]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: reworked cap-related locking, now protected by i_lock
authorSage Weil <sage@newdream.net>
Mon, 31 Mar 2008 19:05:25 +0000 (12:05 -0700)
committerSage Weil <sage@newdream.net>
Mon, 31 Mar 2008 19:05:25 +0000 (12:05 -0700)
src/kernel/dir.c
src/kernel/file.c
src/kernel/inode.c
src/kernel/mds_client.c
src/kernel/mds_client.h
src/kernel/super.c
src/kernel/super.h

index f92990e392c40a5ef6642b4636d6c49286520377..ab8036f67a49edb999df562bede52ffd16a78501 100644 (file)
@@ -487,38 +487,49 @@ static int ceph_dir_rename(struct inode *old_dir, struct dentry *old_dentry,
        return err;
 }
 
+/*
+ * check if dentry lease, or parent directory inode lease or cap says
+ * this dentry is still valid
+ */
 static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
-       int mds = (long)dentry->d_fsdata;
        struct inode *dir = dentry->d_parent->d_inode;
        struct ceph_inode_info *dirci = ceph_inode(dir);
+       struct ceph_dentry_info *di;
 
-       dout(20, "d_revalidate ttl %lu mds %d now %lu\n", dentry->d_time, 
-            mds, jiffies);
-       
        /* does dir inode lease or cap cover it? */
+       spin_lock(&dirci->vfs_inode.i_lock);
        if (dirci->i_lease_session &&
            time_after(dirci->i_lease_ttl, jiffies) &&
            (dirci->i_lease_mask & CEPH_LOCK_ICONTENT)) {
                dout(20, "d_revalidate have ICONTENT on dir inode %p, ok\n",
                     dir);
-               return 1;
+               goto inode_ok;
        }
-       if (ceph_caps_issued(dirci) & (CEPH_CAP_EXCL|CEPH_CAP_RDCACHE)) {
+       if (__ceph_caps_issued(dirci) & (CEPH_CAP_EXCL|CEPH_CAP_RDCACHE)) {
                dout(20, "d_revalidate have EXCL|RDCACHE caps on dir inode %p"
                     ", ok\n", dir);
-               return 1;
+               goto inode_ok;
        }
+       spin_unlock(&dirci->vfs_inode.i_lock);
 
        /* dentry lease? */
-       if (mds >= 0 && time_after(dentry->d_time, jiffies)) {
+       spin_lock(&dentry->d_lock);
+       di = ceph_dentry(dentry);
+       if (di && time_after(dentry->d_time, jiffies)) {
                dout(20, "d_revalidate - dentry %p lease valid\n", dentry);
+               spin_unlock(&dentry->d_lock);
                return 1;
        }
+       spin_unlock(&dentry->d_lock);
 
        dout(20, "d_revalidate - dentry %p expired\n", dentry);
        d_drop(dentry);
        return 0;
+
+inode_ok:
+       spin_unlock(&dirci->vfs_inode.i_lock);
+       return 1;
 }
 
 static void ceph_d_release(struct dentry *dentry)
index 97a65c59d91f231840731a5fbb06964bf6ef167a..3831a6245d965d597bb3a24d3da12fedf2127e11 100644 (file)
@@ -54,24 +54,14 @@ static int ceph_init_file(struct inode *inode, struct file *file,
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_file_info *cf;
        int mode = ceph_file_mode(flags);
-       int wanted;
 
        cf = kzalloc(sizeof(*cf), GFP_KERNEL);
        if (cf == NULL)
                return -ENOMEM;
        file->private_data = cf;
 
-       spin_lock(&inode->i_lock);
        cf->mode = mode;
-       ci->i_nr_by_mode[mode]++;
-       wanted = ceph_caps_wanted(ci);
-       dout(10, "init_file %p flags 0%o mode %d nr now %d.  wanted %d -> %d\n",
-            file, flags,
-            mode, ci->i_nr_by_mode[mode], 
-            ci->i_cap_wanted, ci->i_cap_wanted|wanted);
-       ci->i_cap_wanted |= wanted;   /* FIXME this isn't quite right */
-       spin_unlock(&inode->i_lock);
-
+       ceph_get_mode(ci, mode);
        return 0;
 }
 
@@ -95,11 +85,6 @@ int ceph_open(struct inode *inode, struct file *file)
                return 0;
        }
 
-       /*
-       if (file->f_flags == O_DIRECTORY && ... )
-               cap = ceph_find_cap(inode, 0);
-       */
-
        req = prepare_open_request(inode->i_sb, dentry, flags, 0);
        if (IS_ERR(req))
                return PTR_ERR(req);
@@ -158,8 +143,6 @@ int ceph_release(struct inode *inode, struct file *file)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_file_info *cf = file->private_data;
-       int mode = cf->mode;
-       int wanted;
 
        dout(5, "release inode %p file %p\n", inode, file);
 
@@ -172,16 +155,8 @@ int ceph_release(struct inode *inode, struct file *file)
         *   ceph_file: released 000000006fa3ebd0 flags 0100001 mode 3 nr now -1.  wanted 30 was 30
         * for now, store the open mode in ceph_file_info.
         */
-       mode = cf->mode;
-       ci->i_nr_by_mode[mode]--;
-       wanted = ceph_caps_wanted(ci);
-       dout(10, "released %p flags 0%o mode %d nr now %d, wanted %d -> %d\n",
-            file, file->f_flags, mode, 
-            ci->i_nr_by_mode[mode], wanted, ci->i_cap_wanted);
-       wanted |= ceph_caps_used(ci);
-       if (wanted != ci->i_cap_wanted)
-               ceph_mdsc_update_cap_wanted(ci, wanted);
-       
+
+       ceph_put_mode(ci, cf->mode);
        if (cf->last_readdir)
                ceph_mdsc_put_request(cf->last_readdir);
        kfree(cf);
index 6ad935ca13236e260ebe8ce1468302b5656db645..abb24b30b468c455c88d8be381eede60f4f12dd2 100644 (file)
@@ -81,7 +81,7 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info)
        /* be careful with mtime, atime, size */
        ceph_decode_timespec(&atime, &info->atime);
        ceph_decode_timespec(&mtime, &info->mtime);
-       issued = ceph_caps_issued(ci);
+       issued = __ceph_caps_issued(ci);
        spin_lock(&inode->i_lock);
        if (issued & (CEPH_CAP_WR|CEPH_CAP_WRBUFFER)) {
                if ((issued & CEPH_CAP_EXCL) == 0) {
@@ -225,7 +225,10 @@ void ceph_update_inode_lease(struct inode *inode,
 void ceph_revoke_inode_lease(struct ceph_inode_info *ci, int mask)
 {
        int drop = 0;
+
        spin_lock(&ci->vfs_inode.i_lock);
+       dout(10, "revoke_inode_lease on inode %p, mask %d -> %d\n", 
+            &ci->vfs_inode, ci->i_lease_mask, ci->i_lease_mask & ~mask);
        ci->i_lease_mask &= ~mask;
        if (ci->i_lease_mask == 0) {
                spin_lock(&ci->i_lease_session->s_cap_lock);
@@ -241,6 +244,7 @@ void ceph_revoke_inode_lease(struct ceph_inode_info *ci, int mask)
        }
 }
 
+
 /*
  * dentry lease lock order is
  *     dentry->d_lock
@@ -558,24 +562,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req)
  * capabilities
  */
 
-struct ceph_inode_cap *ceph_find_cap(struct inode *inode, int want)
-{
-       struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_inode_cap *cap;
-       struct list_head *p;
-
-       list_for_each(p, &ci->i_caps) {
-               cap = list_entry(p, struct ceph_inode_cap, ci_caps);
-               if ((cap->caps & want) == want) {
-                       dout(40, "find_cap found %p caps %d want %d\n", cap, 
-                            cap->caps, want);
-                       return cap;
-               }
-       }
-       return 0;
-}
-
-static struct ceph_inode_cap *get_cap_for_mds(struct inode *inode, int mds)
+static struct ceph_inode_cap *__get_cap_for_mds(struct inode *inode, int mds)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_inode_cap *cap;
@@ -589,37 +576,53 @@ static struct ceph_inode_cap *get_cap_for_mds(struct inode *inode, int mds)
        return 0;
 }
 
-
-struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session *session, u32 caps, u32 seq)
+/*
+ * lock ordering is
+ *    inode->i_lock
+ *         session->s_cap_lock
+ */
+struct ceph_inode_cap *ceph_add_cap(struct inode *inode,
+                                   struct ceph_mds_session *session, 
+                                   u32 caps, u32 seq)
 {
        int mds = session->s_mds;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_inode_cap *cap;
+       struct ceph_inode_cap *cap, *new_cap = 0;
        int i;
+       int is_new = 0;
 
-       dout(10, "ceph_add_cap on %p mds%d cap %d seq %d\n", inode, session->s_mds, caps, seq);
-       cap = get_cap_for_mds(inode, mds);
+       dout(10, "ceph_add_cap on %p mds%d cap %d seq %d\n", inode,
+            session->s_mds, caps, seq);
+       spin_lock(&inode->i_lock);
+       cap = __get_cap_for_mds(inode, mds);
        if (!cap) {
                for (i=0; i<STATIC_CAPS; i++)
                        if (ci->i_static_caps[i].mds == -1) {
                                cap = &ci->i_static_caps[i];
                                break;
                        }
-               if (!cap)
-                       cap = kmalloc(sizeof(*cap), GFP_KERNEL);
-               if (cap == 0)
-                       return ERR_PTR(-ENOMEM);
+               if (!cap) {
+                       if (new_cap)
+                               cap = new_cap;
+                       else {
+                               spin_unlock(&inode->i_lock);
+                               new_cap = kmalloc(sizeof(*cap), GFP_KERNEL);
+                               if (new_cap == 0)
+                                       return ERR_PTR(-ENOMEM);
+                               spin_lock(&inode->i_lock);
+                       }
+               }
                
+               is_new = 1;    /* grab inode later */
                cap->caps = 0;
                cap->mds = mds;
                cap->seq = 0;
                cap->flags = 0;
                
-               if (list_empty(&ci->i_caps))
-                       igrab(inode);
                cap->ci = ci;
                list_add(&cap->ci_caps, &ci->i_caps);
 
+               /* add to session cap list */
                cap->session = session;
                spin_lock(&session->s_cap_lock);
                list_add(&cap->session_caps, &session->s_caps);
@@ -631,10 +634,13 @@ struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session
             inode, ceph_ino(inode), caps, caps|cap->caps, seq, mds);
        cap->caps |= caps;
        cap->seq = seq;
+       spin_unlock(&inode->i_lock);
+       if (is_new)
+               igrab(inode);
        return cap;
 }
 
-int ceph_caps_issued(struct ceph_inode_info *ci)
+int __ceph_caps_issued(struct ceph_inode_info *ci)
 {
        int have = 0;
        struct ceph_inode_cap *cap;
@@ -647,49 +653,121 @@ int ceph_caps_issued(struct ceph_inode_info *ci)
        return have;
 }
 
-void ceph_remove_cap(struct ceph_inode_cap *cap)
+void __ceph_remove_cap(struct ceph_inode_cap *cap)
 {
        struct ceph_mds_session *session = cap->session;
-       struct ceph_inode_info *ci = cap->ci;
 
-       dout(10, "ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
+       dout(10, "__ceph_remove_cap %p from %p\n", cap, &cap->ci->vfs_inode);
 
        /* remove from session list */
        spin_lock(&session->s_cap_lock);
        list_del(&cap->session_caps);
        session->s_nr_caps--;
-       cap->session = 0;
        spin_unlock(&session->s_cap_lock);
 
        /* remove from inode list */
-       spin_lock(&ci->vfs_inode.i_lock);
        list_del(&cap->ci_caps);
-       if (list_empty(&ci->i_caps))
-               iput(&ci->vfs_inode);
-       cap->ci = 0;
+       cap->session = 0;
        cap->mds = -1;  /* mark unused */
-       spin_unlock(&ci->vfs_inode.i_lock);
                
-       if (cap < ci->i_static_caps || cap >= ci->i_static_caps + STATIC_CAPS) 
+       if (cap < cap->ci->i_static_caps || 
+           cap >= cap->ci->i_static_caps + STATIC_CAPS) 
                kfree(cap);
 }
 
-void ceph_remove_all_caps(struct ceph_inode_info *ci)
+void ceph_remove_cap(struct ceph_inode_cap *cap)
 {
+       struct inode *inode = &cap->ci->vfs_inode;
+
+       spin_lock(&inode->i_lock);
+       __ceph_remove_cap(cap);
+       spin_unlock(&inode->i_lock);
+       iput(inode);
+}
+
+/*
+ * examine currently wanted versus held caps, and release caps to mds
+ * as appropriate.
+ */
+void ceph_check_caps_wanted(struct ceph_inode_info *ci)
+{
+       struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode);
+       struct ceph_mds_client *mdsc = &client->mdsc;
        struct ceph_inode_cap *cap;
-       dout(10, "remove_caps on %p\n", &ci->vfs_inode);
-       while (!list_empty(&ci->i_caps)) {
-               cap = list_entry(ci->i_caps.next, struct ceph_inode_cap,
-                                ci_caps);
-               ceph_remove_cap(cap);
+       struct list_head *p;
+       int wanted;
+       int keep;
+       __u64 seq;
+       __u64 size, max_size;
+       struct timespec mtime, atime;
+       int mds;
+
+retry:
+       spin_lock(&ci->vfs_inode.i_lock);
+       wanted = __ceph_caps_wanted(ci);
+
+       list_for_each(p, &ci->i_caps) {
+               cap = list_entry(p, struct ceph_inode_cap, ci_caps);
+               if ((cap->caps & ~wanted) == 0)
+                       continue;     /* nothing extra, all good */
+
+               cap->caps &= wanted;  /* drop bits we don't want */
+
+               keep = cap->caps;
+               seq = cap->seq;
+               size = ci->vfs_inode.i_size;
+               max_size = ci->i_max_size;
+               mtime = ci->vfs_inode.i_mtime;
+               atime = ci->vfs_inode.i_atime;
+               mds = cap->mds;
+               if (wanted == 0)
+                       __ceph_remove_cap(cap);
+               spin_unlock(&ci->vfs_inode.i_lock);
+
+               ceph_mdsc_send_cap_ack(mdsc, ceph_ino(&ci->vfs_inode), 
+                                      keep, wanted, seq, 
+                                      size, max_size, &mtime, &atime, mds);
+
+               if (wanted == 0)
+                       iput(&ci->vfs_inode);  /* removed cap */
+               goto retry;
        }
+
+       /* okay */
+       spin_unlock(&ci->vfs_inode.i_lock);
 }
 
+/*
+ * called on struct file init and release, to safely track which
+ * capabilities we want due to currently open files
+ */
+void ceph_get_mode(struct ceph_inode_info *ci, int mode)
+{
+       spin_lock(&ci->vfs_inode.i_lock);
+       ci->i_nr_by_mode[mode]++;
+       spin_unlock(&ci->vfs_inode.i_lock);
+}
+
+void ceph_put_mode(struct ceph_inode_info *ci, int mode)
+{
+       int last = 0;
+
+       spin_lock(&ci->vfs_inode.i_lock);
+       if (--ci->i_nr_by_mode[mode] == 0)
+               last++;
+       spin_unlock(&ci->vfs_inode.i_lock);
+
+       if (last)
+               ceph_check_caps_wanted(ci);
+}
+
+
 /*
  * 0 - ok
  * 1 - send the msg back to mds
  */
-int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, struct ceph_mds_session *session)
+int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant,
+                         struct ceph_mds_session *session)
 {
        struct ceph_inode_cap *cap;
        struct ceph_inode_info *ci = ceph_inode(inode);
@@ -698,7 +776,7 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant,
        int newcaps;
        int used;
        int issued; /* to me, before */
-       int wanted = ceph_caps_wanted(ci) | ceph_caps_used(ci);
+       int wanted;
        int ret = 0;
        u64 size = le64_to_cpu(grant->size);
        u64 max_size = le64_to_cpu(grant->max_size);
@@ -707,7 +785,6 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant,
        
        dout(10, "handle_cap_grant inode %p ci %p mds%d seq %d\n", 
             inode, ci, mds, seq);
-       dout(10, " my wanted = %d\n", wanted);
        dout(10, " size %llu max_size %llu\n", size, max_size);
 
        /* size change? */
@@ -724,7 +801,7 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant,
        }
 
        /* mtime/atime? */
-       issued = ceph_caps_issued(ci);
+       issued = __ceph_caps_issued(ci);
        if ((issued & CEPH_CAP_EXCL) == 0) {
                ceph_decode_timespec(&mtime, &grant->mtime);
                ceph_decode_timespec(&atime, &grant->atime);
@@ -742,9 +819,8 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant,
                }
        }
 
-       cap = get_cap_for_mds(inode, mds);
-
        /* do we have this cap? */
+       cap = __get_cap_for_mds(inode, mds);
        if (!cap) {
                /*
                 * then ignore.  never reply to cap messages out of turn,
@@ -756,20 +832,21 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant,
                goto out;
        } 
 
-       cap->seq = seq;
-
+       wanted = __ceph_caps_wanted(ci);
+       used = __ceph_caps_used(ci);
+       dout(10, " my wanted = %d, used = %d\n", wanted, used);
        if (wanted != le32_to_cpu(grant->wanted)) {
-               dout(10, "wanted %d -> %d\n", le32_to_cpu(grant->wanted), 
+               dout(10, "mds wanted %d -> %d\n", le32_to_cpu(grant->wanted), 
                     wanted);
                grant->wanted = cpu_to_le32(wanted);
        }
 
+       cap->seq = seq;
+
        /* revocation? */
        newcaps = le32_to_cpu(grant->caps);
        if (cap->caps & ~newcaps) {
-               used = ceph_caps_used(ci);
-               dout(10, "revocation: %d -> %d, used %d\n", cap->caps,
-                    newcaps, used);
+               dout(10, "revocation: %d -> %d\n", cap->caps, newcaps);
                if (newcaps & used) {
                        /* FIXME FIXME FIXME DO STUFF HERE */
                        /* but blindly ack for now... */
@@ -835,7 +912,7 @@ int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got)
        dout(10, "get_cap_refs on %p need %d want %d\n", &ci->vfs_inode,
             need, want);
        spin_lock(&ci->vfs_inode.i_lock);
-       have = ceph_caps_issued(ci);
+       have = __ceph_caps_issued(ci);
        if ((have & need) == need) {
                *got = need | (have & want);
                __take_cap_refs(ci, *got);
@@ -849,7 +926,7 @@ int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got)
 
 void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
 {
-       int last = 0, wanted;
+       int last = 0;
 
        spin_lock(&ci->vfs_inode.i_lock);
        if (had & CEPH_CAP_RD)
@@ -866,12 +943,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
                        last++;
        spin_unlock(&ci->vfs_inode.i_lock);
 
-       if (last) {
-               wanted = ceph_caps_wanted(ci);
-               wanted |= ceph_caps_used(ci);
-               if (wanted != ci->i_cap_wanted)
-                       ceph_mdsc_update_cap_wanted(ci, wanted);
-       }
+       if (last) 
+               ceph_check_caps_wanted(ci);
 }
 
 
@@ -988,7 +1061,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
            ((ia_valid & ATTR_MTIME) && 
             !timespec_equal(&inode->i_mtime, &attr->ia_mtime))) {
                /* do i hold CAP_EXCL? */
-               if (ceph_caps_issued(ci) & CEPH_CAP_EXCL) {
+               if (__ceph_caps_issued(ci) & CEPH_CAP_EXCL) {
                        dout(10, "utime holding EXCL, doing nothing\n");
                        inode->i_atime = attr->ia_atime;
                        inode->i_mtime = attr->ia_mtime;
@@ -1036,16 +1109,21 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 int ceph_inode_revalidate(struct inode *inode, int mask)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       int havemask = ci->i_lease_mask;
+       int havemask;
+       int valid;
 
+       spin_lock(&inode->i_lock);
+       havemask = ci->i_lease_mask;
        /* EXCL cap counts for an ICONTENT lease */
-       if (ceph_caps_issued(ci) & CEPH_CAP_EXCL)
+       if (__ceph_caps_issued(ci) & CEPH_CAP_EXCL)
                havemask |= CEPH_LOCK_ICONTENT;
        /* any ICONTENT bits imply all bits */
        if (havemask & CEPH_LOCK_ICONTENT)  
                havemask |= CEPH_LOCK_ICONTENT;
-       
-       if (time_before(jiffies, ci->i_lease_ttl)) {
+       valid = time_before(jiffies, ci->i_lease_ttl);
+       spin_unlock(&inode->i_lock);
+
+       if (valid) {    
                if ((havemask & mask) == mask) {
                        dout(10, "inode_revalidate %p mask %d still valid\n", 
                             inode, mask);
@@ -1056,8 +1134,8 @@ int ceph_inode_revalidate(struct inode *inode, int mask)
        } else {
                dout(10, "inode_revalidate %p have %d want %d, lease expired\n",
                     inode, havemask, mask);
-               ceph_revoke_inode_lease(ci, mask);
        }
+
        return ceph_do_lookup(inode->i_sb, d_find_alias(inode), mask);
 }
 
index 50c0754839d68853a989b56b081f0e3820275778..e56dc25d56558e89ae2ee9410a0964052a3bc625 100644 (file)
@@ -607,13 +607,11 @@ static void remove_session_caps(struct ceph_mds_session *session)
                cap = list_entry(session->s_caps.next, struct ceph_inode_cap,
                                 session_caps);
                ci = cap->ci;
-               igrab(&ci->vfs_inode);
                dout(10, "removing cap %p, ci is %p, inode is %p\n",
                     cap, ci, &ci->vfs_inode);
                spin_unlock(&session->s_cap_lock);
                ceph_remove_cap(cap);
                spin_lock(&session->s_cap_lock);
-               iput(&ci->vfs_inode);
        }
        BUG_ON(session->s_nr_caps > 0);
        spin_unlock(&session->s_cap_lock);
@@ -1127,11 +1125,13 @@ retry:
                rec = p;
                p += sizeof(*rec);
                BUG_ON(p > end);
-               rec->wanted = cpu_to_le32(ceph_caps_wanted(ci));
-               rec->issued = cpu_to_le32(ceph_caps_issued(ci));
+               spin_lock(&ci->vfs_inode.i_lock);
+               rec->wanted = cpu_to_le32(__ceph_caps_wanted(ci));
+               rec->issued = cpu_to_le32(__ceph_caps_issued(ci));
                rec->size = cpu_to_le64(ci->vfs_inode.i_size);
                ceph_encode_timespec(&rec->mtime, &ci->vfs_inode.i_mtime);
                ceph_encode_timespec(&rec->atime, &ci->vfs_inode.i_atime);
+               spin_unlock(&ci->vfs_inode.i_lock);
                dentry = d_find_alias(&ci->vfs_inode);
                path = ceph_build_dentry_path(dentry, &pathlen);
                if (IS_ERR(path)) {
@@ -1236,10 +1236,10 @@ void check_new_map(struct ceph_mds_client *mdsc,
 
 /* caps */
 
-void send_cap_ack(struct ceph_mds_client *mdsc, __u64 ino, int caps,
-                 int wanted, __u32 seq, __u64 size, __u64 max_size, 
-                 struct timespec *mtime, struct timespec *atime,
-                 int mds)
+void ceph_mdsc_send_cap_ack(struct ceph_mds_client *mdsc, __u64 ino, int caps,
+                           int wanted, __u32 seq, __u64 size, __u64 max_size, 
+                           struct timespec *mtime, struct timespec *atime,
+                           int mds)
 {
        struct ceph_mds_file_caps *fc;
        struct ceph_msg *msg;
@@ -1323,7 +1323,8 @@ void ceph_mdsc_handle_filecaps(struct ceph_mds_client *mdsc,
        if (!inode) {
                dout(10, "wtf, i don't have ino %lu=%llx?  closing out cap\n",
                     inot, ino);
-               send_cap_ack(mdsc, ino, 0, 0, seq, size, max_size, 0, 0, mds);
+               ceph_mdsc_send_cap_ack(mdsc, ino, 0, 0, seq, 
+                                      size, max_size, 0, 0, mds);
                return;
        }
 
@@ -1353,36 +1354,6 @@ bad:
        return;
 }
 
-int ceph_mdsc_update_cap_wanted(struct ceph_inode_info *ci, int wanted)
-{
-       struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode);
-       struct ceph_mds_client *mdsc = &client->mdsc;
-       struct ceph_inode_cap *cap;
-       struct ceph_mds_session *session;
-       struct list_head *p;
-
-       dout(10, "update_cap_wanted %d -> %d\n", ci->i_cap_wanted, wanted);
-
-       list_for_each(p, &ci->i_caps) {
-               cap = list_entry(p, struct ceph_inode_cap, ci_caps);
-
-               session = __get_session(mdsc, cap->mds);
-               BUG_ON(!session);
-
-               cap->caps &= wanted;  /* drop caps we don't want */
-               send_cap_ack(mdsc, ceph_ino(&ci->vfs_inode), cap->caps, wanted,
-                            cap->seq, ci->vfs_inode.i_size, ci->i_max_size,
-                            &ci->vfs_inode.i_mtime, &ci->vfs_inode.i_atime, 
-                            cap->mds);
-       }
-
-       ci->i_cap_wanted = wanted;
-       if (wanted == 0)
-               ceph_remove_all_caps(ci);
-
-       return 0;
-}
-
 int send_renewcaps(struct ceph_mds_client *mdsc, int mds)
 {
        struct ceph_msg *msg;
@@ -1454,11 +1425,7 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
 
        /* inode */
        ci = ceph_inode(inode);
-       if (mask & ci->i_lease_mask) {
-               ceph_revoke_inode_lease(ci, mask);
-               dout(10, "lease mask %d revoked on inode %p, still have %d\n", 
-                    mask, inode, ci->i_lease_mask);
-       }
+       ceph_revoke_inode_lease(ci, mask);
 
        /* dentry */
        if (mask & CEPH_LOCK_DN) {
index 479d3a427a98830178d1b78f5051223094c01b0f..1d3a9cbb2ba1896703d1d2f24f95ac50cc7d91eb 100644 (file)
@@ -125,8 +125,6 @@ extern void ceph_mdsc_handle_forward(struct ceph_mds_client *mdsc,
 
 extern void ceph_mdsc_handle_filecaps(struct ceph_mds_client *mdsc,
                                      struct ceph_msg *msg);
-struct ceph_inode_info;
-extern int ceph_mdsc_update_cap_wanted(struct ceph_inode_info *ci, int wanted);
 
 extern void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc,
                                   struct ceph_msg *msg);
@@ -143,4 +141,11 @@ extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
                                struct ceph_mds_request *req);
 extern void ceph_mdsc_put_request(struct ceph_mds_request *req);
 
+extern void ceph_mdsc_send_cap_ack(struct ceph_mds_client *mdsc, __u64 ino, 
+                                  int caps, int wanted, __u32 seq, 
+                                  __u64 size, __u64 max_size, 
+                                  struct timespec *mtime, 
+                                  struct timespec *atime,
+                                  int mds);
+       
 #endif
index 110e3451da9ac898acdc6a18af0119a92de4fd83..a32ab1b244c8acd6c0cc9c54f2faa8a646a55b9a 100644 (file)
@@ -128,7 +128,6 @@ static struct inode *ceph_alloc_inode(struct super_block *sb)
                ci->i_static_caps[i].mds = -1;
        for (i = 0; i < 4; i++)
                ci->i_nr_by_mode[i] = 0;
-       ci->i_cap_wanted = 0;
        init_waitqueue_head(&ci->i_cap_wq);
 
        ci->i_rd_ref = ci->i_rdcache_ref = 0;
index bc0499babd1b89352843a5b3f06d89733afc2dd8..ef7f13123a87c6554a67f9922d6c44b8c12d93f1 100644 (file)
@@ -231,9 +231,23 @@ static inline int ceph_ino_compare(struct inode *inode, void *data)
 /*
  * caps helpers
  */
-extern int ceph_caps_issued(struct ceph_inode_info *ci);
+extern int __ceph_caps_issued(struct ceph_inode_info *ci);
 
-static inline int ceph_caps_wanted(struct ceph_inode_info *ci)
+static inline int __ceph_caps_used(struct ceph_inode_info *ci)
+{
+       int used = 0;
+       if (ci->i_rd_ref)
+               used |= CEPH_CAP_RD;
+       if (ci->i_rdcache_ref)
+               used |= CEPH_CAP_RDCACHE;
+       if (ci->i_wr_ref)
+               used |= CEPH_CAP_WR;
+       if (ci->i_wrbuffer_ref)
+               used |= CEPH_CAP_WRBUFFER;
+       return used;
+}
+
+static inline int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
 {
        int want = 0;
        if (ci->i_nr_by_mode[0])
@@ -249,18 +263,9 @@ static inline int ceph_caps_wanted(struct ceph_inode_info *ci)
        return want;
 }
 
-static inline int ceph_caps_used(struct ceph_inode_info *ci)
+static inline int __ceph_caps_wanted(struct ceph_inode_info *ci)
 {
-       int used = 0;
-       if (ci->i_rd_ref)
-               used |= CEPH_CAP_RD;
-       if (ci->i_rdcache_ref)
-               used |= CEPH_CAP_RDCACHE;
-       if (ci->i_wr_ref)
-               used |= CEPH_CAP_WR;
-       if (ci->i_wrbuffer_ref)
-               used |= CEPH_CAP_WRBUFFER;
-       return used;
+       return __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
 }
 
 static inline int ceph_file_mode(int flags)
@@ -343,7 +348,6 @@ extern void ceph_update_dentry_lease(struct dentry *dentry,
                                     struct ceph_mds_session *session,
                                     unsigned long from_time);
 
-extern struct ceph_inode_cap *ceph_find_cap(struct inode *inode, int want);
 extern struct ceph_inode_cap *ceph_add_cap(struct inode *inode,
                                           struct ceph_mds_session *session,
                                           u32 cap, u32 seq);
@@ -357,6 +361,9 @@ extern int ceph_handle_cap_trunc(struct inode *inode,
                                 struct ceph_mds_session *session);
 extern int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got);
 extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
+extern void ceph_check_caps_wanted(struct ceph_inode_info *ci);
+extern void ceph_get_mode(struct ceph_inode_info *ci, int mode);
+extern void ceph_put_mode(struct ceph_inode_info *ci, int mode);
 
 extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
 extern int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,