mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
nfs: track number of pinned pages in nfs_page
Track the number of pinned pages in nfs_page to handle unpinning correctly, ensuring that only primary requests perform the final unpinning operation, preventing subrequests from incorrectly performing unpinning on behalf of their parent requests. Add wb_nr_pinned to struct nfs_page to store the count of pinned pages owned by the request. Update request creation and cleanup helpers to initialize and use wb_nr_pinned for primary requests. Use the nfs_page_array_len() helper to calculate the number of pages spanned by a request's offset and length. Signed-off-by: Pranjal Shrivastava <praan@google.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
This commit is contained in:
parent
d91ae903f4
commit
00ba5f7320
|
|
@ -457,6 +457,8 @@ struct nfs_page *nfs_page_create_from_page(struct nfs_open_context *ctx,
|
|||
offset_in_page(offset), count);
|
||||
if (!IS_ERR(ret)) {
|
||||
nfs_page_assign_page(ret, page, pinned);
|
||||
if (pinned)
|
||||
ret->wb_nr_pinned = 1;
|
||||
nfs_page_group_init(ret, NULL);
|
||||
}
|
||||
nfs_put_lock_context(l_ctx);
|
||||
|
|
@ -489,6 +491,9 @@ struct nfs_page *nfs_page_create_from_folio(struct nfs_open_context *ctx,
|
|||
ret = nfs_page_create(l_ctx, offset, folio->index, offset, count);
|
||||
if (!IS_ERR(ret)) {
|
||||
nfs_page_assign_folio(ret, folio, pinned);
|
||||
if (pinned)
|
||||
ret->wb_nr_pinned = nfs_page_array_len(offset_in_page(offset),
|
||||
count);
|
||||
nfs_page_group_init(ret, NULL);
|
||||
}
|
||||
nfs_put_lock_context(l_ctx);
|
||||
|
|
@ -567,8 +572,8 @@ static void nfs_clear_request(struct nfs_page *req)
|
|||
|
||||
if (folio != NULL) {
|
||||
if (test_and_clear_bit(PG_PINNED, &req->wb_flags)) {
|
||||
if (req == req->wb_head)
|
||||
unpin_user_folio(folio, 1);
|
||||
if (req->wb_nr_pinned > 0)
|
||||
unpin_user_folio(folio, req->wb_nr_pinned);
|
||||
} else {
|
||||
folio_put(folio);
|
||||
}
|
||||
|
|
@ -576,8 +581,8 @@ static void nfs_clear_request(struct nfs_page *req)
|
|||
clear_bit(PG_FOLIO, &req->wb_flags);
|
||||
} else if (page != NULL) {
|
||||
if (test_and_clear_bit(PG_PINNED, &req->wb_flags)) {
|
||||
if (req == req->wb_head)
|
||||
unpin_user_page(page);
|
||||
if (req->wb_nr_pinned > 0)
|
||||
unpin_user_pages(&page, req->wb_nr_pinned);
|
||||
} else {
|
||||
put_page(page);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ struct nfs_page {
|
|||
struct nfs_page *wb_this_page; /* list of reqs for this page */
|
||||
struct nfs_page *wb_head; /* head pointer for req list */
|
||||
unsigned short wb_nio; /* Number of I/O attempts */
|
||||
unsigned int wb_nr_pinned; /* Number of pinned pages */
|
||||
};
|
||||
|
||||
struct nfs_pgio_mirror;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user