From: Fred Isaman <iisaman@netapp.com>
To: linux-nfs@vger.kernel.org
Subject: [PATCH 19/22] pnfs_submit: API change: remove pnfs_commit layoutget invocation
Date: Sat, 15 May 2010 21:23:10 -0400 [thread overview]
Message-ID: <1273972993-15369-20-git-send-email-iisaman@netapp.com> (raw)
In-Reply-To: <1273972993-15369-19-git-send-email-iisaman@netapp.com>
WARNING - this is an API change.
The layout driver's commit operation no longer takes an lseg.
This is because each nfs_page may or may not have an associated lseg.
It is the layout drivers task to send commits to the appropriate place.
Signed-off-by: Fred Isaman <iisaman@netapp.com>
---
fs/nfs/internal.h | 2 +-
fs/nfs/pagelist.c | 5 ++-
fs/nfs/pnfs.c | 79 ++++++++-------------------------------------
fs/nfs/pnfs.h | 21 +++++-------
fs/nfs/write.c | 23 +++++++------
include/linux/nfs_page.h | 3 +-
6 files changed, 43 insertions(+), 90 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 49c4ea8..f149452 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -288,7 +288,7 @@ extern int nfs_initiate_commit(struct nfs_write_data *data,
extern int pnfs_initiate_commit(struct nfs_write_data *data,
struct rpc_clnt *clnt,
const struct rpc_call_ops *call_ops,
- int how);
+ int how, int pnfs);
extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
extern void nfs_mark_list_commit(struct list_head *head);
#ifdef CONFIG_MIGRATION
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 19ffdc5..52f6f6a 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -386,6 +386,7 @@ void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
* @idx_start: lower bound of page->index to scan
* @npages: idx_start + npages sets the upper bound to scan.
* @tag: tag to scan for
+ * @use_pnfs: will be set TRUE if commit needs to be handled by layout driver
*
* Moves elements from one of the inode request lists.
* If the number of requests is set to 0, the entire address_space
@@ -395,7 +396,7 @@ void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
*/
int nfs_scan_list(struct nfs_inode *nfsi,
struct list_head *dst, pgoff_t idx_start,
- unsigned int npages, int tag)
+ unsigned int npages, int tag, int *use_pnfs)
{
struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES];
struct nfs_page *req;
@@ -426,6 +427,8 @@ int nfs_scan_list(struct nfs_inode *nfsi,
radix_tree_tag_clear(&nfsi->nfs_page_tree,
req->wb_index, tag);
nfs_list_add_request(req, dst);
+ if (req->wb_lseg)
+ *use_pnfs = 1;
res++;
if (res == INT_MAX)
goto out;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 5ccd406..4c3480b 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1673,19 +1673,11 @@ enum pnfs_try_status
_pnfs_try_to_commit(struct nfs_write_data *data,
const struct rpc_call_ops *call_ops, int how)
{
- struct inode *inode = data->inode;
-
- if (!pnfs_enabled_sb(NFS_SERVER(inode))) {
- dprintk("%s: Not using pNFS I/O\n", __func__);
- return PNFS_NOT_ATTEMPTED;
- } else {
- /* data->call_ops and data->how set in nfs_commit_rpcsetup */
- dprintk("%s: Utilizing pNFS I/O\n", __func__);
- data->pdata.call_ops = call_ops;
- data->pdata.pnfs_error = 0;
- data->pdata.how = how;
- return pnfs_commit(data, how);
- }
+ dprintk("%s: Utilizing pNFS I/O\n", __func__);
+ data->pdata.call_ops = call_ops;
+ data->pdata.pnfs_error = 0;
+ data->pdata.how = how;
+ return pnfs_commit(data, how);
}
/* pNFS Commit callback function for all layout drivers */
@@ -1706,76 +1698,33 @@ pnfs_commit_done(struct nfs_write_data *data)
_pnfs_return_layout(data->inode, &range, NULL, RETURN_FILE,
true);
pnfs_initiate_commit(data, NFS_CLIENT(data->inode),
- pdata->call_ops, pdata->how);
+ pdata->call_ops, pdata->how, 1);
}
}
static enum pnfs_try_status
pnfs_commit(struct nfs_write_data *data, int sync)
{
- int result;
struct nfs_inode *nfsi = NFS_I(data->inode);
struct nfs_server *nfss = NFS_SERVER(data->inode);
- struct pnfs_layout_segment *lseg;
- struct nfs_page *first, *last, *p;
- int npages;
enum pnfs_try_status trypnfs;
- u64 count;
dprintk("%s: Begin\n", __func__);
- /* If the layout driver doesn't define its own commit function
- * use standard NFSv4 commit
- */
- first = last = nfs_list_entry(data->pages.next);
- npages = 0;
- list_for_each_entry(p, &data->pages, wb_list) {
- last = p;
- npages++;
- }
- /* COMMIT indicates the whole file with offset = count = 0
- * whereas layout segments indicate whole file with offset = 0,
- * count = NFS4_MAX_UINT64.
+ /* We need to account for possibility that
+ * each nfs_page can point to a different lseg (or be NULL).
+ * For the immediate case of whole-file-only layouts, we at
+ * least know there can be only a single lseg.
+ * We still have to account for the possibility of some being NULL.
+ * This will be done by passing the buck to the layout driver.
*/
- count = ((npages - 1) << PAGE_CACHE_SHIFT) + first->wb_bytes +
- (first != last) ? last->wb_bytes : 0;
- if (first->wb_offset == 0 && count == 0)
- count = NFS4_MAX_UINT64;
-
- /* FIXME: we really ought to keep the layout segment that we used
- to write the page around for committing it and never ask for a
- new one. If it was recalled we better commit the data first
- before returning it, otherwise the data needs to be rewritten,
- either with a new layout or to the MDS */
- result = _pnfs_update_layout(data->inode,
- NULL,
- count,
- first->wb_offset,
- IOMODE_RW,
- &lseg);
- /* If no layout have been retrieved,
- * use standard NFSv4 commit
- */
- if (result) {
- dprintk("%s: Updating layout failed (%d), retry with NFS \n",
- __func__, result);
- trypnfs = PNFS_NOT_ATTEMPTED;
- goto out;
- }
-
- dprintk("%s: Calling layout driver commit\n", __func__);
+ data->pdata.lseg = NULL;
if (!pnfs_use_rpc(nfss))
data->pdata.pnfsflags |= PNFS_NO_RPC;
- data->pdata.lseg = lseg;
trypnfs = nfss->pnfs_curr_ld->ld_io_ops->commit(&nfsi->layout,
sync, data);
- if (trypnfs == PNFS_NOT_ATTEMPTED) {
+ if (trypnfs == PNFS_NOT_ATTEMPTED)
data->pdata.pnfsflags &= ~PNFS_NO_RPC;
- data->pdata.lseg = NULL;
- put_lseg(lseg);
- }
-
-out:
dprintk("%s End (trypnfs:%d)\n", __func__, trypnfs);
return trypnfs;
}
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index d1a4f42..78defc3 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -139,21 +139,18 @@ pnfs_try_to_commit(struct nfs_write_data *data,
const struct rpc_call_ops *call_ops,
int how)
{
- struct inode *inode = data->inode;
- struct nfs_server *nfss = NFS_SERVER(inode);
enum pnfs_try_status ret;
- /* Note that we check for "write_pagelist" and not for "commit"
- since if async writes were done and pages weren't marked as stable
- the commit method MUST be defined by the LD */
- /* FIXME: write_pagelist should probably be mandated */
- if (PNFS_EXISTS_LDIO_OP(nfss, write_pagelist))
- ret = _pnfs_try_to_commit(data, call_ops, how);
- else
- ret = PNFS_NOT_ATTEMPTED;
-
+ /* Unlike in pnfs_try_to_write_data and pnfs_try_to_read_data,
+ * we have no guarantee that all nfs_pages point to the same
+ * lseg. However, if we reach here, we are guaranteed that at
+ * least one points to some lseg.
+ */
+ ret = _pnfs_try_to_commit(data, call_ops, how);
if (ret == PNFS_ATTEMPTED)
- nfs_inc_stats(inode, NFSIOS_PNFS_COMMIT);
+ nfs_inc_stats(data->inode, NFSIOS_PNFS_COMMIT);
+ else
+ _pnfs_clear_lseg_from_pages(&data->pages);
return ret;
}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 2302133..28e4907 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -527,7 +527,7 @@ nfs_need_commit(struct nfs_inode *nfsi)
* The requests are *not* checked to ensure that they form a contiguous set.
*/
static int
-nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages)
+nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages, int *use_pnfs)
{
struct nfs_inode *nfsi = NFS_I(inode);
int ret;
@@ -535,7 +535,8 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, u
if (!nfs_need_commit(nfsi))
return 0;
- ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT);
+ ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT,
+ use_pnfs);
if (ret > 0)
nfsi->ncommit -= ret;
if (nfs_need_commit(NFS_I(inode)))
@@ -1334,9 +1335,10 @@ EXPORT_SYMBOL(nfs_initiate_commit);
int pnfs_initiate_commit(struct nfs_write_data *data,
struct rpc_clnt *clnt,
const struct rpc_call_ops *call_ops,
- int how)
+ int how, int pnfs)
{
- if (pnfs_try_to_commit(data, &nfs_commit_ops, how) == PNFS_ATTEMPTED)
+ if (pnfs &&
+ (pnfs_try_to_commit(data, &nfs_commit_ops, how) == PNFS_ATTEMPTED))
return pnfs_get_write_status(data);
return nfs_initiate_commit(data, clnt, &nfs_commit_ops, how);
@@ -1347,7 +1349,7 @@ int pnfs_initiate_commit(struct nfs_write_data *data,
*/
static int nfs_commit_rpcsetup(struct list_head *head,
struct nfs_write_data *data,
- int how)
+ int how, int pnfs)
{
struct nfs_page *first = nfs_list_entry(head->next);
struct inode *inode = first->wb_context->path.dentry->d_inode;
@@ -1374,7 +1376,7 @@ static int nfs_commit_rpcsetup(struct list_head *head,
data->args.context = first->wb_context; /* used by commit done */
return pnfs_initiate_commit(data, NFS_CLIENT(inode), &nfs_commit_ops,
- how);
+ how, pnfs);
}
/* Handle memory error during commit */
@@ -1398,7 +1400,7 @@ EXPORT_SYMBOL(nfs_mark_list_commit);
* Commit dirty pages
*/
static int
-nfs_commit_list(struct inode *inode, struct list_head *head, int how)
+nfs_commit_list(struct inode *inode, struct list_head *head, int how, int pnfs)
{
struct nfs_write_data *data;
@@ -1407,7 +1409,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
goto out_bad;
/* Set up the argument struct */
- return nfs_commit_rpcsetup(head, data, how);
+ return nfs_commit_rpcsetup(head, data, how, pnfs);
out_bad:
nfs_mark_list_commit(head);
nfs_commit_clear_lock(NFS_I(inode));
@@ -1495,14 +1497,15 @@ static int nfs_commit_inode(struct inode *inode, int how)
LIST_HEAD(head);
int may_wait = how & FLUSH_SYNC;
int res = 0;
+ int use_pnfs = 0;
if (!nfs_commit_set_lock(NFS_I(inode), may_wait))
goto out;
spin_lock(&inode->i_lock);
- res = nfs_scan_commit(inode, &head, 0, 0);
+ res = nfs_scan_commit(inode, &head, 0, 0, &use_pnfs);
spin_unlock(&inode->i_lock);
if (res) {
- int error = nfs_commit_list(inode, &head, how);
+ int error = nfs_commit_list(inode, &head, how, use_pnfs);
if (error < 0)
return error;
if (may_wait)
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 18a455c..06e5157 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -83,7 +83,8 @@ extern void nfs_release_request(struct nfs_page *req);
extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *dst,
- pgoff_t idx_start, unsigned int npages, int tag);
+ pgoff_t idx_start, unsigned int npages, int tag,
+ int *use_pnfs);
extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
struct inode *inode,
int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int),
--
1.6.6.1
next prev parent reply other threads:[~2010-05-20 10:30 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-16 1:22 [PATCH 00/22] LAYOUTGET invocation Fred Isaman
2010-05-16 1:22 ` [PATCH 01/22] Revert "pnfs-nonfilelayout: Prelim support for non-file layout O_DIRECT" Fred Isaman
2010-05-16 1:22 ` [PATCH 02/22] Revert "pnfs: Enable O_DIRECT write path." Fred Isaman
2010-05-16 1:22 ` [PATCH 03/22] Revert "pnfs: Enable O_DIRECT read path." Fred Isaman
2010-05-16 1:22 ` [PATCH 04/22] Revert "pnfs: Add function to set up O_DIRECT I/O" Fred Isaman
2010-05-16 1:22 ` [PATCH 05/22] pnfs: filelayout: clean and breakup nfs4_pnfs_dserver_get Fred Isaman
2010-05-16 1:22 ` [PATCH 06/22] pnfs: filelayout: remove some dead code from filelayout_commit Fred Isaman
2010-05-16 1:22 ` [PATCH 07/22] pnfs: remove PNFS_LAYOUTGET_ON_OPEN Fred Isaman
2010-05-16 1:22 ` [PATCH 08/22] pnfs: track the number of outstanding commits Fred Isaman
2010-05-16 1:23 ` [PATCH 09/22] pnfs_submit: mandate basic io path operations for layout drivers Fred Isaman
2010-05-16 1:23 ` [PATCH 10/22] pnfs_submit: expose pnfs_update_layout, put_lseg, and get_lseg functions Fred Isaman
2010-05-16 1:23 ` [PATCH 11/22] pnfs_submit: stash and refcount lseg in read path Fred Isaman
2010-05-16 1:23 ` [PATCH 12/22] pnfs_submit: read path changeover Fred Isaman
2010-05-16 1:23 ` [PATCH 13/22] pnfs_submit: use fsdata to pass lseg Fred Isaman
2010-05-16 1:23 ` [PATCH 14/22] pnfs_submit: stash and refcount lseg in write path Fred Isaman
2010-05-16 1:23 ` [PATCH 15/22] pnfs_submit: remove pnfs_file_operations Fred Isaman
2010-05-16 1:23 ` [PATCH 16/22] pnfs_submit: remove pnfs_update_layout_commit Fred Isaman
2010-05-16 1:23 ` [PATCH 17/22] pnfs_submit: remove pnfs_writepages LAYOUTGET invocation Fred Isaman
2010-05-16 1:23 ` [PATCH 18/22] pnfs: export some commit error handling for use by layout drivers Fred Isaman
2010-05-16 1:23 ` Fred Isaman [this message]
2010-05-16 1:23 ` [PATCH 20/22] pnfs_submit: filelayout: rewrite filelayout_commit to use new API Fred Isaman
2010-05-16 1:23 ` [PATCH 21/22] pnfs_submit: remove unecessary pnfs_fl_call_data field pnfs_client Fred Isaman
2010-05-16 1:23 ` [PATCH 22/22] pnfs_submit: remove unecessary pnfs_fl_call_data field commit_through_mds Fred Isaman
2010-05-25 18:27 ` [PATCH 00/22] LAYOUTGET invocation Dean Hildebrand
2010-05-25 19:03 ` Fred Isaman
2010-05-25 20:14 ` Dean Hildebrand
2010-05-26 8:43 ` Boaz Harrosh
2010-05-26 17:39 ` Dean Hildebrand
2010-05-26 17:58 ` Fred Isaman
2010-05-26 18:13 ` Boaz Harrosh
2010-05-26 18:53 ` Dean Hildebrand
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=1273972993-15369-20-git-send-email-iisaman@netapp.com \
--to=iisaman@netapp.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).