/*
* build the snap context for a given realm.
*/
-static int build_snap_context(struct ceph_snap_realm *realm)
+static int build_snap_context(struct ceph_snap_realm *realm,
+ struct list_head* dirty_realms)
{
struct ceph_snap_realm *parent = realm->parent;
struct ceph_snap_context *snapc;
*/
if (parent) {
if (!parent->cached_context) {
- err = build_snap_context(parent);
+ err = build_snap_context(parent, dirty_realms);
if (err)
goto fail;
}
" (unchanged)\n",
realm->ino, realm, realm->cached_context,
realm->cached_context->seq,
- (unsigned int) realm->cached_context->num_snaps);
+ (unsigned int)realm->cached_context->num_snaps);
return 0;
}
realm->ino, realm, snapc, snapc->seq,
(unsigned int) snapc->num_snaps);
- ceph_put_snap_context(realm->cached_context);
+ if (realm->cached_context) {
+ ceph_put_snap_context(realm->cached_context);
+ /* queue realm for cap_snap creation */
+ list_add_tail(&realm->dirty_item, dirty_realms);
+ }
realm->cached_context = snapc;
return 0;
/*
* rebuild snap context for the given realm and all of its children.
*/
-static void rebuild_snap_realms(struct ceph_snap_realm *realm)
+static void rebuild_snap_realms(struct ceph_snap_realm *realm,
+ struct list_head *dirty_realms)
{
struct ceph_snap_realm *child;
dout("rebuild_snap_realms %llx %p\n", realm->ino, realm);
- build_snap_context(realm);
+ build_snap_context(realm, dirty_realms);
list_for_each_entry(child, &realm->children, child_item)
- rebuild_snap_realms(child);
+ rebuild_snap_realms(child, dirty_realms);
}
{
struct ceph_inode_info *ci;
struct inode *lastinode = NULL;
- struct ceph_snap_realm *child;
dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino);
spin_lock(&realm->inodes_with_caps_lock);
- list_for_each_entry(ci, &realm->inodes_with_caps,
- i_snap_realm_item) {
+ list_for_each_entry(ci, &realm->inodes_with_caps, i_snap_realm_item) {
struct inode *inode = igrab(&ci->vfs_inode);
if (!inode)
continue;
spin_unlock(&realm->inodes_with_caps_lock);
iput(lastinode);
- list_for_each_entry(child, &realm->children, child_item) {
- dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n",
- realm, realm->ino, child, child->ino);
- list_del_init(&child->dirty_item);
- list_add(&child->dirty_item, &realm->dirty_item);
- }
-
- list_del_init(&realm->dirty_item);
dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino);
}
if (err < 0)
goto fail;
- /* queue realm for cap_snap creation */
- list_add(&realm->dirty_item, &dirty_realms);
if (realm->seq > mdsc->last_snap_seq)
mdsc->last_snap_seq = realm->seq;
/* invalidate when we reach the _end_ (root) of the trace */
if (invalidate && p >= e)
- rebuild_snap_realms(realm);
+ rebuild_snap_realms(realm, &dirty_realms);
if (!first_realm)
first_realm = realm;
while (!list_empty(&dirty_realms)) {
realm = list_first_entry(&dirty_realms, struct ceph_snap_realm,
dirty_item);
+ list_del_init(&realm->dirty_item);
queue_realm_cap_snaps(realm);
}