Skip to content

Commit 3ae0beb

Browse files
ukernelidryomov
authored andcommitted
ceph: queue cap snap only when snap realm's context changes
If we create capsnap when snap realm's context does not change, the new capsnap's snapc is equal to ci->i_head_snapc. Page writeback code can't differentiates dirty pages associated with the new capsnap from dirty pages associated with i_head_snapc. Signed-off-by: "Yan, Zheng" <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent c8fd0d3 commit 3ae0beb

File tree

1 file changed

+16
-21
lines changed

1 file changed

+16
-21
lines changed

fs/ceph/snap.c

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ static int cmpu64_rev(const void *a, const void *b)
299299
/*
300300
* build the snap context for a given realm.
301301
*/
302-
static int build_snap_context(struct ceph_snap_realm *realm)
302+
static int build_snap_context(struct ceph_snap_realm *realm,
303+
struct list_head* dirty_realms)
303304
{
304305
struct ceph_snap_realm *parent = realm->parent;
305306
struct ceph_snap_context *snapc;
@@ -313,7 +314,7 @@ static int build_snap_context(struct ceph_snap_realm *realm)
313314
*/
314315
if (parent) {
315316
if (!parent->cached_context) {
316-
err = build_snap_context(parent);
317+
err = build_snap_context(parent, dirty_realms);
317318
if (err)
318319
goto fail;
319320
}
@@ -332,7 +333,7 @@ static int build_snap_context(struct ceph_snap_realm *realm)
332333
" (unchanged)\n",
333334
realm->ino, realm, realm->cached_context,
334335
realm->cached_context->seq,
335-
(unsigned int) realm->cached_context->num_snaps);
336+
(unsigned int)realm->cached_context->num_snaps);
336337
return 0;
337338
}
338339

@@ -373,7 +374,11 @@ static int build_snap_context(struct ceph_snap_realm *realm)
373374
realm->ino, realm, snapc, snapc->seq,
374375
(unsigned int) snapc->num_snaps);
375376

376-
ceph_put_snap_context(realm->cached_context);
377+
if (realm->cached_context) {
378+
ceph_put_snap_context(realm->cached_context);
379+
/* queue realm for cap_snap creation */
380+
list_add_tail(&realm->dirty_item, dirty_realms);
381+
}
377382
realm->cached_context = snapc;
378383
return 0;
379384

@@ -394,15 +399,16 @@ static int build_snap_context(struct ceph_snap_realm *realm)
394399
/*
395400
* rebuild snap context for the given realm and all of its children.
396401
*/
397-
static void rebuild_snap_realms(struct ceph_snap_realm *realm)
402+
static void rebuild_snap_realms(struct ceph_snap_realm *realm,
403+
struct list_head *dirty_realms)
398404
{
399405
struct ceph_snap_realm *child;
400406

401407
dout("rebuild_snap_realms %llx %p\n", realm->ino, realm);
402-
build_snap_context(realm);
408+
build_snap_context(realm, dirty_realms);
403409

404410
list_for_each_entry(child, &realm->children, child_item)
405-
rebuild_snap_realms(child);
411+
rebuild_snap_realms(child, dirty_realms);
406412
}
407413

408414

@@ -624,13 +630,11 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
624630
{
625631
struct ceph_inode_info *ci;
626632
struct inode *lastinode = NULL;
627-
struct ceph_snap_realm *child;
628633

629634
dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino);
630635

631636
spin_lock(&realm->inodes_with_caps_lock);
632-
list_for_each_entry(ci, &realm->inodes_with_caps,
633-
i_snap_realm_item) {
637+
list_for_each_entry(ci, &realm->inodes_with_caps, i_snap_realm_item) {
634638
struct inode *inode = igrab(&ci->vfs_inode);
635639
if (!inode)
636640
continue;
@@ -643,14 +647,6 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
643647
spin_unlock(&realm->inodes_with_caps_lock);
644648
iput(lastinode);
645649

646-
list_for_each_entry(child, &realm->children, child_item) {
647-
dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n",
648-
realm, realm->ino, child, child->ino);
649-
list_del_init(&child->dirty_item);
650-
list_add(&child->dirty_item, &realm->dirty_item);
651-
}
652-
653-
list_del_init(&realm->dirty_item);
654650
dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino);
655651
}
656652

@@ -721,8 +717,6 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
721717
if (err < 0)
722718
goto fail;
723719

724-
/* queue realm for cap_snap creation */
725-
list_add(&realm->dirty_item, &dirty_realms);
726720
if (realm->seq > mdsc->last_snap_seq)
727721
mdsc->last_snap_seq = realm->seq;
728722

@@ -741,7 +735,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
741735

742736
/* invalidate when we reach the _end_ (root) of the trace */
743737
if (invalidate && p >= e)
744-
rebuild_snap_realms(realm);
738+
rebuild_snap_realms(realm, &dirty_realms);
745739

746740
if (!first_realm)
747741
first_realm = realm;
@@ -758,6 +752,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
758752
while (!list_empty(&dirty_realms)) {
759753
realm = list_first_entry(&dirty_realms, struct ceph_snap_realm,
760754
dirty_item);
755+
list_del_init(&realm->dirty_item);
761756
queue_realm_cap_snaps(realm);
762757
}
763758

0 commit comments

Comments
 (0)