summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2020-03-22 21:08:55 +0100
committerTrond Myklebust <trond.myklebust@hammerspace.com>2020-03-27 21:34:35 +0100
commite18c18ebd7c128346b532729792e21d97eeb15b0 (patch)
tree32498e048d604b3451a7b8e03dbf6b959f8d646a
parentNFS/pNFS: Simplify bucket layout segment reference counting (diff)
downloadlinux-e18c18ebd7c128346b532729792e21d97eeb15b0.tar.xz
linux-e18c18ebd7c128346b532729792e21d97eeb15b0.zip
NFS/pNFS: Fix pnfs_layout_mark_request_commit() invalid layout segment handling
Fix up pnfs_layout_mark_request_commit() to alway reschedule the write if the layout segment is invalid. Also minor cleanup. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
-rw-r--r--fs/nfs/pnfs_nfs.c28
1 files changed, 12 insertions, 16 deletions
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index abf16fc98346..25f135572fc8 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -1166,26 +1166,22 @@ pnfs_layout_mark_request_commit(struct nfs_page *req,
{
struct list_head *list;
struct pnfs_commit_array *array;
- struct pnfs_commit_bucket *buckets;
+ struct pnfs_commit_bucket *bucket;
mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
array = pnfs_lookup_commit_array(cinfo->ds, lseg);
- if (!array)
+ if (!array || !pnfs_is_valid_lseg(lseg))
goto out_resched;
- buckets = array->buckets;
- list = &buckets[ds_commit_idx].written;
- if (list_empty(list)) {
- if (!pnfs_is_valid_lseg(lseg))
- goto out_resched;
- /* Non-empty buckets hold a reference on the lseg. That ref
- * is normally transferred to the COMMIT call and released
- * there. It could also be released if the last req is pulled
- * off due to a rewrite, in which case it will be done in
- * pnfs_common_clear_request_commit
- */
- if (!buckets[ds_commit_idx].lseg)
- buckets[ds_commit_idx].lseg = pnfs_get_lseg(lseg);
- }
+ bucket = &array->buckets[ds_commit_idx];
+ list = &bucket->written;
+ /* Non-empty buckets hold a reference on the lseg. That ref
+ * is normally transferred to the COMMIT call and released
+ * there. It could also be released if the last req is pulled
+ * off due to a rewrite, in which case it will be done in
+ * pnfs_common_clear_request_commit
+ */
+ if (!bucket->lseg)
+ bucket->lseg = pnfs_get_lseg(lseg);
set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
cinfo->ds->nwritten++;