From: andros@netapp.com
To: bhalevy@panasas.com
Cc: linux-nfs@vger.kernel.org, Andy Adamson <andros@netapp.com>
Subject: [PATCH 33/50] pnfs_submit: associate layout segmennt with nfs_page
Date: Fri, 13 Aug 2010 17:31:45 -0400 [thread overview]
Message-ID: <1281735122-1496-34-git-send-email-andros@netapp.com> (raw)
In-Reply-To: <1281735122-1496-33-git-send-email-andros@netapp.com>
From: Andy Adamson <andros@netapp.com>
Signed-off-by: Andy Adamson <andros@netapp.com>
---
fs/nfs/file.c | 32 +++++++++++++++++++++++++-------
fs/nfs/pagelist.c | 12 ++++++++++--
fs/nfs/pnfs.c | 10 ++++++++++
fs/nfs/read.c | 8 ++++++--
fs/nfs/write.c | 42 ++++++++++++++++++++++++++++++------------
include/linux/nfs_fs.h | 8 ++++++--
include/linux/nfs_page.h | 3 ++-
7 files changed, 89 insertions(+), 26 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f036153..d0ed767 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -36,6 +36,7 @@
#include "internal.h"
#include "iostat.h"
#include "fscache.h"
+#include "pnfs.h"
#define NFSDBG_FACILITY NFSDBG_FILE
@@ -389,12 +390,17 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
struct page *page;
int once_thru = 0;
+ struct pnfs_layout_segment *lseg;
dfprintk(PAGECACHE, "NFS: write_begin(%s/%s(%ld), %u@%lld)\n",
file->f_path.dentry->d_parent->d_name.name,
file->f_path.dentry->d_name.name,
mapping->host->i_ino, len, (long long) pos);
+ pnfs_update_layout(mapping->host,
+ nfs_file_open_context(file),
+ IOMODE_RW,
+ &lseg);
start:
/*
* Prevent starvation issues if someone is doing a consistency
@@ -403,14 +409,16 @@ start:
ret = wait_on_bit(&NFS_I(mapping->host)->flags, NFS_INO_FLUSHING,
nfs_wait_bit_killable, TASK_KILLABLE);
if (ret)
- return ret;
+ goto out;
page = grab_cache_page_write_begin(mapping, index, flags);
- if (!page)
- return -ENOMEM;
+ if (!page) {
+ ret = -ENOMEM;
+ goto out;
+ }
*pagep = page;
- ret = nfs_flush_incompatible(file, page);
+ ret = nfs_flush_incompatible(file, page, lseg);
if (ret) {
unlock_page(page);
page_cache_release(page);
@@ -422,6 +430,12 @@ start:
if (!ret)
goto start;
}
+ *fsdata = lseg;
+ out:
+ if (ret) {
+ put_lseg(lseg);
+ *fsdata = NULL;
+ }
return ret;
}
@@ -431,6 +445,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
{
unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
int status;
+ struct pnfs_layout_segment *lseg = fsdata;
dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n",
file->f_path.dentry->d_parent->d_name.name,
@@ -457,10 +472,11 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
zero_user_segment(page, pglen, PAGE_CACHE_SIZE);
}
- status = nfs_updatepage(file, page, offset, copied);
+ status = nfs_updatepage(file, page, offset, copied, lseg);
unlock_page(page);
page_cache_release(page);
+ put_lseg(lseg);
if (status < 0)
return status;
@@ -571,6 +587,8 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
/* make sure the cache has finished storing the page */
nfs_fscache_wait_on_page_write(NFS_I(dentry->d_inode), page);
+ /* XXX Do we want to call pnfs_update_layout here? */
+
lock_page(page);
mapping = page->mapping;
if (mapping != dentry->d_inode->i_mapping)
@@ -581,11 +599,11 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
if (pagelen == 0)
goto out_unlock;
- ret = nfs_flush_incompatible(filp, page);
+ ret = nfs_flush_incompatible(filp, page, NULL);
if (ret != 0)
goto out_unlock;
- ret = nfs_updatepage(filp, page, 0, pagelen);
+ ret = nfs_updatepage(filp, page, 0, pagelen, NULL);
out_unlock:
if (!ret)
return VM_FAULT_LOCKED;
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 41b3966..a014814 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -20,6 +20,7 @@
#include <linux/nfs_mount.h>
#include "internal.h"
+#include "pnfs.h"
static struct kmem_cache *nfs_page_cachep;
@@ -56,7 +57,8 @@ nfs_page_free(struct nfs_page *p)
struct nfs_page *
nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
struct page *page,
- unsigned int offset, unsigned int count)
+ unsigned int offset, unsigned int count,
+ struct pnfs_layout_segment *lseg)
{
struct nfs_page *req;
@@ -81,6 +83,9 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
req->wb_context = get_nfs_open_context(ctx);
req->wb_lock_context = nfs_get_lock_context(ctx);
kref_init(&req->wb_kref);
+ req->wb_lseg = lseg;
+ if (lseg)
+ get_lseg(lseg);
return req;
}
@@ -156,9 +161,12 @@ void nfs_clear_request(struct nfs_page *req)
put_nfs_open_context(ctx);
req->wb_context = NULL;
}
+ if (req->wb_lseg != NULL) {
+ put_lseg(req->wb_lseg);
+ req->wb_lseg = NULL;
+ }
}
-
/**
* nfs_release_request - Release the count on an NFS read/write request
* @req: request to release
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index e25e5d9..3ff193b 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1234,6 +1234,16 @@ pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode)
pnfs_set_pg_test(inode, pgio);
}
+static void _pnfs_clear_lseg_from_pages(struct list_head *head)
+{
+ struct nfs_page *req;
+
+ list_for_each_entry(req, head, wb_list) {
+ put_lseg(req->wb_lseg);
+ req->wb_lseg = NULL;
+ }
+}
+
/*
* Set up the argument/result storage required for the RPC call.
*/
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 99d95ec..324b577 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -118,11 +118,14 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
LIST_HEAD(one_request);
struct nfs_page *new;
unsigned int len;
+ struct pnfs_layout_segment *lseg;
len = nfs_page_length(page);
if (len == 0)
return nfs_return_empty_page(page);
- new = nfs_create_request(ctx, inode, page, 0, len);
+ pnfs_update_layout(inode, ctx, IOMODE_READ, &lseg);
+ new = nfs_create_request(ctx, inode, page, 0, len, lseg);
+ put_lseg(lseg);
if (IS_ERR(new)) {
unlock_page(page);
return PTR_ERR(new);
@@ -570,7 +573,8 @@ readpage_async_filler(void *data, struct page *page)
if (len == 0)
return nfs_return_empty_page(page);
- new = nfs_create_request(desc->ctx, inode, page, 0, len);
+ new = nfs_create_request(desc->ctx, inode, page, 0, len,
+ desc->pgio->pg_lseg);
if (IS_ERR(new))
goto out_error;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 0667eda..a1f28c5 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -430,6 +430,17 @@ static void nfs_inode_remove_request(struct nfs_page *req)
nfs_clear_request(req);
nfs_release_request(req);
}
+static void
+nfs_mark_request_nopnfs(struct nfs_page *req)
+{
+ struct pnfs_layout_segment *lseg = req->wb_lseg;
+
+ if (req->wb_lseg == NULL)
+ return;
+ req->wb_lseg = NULL;
+ put_lseg(lseg);
+ dprintk(" retry through MDS\n");
+}
static void
nfs_mark_request_dirty(struct nfs_page *req)
@@ -572,7 +583,8 @@ static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, pg
static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
struct page *page,
unsigned int offset,
- unsigned int bytes)
+ unsigned int bytes,
+ struct pnfs_layout_segment *lseg)
{
struct nfs_page *req;
unsigned int rqend;
@@ -597,8 +609,8 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
* Note: nfs_flush_incompatible() will already
* have flushed out requests having wrong owners.
*/
- if (offset > rqend
- || end < req->wb_offset)
+ if (offset > rqend || end < req->wb_offset ||
+ req->wb_lseg != lseg)
goto out_flushme;
if (nfs_set_page_tag_locked(req))
@@ -646,16 +658,17 @@ out_err:
* already called nfs_flush_incompatible() if necessary.
*/
static struct nfs_page * nfs_setup_write_request(struct nfs_open_context* ctx,
- struct page *page, unsigned int offset, unsigned int bytes)
+ struct page *page, unsigned int offset, unsigned int bytes,
+ struct pnfs_layout_segment *lseg)
{
struct inode *inode = page->mapping->host;
struct nfs_page *req;
int error;
- req = nfs_try_to_update_request(inode, page, offset, bytes);
+ req = nfs_try_to_update_request(inode, page, offset, bytes, lseg);
if (req != NULL)
goto out;
- req = nfs_create_request(ctx, inode, page, offset, bytes);
+ req = nfs_create_request(ctx, inode, page, offset, bytes, lseg);
if (IS_ERR(req))
goto out;
error = nfs_inode_add_request(inode, req);
@@ -668,11 +681,12 @@ out:
}
static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
- unsigned int offset, unsigned int count)
+ unsigned int offset, unsigned int count,
+ struct pnfs_layout_segment *lseg)
{
struct nfs_page *req;
- req = nfs_setup_write_request(ctx, page, offset, count);
+ req = nfs_setup_write_request(ctx, page, offset, count, lseg);
if (IS_ERR(req))
return PTR_ERR(req);
nfs_mark_request_dirty(req);
@@ -684,7 +698,8 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
return 0;
}
-int nfs_flush_incompatible(struct file *file, struct page *page)
+int nfs_flush_incompatible(struct file *file, struct page *page,
+ struct pnfs_layout_segment *lseg)
{
struct nfs_open_context *ctx = nfs_file_open_context(file);
struct nfs_page *req;
@@ -703,7 +718,8 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
return 0;
do_flush = req->wb_page != page || req->wb_context != ctx ||
req->wb_lock_context->lockowner != current->files ||
- req->wb_lock_context->pid != current->tgid;
+ req->wb_lock_context->pid != current->tgid ||
+ req->wb_lseg != lseg;
nfs_release_request(req);
if (!do_flush)
return 0;
@@ -730,7 +746,8 @@ static int nfs_write_pageuptodate(struct page *page, struct inode *inode)
* things with a page scheduled for an RPC call (e.g. invalidate it).
*/
int nfs_updatepage(struct file *file, struct page *page,
- unsigned int offset, unsigned int count)
+ unsigned int offset, unsigned int count,
+ struct pnfs_layout_segment *lseg)
{
struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = page->mapping->host;
@@ -755,7 +772,7 @@ int nfs_updatepage(struct file *file, struct page *page,
offset = 0;
}
- status = nfs_writepage_setup(ctx, page, offset, count);
+ status = nfs_writepage_setup(ctx, page, offset, count, lseg);
if (status < 0)
nfs_set_pageerror(page);
@@ -874,6 +891,7 @@ static void nfs_redirty_request(struct nfs_page *req)
{
struct page *page = req->wb_page;
+ nfs_mark_request_nopnfs(req);
nfs_mark_request_dirty(req);
nfs_clear_page_tag_locked(req);
nfs_end_page_writeback(page);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 7202c05..6f67aec 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -517,8 +517,12 @@ extern void nfs_unblock_sillyrename(struct dentry *dentry);
extern int nfs_congestion_kb;
extern int nfs_writepage(struct page *page, struct writeback_control *wbc);
extern int nfs_writepages(struct address_space *, struct writeback_control *);
-extern int nfs_flush_incompatible(struct file *file, struct page *page);
-extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
+struct pnfs_layout_segment;
+extern int nfs_flush_incompatible(struct file *file, struct page *page,
+ struct pnfs_layout_segment *lseg);
+extern int nfs_updatepage(struct file *, struct page *,
+ unsigned int offset, unsigned int count,
+ struct pnfs_layout_segment *lseg);
extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
/*
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index d7deec9..ce0a1a5 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -76,7 +76,8 @@ extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
struct inode *inode,
struct page *page,
unsigned int offset,
- unsigned int count);
+ unsigned int count,
+ struct pnfs_layout_segment *lseg);
extern void nfs_clear_request(struct nfs_page *req);
extern void nfs_release_request(struct nfs_page *req);
--
1.6.2.5
next prev parent reply other threads:[~2010-08-13 21:32 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-13 21:31 [PATCH 0/50] Squashed and re-organized pnfs-submit tree andros
2010-08-13 21:31 ` [PATCH 01/50] nfs41: prevent exchange_id from sending server-only flag andros
2010-08-13 21:31 ` [PATCH 02/50] sunrpc: define xdr_decode_opaque_fixed andros
2010-08-13 21:31 ` [PATCH 03/50] sunrpc: don't reset buflen twice in xdr_shrink_pagelen andros
2010-08-13 21:31 ` [PATCH 04/50] nfsd: remove duplicate NFS4_STATEID_SIZE declaration andros
2010-08-13 21:31 ` [PATCH 05/50] pnfs_submit: pnfs and nfslayoutdriver kconfig andros
2010-08-13 21:31 ` [PATCH 06/50] pnfs_submit: introduce include/linux/nfs4_pnfs.h andros
2010-08-13 21:31 ` [PATCH 07/50] pnfs_submit: introduce include/linux/pnfs_xdr.h andros
2010-08-13 21:31 ` [PATCH 08/50] pnfs_submit: introduce fs/nfs/pnfs.h andros
2010-08-13 21:31 ` [PATCH 09/50] pnfs_submit: introduce fs/nfs/pnfs.c andros
2010-08-13 21:31 ` [PATCH 10/50] pnfs_submit: register unregister pnfs module andros
2010-08-13 21:31 ` [PATCH 11/50] pnfs_submit: set and unset pnfs layoutdriver modules andros
2010-08-13 21:31 ` [PATCH 12/50] pnfs_submit: generic pnfs deviceid cache andros
2010-08-13 21:31 ` [PATCH 13/50] pnfs_submit: introduce nfs4layoutdriver module andros
2010-08-13 21:31 ` [PATCH 14/50] pnfs_submit: filelayout data server cache andros
2010-08-13 21:31 ` [PATCH 15/50] pnfs_submit: filelayout deviceid cache andros
2010-08-13 21:31 ` [PATCH 16/50] pnfs_submit: generic getdeviceinfo andros
2010-08-13 21:31 ` [PATCH 17/50] pnfs_submit: filelayout getdeviceinfo andros
2010-08-13 21:31 ` [PATCH 18/50] pnfs-submit: change stateid to be a union andros
2010-08-13 21:31 ` [PATCH 19/50] pnfs_submit: layout header alloc,reference, and destroy andros
2010-08-13 21:31 ` [PATCH 20/50] pnfs_submit: filelayout alloc_layout and free_layout andros
2010-08-13 21:31 ` [PATCH 21/50] pnfs_submit: layout segment alloc, reference, destroy andros
2010-08-13 21:31 ` [PATCH 22/50] pnfs_submit: layoutget andros
2010-08-13 21:31 ` [PATCH 23/50] pnfs_submit: layout helper functions andros
2010-08-13 21:31 ` [PATCH 24/50] pnfs_submit: filelayout layout segment alloc and free andros
2010-08-13 21:31 ` [PATCH 25/50] pnfs_submit: layoutcommit helper functions andros
2010-08-13 21:31 ` [PATCH 26/50] pnfs_submit: layoutcommit andros
2010-08-13 21:31 ` [PATCH 27/50] pnfs_submit: layoutreturn helper functions andros
2010-08-13 21:31 ` [PATCH 28/50] pnfs_submit: layoutreturn andros
2010-08-13 21:31 ` [PATCH 29/50] pnfs_submit: add data server session to nfs4_setup_sequence andros
2010-08-13 21:31 ` [PATCH 30/50] pnfs_submit: update nfs4_async_handle_error for data server andros
2010-08-13 21:31 ` [PATCH 31/50] pnfs_submit: update state renewal for data servers andros
2010-08-13 21:31 ` [PATCH 32/50] pnfs_submit-pageio-helpers.patch andros
2010-08-13 21:31 ` andros [this message]
2010-08-13 21:31 ` [PATCH 34/50] pnfs_submit: filelayout policy operations andros
2010-08-13 21:31 ` [PATCH 35/50] pnfs_submit: filelayout i/o helpers andros
2010-08-13 21:31 ` [PATCH 36/50] pnfs_submit: generic read andros
2010-08-13 21:31 ` [PATCH 37/50] pnfs_submit: filelayout read andros
2010-08-13 21:31 ` [PATCH 38/50] pnfs_submit: generic write andros
2010-08-13 21:31 ` [PATCH 39/50] pnfs_submit: data server write with no getattr andros
2010-08-13 21:31 ` [PATCH 40/50] pnfs_submit: filelayout write andros
2010-08-13 21:31 ` [PATCH 41/50] pnfs_submit: signal layoutdriver commit andros
2010-08-13 21:31 ` [PATCH 42/50] pnfs_submit: generic commit andros
2010-08-13 21:31 ` [PATCH 43/50] pnfs_submit: data server commit with no getattr andros
2010-08-13 21:31 ` [PATCH 44/50] pnfs_submit: filelayout commit andros
2010-08-13 21:31 ` [PATCH 45/50] pnfs_submit: cb_layoutrecall andros
2010-08-13 21:31 ` [PATCH 46/50] pnfs_submit: increase NFS_MAX_FILE_IO_SIZE andros
2010-08-13 21:31 ` [PATCH 47/50] SQUASHME pnfs_post_submit: direct i/o andros
2010-08-13 21:32 ` [PATCH 48/50] SQUASHME pnfs_post_submit: layout type enum andros
2010-08-13 21:32 ` [PATCH 49/50] SQUASHME pnfs_post_submit: cb notify deviceid declarations andros
2010-08-13 21:32 ` [PATCH 50/50] SQUASHME pnfs_submit: remove this unused code andros
2010-08-19 20:25 ` Benny Halevy
2010-08-31 16:32 ` Boaz Harrosh
2010-08-31 15:52 ` [PATCH 48/50] SQUASHME pnfs_post_submit: layout type enum Boaz Harrosh
2010-08-18 20:31 ` [PATCH 11/50] pnfs_submit: set and unset pnfs layoutdriver modules Christoph Hellwig
2010-08-18 20:46 ` Benny Halevy
2010-08-19 9:43 ` Christoph Hellwig
2010-08-18 20:29 ` [PATCH 10/50] pnfs_submit: register unregister pnfs module Christoph Hellwig
2010-08-18 20:49 ` Benny Halevy
2010-08-18 20:28 ` [PATCH 09/50] pnfs_submit: introduce fs/nfs/pnfs.c Christoph Hellwig
2010-08-19 17:21 ` J. Bruce Fields
2010-08-18 20:27 ` [PATCH 06/50] pnfs_submit: introduce include/linux/nfs4_pnfs.h Christoph Hellwig
2010-08-18 20:48 ` William A. (Andy) Adamson
2010-08-18 20:50 ` Benny Halevy
2010-08-18 20:25 ` [PATCH 05/50] pnfs_submit: pnfs and nfslayoutdriver kconfig Christoph Hellwig
2010-08-18 21:09 ` Benny Halevy
2010-08-19 9:45 ` Christoph Hellwig
2010-08-20 22:13 ` [PATCH 04/50] nfsd: remove duplicate NFS4_STATEID_SIZE declaration J. Bruce Fields
2010-08-19 20:50 ` [PATCH 0/50] Squashed and re-organized pnfs-submit tree Benny Halevy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1281735122-1496-34-git-send-email-andros@netapp.com \
--to=andros@netapp.com \
--cc=bhalevy@panasas.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).