@@ -59,6 +59,17 @@ void pnfs_generic_commit_release(void *calldata)
5959}
6060EXPORT_SYMBOL_GPL (pnfs_generic_commit_release );
6161
62+ static struct pnfs_layout_segment *
63+ pnfs_free_bucket_lseg (struct pnfs_commit_bucket * bucket )
64+ {
65+ if (list_empty (& bucket -> committing ) && list_empty (& bucket -> written )) {
66+ struct pnfs_layout_segment * freeme = bucket -> lseg ;
67+ bucket -> lseg = NULL ;
68+ return freeme ;
69+ }
70+ return NULL ;
71+ }
72+
6273/* The generic layer is about to remove the req from the commit list.
6374 * If this will make the bucket empty, it will need to put the lseg reference.
6475 * Note this must be called holding nfsi->commit_mutex
@@ -78,8 +89,7 @@ pnfs_generic_clear_request_commit(struct nfs_page *req,
7889 bucket = list_first_entry (& req -> wb_list ,
7990 struct pnfs_commit_bucket ,
8091 written );
81- freeme = bucket -> wlseg ;
82- bucket -> wlseg = NULL ;
92+ freeme = pnfs_free_bucket_lseg (bucket );
8393 }
8494out :
8595 nfs_request_remove_commit_list (req , cinfo );
@@ -103,8 +113,7 @@ pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags)
103113 for (b = & p -> buckets [0 ]; n != 0 ; b ++ , n -- ) {
104114 INIT_LIST_HEAD (& b -> written );
105115 INIT_LIST_HEAD (& b -> committing );
106- b -> wlseg = NULL ;
107- b -> clseg = NULL ;
116+ b -> lseg = NULL ;
108117 b -> direct_verf .committed = NFS_INVALID_STABLE_HOW ;
109118 }
110119 return p ;
@@ -246,12 +255,6 @@ pnfs_bucket_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
246255 if (ret ) {
247256 cinfo -> ds -> nwritten -= ret ;
248257 cinfo -> ds -> ncommitting += ret ;
249- if (bucket -> clseg == NULL )
250- bucket -> clseg = pnfs_get_lseg (bucket -> wlseg );
251- if (list_empty (src )) {
252- pnfs_put_lseg (bucket -> wlseg );
253- bucket -> wlseg = NULL ;
254- }
255258 }
256259 return ret ;
257260}
@@ -317,9 +320,8 @@ pnfs_bucket_recover_commit_reqs(struct list_head *dst,
317320 if (!nwritten )
318321 continue ;
319322 ret += nwritten ;
320- if (list_empty (& b -> written )) {
321- freeme = b -> wlseg ;
322- b -> wlseg = NULL ;
323+ freeme = pnfs_free_bucket_lseg (b );
324+ if (freeme ) {
323325 pnfs_put_lseg (freeme );
324326 goto restart ;
325327 }
@@ -405,15 +407,12 @@ pnfs_bucket_get_committing(struct list_head *head,
405407 struct pnfs_commit_bucket * bucket ,
406408 struct nfs_commit_info * cinfo )
407409{
408- struct pnfs_layout_segment * freeme ;
409410 struct list_head * pos ;
410411
411412 list_for_each (pos , & bucket -> committing )
412413 cinfo -> ds -> ncommitting -- ;
413414 list_splice_init (& bucket -> committing , head );
414- freeme = bucket -> clseg ;
415- bucket -> clseg = NULL ;
416- return freeme ;
415+ return pnfs_free_bucket_lseg (bucket );
417416}
418417
419418static struct nfs_commit_data *
@@ -425,6 +424,8 @@ pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket *bucket,
425424 if (!data )
426425 return NULL ;
427426 data -> lseg = pnfs_bucket_get_committing (& data -> pages , bucket , cinfo );
427+ if (!data -> lseg )
428+ data -> lseg = pnfs_get_lseg (bucket -> lseg );
428429 return data ;
429430}
430431
@@ -1182,8 +1183,8 @@ pnfs_layout_mark_request_commit(struct nfs_page *req,
11821183 * off due to a rewrite, in which case it will be done in
11831184 * pnfs_common_clear_request_commit
11841185 */
1185- WARN_ON_ONCE ( buckets [ds_commit_idx ].wlseg != NULL );
1186- buckets [ds_commit_idx ].wlseg = pnfs_get_lseg (lseg );
1186+ if (! buckets [ds_commit_idx ].lseg )
1187+ buckets [ds_commit_idx ].lseg = pnfs_get_lseg (lseg );
11871188 }
11881189 set_bit (PG_COMMIT_TO_DS , & req -> wb_flags );
11891190 cinfo -> ds -> nwritten ++ ;
0 commit comments