From d012119736a89ed96cd9ebb83929d3cc738c426e Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 11 Feb 2014 13:32:23 +0800 Subject: [PATCH] mds: remove xattr when null value is given to setxattr() setxattr() should remove xattr if parameter 'value' is NULL. To distinguish it from the zero-length value case, introduce a new flag CEPH_XATTR_REMOVE for the setxattr request. Signed-off-by: Yan, Zheng --- src/client/Client.cc | 3 +++ src/include/ceph_fs.h | 5 +++-- src/mds/Server.cc | 8 +++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index b336453b2ce..91e27d6c2fe 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -7167,6 +7167,9 @@ int Client::_setxattr(Inode *in, const char *name, const void *value, size_t siz strncmp(name, "ceph.", 5)) return -EOPNOTSUPP; + if (!value) + flags |= CEPH_XATTR_REMOVE; + MetaRequest *req = new MetaRequest(CEPH_MDS_OP_SETXATTR); filepath path; in->make_nosnap_relative_path(path); diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 003f03cd1d8..f075da4e8f0 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -354,8 +354,9 @@ extern const char *ceph_mds_op_name(int op); /* * Ceph setxattr request flags. */ -#define CEPH_XATTR_CREATE 1 -#define CEPH_XATTR_REPLACE 2 +#define CEPH_XATTR_CREATE (1 << 0) +#define CEPH_XATTR_REPLACE (1 << 1) +#define CEPH_XATTR_REMOVE (1 << 31) union ceph_mds_request_args { struct { diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 36c11402840..dd7caf9122f 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -3799,9 +3799,11 @@ void Server::handle_client_setxattr(MDRequest *mdr) pi->ctime = ceph_clock_now(g_ceph_context); pi->xattr_version++; px->erase(name); - (*px)[name] = buffer::create(len); - if (len) - req->get_data().copy(0, len, (*px)[name].c_str()); + if (!(flags & CEPH_XATTR_REMOVE)) { + (*px)[name] = buffer::create(len); + if (len) + req->get_data().copy(0, len, (*px)[name].c_str()); + } // log + wait mdr->ls = mdlog->get_current_segment();