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);
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);
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);
}
/*
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);
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;
}
*/
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");
}
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);
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;
struct ceph_snap_context *cached_context;
struct list_head inodes_with_caps;
+ spinlock_t inodes_with_caps_lock;
};