diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-04-21 12:11:54 +0800 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-05-26 01:15:33 +0200 |
commit | 04303d8ad06985bed4ea4f46018fc8f55a0962a8 (patch) | |
tree | 1d0c59cb25abf8882c3d8d084f28cb04bd2125fe | |
parent | 3f38495409b613071021fca86629df7ae81820ad (diff) |
ceph: use CEPH_MDS_OP_RMXATTR request to remove xattr
Setxattr with NULL value and XATTR_REPLACE flag should be equivalent
to removexattr. But current MDS does not support deleting vxattrs through
MDS_OP_SETXATTR request. The workaround is sending MDS_OP_RMXATTR request
if setxattr actually removs xattr.
Signed-off-by: Yan, Zheng <zyan@redhat.com>
-rw-r--r-- | fs/ceph/xattr.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 5afabc4bf4c7..426c83cc683a 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -886,6 +886,7 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name, struct ceph_mds_request *req; struct ceph_mds_client *mdsc = fsc->mdsc; struct ceph_pagelist *pagelist = NULL; + int op = CEPH_MDS_OP_SETXATTR; int err; if (size > 0) { @@ -899,20 +900,21 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name, if (err) goto out; } else if (!value) { - flags |= CEPH_XATTR_REMOVE; + if (flags & CEPH_XATTR_REPLACE) + op = CEPH_MDS_OP_RMXATTR; + else + flags |= CEPH_XATTR_REMOVE; } dout("setxattr value=%.*s\n", (int)size, value); /* do request */ - req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, - USE_AUTH_MDS); + req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); if (IS_ERR(req)) { err = PTR_ERR(req); goto out; } - req->r_args.setxattr.flags = cpu_to_le32(flags); req->r_path2 = kstrdup(name, GFP_NOFS); if (!req->r_path2) { ceph_mdsc_put_request(req); @@ -920,8 +922,11 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name, goto out; } - req->r_pagelist = pagelist; - pagelist = NULL; + if (op == CEPH_MDS_OP_SETXATTR) { + req->r_args.setxattr.flags = cpu_to_le32(flags); + req->r_pagelist = pagelist; + pagelist = NULL; + } req->r_inode = inode; ihold(inode); |