]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: invalidate pages outside i_lock; carry inode ref for delayed work
authorSage Weil <sage@newdream.net>
Wed, 16 Apr 2008 02:41:27 +0000 (19:41 -0700)
committerSage Weil <sage@newdream.net>
Wed, 16 Apr 2008 02:41:27 +0000 (19:41 -0700)
src/kernel/dir.c
src/kernel/inode.c
src/kernel/mds_client.c
src/kernel/super.c
src/psim.cc

index 7689bf7431650a6bd6a8d223c6cb961e53134b3c..d5e5a90ca267149e71555526697a41502db3c130 100644 (file)
@@ -511,6 +511,8 @@ static int ceph_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *dir = dentry->d_parent->d_inode;
 
+       dout(10, "nd flags %d chdir=%d\n", nd->flags, nd->flags & LOOKUP_CHDIR);
+
        if (ceph_inode_lease_valid(dir, CEPH_LOCK_ICONTENT)) {
                dout(20, "dentry_revalidate %p have ICONTENT on dir inode %p\n",
                     dentry, dir);
index 9daee6381b8408449901c97b335aa2cff4575ded..0c3905ddb42ef73746fd1d9773dcf53c02105bb9 100644 (file)
@@ -763,15 +763,19 @@ void ceph_cap_delayed_work(struct work_struct *work)
                                                  i_cap_dwork.work);
        spin_lock(&ci->vfs_inode.i_lock);
        if (ci->i_hold_caps_until > jiffies) {
-               dout(10, "cap_dwork on %p -- rescheduling\n", &ci->vfs_inode);
-               schedule_delayed_work(&ci->i_cap_dwork, 
-                                     ci->i_hold_caps_until - jiffies);
+               dout(-10, "cap_dwork on %p -- rescheduling\n", &ci->vfs_inode);
+               if (schedule_delayed_work(&ci->i_cap_dwork, 
+                                         ci->i_hold_caps_until - jiffies))
+                       igrab(&ci->vfs_inode);
                spin_unlock(&ci->vfs_inode.i_lock);
-               return;
+               goto out;
        }
-       dout(10, "cap_dwork on %p\n", &ci->vfs_inode);
+       dout(-10, "cap_dwork on %p\n", &ci->vfs_inode);
        spin_unlock(&ci->vfs_inode.i_lock);
        ceph_check_caps(ci, 0);
+out:
+       iput(&ci->vfs_inode);
+       dout(-10, "cap_dwork on %p done\n", &ci->vfs_inode);
 }
 
 /*
@@ -783,6 +787,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int was_last)
 {
        struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode);
        struct ceph_mds_client *mdsc = &client->mdsc;
+       struct inode *inode = &ci->vfs_inode;
        struct ceph_inode_cap *cap;
        struct list_head *p;
        int wanted, used;
@@ -794,10 +799,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int was_last)
        struct ceph_mds_session *session = 0;  /* if non-NULL, i hold s_mutex */
 
 retry:
-       spin_lock(&ci->vfs_inode.i_lock);
+       spin_lock(&inode->i_lock);
        wanted = __ceph_caps_wanted(ci);
        used = __ceph_caps_used(ci);
-       dout(10, "check_caps %p wanted %d used %d issued %d\n", &ci->vfs_inode, 
+       dout(10, "check_caps %p wanted %d used %d issued %d\n", inode, 
             wanted, used, __ceph_caps_issued(ci));
 
        if (was_last) {
@@ -805,8 +810,9 @@ retry:
                if (until > ci->i_hold_caps_until) {
                        ci->i_hold_caps_until = until;
                        dout(10, "hold_caps_until %lu\n", until);
-                       schedule_delayed_work(&ci->i_cap_dwork, 
-                                             until - jiffies);
+                       if (schedule_delayed_work(&ci->i_cap_dwork, 
+                                                 until - jiffies))
+                               igrab(inode);
                }
        }
 
@@ -830,7 +836,7 @@ retry:
 
                /* approaching file_max? */
                if ((cap->issued & CEPH_CAP_WR) &&
-                   (ci->vfs_inode.i_size << 1) >= ci->i_max_size &&
+                   (inode->i_size << 1) >= ci->i_max_size &&
                    (ci->i_reported_size << 1) < ci->i_max_size) {
                        dout(10, "i_size approaching max_size\n");
                        goto ack;
@@ -856,7 +862,7 @@ retry:
                        session = cap->session;
                        if (down_trylock(&session->s_mutex) != 0) {
                                dout(10, "inverting session/inode locking\n");
-                               spin_unlock(&ci->vfs_inode.i_lock);
+                               spin_unlock(&inode->i_lock);
                                down(&session->s_mutex);
                                goto retry;
                        }
@@ -864,10 +870,6 @@ retry:
 
                /* ok */
                dropping = cap->issued & ~wanted;
-               if (dropping & CEPH_CAP_RDCACHE) {
-                       dout(20, "invalidating pages on %p\n", &ci->vfs_inode);
-                       invalidate_mapping_pages(&ci->vfs_inode.i_data, 0, -1);
-               }
                cap->issued &= wanted;  /* drop bits we don't want */
 
                if (revoking && (revoking && used) == 0) 
@@ -875,29 +877,35 @@ retry:
                
                keep = cap->issued;
                seq = cap->seq;
-               size = ci->vfs_inode.i_size;
+               size = inode->i_size;
                ci->i_reported_size = size;
                max_size = ci->i_wanted_max_size;
                ci->i_requested_max_size = max_size;
-               mtime = ci->vfs_inode.i_mtime;
-               atime = ci->vfs_inode.i_atime;
+               mtime = inode->i_mtime;
+               atime = inode->i_atime;
                mds = cap->mds;
                if (wanted == 0)
                        __ceph_remove_cap(cap);
-               spin_unlock(&ci->vfs_inode.i_lock);
+               spin_unlock(&inode->i_lock);
 
-               ceph_mdsc_send_cap_ack(mdsc, ceph_ino(&ci->vfs_inode), 
+               if (dropping & CEPH_CAP_RDCACHE) {
+                       dout(20, "invalidating pages on %p\n", inode);
+                       invalidate_mapping_pages(&inode->i_data, 0, -1);
+                       dout(20, "done invalidating pages on %p\n", inode);
+               }
+
+               ceph_mdsc_send_cap_ack(mdsc, ceph_ino(inode), 
                                       keep, wanted, seq, 
                                       size, max_size, &mtime, &atime, mds);
 
                if (wanted == 0)
-                       iput(&ci->vfs_inode);  /* removed cap */
+                       iput(inode);  /* removed cap */
                up(&session->s_mutex);
                goto retry;
        }
 
        /* okay */
-       spin_unlock(&ci->vfs_inode.i_lock);
+       spin_unlock(&inode->i_lock);
 
        if (session)
                up(&session->s_mutex);
index 5ca332b0a16c9dfbf96cb9f546f7b5951b155f9c..3403b56689bbda91d7c0ca89a87e594099a98fc2 100644 (file)
@@ -656,7 +656,7 @@ void ceph_mdsc_handle_session(struct ceph_mds_client *mdsc,
        session = __get_session(mdsc, mds);
        down(&session->s_mutex);
        
-       dout(1, "handle_session %p op %d seq %llu\n", session, op, seq);
+       dout(-1, "handle_session %p op %d seq %llu\n", session, op, seq);
        switch (op) {
        case CEPH_SESSION_OPEN:
                dout(1, "session open from mds%d\n", mds);
@@ -1542,7 +1542,7 @@ void schedule_delayed(struct ceph_mds_client *mdsc)
        int delay = mdsc->mdsmap->m_cap_bit_timeout >> 1;
        unsigned hz = round_jiffies_relative(HZ * delay);
        int r;
-       dout(10, "schedule_delayed for %d seconds (%u hz)\n", delay, hz);
+       dout(-10, "schedule_delayed for %d seconds (%u hz)\n", delay, hz);
        r = schedule_delayed_work(&mdsc->delayed_work, hz);
 }
 
@@ -1552,7 +1552,7 @@ void delayed_work(struct work_struct *work)
        struct ceph_mds_client *mdsc =
                container_of(work, struct ceph_mds_client, delayed_work.work);
 
-       dout(10, "delayed_work on %p\n", mdsc);
+       dout(-10, "delayed_work on %p\n", mdsc);
 
        /* renew caps */
        spin_lock(&mdsc->lock);
index b2b651879a31b7f1d38f2592e4774f8cbf56cda8..0627352302e0329faffe733883feb7d16c76cefc 100644 (file)
@@ -163,8 +163,9 @@ static struct inode *ceph_alloc_inode(struct super_block *sb)
 static void ceph_destroy_inode(struct inode *inode)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       dout(30, "destroy_inode %p ino %llx\n", inode, ceph_ino(inode));
-       cancel_delayed_work_sync(&ci->i_cap_dwork);
+       dout(-30, "destroy_inode %p ino %llx\n", inode, ceph_ino(inode));
+       if (cancel_delayed_work_sync(&ci->i_cap_dwork))
+               iput(inode);
        kfree(ci->i_symlink);
        kmem_cache_free(ceph_inode_cachep, ci);
 }
index deab7c8aa0dd01d332d35bea7c8fd43f8f85d8cd..b21610db00dbe26053fd801243598bfa047afd7f 100644 (file)
@@ -25,7 +25,7 @@ int main()
     count[i] = 0;
   }
 
-  for (int f = 1; f < 1000; f++) {  // files
+  for (int f = 1; f < 10000; f++) {  // files
     for (int b = 0; b < 4; b++) {   // blocks
       object_t oid(f, b);
       //cout << "oid " << oid << std::endl;