diff options
author | Weston Andros Adamson <dros@primarydata.com> | 2014-07-18 02:42:17 +0200 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-08-03 23:05:25 +0200 |
commit | 02d1426c7053da7c5a828ae9cd7b636ea4e46bf7 (patch) | |
tree | c241cc5c33ce52da89ecf04486988b21c85d0203 /fs/nfs/filelayout | |
parent | nfs: fix comment and add warn_on for PG_INODE_REF (diff) | |
download | linux-02d1426c7053da7c5a828ae9cd7b636ea4e46bf7.tar.xz linux-02d1426c7053da7c5a828ae9cd7b636ea4e46bf7.zip |
pnfs: find swapped pages on pnfs commit lists too
nfs_page_find_head_request_locked looks through the regular nfs commit lists
when the page is swapped out, but doesn't look through the pnfs commit lists.
I'm not sure if anyone has hit any issues caused by this.
Suggested-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/filelayout')
-rw-r--r-- | fs/nfs/filelayout/filelayout.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index 2576d28bffc0..524e66f6bb9c 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -1237,6 +1237,36 @@ restart: spin_unlock(cinfo->lock); } +/* filelayout_search_commit_reqs - Search lists in @cinfo for the head reqest + * for @page + * @cinfo - commit info for current inode + * @page - page to search for matching head request + * + * Returns a the head request if one is found, otherwise returns NULL. + */ +static struct nfs_page * +filelayout_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page) +{ + struct nfs_page *freq, *t; + struct pnfs_commit_bucket *b; + int i; + + /* Linearly search the commit lists for each bucket until a matching + * request is found */ + for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) { + list_for_each_entry_safe(freq, t, &b->written, wb_list) { + if (freq->wb_page == page) + return freq->wb_head; + } + list_for_each_entry_safe(freq, t, &b->committing, wb_list) { + if (freq->wb_page == page) + return freq->wb_head; + } + } + + return NULL; +} + static void filelayout_retry_commit(struct nfs_commit_info *cinfo, int idx) { struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds; @@ -1386,6 +1416,7 @@ static struct pnfs_layoutdriver_type filelayout_type = { .clear_request_commit = filelayout_clear_request_commit, .scan_commit_lists = filelayout_scan_commit_lists, .recover_commit_reqs = filelayout_recover_commit_reqs, + .search_commit_reqs = filelayout_search_commit_reqs, .commit_pagelist = filelayout_commit_pagelist, .read_pagelist = filelayout_read_pagelist, .write_pagelist = filelayout_write_pagelist, |