summaryrefslogtreecommitdiffstats
path: root/fs/nfs/filelayout
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@primarydata.com>2014-07-18 02:42:17 +0200
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-08-03 23:05:25 +0200
commit02d1426c7053da7c5a828ae9cd7b636ea4e46bf7 (patch)
treec241cc5c33ce52da89ecf04486988b21c85d0203 /fs/nfs/filelayout
parentnfs: fix comment and add warn_on for PG_INODE_REF (diff)
downloadlinux-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.c31
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,