pnfs: fix filelayout_retry_commit when idx > 0
[firefly-linux-kernel-4.4.55.git] / fs / nfs / filelayout / filelayout.c
index 524e66f6bb9c1040fc2e1ff573585915afd80366..90978075f7302a791813b6dd29c0ec9f9e5850eb 100644 (file)
@@ -1009,6 +1009,7 @@ static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j)
 
 /* The generic layer is about to remove the req from the commit list.
  * If this will make the bucket empty, it will need to put the lseg reference.
+ * Note this is must be called holding the inode (/cinfo) lock
  */
 static void
 filelayout_clear_request_commit(struct nfs_page *req,
@@ -1016,7 +1017,6 @@ filelayout_clear_request_commit(struct nfs_page *req,
 {
        struct pnfs_layout_segment *freeme = NULL;
 
-       spin_lock(cinfo->lock);
        if (!test_and_clear_bit(PG_COMMIT_TO_DS, &req->wb_flags))
                goto out;
        cinfo->ds->nwritten--;
@@ -1031,8 +1031,7 @@ filelayout_clear_request_commit(struct nfs_page *req,
        }
 out:
        nfs_request_remove_commit_list(req, cinfo);
-       spin_unlock(cinfo->lock);
-       pnfs_put_lseg(freeme);
+       pnfs_put_lseg_async(freeme);
 }
 
 static void
@@ -1270,11 +1269,12 @@ filelayout_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page)
 static void filelayout_retry_commit(struct nfs_commit_info *cinfo, int idx)
 {
        struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
-       struct pnfs_commit_bucket *bucket = fl_cinfo->buckets;
+       struct pnfs_commit_bucket *bucket;
        struct pnfs_layout_segment *freeme;
        int i;
 
-       for (i = idx; i < fl_cinfo->nbuckets; i++, bucket++) {
+       for (i = idx; i < fl_cinfo->nbuckets; i++) {
+               bucket = &fl_cinfo->buckets[i];
                if (list_empty(&bucket->committing))
                        continue;
                nfs_retry_commit(&bucket->committing, bucket->clseg, cinfo);