fs/9p: Update ACL on chmod
We need update the acl value on chmod Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
This commit is contained in:
Родитель
22d8dcdf8f
Коммит
6e8dc55550
55
fs/9p/acl.c
55
fs/9p/acl.c
|
@ -97,6 +97,61 @@ int v9fs_check_acl(struct inode *inode, int mask)
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl)
|
||||
{
|
||||
int retval;
|
||||
char *name;
|
||||
size_t size;
|
||||
void *buffer;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
set_cached_acl(inode, type, acl);
|
||||
/* Set a setxattr request to server */
|
||||
size = posix_acl_xattr_size(acl->a_count);
|
||||
buffer = kmalloc(size, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
retval = posix_acl_to_xattr(acl, buffer, size);
|
||||
if (retval < 0)
|
||||
goto err_free_out;
|
||||
switch (type) {
|
||||
case ACL_TYPE_ACCESS:
|
||||
name = POSIX_ACL_XATTR_ACCESS;
|
||||
break;
|
||||
case ACL_TYPE_DEFAULT:
|
||||
name = POSIX_ACL_XATTR_DEFAULT;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
retval = v9fs_xattr_set(dentry, name, buffer, size, 0);
|
||||
err_free_out:
|
||||
kfree(buffer);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int v9fs_acl_chmod(struct dentry *dentry)
|
||||
{
|
||||
int retval = 0;
|
||||
struct posix_acl *acl, *clone;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
if (S_ISLNK(inode->i_mode))
|
||||
return -EOPNOTSUPP;
|
||||
acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
|
||||
if (acl) {
|
||||
clone = posix_acl_clone(acl, GFP_KERNEL);
|
||||
posix_acl_release(acl);
|
||||
if (!clone)
|
||||
return -ENOMEM;
|
||||
retval = posix_acl_chmod_masq(clone, inode->i_mode);
|
||||
if (!retval)
|
||||
retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, clone);
|
||||
posix_acl_release(clone);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
|
||||
void *buffer, size_t size, int type)
|
||||
{
|
||||
|
|
|
@ -17,11 +17,16 @@
|
|||
#ifdef CONFIG_9P_FS_POSIX_ACL
|
||||
extern int v9fs_get_acl(struct inode *, struct p9_fid *);
|
||||
extern int v9fs_check_acl(struct inode *inode, int mask);
|
||||
extern int v9fs_acl_chmod(struct dentry *);
|
||||
#else
|
||||
#define v9fs_check_acl NULL
|
||||
static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int v9fs_acl_chmod(struct dentry *dentry)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* FS_9P_XATTR_H */
|
||||
|
|
|
@ -1284,6 +1284,12 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
|
|||
|
||||
setattr_copy(dentry->d_inode, iattr);
|
||||
mark_inode_dirty(dentry->d_inode);
|
||||
if (iattr->ia_valid & ATTR_MODE) {
|
||||
/* We also want to update ACL when we update mode bits */
|
||||
retval = v9fs_acl_chmod(dentry);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче