nfsd: Set PF_LOCAL_THROTTLE on local filesystems only
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 30 Nov 2020 22:03:19 +0000 (17:03 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Wed, 9 Dec 2020 14:39:38 +0000 (09:39 -0500)
Don't set PF_LOCAL_THROTTLE on remote filesystems like NFS, since they
aren't expected to ever be subject to double buffering.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfs/export.c
fs/nfsd/vfs.c
include/linux/exportfs.h

index 5428713..48b879c 100644 (file)
@@ -171,5 +171,6 @@ const struct export_operations nfs_export_ops = {
        .encode_fh = nfs_encode_fh,
        .fh_to_dentry = nfs_fh_to_dentry,
        .get_parent = nfs_get_parent,
-       .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|EXPORT_OP_CLOSE_BEFORE_UNLINK,
+       .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|
+               EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS,
 };
index 79cba94..04937e5 100644 (file)
@@ -978,18 +978,25 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
                                __be32 *verf)
 {
        struct file             *file = nf->nf_file;
+       struct super_block      *sb = file_inode(file)->i_sb;
        struct svc_export       *exp;
        struct iov_iter         iter;
        __be32                  nfserr;
        int                     host_err;
        int                     use_wgather;
        loff_t                  pos = offset;
+       unsigned long           exp_op_flags = 0;
        unsigned int            pflags = current->flags;
        rwf_t                   flags = 0;
+       bool                    restore_flags = false;
 
        trace_nfsd_write_opened(rqstp, fhp, offset, *cnt);
 
-       if (test_bit(RQ_LOCAL, &rqstp->rq_flags))
+       if (sb->s_export_op)
+               exp_op_flags = sb->s_export_op->flags;
+
+       if (test_bit(RQ_LOCAL, &rqstp->rq_flags) &&
+           !(exp_op_flags & EXPORT_OP_REMOTE_FS)) {
                /*
                 * We want throttling in balance_dirty_pages()
                 * and shrink_inactive_list() to only consider
@@ -998,6 +1005,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
                 * the client's dirty pages or its congested queue.
                 */
                current->flags |= PF_LOCAL_THROTTLE;
+               restore_flags = true;
+       }
 
        exp = fhp->fh_export;
        use_wgather = (rqstp->rq_vers == 2) && EX_WGATHER(exp);
@@ -1049,7 +1058,7 @@ out_nfserr:
                trace_nfsd_write_err(rqstp, fhp, offset, host_err);
                nfserr = nfserrno(host_err);
        }
-       if (test_bit(RQ_LOCAL, &rqstp->rq_flags))
+       if (restore_flags)
                current_restore_flags(pflags, PF_LOCAL_THROTTLE);
        return nfserr;
 }
index 846df3c..d93e8a6 100644 (file)
@@ -216,6 +216,7 @@ struct export_operations {
 #define        EXPORT_OP_NOWCC                 (0x1) /* don't collect v3 wcc data */
 #define        EXPORT_OP_NOSUBTREECHK          (0x2) /* no subtree checking */
 #define        EXPORT_OP_CLOSE_BEFORE_UNLINK   (0x4) /* close files before unlink */
+#define EXPORT_OP_REMOTE_FS            (0x8) /* Filesystem is remote */
        unsigned long   flags;
 };