]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix cap release logic a bit
authorSage Weil <sage@newdream.net>
Wed, 7 Jan 2009 22:11:48 +0000 (14:11 -0800)
committerSage Weil <sage@newdream.net>
Wed, 7 Jan 2009 22:11:48 +0000 (14:11 -0800)
Keep an EXCL bits we have, as long as we have something wanted or
used.

Fix wanted update vs delayed cap release behavior.

src/kernel/caps.c
src/kernel/inode.c

index 96e5b9c49c995e9f07a079919e8bc7041614fc53..1a7f7cd0326fc80c93daa9f8c0b9aa8a09eff2f1 100644 (file)
@@ -727,10 +727,15 @@ retry_locked:
        want = file_wanted | used;
        
        retain = want;
-       if (!mdsc->stopping)
+       if (!mdsc->stopping) {
                retain |= CEPH_CAP_PIN |
                        (S_ISDIR(inode->i_mode) ? CEPH_CAP_ANY_RDCACHE :
                         CEPH_CAP_ANY_RD);
+
+               /* keep any EXCL bits too, while we are holding caps anyway */
+               if (want)
+                       retain |= CEPH_CAP_ANY_EXCL;
+       }
        retain &= ~drop;
 
        dout(10, "check_caps %p file_wanted %s used %s retain %s issued %s\n",
@@ -815,12 +820,9 @@ retry_locked:
                if (!revoking && mdsc->stopping && (used == 0))
                        goto ack;
 
-               /* adjust wanted? */
-               if (cap->mds_wanted != want)
-                       goto ack;
-
-               if ((cap->issued & ~retain) == 0)
-                       continue;     /* nothing extra, all good */
+               if ((cap->issued & ~retain) == 0 &&
+                   cap->mds_wanted == want)
+                       continue;     /* nothing extra, wanted is correct */
 
                /* delay cap release for a bit? */
                if (!is_delayed &&
@@ -1699,10 +1701,12 @@ void ceph_trim_session_rdcaps(struct ceph_mds_session *session)
        struct inode *inode;
        struct ceph_cap *cap;
        struct list_head *p, *n;
-       int wanted, last_cap;
+       int wanted;
 
        dout(10, "trim_rdcaps for mds%d\n", session->s_mds);
        list_for_each_safe(p, n, &session->s_rdcaps) {
+               int last_cap = 0;
+
                cap = list_entry(p, struct ceph_cap, session_rdcaps);
 
                inode = &cap->ci->vfs_inode;
index 8f45fddfcd2820649047274a6df376905b711971..60fc2a8da11b5a922217c2f7a0f75c06afddf998 100644 (file)
@@ -1392,7 +1392,7 @@ static int ceph_setattr_chown(struct dentry *dentry, struct iattr *attr)
 
        spin_lock(&inode->i_lock);
        if (__ceph_caps_issued(ci, NULL) & CEPH_CAP_AUTH_EXCL) {
-               dout(10, " holding auth EXCL, doing locally\n");
+               dout(10, "chown holding auth EXCL, doing locally\n");
                if (ia_valid & ATTR_UID)
                        inode->i_uid = attr->ia_uid;
                if (ia_valid & ATTR_GID)
@@ -1436,7 +1436,7 @@ static int ceph_setattr_chmod(struct dentry *dentry, struct iattr *attr)
 
        spin_lock(&inode->i_lock);
        if (__ceph_caps_issued(ci, NULL) & CEPH_CAP_AUTH_EXCL) {
-               dout(10, " holding auth EXCL, doing locally\n");
+               dout(10, "chmod 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;