[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170509154930.29524-25-jlayton@redhat.com>
Date: Tue, 9 May 2017 11:49:27 -0400
From: Jeff Layton <jlayton@...hat.com>
To: linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-btrfs@...r.kernel.org, linux-ext4@...r.kernel.org,
linux-cifs@...r.kernel.org, linux-nfs@...r.kernel.org,
linux-mm@...ck.org, jfs-discussion@...ts.sourceforge.net,
linux-xfs@...r.kernel.org, cluster-devel@...hat.com,
linux-f2fs-devel@...ts.sourceforge.net,
v9fs-developer@...ts.sourceforge.net, linux-nilfs@...r.kernel.org,
linux-block@...r.kernel.org
Cc: dhowells@...hat.com, akpm@...ux-foundation.org, hch@...radead.org,
ross.zwisler@...ux.intel.com, mawilcox@...rosoft.com,
jack@...e.com, viro@...iv.linux.org.uk, corbet@....net,
neilb@...e.de, clm@...com, tytso@....edu, axboe@...nel.dk,
josef@...icpanda.com, hubcap@...ibond.com, rpeterso@...hat.com,
bo.li.liu@...cle.com
Subject: [PATCH v4 24/27][RFC] nfs: convert to new errseq_t based error tracking for writeback errors
Drop the ERROR_WRITE flag and convert the error field in the context to
a errseq_t. Add a new wb_err_cursor to track the reporting of the
errseq_t. In principle, we could use the f_wb_err field in struct file
for that, but that's problematic with the stock reporting in call_fsync.
Signed-off-by: Jeff Layton <jlayton@...hat.com>
---
fs/nfs/file.c | 19 +++++++++++--------
fs/nfs/inode.c | 5 +++--
fs/nfs/write.c | 2 +-
include/linux/nfs_fs.h | 3 ++-
4 files changed, 17 insertions(+), 12 deletions(-)
I did this on a lark to see how it would be, but I don't think this is
really better than what's there already. There may be a better way to
provide the right semantics without using an errseq_t here.
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 668213984d68..fd4d2b381d4b 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -212,21 +212,24 @@ nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
{
struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = file_inode(file);
- int have_error, do_resend, status;
- int ret = 0;
+ int do_resend, status;
+ int ret;
dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
- have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
+ clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
status = nfs_commit_inode(inode, FLUSH_SYNC);
- have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
- if (have_error) {
- ret = xchg(&ctx->error, 0);
- if (ret)
- goto out;
+ ret = errseq_check(&ctx->wb_err, READ_ONCE(ctx->wb_err_cursor));
+ if (ret) {
+ /* Use f_lock to serialize changes to wb_err_cursor */
+ spin_lock(&file->f_lock);
+ ret = errseq_check_and_advance(&ctx->wb_err, &ctx->wb_err_cursor);
+ spin_unlock(&file->f_lock);
}
+ if (ret)
+ goto out;
if (status < 0) {
ret = status;
goto out;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f489a5a71bd5..ca85f6b39e3b 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -869,7 +869,8 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
ctx->state = NULL;
ctx->mode = f_mode;
ctx->flags = 0;
- ctx->error = 0;
+ ctx->wb_err = 0;
+ ctx->wb_err_cursor = 0;
ctx->flock_owner = (fl_owner_t)filp;
nfs_init_lock_context(&ctx->lock_context);
ctx->lock_context.open_context = ctx;
@@ -978,7 +979,7 @@ void nfs_file_clear_open_context(struct file *filp)
* We fatal error on write before. Try to writeback
* every page again.
*/
- if (ctx->error < 0)
+ if (errseq_check(&ctx->wb_err, ctx->wb_err_cursor))
invalidate_inode_pages2(inode->i_mapping);
filp->private_data = NULL;
spin_lock(&inode->i_lock);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index abb2c8a3be42..95a5b4ac6714 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -94,7 +94,7 @@ static void nfs_writehdr_free(struct nfs_pgio_header *hdr)
static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
{
- ctx->error = error;
+ errseq_set(&ctx->wb_err, error);
smp_wmb();
set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
}
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 287f34161086..336adf1a38f7 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -76,7 +76,8 @@ struct nfs_open_context {
#define NFS_CONTEXT_ERROR_WRITE (0)
#define NFS_CONTEXT_RESEND_WRITES (1)
#define NFS_CONTEXT_BAD (2)
- int error;
+ errseq_t wb_err; /* where wb errors are tracked */
+ errseq_t wb_err_cursor; /* reporting cursor */
struct list_head list;
struct nfs4_threshold *mdsthreshold;
--
2.9.3
Powered by blists - more mailing lists