]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: protect realm->inodes_with_caps_lock
authorYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 3 Apr 2009 21:51:46 +0000 (14:51 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 3 Apr 2009 21:52:27 +0000 (14:52 -0700)
src/kernel/caps.c
src/kernel/inode.c
src/kernel/snap.c
src/kernel/super.h

index d694772366c508e0a84fb23a30404df808f785f3..f6b5b4cbb77888f455ee01b16fcec76f6122bbe8 100644 (file)
@@ -448,9 +448,11 @@ retry:
                                                               realmino);
                if (realm) {
                        ceph_get_snap_realm(mdsc, realm);
+                       spin_lock(&realm->inodes_with_caps_lock);
                        ci->i_snap_realm = realm;
                        list_add(&ci->i_snap_realm_item,
                                 &realm->inodes_with_caps);
+                       spin_unlock(&realm->inodes_with_caps_lock);
                } else {
                        derr(0, "couldn't find snap realm realmino=%llu\n",
                                realmino);
@@ -611,6 +613,7 @@ static void __ceph_remove_cap(struct ceph_cap *cap,
        spin_lock(&session->s_cap_lock);
        list_del_init(&cap->session_caps);
        session->s_nr_caps--;
+       spin_unlock(&session->s_cap_lock);
 
        /* remove from inode list */
        rb_erase(&cap->ci_node, &ci->i_caps);
@@ -621,13 +624,16 @@ static void __ceph_remove_cap(struct ceph_cap *cap,
        put_cap(cap, ctx);
 
        if (!__ceph_is_any_caps(ci)) {
+               struct ceph_snap_realm *realm = ci->i_snap_realm;
+               spin_lock(&realm->inodes_with_caps_lock);
                list_del_init(&ci->i_snap_realm_item);
-               ceph_put_snap_realm(mdsc, ci->i_snap_realm);
+               ci->i_snap_realm_counter++;
                ci->i_snap_realm = NULL;
+               spin_unlock(&realm->inodes_with_caps_lock);
+               ceph_put_snap_realm(mdsc, realm);
        }
        if (!__ceph_is_any_real_caps(ci))
                __cap_delay_cancel(mdsc, ci);
-       spin_unlock(&session->s_cap_lock);
 }
 
 /*
index 4d4e54be92d92f5c0c2214df27eae8f6d65b459c..6f23f361655eab41af4b25f62b8fa68466e37e48 100644 (file)
@@ -301,6 +301,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
        ci->i_snap_realm = NULL;
        INIT_LIST_HEAD(&ci->i_snap_realm_item);
        INIT_LIST_HEAD(&ci->i_snap_flush_item);
+#warning remove me
+       ci->i_snap_realm_counter = 0;
 
        INIT_WORK(&ci->i_wb_work, ceph_inode_writeback);
        INIT_WORK(&ci->i_pg_inv_work, ceph_inode_invalidate_pages);
index 27c9d308ce419ae81442e6d2b6c5046176a3292c..c184f49d88d24baf79b4fc04971faf4909363f4d 100644 (file)
@@ -104,6 +104,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm(struct ceph_mds_client *md
        INIT_LIST_HEAD(&realm->child_item);
        INIT_LIST_HEAD(&realm->empty_item);
        INIT_LIST_HEAD(&realm->inodes_with_caps);
+       spin_lock_init(&realm->inodes_with_caps_lock);
        dout(20, "create_snap_realm %llx %p\n", realm->ino, realm);
        return realm;
 }
@@ -565,13 +566,16 @@ more:
                 */
                if (!deletion) {
                        struct list_head *pi;
-
+                       spin_lock(&realm->inodes_with_caps_lock);
                        list_for_each(pi, &realm->inodes_with_caps) {
                                struct ceph_inode_info *ci =
                                        list_entry(pi, struct ceph_inode_info,
                                                   i_snap_realm_item);
+                               spin_unlock(&realm->inodes_with_caps_lock);
                                ceph_queue_cap_snap(ci, realm->cached_context);
+                               spin_lock(&realm->inodes_with_caps_lock);
                        }
+                       spin_unlock(&realm->inodes_with_caps_lock);
                        dout(20, "update_snap_trace cap_snaps queued\n");
                }
 
@@ -851,9 +855,11 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
                        if (!ci->i_snap_realm)
                                goto split_skip_inode;
                        ceph_put_snap_realm(mdsc, ci->i_snap_realm);
+                       spin_lock(&realm->inodes_with_caps_lock);
                        list_add(&ci->i_snap_realm_item,
                                 &realm->inodes_with_caps);
                        ci->i_snap_realm = realm;
+                       spin_unlock(&realm->inodes_with_caps_lock);
                        ceph_get_snap_realm(mdsc, realm);
                split_skip_inode:
                        spin_unlock(&inode->i_lock);
index c752d6cf8dffac91c3203bee36cdc36a031ebb1d..493d4c4c9223469df893daf3fe278bc4e431ba7a 100644 (file)
@@ -296,6 +296,7 @@ struct ceph_inode_info {
        spinlock_t i_unsafe_lock;
 
        struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
+       int i_snap_realm_counter; /* snap realm (if caps) */
        struct list_head i_snap_realm_item;
        struct list_head i_snap_flush_item;
 
@@ -643,6 +644,7 @@ struct ceph_snap_realm {
        struct ceph_snap_context *cached_context;
 
        struct list_head inodes_with_caps;
+       spinlock_t inodes_with_caps_lock;
 };