From 818563590cf79e844f3e4985a39d94afdeccde0b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Jan 2009 14:50:26 -0800 Subject: [PATCH] kclient: local chmod/chown if holding CEPH_CAP_AUTH_EXCL --- src/kernel/inode.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/kernel/inode.c b/src/kernel/inode.c index b91a4f7e634e7..83e067e1f8eec 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -1378,6 +1378,7 @@ static struct ceph_mds_request *prepare_setattr(struct ceph_mds_client *mdsc, static int ceph_setattr_chown(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_client *client = ceph_sb_to_client(inode->i_sb); struct ceph_mds_client *mdsc = &client->mdsc; const unsigned int ia_valid = attr->ia_valid; @@ -1386,6 +1387,20 @@ static int ceph_setattr_chown(struct dentry *dentry, struct iattr *attr) int err; int mask = 0; + spin_lock(&inode->i_lock); + if (__ceph_caps_issued(ci, NULL) & CEPH_CAP_AUTH_EXCL) { + dout(10, " holding auth EXCL, doing locally\n"); + if (ia_valid & ATTR_UID) + inode->i_uid = attr->ia_uid; + if (ia_valid & ATTR_GID) + inode->i_uid = attr->ia_gid; + inode->i_ctime = CURRENT_TIME; + ci->i_dirty_caps |= CEPH_CAP_AUTH_EXCL; + spin_unlock(&inode->i_lock); + return 0; + } + spin_unlock(&inode->i_lock); + req = prepare_setattr(mdsc, dentry, ia_valid, CEPH_MDS_OP_LCHOWN); if (IS_ERR(req)) return PTR_ERR(req); @@ -1409,12 +1424,24 @@ static int ceph_setattr_chown(struct dentry *dentry, struct iattr *attr) static int ceph_setattr_chmod(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_client *client = ceph_sb_to_client(inode->i_sb); struct ceph_mds_client *mdsc = &client->mdsc; struct ceph_mds_request *req; struct ceph_mds_request_head *reqh; int err; + spin_lock(&inode->i_lock); + if (__ceph_caps_issued(ci, NULL) & CEPH_CAP_AUTH_EXCL) { + dout(10, " holding auth EXCL, doing locally\n"); + inode->i_mode = attr->ia_mode; + inode->i_ctime = CURRENT_TIME; + ci->i_dirty_caps |= CEPH_CAP_AUTH_EXCL; + spin_unlock(&inode->i_lock); + return 0; + } + spin_unlock(&inode->i_lock); + req = prepare_setattr(mdsc, dentry, attr->ia_valid, CEPH_MDS_OP_LCHMOD); if (IS_ERR(req)) return PTR_ERR(req); -- 2.39.5