@@ -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