Skip to content

Commit

Permalink
NFS: Don't check request offset and size without holding a lock
Browse files Browse the repository at this point in the history
Request offsets and sizes are not guaranteed to be stable unless you
are holding the request locked.

Signed-off-by: Trond Myklebust <[email protected]>
  • Loading branch information
trondmypd committed Aug 15, 2017
1 parent a0e265b commit e14bebf
Showing 1 changed file with 12 additions and 12 deletions.
24 changes: 12 additions & 12 deletions fs/nfs/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,17 @@ nfs_lock_and_join_requests(struct page *page)
total_bytes = head->wb_bytes;
for (subreq = head->wb_this_page; subreq != head;
subreq = subreq->wb_this_page) {
if (!nfs_lock_request(subreq)) {
/* releases page group bit lock and
* inode spin lock and all references */
ret = nfs_unroll_locks_and_wait(inode, head,
subreq);

if (ret == 0)
goto try_again;

return ERR_PTR(ret);
}
/*
* Subrequests are always contiguous, non overlapping
* and in order - but may be repeated (mirrored writes).
Expand All @@ -533,21 +544,10 @@ nfs_lock_and_join_requests(struct page *page)
} else if (WARN_ON_ONCE(subreq->wb_offset < head->wb_offset ||
((subreq->wb_offset + subreq->wb_bytes) >
(head->wb_offset + total_bytes)))) {
nfs_unlock_request(subreq);
nfs_unroll_locks_and_wait(inode, head, subreq);
return ERR_PTR(-EIO);
}

if (!nfs_lock_request(subreq)) {
/* releases page group bit lock and
* inode spin lock and all references */
ret = nfs_unroll_locks_and_wait(inode, head,
subreq);

if (ret == 0)
goto try_again;

return ERR_PTR(ret);
}
}

/* Now that all requests are locked, make sure they aren't on any list.
Expand Down

0 comments on commit e14bebf

Please sign in to comment.