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;
|
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,
|
static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
|
||||||
void *buffer, size_t size, int type)
|
void *buffer, size_t size, int type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,11 +17,16 @@
|
||||||
#ifdef CONFIG_9P_FS_POSIX_ACL
|
#ifdef CONFIG_9P_FS_POSIX_ACL
|
||||||
extern int v9fs_get_acl(struct inode *, struct p9_fid *);
|
extern int v9fs_get_acl(struct inode *, struct p9_fid *);
|
||||||
extern int v9fs_check_acl(struct inode *inode, int mask);
|
extern int v9fs_check_acl(struct inode *inode, int mask);
|
||||||
|
extern int v9fs_acl_chmod(struct dentry *);
|
||||||
#else
|
#else
|
||||||
#define v9fs_check_acl NULL
|
#define v9fs_check_acl NULL
|
||||||
static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
|
static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
static inline int v9fs_acl_chmod(struct dentry *dentry)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* FS_9P_XATTR_H */
|
#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);
|
setattr_copy(dentry->d_inode, iattr);
|
||||||
mark_inode_dirty(dentry->d_inode);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче