Merge tag 'nfs-for-5.16-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Nov 2021 00:32:46 +0000 (16:32 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Nov 2021 00:32:46 +0000 (16:32 -0800)
Pull NFS client updates from Trond Myklebust:
 "Highlights include:

  Features:
   - NFSv4.1 can always retrieve and cache the ACCESS mode on OPEN
   - Optimisations for READDIR and the 'ls -l' style workload
   - Further replacements of dprintk() with tracepoints and other
     tracing improvements
   - Ensure we re-probe NFSv4 server capabilities when the user does a
     "mount -o remount"

  Bugfixes:
   - Fix an Oops in pnfs_mark_request_commit()
   - Fix up deadlocks in the commit code
   - Fix regressions in NFSv2/v3 attribute revalidation due to the
     change_attr_type optimisations
   - Fix some dentry verifier races
   - Fix some missing dentry verifier settings
   - Fix a performance regression in nfs_set_open_stateid_locked()
   - SUNRPC was sending multiple SYN calls when re-establishing a TCP
     connection.
   - Fix multiple NFSv4 issues due to missing sanity checking of server
     return values
   - Fix a potential Oops when FREE_STATEID races with an unmount

  Cleanups:
   - Clean up the labelled NFS code
   - Remove unused header <linux/pnfs_osd_xdr.h>"

* tag 'nfs-for-5.16-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (84 commits)
  NFSv4: Sanity check the parameters in nfs41_update_target_slotid()
  NFS: Remove the nfs4_label argument from decode_getattr_*() functions
  NFS: Remove the nfs4_label argument from nfs_setsecurity
  NFS: Remove the nfs4_label argument from nfs_fhget()
  NFS: Remove the nfs4_label argument from nfs_add_or_obtain()
  NFS: Remove the nfs4_label argument from nfs_instantiate()
  NFS: Remove the nfs4_label from the nfs_setattrres
  NFS: Remove the nfs4_label from the nfs4_getattr_res
  NFS: Remove the f_label from the nfs4_opendata and nfs_openres
  NFS: Remove the nfs4_label from the nfs4_lookupp_res struct
  NFS: Remove the label from the nfs4_lookup_res struct
  NFS: Remove the nfs4_label from the nfs4_link_res struct
  NFS: Remove the nfs4_label from the nfs4_create_res struct
  NFS: Remove the nfs4_label from the nfs_entry struct
  NFS: Create a new nfs_alloc_fattr_with_label() function
  NFS: Always initialise fattr->label in nfs_fattr_alloc()
  NFSv4.2: alloc_file_pseudo() takes an open flag, not an f_mode
  NFS: Don't allocate nfs_fattr on the stack in __nfs42_ssc_open()
  NFSv4: Remove unnecessary 'minor version' check
  NFSv4: Fix potential Oops in decode_op_map()
  ...

59 files changed:
fs/lockd/clntproc.c
fs/lockd/svc4proc.c
fs/lockd/svcproc.c
fs/nfs/callback_proc.c
fs/nfs/client.c
fs/nfs/delegation.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/export.c
fs/nfs/filelayout/filelayout.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/getroot.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/namespace.c
fs/nfs/nfs3proc.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs42proc.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4file.c
fs/nfs/nfs4idmap.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4session.c
fs/nfs/nfs4session.h
fs/nfs/nfs4state.c
fs/nfs/nfs4trace.h
fs/nfs/nfs4xdr.c
fs/nfs/nfstrace.h
fs/nfs/pagelist.c
fs/nfs/pnfs.h
fs/nfs/pnfs_nfs.c
fs/nfs/proc.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/trace.h
include/linux/nfs4.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/pnfs_osd_xdr.h [deleted file]
include/linux/sunrpc/clnt.h
include/linux/sunrpc/sched.h
include/trace/events/fs.h [new file with mode: 0644]
include/trace/events/nfs.h [new file with mode: 0644]
include/trace/events/rpcgss.h
include/trace/events/rpcrdma.h
include/trace/events/sunrpc.h
include/trace/events/sunrpc_base.h [new file with mode: 0644]
net/sunrpc/clnt.c
net/sunrpc/sched.c
net/sunrpc/sysfs.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtrdma/xprt_rdma.h
net/sunrpc/xprtsock.c

index b11f2af..99fffc9 100644 (file)
@@ -794,9 +794,6 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
                goto retry_cancel;
        }
 
-       dprintk("lockd: cancel status %u (task %u)\n",
-                       status, task->tk_pid);
-
        switch (status) {
        case NLM_LCK_GRANTED:
        case NLM_LCK_DENIED_GRACE_PERIOD:
index e10ae2c..176b468 100644 (file)
@@ -269,8 +269,6 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp)
  */
 static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
 {
-       dprintk("lockd: %5u callback returned %d\n", task->tk_pid,
-                       -task->tk_status);
 }
 
 static void nlm4svc_callback_release(void *data)
index 99696d3..4dc1b40 100644 (file)
@@ -301,8 +301,6 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp)
  */
 static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
 {
-       dprintk("lockd: %5u callback returned %d\n", task->tk_pid,
-                       -task->tk_status);
 }
 
 void nlmsvc_release_call(struct nlm_rqst *call)
index ed9d580..09c5b1c 100644 (file)
@@ -739,6 +739,9 @@ out:
                kfree(copy);
        spin_unlock(&cps->clp->cl_lock);
 
+       trace_nfs4_cb_offload(&args->coa_fh, &args->coa_stateid,
+                       args->wr_count, args->error,
+                       args->wr_writeverf.committed);
        return 0;
 }
 #endif /* CONFIG_NFS_V4_2 */
index 23e165d..1e4dc1a 100644 (file)
@@ -828,7 +828,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
 /*
  * Probe filesystem information, including the FSID on v2/v3
  */
-int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
+static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
 {
        struct nfs_fsinfo fsinfo;
        struct nfs_client *clp = server->nfs_client;
@@ -862,7 +862,30 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(nfs_probe_fsinfo);
+
+/*
+ * Grab the destination's particulars, including lease expiry time.
+ *
+ * Returns zero if probe succeeded and retrieved FSID matches the FSID
+ * we have cached.
+ */
+int nfs_probe_server(struct nfs_server *server, struct nfs_fh *mntfh)
+{
+       struct nfs_fattr *fattr;
+       int error;
+
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               return -ENOMEM;
+
+       /* Sanity: the probe won't work if the destination server
+        * does not recognize the migrated FH. */
+       error = nfs_probe_fsinfo(server, mntfh, fattr);
+
+       nfs_free_fattr(fattr);
+       return error;
+}
+EXPORT_SYMBOL_GPL(nfs_probe_server);
 
 /*
  * Copy useful information when duplicating a server record
@@ -1025,7 +1048,7 @@ struct nfs_server *nfs_create_server(struct fs_context *fc)
 
        if (!(fattr->valid & NFS_ATTR_FATTR)) {
                error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh,
-                                                      fattr, NULL, NULL);
+                                                      fattr, NULL);
                if (error < 0) {
                        dprintk("nfs_create_server: getattr error = %d\n", -error);
                        goto error;
@@ -1058,7 +1081,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
                                    rpc_authflavor_t flavor)
 {
        struct nfs_server *server;
-       struct nfs_fattr *fattr_fsinfo;
        int error;
 
        server = nfs_alloc_server();
@@ -1067,11 +1089,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 
        server->cred = get_cred(source->cred);
 
-       error = -ENOMEM;
-       fattr_fsinfo = nfs_alloc_fattr();
-       if (fattr_fsinfo == NULL)
-               goto out_free_server;
-
        /* Copy data from the source */
        server->nfs_client = source->nfs_client;
        server->destroy = source->destroy;
@@ -1087,7 +1104,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
                goto out_free_server;
 
        /* probe the filesystem info for this server filesystem */
-       error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
+       error = nfs_probe_server(server, fh);
        if (error < 0)
                goto out_free_server;
 
@@ -1101,11 +1118,9 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
        nfs_server_insert_lists(server);
        server->mount_time = jiffies;
 
-       nfs_free_fattr(fattr_fsinfo);
        return server;
 
 out_free_server:
-       nfs_free_fattr(fattr_fsinfo);
        nfs_free_server(server);
        return ERR_PTR(error);
 }
index 1111839..7c9eb67 100644 (file)
@@ -755,11 +755,13 @@ int nfs4_inode_return_delegation(struct inode *inode)
        struct nfs_delegation *delegation;
 
        delegation = nfs_start_delegation_return(nfsi);
-       /* Synchronous recall of any application leases */
-       break_lease(inode, O_WRONLY | O_RDWR);
-       nfs_wb_all(inode);
-       if (delegation != NULL)
+       if (delegation != NULL) {
+               /* Synchronous recall of any application leases */
+               break_lease(inode, O_WRONLY | O_RDWR);
+               if (S_ISREG(inode->i_mode))
+                       nfs_wb_all(inode);
                return nfs_end_delegation_return(inode, delegation, 1);
+       }
        return 0;
 }
 
index 1a6d286..731d310 100644 (file)
@@ -78,6 +78,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir
                ctx->attr_gencount = nfsi->attr_gencount;
                ctx->dir_cookie = 0;
                ctx->dup_cookie = 0;
+               ctx->page_index = 0;
                spin_lock(&dir->i_lock);
                if (list_empty(&nfsi->open_files) &&
                    (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER))
@@ -85,6 +86,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir
                                              NFS_INO_INVALID_DATA |
                                                      NFS_INO_REVAL_FORCED);
                list_add(&ctx->list, &nfsi->open_files);
+               clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags);
                spin_unlock(&dir->i_lock);
                return ctx;
        }
@@ -411,7 +413,8 @@ out_eof:
 static bool
 nfs_readdir_inode_mapping_valid(struct nfs_inode *nfsi)
 {
-       if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
+       if (nfsi->cache_validity & (NFS_INO_INVALID_CHANGE |
+                                   NFS_INO_INVALID_DATA))
                return false;
        smp_rmb();
        return !test_bit(NFS_INO_INVALIDATING, &nfsi->flags);
@@ -626,8 +629,7 @@ void nfs_force_use_readdirplus(struct inode *dir)
        if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) &&
            !list_empty(&nfsi->open_files)) {
                set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
-               invalidate_mapping_pages(dir->i_mapping,
-                       nfsi->page_index + 1, -1);
+               set_bit(NFS_INO_FORCE_READDIR, &nfsi->flags);
        }
 }
 
@@ -680,7 +682,7 @@ again:
                        nfs_set_verifier(dentry, dir_verifier);
                        status = nfs_refresh_inode(d_inode(dentry), entry->fattr);
                        if (!status)
-                               nfs_setsecurity(d_inode(dentry), entry->fattr, entry->label);
+                               nfs_setsecurity(d_inode(dentry), entry->fattr);
                        goto out;
                } else {
                        d_invalidate(dentry);
@@ -694,7 +696,7 @@ again:
                goto out;
        }
 
-       inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label);
+       inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
        alias = d_splice_alias(inode, dentry);
        d_lookup_done(dentry);
        if (alias) {
@@ -730,8 +732,8 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc,
        xdr_set_scratch_page(&stream, scratch);
 
        do {
-               if (entry->label)
-                       entry->label->len = NFS4_MAXLABELLEN;
+               if (entry->fattr->label)
+                       entry->fattr->label->len = NFS4_MAXLABELLEN;
 
                status = xdr_decode(desc, entry, &stream);
                if (status != 0)
@@ -836,21 +838,15 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
                return -ENOMEM;
        entry->cookie = nfs_readdir_page_last_cookie(page);
        entry->fh = nfs_alloc_fhandle();
-       entry->fattr = nfs_alloc_fattr();
+       entry->fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
        entry->server = NFS_SERVER(inode);
        if (entry->fh == NULL || entry->fattr == NULL)
                goto out;
 
-       entry->label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
-       if (IS_ERR(entry->label)) {
-               status = PTR_ERR(entry->label);
-               goto out;
-       }
-
        array_size = (dtsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
        pages = nfs_readdir_alloc_pages(array_size);
        if (!pages)
-               goto out_release_label;
+               goto out;
 
        do {
                unsigned int pglen;
@@ -873,8 +869,6 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
        } while (!status && nfs_readdir_page_needs_filling(page));
 
        nfs_readdir_free_pages(pages, array_size);
-out_release_label:
-       nfs4_label_free(entry->label);
 out:
        nfs_free_fattr(entry->fattr);
        nfs_free_fhandle(entry->fh);
@@ -937,10 +931,8 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
                               sizeof(nfsi->cookieverf));
        }
        res = nfs_readdir_search_array(desc);
-       if (res == 0) {
-               nfsi->page_index = desc->page_index;
+       if (res == 0)
                return 0;
-       }
        nfs_readdir_page_unlock_and_put_cached(desc);
        return res;
 }
@@ -1079,6 +1071,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
        struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs_open_dir_context *dir_ctx = file->private_data;
        struct nfs_readdir_descriptor *desc;
+       pgoff_t page_index;
        int res;
 
        dfprintk(FILE, "NFS: readdir(%pD2) starting at cookie %llu\n",
@@ -1109,10 +1102,15 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
        desc->dir_cookie = dir_ctx->dir_cookie;
        desc->dup_cookie = dir_ctx->dup_cookie;
        desc->duped = dir_ctx->duped;
+       page_index = dir_ctx->page_index;
        desc->attr_gencount = dir_ctx->attr_gencount;
        memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf));
        spin_unlock(&file->f_lock);
 
+       if (test_and_clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags) &&
+           list_is_singular(&nfsi->open_files))
+               invalidate_mapping_pages(inode->i_mapping, page_index + 1, -1);
+
        do {
                res = readdir_search_pagecache(desc);
 
@@ -1149,6 +1147,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
        dir_ctx->dup_cookie = desc->dup_cookie;
        dir_ctx->duped = desc->duped;
        dir_ctx->attr_gencount = desc->attr_gencount;
+       dir_ctx->page_index = desc->page_index;
        memcpy(dir_ctx->verf, desc->verf, sizeof(dir_ctx->verf));
        spin_unlock(&file->f_lock);
 
@@ -1269,13 +1268,12 @@ static bool nfs_verifier_is_delegated(struct dentry *dentry)
 static void nfs_set_verifier_locked(struct dentry *dentry, unsigned long verf)
 {
        struct inode *inode = d_inode(dentry);
+       struct inode *dir = d_inode(dentry->d_parent);
 
-       if (!nfs_verifier_is_delegated(dentry) &&
-           !nfs_verify_change_attribute(d_inode(dentry->d_parent), verf))
-               goto out;
+       if (!nfs_verify_change_attribute(dir, verf))
+               return;
        if (inode && NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
                nfs_set_verifier_delegated(&verf);
-out:
        dentry->d_time = verf;
 }
 
@@ -1413,7 +1411,7 @@ out_force:
 static void nfs_mark_dir_for_revalidate(struct inode *inode)
 {
        spin_lock(&inode->i_lock);
-       nfs_set_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE);
+       nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE);
        spin_unlock(&inode->i_lock);
 }
 
@@ -1495,19 +1493,17 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,
 {
        struct nfs_fh *fhandle;
        struct nfs_fattr *fattr;
-       struct nfs4_label *label;
        unsigned long dir_verifier;
        int ret;
 
        ret = -ENOMEM;
        fhandle = nfs_alloc_fhandle();
-       fattr = nfs_alloc_fattr();
-       label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
-       if (fhandle == NULL || fattr == NULL || IS_ERR(label))
+       fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
+       if (fhandle == NULL || fattr == NULL)
                goto out;
 
        dir_verifier = nfs_save_change_attribute(dir);
-       ret = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label);
+       ret = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr);
        if (ret < 0) {
                switch (ret) {
                case -ESTALE:
@@ -1526,7 +1522,7 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,
        if (nfs_refresh_inode(inode, fattr) < 0)
                goto out;
 
-       nfs_setsecurity(inode, fattr, label);
+       nfs_setsecurity(inode, fattr);
        nfs_set_verifier(dentry, dir_verifier);
 
        /* set a readdirplus hint that we had a cache miss */
@@ -1535,7 +1531,6 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,
 out:
        nfs_free_fattr(fattr);
        nfs_free_fhandle(fhandle);
-       nfs4_label_free(label);
 
        /*
         * If the lookup failed despite the dentry change attribute being
@@ -1721,10 +1716,6 @@ static void nfs_drop_nlink(struct inode *inode)
  */
 static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
 {
-       if (S_ISDIR(inode->i_mode))
-               /* drop any readdir cache as it could easily be old */
-               nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
-
        if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
                nfs_complete_unlink(dentry, inode);
                nfs_drop_nlink(inode);
@@ -1759,7 +1750,6 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
        struct inode *inode = NULL;
        struct nfs_fh *fhandle = NULL;
        struct nfs_fattr *fattr = NULL;
-       struct nfs4_label *label = NULL;
        unsigned long dir_verifier;
        int error;
 
@@ -1778,27 +1768,23 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
 
        res = ERR_PTR(-ENOMEM);
        fhandle = nfs_alloc_fhandle();
-       fattr = nfs_alloc_fattr();
+       fattr = nfs_alloc_fattr_with_label(NFS_SERVER(dir));
        if (fhandle == NULL || fattr == NULL)
                goto out;
 
-       label = nfs4_label_alloc(NFS_SERVER(dir), GFP_NOWAIT);
-       if (IS_ERR(label))
-               goto out;
-
        dir_verifier = nfs_save_change_attribute(dir);
        trace_nfs_lookup_enter(dir, dentry, flags);
-       error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label);
+       error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr);
        if (error == -ENOENT)
                goto no_entry;
        if (error < 0) {
                res = ERR_PTR(error);
-               goto out_label;
+               goto out;
        }
-       inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
+       inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
        res = ERR_CAST(inode);
        if (IS_ERR(res))
-               goto out_label;
+               goto out;
 
        /* Notify readdir to use READDIRPLUS */
        nfs_force_use_readdirplus(dir);
@@ -1807,14 +1793,12 @@ no_entry:
        res = d_splice_alias(inode, dentry);
        if (res != NULL) {
                if (IS_ERR(res))
-                       goto out_label;
+                       goto out;
                dentry = res;
        }
        nfs_set_verifier(dentry, dir_verifier);
-out_label:
-       trace_nfs_lookup_exit(dir, dentry, flags, error);
-       nfs4_label_free(label);
 out:
+       trace_nfs_lookup_exit(dir, dentry, flags, PTR_ERR_OR_ZERO(res));
        nfs_free_fattr(fattr);
        nfs_free_fhandle(fhandle);
        return res;
@@ -2051,8 +2035,7 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
 
 struct dentry *
 nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
-                               struct nfs_fattr *fattr,
-                               struct nfs4_label *label)
+                               struct nfs_fattr *fattr)
 {
        struct dentry *parent = dget_parent(dentry);
        struct inode *dir = d_inode(parent);
@@ -2063,7 +2046,7 @@ nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
        d_drop(dentry);
 
        if (fhandle->size == 0) {
-               error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, NULL);
+               error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr);
                if (error)
                        goto out_error;
        }
@@ -2071,11 +2054,11 @@ nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
        if (!(fattr->valid & NFS_ATTR_FATTR)) {
                struct nfs_server *server = NFS_SB(dentry->d_sb);
                error = server->nfs_client->rpc_ops->getattr(server, fhandle,
-                               fattr, NULL, NULL);
+                               fattr, NULL);
                if (error < 0)
                        goto out_error;
        }
-       inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
+       inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
        d = d_splice_alias(inode, dentry);
 out:
        dput(parent);
@@ -2090,12 +2073,11 @@ EXPORT_SYMBOL_GPL(nfs_add_or_obtain);
  * Code common to create, mkdir, and mknod.
  */
 int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
-                               struct nfs_fattr *fattr,
-                               struct nfs4_label *label)
+                               struct nfs_fattr *fattr)
 {
        struct dentry *d;
 
-       d = nfs_add_or_obtain(dentry, fhandle, fattr, label);
+       d = nfs_add_or_obtain(dentry, fhandle, fattr);
        if (IS_ERR(d))
                return PTR_ERR(d);
 
@@ -2197,6 +2179,18 @@ static void nfs_dentry_handle_enoent(struct dentry *dentry)
                d_delete(dentry);
 }
 
+static void nfs_dentry_remove_handle_error(struct inode *dir,
+                                          struct dentry *dentry, int error)
+{
+       switch (error) {
+       case -ENOENT:
+               d_delete(dentry);
+               fallthrough;
+       case 0:
+               nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+       }
+}
+
 int nfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
        int error;
@@ -2219,6 +2213,7 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)
                up_write(&NFS_I(d_inode(dentry))->rmdir_sem);
        } else
                error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
+       nfs_dentry_remove_handle_error(dir, dentry, error);
        trace_nfs_rmdir_exit(dir, dentry, error);
 
        return error;
@@ -2288,9 +2283,8 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
        }
        spin_unlock(&dentry->d_lock);
        error = nfs_safe_remove(dentry);
-       if (!error || error == -ENOENT) {
-               nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
-       } else if (need_rehash)
+       nfs_dentry_remove_handle_error(dir, dentry, error);
+       if (need_rehash)
                d_rehash(dentry);
 out:
        trace_nfs_unlink_exit(dir, dentry, error);
@@ -2352,6 +2346,8 @@ int nfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
                return error;
        }
 
+       nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+
        /*
         * No big deal if we can't add this page to the page cache here.
         * READLINK will get the missing page from the server if needed.
@@ -2385,6 +2381,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
        d_drop(dentry);
        error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
        if (error == 0) {
+               nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
                ihold(inode);
                d_add(dentry, inode);
        }
index 7a5f287..9cff870 100644 (file)
@@ -620,7 +620,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
                nfs_unlock_and_release_request(req);
        }
 
-       if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
+       if (nfs_commit_end(cinfo.mds))
                nfs_direct_write_complete(dreq);
 }
 
index d772c20..171c424 100644 (file)
@@ -64,7 +64,6 @@ static struct dentry *
 nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
                 int fh_len, int fh_type)
 {
-       struct nfs4_label *label = NULL;
        struct nfs_fattr *fattr = NULL;
        struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
        size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
@@ -79,7 +78,7 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
        if (fh_len < len || fh_type != len)
                return NULL;
 
-       fattr = nfs_alloc_fattr();
+       fattr = nfs_alloc_fattr_with_label(NFS_SB(sb));
        if (fattr == NULL) {
                dentry = ERR_PTR(-ENOMEM);
                goto out;
@@ -95,28 +94,19 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
        if (inode)
                goto out_found;
 
-       label = nfs4_label_alloc(NFS_SB(sb), GFP_KERNEL);
-       if (IS_ERR(label)) {
-               dentry = ERR_CAST(label);
-               goto out_free_fattr;
-       }
-
        rpc_ops = NFS_SB(sb)->nfs_client->rpc_ops;
-       ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, label, NULL);
+       ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, NULL);
        if (ret) {
                dprintk("%s: getattr failed %d\n", __func__, ret);
                trace_nfs_fh_to_dentry(sb, server_fh, fattr->fileid, ret);
                dentry = ERR_PTR(ret);
-               goto out_free_label;
+               goto out_free_fattr;
        }
 
-       inode = nfs_fhget(sb, server_fh, fattr, label);
+       inode = nfs_fhget(sb, server_fh, fattr);
 
 out_found:
        dentry = d_obtain_alias(inode);
-
-out_free_label:
-       nfs4_label_free(label);
 out_free_fattr:
        nfs_free_fattr(fattr);
 out:
@@ -131,7 +121,6 @@ nfs_get_parent(struct dentry *dentry)
        struct super_block *sb = inode->i_sb;
        struct nfs_server *server = NFS_SB(sb);
        struct nfs_fattr *fattr = NULL;
-       struct nfs4_label *label = NULL;
        struct dentry *parent;
        struct nfs_rpc_ops const *ops = server->nfs_client->rpc_ops;
        struct nfs_fh fh;
@@ -139,31 +128,20 @@ nfs_get_parent(struct dentry *dentry)
        if (!ops->lookupp)
                return ERR_PTR(-EACCES);
 
-       fattr = nfs_alloc_fattr();
-       if (fattr == NULL) {
-               parent = ERR_PTR(-ENOMEM);
-               goto out;
-       }
+       fattr = nfs_alloc_fattr_with_label(server);
+       if (fattr == NULL)
+               return ERR_PTR(-ENOMEM);
 
-       label = nfs4_label_alloc(server, GFP_KERNEL);
-       if (IS_ERR(label)) {
-               parent = ERR_CAST(label);
-               goto out_free_fattr;
-       }
-
-       ret = ops->lookupp(inode, &fh, fattr, label);
+       ret = ops->lookupp(inode, &fh, fattr);
        if (ret) {
                parent = ERR_PTR(ret);
-               goto out_free_label;
+               goto out;
        }
 
-       pinode = nfs_fhget(sb, &fh, fattr, label);
+       pinode = nfs_fhget(sb, &fh, fattr);
        parent = d_obtain_alias(pinode);
-out_free_label:
-       nfs4_label_free(label);
-out_free_fattr:
-       nfs_free_fattr(fattr);
 out:
+       nfs_free_fattr(fattr);
        return parent;
 }
 
index d210385..9c96e3e 100644 (file)
@@ -293,8 +293,6 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data)
 {
        struct nfs_pgio_header *hdr = data;
 
-       dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status);
-
        if (test_bit(NFS_IOHDR_REDO, &hdr->flags) &&
            task->tk_status == 0) {
                nfs41_sequence_done(task, &hdr->res.seq_res);
index d383de0..a553d59 100644 (file)
@@ -1414,8 +1414,6 @@ static void ff_layout_read_call_done(struct rpc_task *task, void *data)
 {
        struct nfs_pgio_header *hdr = data;
 
-       dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status);
-
        if (test_bit(NFS_IOHDR_REDO, &hdr->flags) &&
            task->tk_status == 0) {
                nfs4_sequence_done(task, &hdr->res.seq_res);
index c9b61b8..bfa7202 100644 (file)
@@ -378,10 +378,10 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
                goto noconnect;
 
        ds = mirror->mirror_ds->ds;
+       if (READ_ONCE(ds->ds_clp))
+               goto out;
        /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
        smp_rmb();
-       if (ds->ds_clp)
-               goto out;
 
        /* FIXME: For now we assume the server sent only one version of NFS
         * to use for the DS.
index 59355c1..11ff2b2 100644 (file)
@@ -80,31 +80,28 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
                goto out;
 
        /* get the actual root for this mount */
-       fsinfo.fattr = nfs_alloc_fattr();
+       fsinfo.fattr = nfs_alloc_fattr_with_label(server);
        if (fsinfo.fattr == NULL)
                goto out_name;
 
-       fsinfo.fattr->label = nfs4_label_alloc(server, GFP_KERNEL);
-       if (IS_ERR(fsinfo.fattr->label))
-               goto out_fattr;
        error = server->nfs_client->rpc_ops->getroot(server, ctx->mntfh, &fsinfo);
        if (error < 0) {
                dprintk("nfs_get_root: getattr error = %d\n", -error);
                nfs_errorf(fc, "NFS: Couldn't getattr on root");
-               goto out_label;
+               goto out_fattr;
        }
 
-       inode = nfs_fhget(s, ctx->mntfh, fsinfo.fattr, NULL);
+       inode = nfs_fhget(s, ctx->mntfh, fsinfo.fattr);
        if (IS_ERR(inode)) {
                dprintk("nfs_get_root: get root inode failed\n");
                error = PTR_ERR(inode);
                nfs_errorf(fc, "NFS: Couldn't get root inode");
-               goto out_label;
+               goto out_fattr;
        }
 
        error = nfs_superblock_set_dummy_root(s, inode);
        if (error != 0)
-               goto out_label;
+               goto out_fattr;
 
        /* root dentries normally start off anonymous and get spliced in later
         * if the dentry tree reaches them; however if the dentry already
@@ -115,7 +112,7 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
                dprintk("nfs_get_root: get root dentry failed\n");
                error = PTR_ERR(root);
                nfs_errorf(fc, "NFS: Couldn't get root dentry");
-               goto out_label;
+               goto out_fattr;
        }
 
        security_d_instantiate(root, inode);
@@ -151,11 +148,9 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
                !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
                server->caps &= ~NFS_CAP_SECURITY_LABEL;
 
-       nfs_setsecurity(inode, fsinfo.fattr, fsinfo.fattr->label);
+       nfs_setsecurity(inode, fsinfo.fattr);
        error = 0;
 
-out_label:
-       nfs4_label_free(fsinfo.fattr->label);
 out_fattr:
        nfs_free_fattr(fsinfo.fattr);
 out_name:
@@ -165,5 +160,5 @@ out:
 error_splat_root:
        dput(fc->root);
        fc->root = NULL;
-       goto out_label;
+       goto out_fattr;
 }
index 853213b..dd53704 100644 (file)
@@ -210,10 +210,15 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
                flags &= ~NFS_INO_INVALID_XATTR;
        if (flags & NFS_INO_INVALID_DATA)
                nfs_fscache_invalidate(inode);
-       if (inode->i_mapping->nrpages == 0)
-               flags &= ~(NFS_INO_INVALID_DATA|NFS_INO_DATA_INVAL_DEFER);
        flags &= ~(NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED);
+
        nfsi->cache_validity |= flags;
+
+       if (inode->i_mapping->nrpages == 0)
+               nfsi->cache_validity &= ~(NFS_INO_INVALID_DATA |
+                                         NFS_INO_DATA_INVAL_DEFER);
+       else if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+               nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER;
 }
 EXPORT_SYMBOL_GPL(nfs_set_cache_invalid);
 
@@ -350,37 +355,32 @@ static void nfs_clear_label_invalid(struct inode *inode)
        spin_unlock(&inode->i_lock);
 }
 
-void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
-                                       struct nfs4_label *label)
+void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr)
 {
        int error;
 
-       if (label == NULL)
+       if (fattr->label == NULL)
                return;
 
        if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) {
-               error = security_inode_notifysecctx(inode, label->label,
-                               label->len);
+               error = security_inode_notifysecctx(inode, fattr->label->label,
+                               fattr->label->len);
                if (error)
                        printk(KERN_ERR "%s() %s %d "
                                        "security_inode_notifysecctx() %d\n",
                                        __func__,
-                                       (char *)label->label,
-                                       label->len, error);
+                                       (char *)fattr->label->label,
+                                       fattr->label->len, error);
                nfs_clear_label_invalid(inode);
        }
 }
 
 struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)
 {
-       struct nfs4_label *label = NULL;
-       int minor_version = server->nfs_client->cl_minorversion;
-
-       if (minor_version < 2)
-               return label;
+       struct nfs4_label *label;
 
        if (!(server->caps & NFS_CAP_SECURITY_LABEL))
-               return label;
+               return NULL;
 
        label = kzalloc(sizeof(struct nfs4_label), flags);
        if (label == NULL)
@@ -397,8 +397,7 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)
 }
 EXPORT_SYMBOL_GPL(nfs4_label_alloc);
 #else
-void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
-                                       struct nfs4_label *label)
+void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr)
 {
 }
 #endif
@@ -426,12 +425,28 @@ nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh)
        return inode;
 }
 
+static void nfs_inode_init_regular(struct nfs_inode *nfsi)
+{
+       atomic_long_set(&nfsi->nrequests, 0);
+       INIT_LIST_HEAD(&nfsi->commit_info.list);
+       atomic_long_set(&nfsi->commit_info.ncommit, 0);
+       atomic_set(&nfsi->commit_info.rpcs_out, 0);
+       mutex_init(&nfsi->commit_mutex);
+}
+
+static void nfs_inode_init_dir(struct nfs_inode *nfsi)
+{
+       nfsi->cache_change_attribute = 0;
+       memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
+       init_rwsem(&nfsi->rmdir_sem);
+}
+
 /*
  * This is our front-end to iget that looks up inodes by file handle
  * instead of inode number.
  */
 struct inode *
-nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, struct nfs4_label *label)
+nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
 {
        struct nfs_find_desc desc = {
                .fh     = fh,
@@ -480,10 +495,12 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                if (S_ISREG(inode->i_mode)) {
                        inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
                        inode->i_data.a_ops = &nfs_file_aops;
+                       nfs_inode_init_regular(nfsi);
                } else if (S_ISDIR(inode->i_mode)) {
                        inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
                        inode->i_fop = &nfs_dir_operations;
                        inode->i_data.a_ops = &nfs_dir_aops;
+                       nfs_inode_init_dir(nfsi);
                        /* Deal with crossing mountpoints */
                        if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT ||
                                        fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
@@ -509,7 +526,6 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                inode->i_uid = make_kuid(&init_user_ns, -2);
                inode->i_gid = make_kgid(&init_user_ns, -2);
                inode->i_blocks = 0;
-               memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
                nfsi->write_io = 0;
                nfsi->read_io = 0;
 
@@ -563,7 +579,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                           fattr->size != 0)
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_BLOCKS);
 
-               nfs_setsecurity(inode, fattr, label);
+               nfs_setsecurity(inode, fattr);
 
                nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
                nfsi->attrtimeo_timestamp = now;
@@ -632,7 +648,7 @@ nfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
        if (S_ISREG(inode->i_mode))
                nfs_sync_inode(inode);
 
-       fattr = nfs_alloc_fattr();
+       fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
        if (fattr == NULL) {
                error = -ENOMEM;
                goto out;
@@ -666,6 +682,7 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset)
        if (err)
                goto out;
 
+       trace_nfs_size_truncate(inode, offset);
        i_size_write(inode, offset);
        /* Optimisation */
        if (offset == 0)
@@ -1024,7 +1041,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
                ctx->cred = get_cred(filp->f_cred);
        else
                ctx->cred = get_current_cred();
-       ctx->ll_cred = NULL;
+       rcu_assign_pointer(ctx->ll_cred, NULL);
        ctx->state = NULL;
        ctx->mode = f_mode;
        ctx->flags = 0;
@@ -1063,7 +1080,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
        put_cred(ctx->cred);
        dput(ctx->dentry);
        nfs_sb_deactive(sb);
-       put_rpccred(ctx->ll_cred);
+       put_rpccred(rcu_dereference_protected(ctx->ll_cred, 1));
        kfree(ctx->mdsthreshold);
        kfree_rcu(ctx, rcu_head);
 }
@@ -1175,7 +1192,6 @@ int
 __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 {
        int              status = -ESTALE;
-       struct nfs4_label *label = NULL;
        struct nfs_fattr *fattr = NULL;
        struct nfs_inode *nfsi = NFS_I(inode);
 
@@ -1197,20 +1213,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
        }
 
        status = -ENOMEM;
-       fattr = nfs_alloc_fattr();
+       fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
        if (fattr == NULL)
                goto out;
 
        nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
 
-       label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
-       if (IS_ERR(label)) {
-               status = PTR_ERR(label);
-               goto out;
-       }
-
-       status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr,
-                       label, inode);
+       status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, inode);
        if (status != 0) {
                dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n",
                         inode->i_sb->s_id,
@@ -1227,7 +1236,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
                        else
                                nfs_zap_caches(inode);
                }
-               goto err_out;
+               goto out;
        }
 
        status = nfs_refresh_inode(inode, fattr);
@@ -1235,20 +1244,18 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
                dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) refresh failed, error=%d\n",
                         inode->i_sb->s_id,
                         (unsigned long long)NFS_FILEID(inode), status);
-               goto err_out;
+               goto out;
        }
 
        if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
                nfs_zap_acl_cache(inode);
 
-       nfs_setsecurity(inode, fattr, label);
+       nfs_setsecurity(inode, fattr);
 
        dfprintk(PAGECACHE, "NFS: (%s/%Lu) revalidation complete\n",
                inode->i_sb->s_id,
                (unsigned long long)NFS_FILEID(inode));
 
-err_out:
-       nfs4_label_free(label);
 out:
        nfs_free_fattr(fattr);
        trace_nfs_revalidate_inode_exit(inode, status);
@@ -1446,13 +1453,12 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        && (fattr->valid & NFS_ATTR_FATTR_MTIME)
                        && timespec64_equal(&ts, &fattr->pre_mtime)) {
                inode->i_mtime = fattr->mtime;
-               if (S_ISDIR(inode->i_mode))
-                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
        }
        if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
                        && (fattr->valid & NFS_ATTR_FATTR_SIZE)
                        && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
                        && !nfs_have_writebacks(inode)) {
+               trace_nfs_size_wcc(inode, fattr->size);
                i_size_write(inode, nfs_size_to_loff_t(fattr->size));
        }
 }
@@ -1580,12 +1586,31 @@ struct nfs_fattr *nfs_alloc_fattr(void)
        struct nfs_fattr *fattr;
 
        fattr = kmalloc(sizeof(*fattr), GFP_NOFS);
-       if (fattr != NULL)
+       if (fattr != NULL) {
                nfs_fattr_init(fattr);
+               fattr->label = NULL;
+       }
        return fattr;
 }
 EXPORT_SYMBOL_GPL(nfs_alloc_fattr);
 
+struct nfs_fattr *nfs_alloc_fattr_with_label(struct nfs_server *server)
+{
+       struct nfs_fattr *fattr = nfs_alloc_fattr();
+
+       if (!fattr)
+               return NULL;
+
+       fattr->label = nfs4_label_alloc(server, GFP_NOFS);
+       if (IS_ERR(fattr->label)) {
+               kfree(fattr);
+               return NULL;
+       }
+
+       return fattr;
+}
+EXPORT_SYMBOL_GPL(nfs_alloc_fattr_with_label);
+
 struct nfs_fh *nfs_alloc_fhandle(void)
 {
        struct nfs_fh *fh;
@@ -1777,8 +1802,10 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr,
                NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_OTHER |
                NFS_INO_INVALID_NLINK;
        unsigned long cache_validity = NFS_I(inode)->cache_validity;
+       enum nfs4_change_attr_type ctype = NFS_SERVER(inode)->change_attr_type;
 
-       if (!(cache_validity & NFS_INO_INVALID_CHANGE) &&
+       if (ctype != NFS4_CHANGE_TYPE_IS_UNDEFINED &&
+           !(cache_validity & NFS_INO_INVALID_CHANGE) &&
            (cache_validity & check_valid) != 0 &&
            (fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
            nfs_inode_attrs_cmp_monotonic(fattr, inode) == 0)
@@ -2095,16 +2122,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        /* Do we perhaps have any outstanding writes, or has
                         * the file grown beyond our last write? */
                        if (!nfs_have_writebacks(inode) || new_isize > cur_isize) {
+                               trace_nfs_size_update(inode, new_isize);
                                i_size_write(inode, new_isize);
                                if (!have_writers)
                                        invalid |= NFS_INO_INVALID_DATA;
                        }
-                       dprintk("NFS: isize change on server for file %s/%ld "
-                                       "(%Ld to %Ld)\n",
-                                       inode->i_sb->s_id,
-                                       inode->i_ino,
-                                       (long long)cur_isize,
-                                       (long long)new_isize);
                }
                if (new_isize == 0 &&
                    !(fattr->valid & (NFS_ATTR_FATTR_SPACE_USED |
@@ -2155,11 +2177,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        save_cache_validity & NFS_INO_INVALID_OTHER;
 
        if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
-               if (inode->i_nlink != fattr->nlink) {
-                       if (S_ISDIR(inode->i_mode))
-                               invalid |= NFS_INO_INVALID_DATA;
+               if (inode->i_nlink != fattr->nlink)
                        set_nlink(inode, fattr->nlink);
-               }
        } else if (fattr_supported & NFS_ATTR_FATTR_NLINK)
                nfsi->cache_validity |=
                        save_cache_validity & NFS_INO_INVALID_NLINK;
@@ -2260,14 +2279,7 @@ static void init_once(void *foo)
        INIT_LIST_HEAD(&nfsi->open_files);
        INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
        INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
-       INIT_LIST_HEAD(&nfsi->commit_info.list);
-       atomic_long_set(&nfsi->nrequests, 0);
-       atomic_long_set(&nfsi->commit_info.ncommit, 0);
-       atomic_set(&nfsi->commit_info.rpcs_out, 0);
-       init_rwsem(&nfsi->rmdir_sem);
-       mutex_init(&nfsi->commit_mutex);
        nfs4_init_once(nfsi);
-       nfsi->cache_change_attribute = 0;
 }
 
 static int __init nfs_init_inodecache(void)
index 66fc936..12f6acb 100644 (file)
@@ -193,7 +193,7 @@ extern void nfs_clients_exit(struct net *net);
 extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
 int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
 struct nfs_client *nfs_get_client(const struct nfs_client_initdata *);
-int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
+int nfs_probe_server(struct nfs_server *, struct nfs_fh *);
 void nfs_server_insert_lists(struct nfs_server *);
 void nfs_server_remove_lists(struct nfs_server *);
 void nfs_init_timeout_values(struct rpc_timeout *to, int proto, int timeo, int retrans);
@@ -209,6 +209,7 @@ extern struct nfs_client *
 nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
                                struct nfs4_sessionid *, u32);
 extern struct nfs_server *nfs_create_server(struct fs_context *);
+extern void nfs4_server_set_init_caps(struct nfs_server *);
 extern struct nfs_server *nfs4_create_server(struct fs_context *);
 extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
 extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
@@ -341,14 +342,6 @@ nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
 
        return dst;
 }
-static inline void nfs4_label_free(struct nfs4_label *label)
-{
-       if (label) {
-               kfree(label->label);
-               kfree(label);
-       }
-       return;
-}
 
 static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
 {
@@ -357,7 +350,6 @@ static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
 }
 #else
 static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
-static inline void nfs4_label_free(void *label) {}
 static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
 {
 }
index bc0c698..3295af4 100644 (file)
@@ -308,8 +308,7 @@ int nfs_submount(struct fs_context *fc, struct nfs_server *server)
 
        /* Look it up again to get its attributes */
        err = server->nfs_client->rpc_ops->lookup(d_inode(parent), dentry,
-                                                 ctx->mntfh, ctx->clone_data.fattr,
-                                                 NULL);
+                                                 ctx->mntfh, ctx->clone_data.fattr);
        dput(parent);
        if (err != 0)
                return err;
index f752431..7100514 100644 (file)
@@ -100,8 +100,7 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  */
 static int
 nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
-               struct nfs_fattr *fattr, struct nfs4_label *label,
-               struct inode *inode)
+               struct nfs_fattr *fattr, struct inode *inode)
 {
        struct rpc_message msg = {
                .rpc_proc       = &nfs3_procedures[NFS3PROC_GETATTR],
@@ -193,8 +192,7 @@ __nfs3_proc_lookup(struct inode *dir, const char *name, size_t len,
 
 static int
 nfs3_proc_lookup(struct inode *dir, struct dentry *dentry,
-                struct nfs_fh *fhandle, struct nfs_fattr *fattr,
-                struct nfs4_label *label)
+                struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
        unsigned short task_flags = 0;
 
@@ -209,7 +207,7 @@ nfs3_proc_lookup(struct inode *dir, struct dentry *dentry,
 }
 
 static int nfs3_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
-                            struct nfs_fattr *fattr, struct nfs4_label *label)
+                            struct nfs_fattr *fattr)
 {
        const char dotdot[] = "..";
        const size_t len = strlen(dotdot);
@@ -323,7 +321,7 @@ nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata
        if (status != 0)
                return ERR_PTR(status);
 
-       return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr, NULL);
+       return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr);
 }
 
 static void nfs3_free_createdata(struct nfs3_createdata *data)
index e6eca1d..9274c9c 100644 (file)
@@ -2227,7 +2227,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr,
 
        /* ignore properties */
        result->lease_time = 0;
-       result->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
+       result->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
        return 0;
 }
 
index a243495..08355b6 100644 (file)
@@ -83,6 +83,10 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
                status = nfs_post_op_update_inode_force_wcc(inode,
                                                            res.falloc_fattr);
 
+       if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE])
+               trace_nfs4_fallocate(inode, &args, status);
+       else
+               trace_nfs4_deallocate(inode, &args, status);
        kfree(res.falloc_fattr);
        return status;
 }
@@ -363,6 +367,7 @@ static ssize_t _nfs42_proc_copy(struct file *src,
 
        status = nfs4_call_sync(dst_server->client, dst_server, &msg,
                                &args->seq_args, &res->seq_res, 0);
+       trace_nfs4_copy(src_inode, dst_inode, args, res, nss, status);
        if (status == -ENOTSUPP)
                dst_server->caps &= ~NFS_CAP_COPY;
        if (status)
@@ -504,6 +509,7 @@ static void nfs42_offload_cancel_done(struct rpc_task *task, void *calldata)
 {
        struct nfs42_offloadcancel_data *data = calldata;
 
+       trace_nfs4_offload_cancel(&data->args, task->tk_status);
        nfs41_sequence_done(task, &data->res.osr_seq_res);
        if (task->tk_status &&
                nfs4_async_handle_error(task, data->seq_server, NULL,
@@ -598,6 +604,7 @@ static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
 
        status = nfs4_call_sync(src_server->client, src_server, &msg,
                                &args->cna_seq_args, &res->cnr_seq_res, 0);
+       trace_nfs4_copy_notify(file_inode(src), args, res, status);
        if (status == -ENOTSUPP)
                src_server->caps &= ~NFS_CAP_COPY_NOTIFY;
 
@@ -678,6 +685,7 @@ static loff_t _nfs42_proc_llseek(struct file *filep,
 
        status = nfs4_call_sync(server->client, server, &msg,
                                &args.seq_args, &res.seq_res, 0);
+       trace_nfs4_llseek(inode, &args, &res, status);
        if (status == -ENOTSUPP)
                server->caps &= ~NFS_CAP_SEEK;
        if (status)
@@ -1071,6 +1079,7 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
 
        status = nfs4_call_sync(server->client, server, msg,
                                &args.seq_args, &res.seq_res, 0);
+       trace_nfs4_clone(src_inode, dst_inode, &args, status);
        if (status == 0) {
                nfs42_copy_dest_done(dst_inode, dst_offset, count);
                status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
index ba78df4..ed5eaca 100644 (file)
@@ -234,7 +234,6 @@ struct nfs4_opendata {
        struct nfs4_string group_name;
        struct nfs4_label *a_label;
        struct nfs_fattr f_attr;
-       struct nfs4_label *f_label;
        struct dentry *dir;
        struct dentry *dentry;
        struct nfs4_state_owner *owner;
@@ -317,8 +316,7 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
                const struct nfs_lock_context *l_ctx,
                fmode_t fmode);
 extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
-                            struct nfs_fattr *fattr, struct nfs4_label *label,
-                            struct inode *inode);
+                            struct nfs_fattr *fattr, struct inode *inode);
 extern int update_open_stateid(struct nfs4_state *state,
                                const nfs4_stateid *open_stateid,
                                const nfs4_stateid *deleg_stateid,
index af57332..d8b5a25 100644 (file)
@@ -1059,31 +1059,15 @@ static void nfs4_session_limit_xasize(struct nfs_server *server)
 #endif
 }
 
-static int nfs4_server_common_setup(struct nfs_server *server,
-               struct nfs_fh *mntfh, bool auth_probe)
+void nfs4_server_set_init_caps(struct nfs_server *server)
 {
-       struct nfs_fattr *fattr;
-       int error;
-
-       /* data servers support only a subset of NFSv4.1 */
-       if (is_ds_only_client(server->nfs_client))
-               return -EPROTONOSUPPORT;
-
-       fattr = nfs_alloc_fattr();
-       if (fattr == NULL)
-               return -ENOMEM;
-
-       /* We must ensure the session is initialised first */
-       error = nfs4_init_session(server->nfs_client);
-       if (error < 0)
-               goto out;
-
        /* Set the basic capabilities */
        server->caps |= server->nfs_client->cl_mvops->init_caps;
        if (server->flags & NFS_MOUNT_NORDIRPLUS)
                        server->caps &= ~NFS_CAP_READDIRPLUS;
        if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
                server->caps &= ~NFS_CAP_READ_PLUS;
+
        /*
         * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
         * authentication.
@@ -1091,7 +1075,23 @@ static int nfs4_server_common_setup(struct nfs_server *server,
        if (nfs4_disable_idmapping &&
                        server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
                server->caps |= NFS_CAP_UIDGID_NOMAP;
+}
 
+static int nfs4_server_common_setup(struct nfs_server *server,
+               struct nfs_fh *mntfh, bool auth_probe)
+{
+       int error;
+
+       /* data servers support only a subset of NFSv4.1 */
+       if (is_ds_only_client(server->nfs_client))
+               return -EPROTONOSUPPORT;
+
+       /* We must ensure the session is initialised first */
+       error = nfs4_init_session(server->nfs_client);
+       if (error < 0)
+               goto out;
+
+       nfs4_server_set_init_caps(server);
 
        /* Probe the root fh to retrieve its FSID and filehandle */
        error = nfs4_get_rootfh(server, mntfh, auth_probe);
@@ -1103,7 +1103,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
                        (unsigned long long) server->fsid.minor);
        nfs_display_fhandle(mntfh, "Pseudo-fs root FH");
 
-       error = nfs_probe_fsinfo(server, mntfh, fattr);
+       error = nfs_probe_server(server, mntfh);
        if (error < 0)
                goto out;
 
@@ -1117,7 +1117,6 @@ static int nfs4_server_common_setup(struct nfs_server *server,
        server->mount_time = jiffies;
        server->destroy = nfs4_destroy_server;
 out:
-       nfs_free_fattr(fattr);
        return error;
 }
 
@@ -1288,30 +1287,6 @@ error:
        return ERR_PTR(error);
 }
 
-/*
- * Grab the destination's particulars, including lease expiry time.
- *
- * Returns zero if probe succeeded and retrieved FSID matches the FSID
- * we have cached.
- */
-static int nfs_probe_destination(struct nfs_server *server)
-{
-       struct inode *inode = d_inode(server->super->s_root);
-       struct nfs_fattr *fattr;
-       int error;
-
-       fattr = nfs_alloc_fattr();
-       if (fattr == NULL)
-               return -ENOMEM;
-
-       /* Sanity: the probe won't work if the destination server
-        * does not recognize the migrated FH. */
-       error = nfs_probe_fsinfo(server, NFS_FH(inode), fattr);
-
-       nfs_free_fattr(fattr);
-       return error;
-}
-
 /**
  * nfs4_update_server - Move an nfs_server to a different nfs_client
  *
@@ -1372,5 +1347,5 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
                server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
        nfs_server_insert_lists(server);
 
-       return nfs_probe_destination(server);
+       return nfs_probe_server(server, NFS_FH(d_inode(server->super->s_root)));
 }
index c915652..e79ae4c 100644 (file)
@@ -317,7 +317,7 @@ static int read_name_gen = 1;
 static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
                struct nfs_fh *src_fh, nfs4_stateid *stateid)
 {
-       struct nfs_fattr fattr;
+       struct nfs_fattr *fattr = nfs_alloc_fattr();
        struct file *filep, *res;
        struct nfs_server *server;
        struct inode *r_ino = NULL;
@@ -328,9 +328,10 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
 
        server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
 
-       nfs_fattr_init(&fattr);
+       if (!fattr)
+               return ERR_PTR(-ENOMEM);
 
-       status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL);
+       status = nfs4_proc_getattr(server, src_fh, fattr, NULL);
        if (status < 0) {
                res = ERR_PTR(status);
                goto out;
@@ -343,20 +344,18 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
                goto out;
        snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
 
-       r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr,
-                       NULL);
+       r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, fattr);
        if (IS_ERR(r_ino)) {
                res = ERR_CAST(r_ino);
                goto out_free_name;
        }
 
-       filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, FMODE_READ,
+       filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, O_RDONLY,
                                     r_ino->i_fop);
        if (IS_ERR(filep)) {
                res = ERR_CAST(filep);
                goto out_free_name;
        }
-       filep->f_mode |= FMODE_READ;
 
        ctx = alloc_nfs_open_context(filep->f_path.dentry, filep->f_mode,
                                        filep);
@@ -388,6 +387,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
 out_free_name:
        kfree(read_name);
 out:
+       nfs_free_fattr(fattr);
        return res;
 out_stateowner:
        nfs4_put_state_owner(sp);
index 8d8aba3..f331866 100644 (file)
@@ -487,7 +487,7 @@ nfs_idmap_new(struct nfs_client *clp)
 err_destroy_pipe:
        rpc_destroy_pipe_data(idmap->idmap_pipe);
 err:
-       get_user_ns(idmap->user_ns);
+       put_user_ns(idmap->user_ns);
        kfree(idmap);
        return error;
 }
index 459860a..ee3bc79 100644 (file)
@@ -93,11 +93,11 @@ struct nfs4_opendata;
 static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
 static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
 static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
-static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);
+static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+                             struct nfs_fattr *fattr, struct inode *inode);
 static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
                            struct nfs_fattr *fattr, struct iattr *sattr,
-                           struct nfs_open_context *ctx, struct nfs4_label *ilabel,
-                           struct nfs4_label *olabel);
+                           struct nfs_open_context *ctx, struct nfs4_label *ilabel);
 #ifdef CONFIG_NFS_V4_1
 static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
                const struct cred *cred,
@@ -1330,7 +1330,6 @@ nfs4_map_atomic_open_claim(struct nfs_server *server,
 static void nfs4_init_opendata_res(struct nfs4_opendata *p)
 {
        p->o_res.f_attr = &p->f_attr;
-       p->o_res.f_label = p->f_label;
        p->o_res.seqid = p->o_arg.seqid;
        p->c_res.seqid = p->c_arg.seqid;
        p->o_res.server = p->o_arg.server;
@@ -1356,8 +1355,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
        if (p == NULL)
                goto err;
 
-       p->f_label = nfs4_label_alloc(server, gfp_mask);
-       if (IS_ERR(p->f_label))
+       p->f_attr.label = nfs4_label_alloc(server, gfp_mask);
+       if (IS_ERR(p->f_attr.label))
                goto err_free_p;
 
        p->a_label = nfs4_label_alloc(server, gfp_mask);
@@ -1389,27 +1388,22 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
                                        sizeof(p->o_arg.u.verifier.data));
                }
        }
-       /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS
-        * will return permission denied for all bits until close */
-       if (!(flags & O_EXCL)) {
-               /* ask server to check for all possible rights as results
-                * are cached */
-               switch (p->o_arg.claim) {
-               default:
-                       break;
-               case NFS4_OPEN_CLAIM_NULL:
-               case NFS4_OPEN_CLAIM_FH:
-                       p->o_arg.access = NFS4_ACCESS_READ |
-                               NFS4_ACCESS_MODIFY |
-                               NFS4_ACCESS_EXTEND |
-                               NFS4_ACCESS_EXECUTE;
+       /* ask server to check for all possible rights as results
+        * are cached */
+       switch (p->o_arg.claim) {
+       default:
+               break;
+       case NFS4_OPEN_CLAIM_NULL:
+       case NFS4_OPEN_CLAIM_FH:
+               p->o_arg.access = NFS4_ACCESS_READ | NFS4_ACCESS_MODIFY |
+                                 NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE |
+                                 NFS4_ACCESS_EXECUTE;
 #ifdef CONFIG_NFS_V4_2
-                       if (server->caps & NFS_CAP_XATTR)
-                               p->o_arg.access |= NFS4_ACCESS_XAREAD |
-                                   NFS4_ACCESS_XAWRITE |
-                                   NFS4_ACCESS_XALIST;
+               if (!(server->caps & NFS_CAP_XATTR))
+                       break;
+               p->o_arg.access |= NFS4_ACCESS_XAREAD | NFS4_ACCESS_XAWRITE |
+                                  NFS4_ACCESS_XALIST;
 #endif
-               }
        }
        p->o_arg.clientid = server->nfs_client->cl_clientid;
        p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time);
@@ -1440,7 +1434,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
 err_free_label:
        nfs4_label_free(p->a_label);
 err_free_f:
-       nfs4_label_free(p->f_label);
+       nfs4_label_free(p->f_attr.label);
 err_free_p:
        kfree(p);
 err:
@@ -1462,7 +1456,7 @@ static void nfs4_opendata_free(struct kref *kref)
        nfs4_put_state_owner(p->owner);
 
        nfs4_label_free(p->a_label);
-       nfs4_label_free(p->f_label);
+       nfs4_label_free(p->f_attr.label);
 
        dput(p->dir);
        dput(p->dentry);
@@ -1610,15 +1604,16 @@ static bool nfs_stateid_is_sequential(struct nfs4_state *state,
 {
        if (test_bit(NFS_OPEN_STATE, &state->flags)) {
                /* The common case - we're updating to a new sequence number */
-               if (nfs4_stateid_match_other(stateid, &state->open_stateid) &&
-                       nfs4_stateid_is_next(&state->open_stateid, stateid)) {
-                       return true;
+               if (nfs4_stateid_match_other(stateid, &state->open_stateid)) {
+                       if (nfs4_stateid_is_next(&state->open_stateid, stateid))
+                               return true;
+                       return false;
                }
-       } else {
-               /* This is the first OPEN in this generation */
-               if (stateid->seqid == cpu_to_be32(1))
-                       return true;
+               /* The server returned a new stateid */
        }
+       /* This is the first OPEN in this generation */
+       if (stateid->seqid == cpu_to_be32(1))
+               return true;
        return false;
 }
 
@@ -2014,7 +2009,7 @@ nfs4_opendata_get_inode(struct nfs4_opendata *data)
                if (!(data->f_attr.valid & NFS_ATTR_FATTR))
                        return ERR_PTR(-EAGAIN);
                inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh,
-                               &data->f_attr, data->f_label);
+                               &data->f_attr);
                break;
        default:
                inode = d_inode(data->dentry);
@@ -2473,11 +2468,15 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
        /* Set the create mode (note dependency on the session type) */
        data->o_arg.createmode = NFS4_CREATE_UNCHECKED;
        if (data->o_arg.open_flags & O_EXCL) {
-               data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE;
-               if (nfs4_has_persistent_session(clp))
+               data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1;
+               if (clp->cl_mvops->minor_version == 0) {
+                       data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE;
+                       /* don't put an ACCESS op in OPEN compound if O_EXCL,
+                        * because ACCESS will return permission denied for
+                        * all bits until close */
+                       data->o_res.access_request = data->o_arg.access = 0;
+               } else if (nfs4_has_persistent_session(clp))
                        data->o_arg.createmode = NFS4_CREATE_GUARDED;
-               else if (clp->cl_mvops->minor_version > 0)
-                       data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1;
        }
        return;
 unlock_no_action:
@@ -2709,8 +2708,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data,
        }
        if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) {
                nfs4_sequence_free_slot(&o_res->seq_res);
-               nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr,
-                               o_res->f_label, NULL);
+               nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, NULL);
        }
        return 0;
 }
@@ -3126,7 +3124,6 @@ static int _nfs4_do_open(struct inode *dir,
        enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
        struct iattr *sattr = c->sattr;
        struct nfs4_label *label = c->label;
-       struct nfs4_label *olabel = NULL;
        int status;
 
        /* Protect against reboot recovery conflicts */
@@ -3149,19 +3146,11 @@ static int _nfs4_do_open(struct inode *dir,
        if (opendata == NULL)
                goto err_put_state_owner;
 
-       if (label) {
-               olabel = nfs4_label_alloc(server, GFP_KERNEL);
-               if (IS_ERR(olabel)) {
-                       status = PTR_ERR(olabel);
-                       goto err_opendata_put;
-               }
-       }
-
        if (server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
                if (!opendata->f_attr.mdsthreshold) {
                        opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
                        if (!opendata->f_attr.mdsthreshold)
-                               goto err_free_label;
+                               goto err_opendata_put;
                }
                opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
        }
@@ -3170,7 +3159,7 @@ static int _nfs4_do_open(struct inode *dir,
 
        status = _nfs4_open_and_get_state(opendata, flags, ctx);
        if (status != 0)
-               goto err_free_label;
+               goto err_opendata_put;
        state = ctx->state;
 
        if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) &&
@@ -3187,11 +3176,11 @@ static int _nfs4_do_open(struct inode *dir,
                        nfs_fattr_init(opendata->o_res.f_attr);
                        status = nfs4_do_setattr(state->inode, cred,
                                        opendata->o_res.f_attr, sattr,
-                                       ctx, label, olabel);
+                                       ctx, label);
                        if (status == 0) {
                                nfs_setattr_update_inode(state->inode, sattr,
                                                opendata->o_res.f_attr);
-                               nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel);
+                               nfs_setsecurity(state->inode, opendata->o_res.f_attr);
                        }
                        sattr->ia_valid = ia_old;
                }
@@ -3204,13 +3193,9 @@ static int _nfs4_do_open(struct inode *dir,
                opendata->f_attr.mdsthreshold = NULL;
        }
 
-       nfs4_label_free(olabel);
-
        nfs4_opendata_put(opendata);
        nfs4_put_state_owner(sp);
        return 0;
-err_free_label:
-       nfs4_label_free(olabel);
 err_opendata_put:
        nfs4_opendata_put(opendata);
 err_put_state_owner:
@@ -3355,8 +3340,7 @@ zero_stateid:
 
 static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
                           struct nfs_fattr *fattr, struct iattr *sattr,
-                          struct nfs_open_context *ctx, struct nfs4_label *ilabel,
-                          struct nfs4_label *olabel)
+                          struct nfs_open_context *ctx, struct nfs4_label *ilabel)
 {
        struct nfs_server *server = NFS_SERVER(inode);
        __u32 bitmask[NFS4_BITMASK_SZ];
@@ -3370,7 +3354,6 @@ static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
        };
        struct nfs_setattrres  res = {
                .fattr          = fattr,
-               .label          = olabel,
                .server         = server,
        };
        struct nfs4_exception exception = {
@@ -3387,7 +3370,7 @@ static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
                adjust_flags |= NFS_INO_INVALID_OTHER;
 
        do {
-               nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, olabel),
+               nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label),
                                        inode, adjust_flags);
 
                err = _nfs4_do_setattr(inode, &arg, &res, cred, ctx);
@@ -3562,7 +3545,6 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
                .stateid = &calldata->arg.stateid,
        };
 
-       dprintk("%s: begin!\n", __func__);
        if (!nfs4_sequence_done(task, &calldata->res.seq_res))
                return;
        trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);
@@ -3617,7 +3599,7 @@ out_release:
        task->tk_status = 0;
        nfs_release_seqid(calldata->arg.seqid);
        nfs_refresh_inode(calldata->inode, &calldata->fattr);
-       dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);
+       dprintk("%s: ret = %d\n", __func__, task->tk_status);
        return;
 out_restart:
        task->tk_status = 0;
@@ -3635,7 +3617,6 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
        bool is_rdonly, is_wronly, is_rdwr;
        int call_close = 0;
 
-       dprintk("%s: begin!\n", __func__);
        if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
                goto out_wait;
 
@@ -3709,7 +3690,6 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
                                &calldata->res.seq_res,
                                task) != 0)
                nfs_release_seqid(calldata->arg.seqid);
-       dprintk("%s: done!\n", __func__);
        return;
 out_no_action:
        task->tk_action = NULL;
@@ -3942,6 +3922,8 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
                .interruptible = true,
        };
        int err;
+
+       nfs4_server_set_init_caps(server);
        do {
                err = nfs4_handle_exception(server,
                                _nfs4_server_capabilities(server, fhandle),
@@ -4105,7 +4087,6 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
 {
        int error;
        struct nfs_fattr *fattr = info->fattr;
-       struct nfs4_label *label = fattr->label;
 
        error = nfs4_server_capabilities(server, mntfh);
        if (error < 0) {
@@ -4113,7 +4094,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
                return error;
        }
 
-       error = nfs4_proc_getattr(server, mntfh, fattr, label, NULL);
+       error = nfs4_proc_getattr(server, mntfh, fattr, NULL);
        if (error < 0) {
                dprintk("nfs4_get_root: getattr error = %d\n", -error);
                goto out;
@@ -4176,8 +4157,7 @@ out:
 }
 
 static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
-                               struct nfs_fattr *fattr, struct nfs4_label *label,
-                               struct inode *inode)
+                               struct nfs_fattr *fattr, struct inode *inode)
 {
        __u32 bitmask[NFS4_BITMASK_SZ];
        struct nfs4_getattr_arg args = {
@@ -4186,7 +4166,6 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
        };
        struct nfs4_getattr_res res = {
                .fattr = fattr,
-               .label = label,
                .server = server,
        };
        struct rpc_message msg = {
@@ -4203,7 +4182,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
        if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
                task_flags |= RPC_TASK_TIMEOUT;
 
-       nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode, 0);
+       nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label), inode, 0);
        nfs_fattr_init(fattr);
        nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
        return nfs4_do_call_sync(server->client, server, &msg,
@@ -4211,15 +4190,14 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
 }
 
 int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
-                               struct nfs_fattr *fattr, struct nfs4_label *label,
-                               struct inode *inode)
+                               struct nfs_fattr *fattr, struct inode *inode)
 {
        struct nfs4_exception exception = {
                .interruptible = true,
        };
        int err;
        do {
-               err = _nfs4_proc_getattr(server, fhandle, fattr, label, inode);
+               err = _nfs4_proc_getattr(server, fhandle, fattr, inode);
                trace_nfs4_getattr(server, fhandle, fattr, err);
                err = nfs4_handle_exception(server, err,
                                &exception);
@@ -4251,7 +4229,6 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
        struct inode *inode = d_inode(dentry);
        const struct cred *cred = NULL;
        struct nfs_open_context *ctx = NULL;
-       struct nfs4_label *label = NULL;
        int status;
 
        if (pnfs_ld_layoutret_on_setattr(inode) &&
@@ -4277,26 +4254,21 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
                        cred = ctx->cred;
        }
 
-       label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
-       if (IS_ERR(label))
-               return PTR_ERR(label);
-
        /* Return any delegations if we're going to change ACLs */
        if ((sattr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
                nfs4_inode_make_writeable(inode);
 
-       status = nfs4_do_setattr(inode, cred, fattr, sattr, ctx, NULL, label);
+       status = nfs4_do_setattr(inode, cred, fattr, sattr, ctx, NULL);
        if (status == 0) {
                nfs_setattr_update_inode(inode, sattr, fattr);
-               nfs_setsecurity(inode, fattr, label);
+               nfs_setsecurity(inode, fattr);
        }
-       nfs4_label_free(label);
        return status;
 }
 
 static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
                struct dentry *dentry, struct nfs_fh *fhandle,
-               struct nfs_fattr *fattr, struct nfs4_label *label)
+               struct nfs_fattr *fattr)
 {
        struct nfs_server *server = NFS_SERVER(dir);
        int                    status;
@@ -4308,7 +4280,6 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
        struct nfs4_lookup_res res = {
                .server = server,
                .fattr = fattr,
-               .label = label,
                .fh = fhandle,
        };
        struct rpc_message msg = {
@@ -4325,7 +4296,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
        if (nfs_lookup_is_soft_revalidate(dentry))
                task_flags |= RPC_TASK_TIMEOUT;
 
-       args.bitmask = nfs4_bitmask(server, label);
+       args.bitmask = nfs4_bitmask(server, fattr->label);
 
        nfs_fattr_init(fattr);
 
@@ -4347,7 +4318,7 @@ static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)
 
 static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
                                   struct dentry *dentry, struct nfs_fh *fhandle,
-                                  struct nfs_fattr *fattr, struct nfs4_label *label)
+                                  struct nfs_fattr *fattr)
 {
        struct nfs4_exception exception = {
                .interruptible = true,
@@ -4356,7 +4327,7 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
        const struct qstr *name = &dentry->d_name;
        int err;
        do {
-               err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr, label);
+               err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr);
                trace_nfs4_lookup(dir, name, err);
                switch (err) {
                case -NFS4ERR_BADNAME:
@@ -4392,13 +4363,12 @@ out:
 }
 
 static int nfs4_proc_lookup(struct inode *dir, struct dentry *dentry,
-                           struct nfs_fh *fhandle, struct nfs_fattr *fattr,
-                           struct nfs4_label *label)
+                           struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
        int status;
        struct rpc_clnt *client = NFS_CLIENT(dir);
 
-       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, label);
+       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr);
        if (client != NFS_CLIENT(dir)) {
                rpc_shutdown_client(client);
                nfs_fixup_secinfo_attributes(fattr);
@@ -4413,15 +4383,14 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, struct dentry *dentry,
        struct rpc_clnt *client = NFS_CLIENT(dir);
        int status;
 
-       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, NULL);
+       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr);
        if (status < 0)
                return ERR_PTR(status);
        return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
 }
 
 static int _nfs4_proc_lookupp(struct inode *inode,
-               struct nfs_fh *fhandle, struct nfs_fattr *fattr,
-               struct nfs4_label *label)
+               struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
        struct rpc_clnt *clnt = NFS_CLIENT(inode);
        struct nfs_server *server = NFS_SERVER(inode);
@@ -4433,7 +4402,6 @@ static int _nfs4_proc_lookupp(struct inode *inode,
        struct nfs4_lookupp_res res = {
                .server = server,
                .fattr = fattr,
-               .label = label,
                .fh = fhandle,
        };
        struct rpc_message msg = {
@@ -4446,7 +4414,7 @@ static int _nfs4_proc_lookupp(struct inode *inode,
        if (NFS_SERVER(inode)->flags & NFS_MOUNT_SOFTREVAL)
                task_flags |= RPC_TASK_TIMEOUT;
 
-       args.bitmask = nfs4_bitmask(server, label);
+       args.bitmask = nfs4_bitmask(server, fattr->label);
 
        nfs_fattr_init(fattr);
 
@@ -4458,14 +4426,14 @@ static int _nfs4_proc_lookupp(struct inode *inode,
 }
 
 static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
-                            struct nfs_fattr *fattr, struct nfs4_label *label)
+                            struct nfs_fattr *fattr)
 {
        struct nfs4_exception exception = {
                .interruptible = true,
        };
        int err;
        do {
-               err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
+               err = _nfs4_proc_lookupp(inode, fhandle, fattr);
                trace_nfs4_lookupp(inode, err);
                err = nfs4_handle_exception(NFS_SERVER(inode), err,
                                &exception);
@@ -4792,7 +4760,6 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
        };
        struct nfs4_link_res res = {
                .server = server,
-               .label = NULL,
        };
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
@@ -4801,18 +4768,12 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
        };
        int status = -ENOMEM;
 
-       res.fattr = nfs_alloc_fattr();
+       res.fattr = nfs_alloc_fattr_with_label(server);
        if (res.fattr == NULL)
                goto out;
 
-       res.label = nfs4_label_alloc(server, GFP_KERNEL);
-       if (IS_ERR(res.label)) {
-               status = PTR_ERR(res.label);
-               goto out;
-       }
-
        nfs4_inode_make_writeable(inode);
-       nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, res.label), inode,
+       nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, res.fattr->label), inode,
                                NFS_INO_INVALID_CHANGE);
        status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
        if (!status) {
@@ -4821,12 +4782,9 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
                nfs4_inc_nlink(inode);
                status = nfs_post_op_update_inode(inode, res.fattr);
                if (!status)
-                       nfs_setsecurity(inode, res.fattr, res.label);
+                       nfs_setsecurity(inode, res.fattr);
        }
 
-
-       nfs4_label_free(res.label);
-
 out:
        nfs_free_fattr(res.fattr);
        return status;
@@ -4852,7 +4810,6 @@ struct nfs4_createdata {
        struct nfs4_create_res res;
        struct nfs_fh fh;
        struct nfs_fattr fattr;
-       struct nfs4_label *label;
 };
 
 static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
@@ -4864,8 +4821,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
        if (data != NULL) {
                struct nfs_server *server = NFS_SERVER(dir);
 
-               data->label = nfs4_label_alloc(server, GFP_KERNEL);
-               if (IS_ERR(data->label))
+               data->fattr.label = nfs4_label_alloc(server, GFP_KERNEL);
+               if (IS_ERR(data->fattr.label))
                        goto out_free;
 
                data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE];
@@ -4876,12 +4833,11 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
                data->arg.name = name;
                data->arg.attrs = sattr;
                data->arg.ftype = ftype;
-               data->arg.bitmask = nfs4_bitmask(server, data->label);
+               data->arg.bitmask = nfs4_bitmask(server, data->fattr.label);
                data->arg.umask = current_umask();
                data->res.server = server;
                data->res.fh = &data->fh;
                data->res.fattr = &data->fattr;
-               data->res.label = data->label;
                nfs_fattr_init(data->res.fattr);
        }
        return data;
@@ -4903,14 +4859,14 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
                                              data->res.fattr->time_start,
                                              NFS_INO_INVALID_DATA);
                spin_unlock(&dir->i_lock);
-               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label);
+               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
        }
        return status;
 }
 
 static void nfs4_free_createdata(struct nfs4_createdata *data)
 {
-       nfs4_label_free(data->label);
+       nfs4_label_free(data->fattr.label);
        kfree(data);
 }
 
@@ -5348,8 +5304,6 @@ static bool nfs4_read_plus_not_supported(struct rpc_task *task,
 
 static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
 {
-       dprintk("--> %s\n", __func__);
-
        if (!nfs4_sequence_done(task, &hdr->res.seq_res))
                return -EAGAIN;
        if (nfs4_read_stateid_changed(task, &hdr->args))
@@ -6005,17 +5959,18 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,
                                        size_t buflen)
 {
        struct nfs_server *server = NFS_SERVER(inode);
-       struct nfs_fattr fattr;
        struct nfs4_label label = {0, 0, buflen, buf};
 
        u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
+       struct nfs_fattr fattr = {
+               .label = &label,
+       };
        struct nfs4_getattr_arg arg = {
                .fh             = NFS_FH(inode),
                .bitmask        = bitmask,
        };
        struct nfs4_getattr_res res = {
                .fattr          = &fattr,
-               .label          = &label,
                .server         = server,
        };
        struct rpc_message msg = {
@@ -6057,8 +6012,7 @@ static int nfs4_get_security_label(struct inode *inode, void *buf,
 
 static int _nfs4_do_set_security_label(struct inode *inode,
                struct nfs4_label *ilabel,
-               struct nfs_fattr *fattr,
-               struct nfs4_label *olabel)
+               struct nfs_fattr *fattr)
 {
 
        struct iattr sattr = {0};
@@ -6073,7 +6027,6 @@ static int _nfs4_do_set_security_label(struct inode *inode,
        };
        struct nfs_setattrres res = {
                .fattr          = fattr,
-               .label          = olabel,
                .server         = server,
        };
        struct rpc_message msg = {
@@ -6094,15 +6047,13 @@ static int _nfs4_do_set_security_label(struct inode *inode,
 
 static int nfs4_do_set_security_label(struct inode *inode,
                struct nfs4_label *ilabel,
-               struct nfs_fattr *fattr,
-               struct nfs4_label *olabel)
+               struct nfs_fattr *fattr)
 {
        struct nfs4_exception exception = { };
        int err;
 
        do {
-               err = _nfs4_do_set_security_label(inode, ilabel,
-                               fattr, olabel);
+               err = _nfs4_do_set_security_label(inode, ilabel, fattr);
                trace_nfs4_set_security_label(inode, err);
                err = nfs4_handle_exception(NFS_SERVER(inode), err,
                                &exception);
@@ -6113,32 +6064,21 @@ static int nfs4_do_set_security_label(struct inode *inode,
 static int
 nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
 {
-       struct nfs4_label ilabel, *olabel = NULL;
-       struct nfs_fattr fattr;
+       struct nfs4_label ilabel = {0, 0, buflen, (char *)buf };
+       struct nfs_fattr *fattr;
        int status;
 
        if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
                return -EOPNOTSUPP;
 
-       nfs_fattr_init(&fattr);
-
-       ilabel.pi = 0;
-       ilabel.lfs = 0;
-       ilabel.label = (char *)buf;
-       ilabel.len = buflen;
-
-       olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
-       if (IS_ERR(olabel)) {
-               status = -PTR_ERR(olabel);
-               goto out;
-       }
+       fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
+       if (fattr == NULL)
+               return -ENOMEM;
 
-       status = nfs4_do_set_security_label(inode, &ilabel, &fattr, olabel);
+       status = nfs4_do_set_security_label(inode, &ilabel, fattr);
        if (status == 0)
-               nfs_setsecurity(inode, &fattr, olabel);
+               nfs_setsecurity(inode, fattr);
 
-       nfs4_label_free(olabel);
-out:
        return status;
 }
 #endif /* CONFIG_NFS_V4_SECURITY_LABEL */
@@ -7004,7 +6944,6 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
        struct nfs4_lockdata *data = calldata;
        struct nfs4_state *state = data->lsp->ls_state;
 
-       dprintk("%s: begin!\n", __func__);
        if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0)
                goto out_wait;
        /* Do we need to do an open_to_lock_owner? */
@@ -7038,7 +6977,7 @@ out_release_lock_seqid:
        nfs_release_seqid(data->arg.lock_seqid);
 out_wait:
        nfs4_sequence_done(task, &data->res.seq_res);
-       dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
+       dprintk("%s: ret = %d\n", __func__, data->rpc_status);
 }
 
 static void nfs4_lock_done(struct rpc_task *task, void *calldata)
@@ -7046,8 +6985,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
        struct nfs4_lockdata *data = calldata;
        struct nfs4_lock_state *lsp = data->lsp;
 
-       dprintk("%s: begin!\n", __func__);
-
        if (!nfs4_sequence_done(task, &data->res.seq_res))
                return;
 
@@ -7081,7 +7018,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
                                goto out_restart;
        }
 out_done:
-       dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status);
+       dprintk("%s: ret = %d!\n", __func__, data->rpc_status);
        return;
 out_restart:
        if (!data->cancelled)
@@ -7093,7 +7030,6 @@ static void nfs4_lock_release(void *calldata)
 {
        struct nfs4_lockdata *data = calldata;
 
-       dprintk("%s: begin!\n", __func__);
        nfs_free_seqid(data->arg.open_seqid);
        if (data->cancelled && data->rpc_status == 0) {
                struct rpc_task *task;
@@ -7107,7 +7043,6 @@ static void nfs4_lock_release(void *calldata)
        nfs4_put_lock_state(data->lsp);
        put_nfs_open_context(data->ctx);
        kfree(data);
-       dprintk("%s: done!\n", __func__);
 }
 
 static const struct rpc_call_ops nfs4_lock_ops = {
@@ -7154,7 +7089,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
        if (client->cl_minorversion)
                task_setup_data.flags |= RPC_TASK_MOVEABLE;
 
-       dprintk("%s: begin!\n", __func__);
        data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),
                        fl->fl_u.nfs4_fl.owner,
                        recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS);
@@ -7185,7 +7119,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
                data->cancelled = true;
        trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret);
        rpc_put_task(task);
-       dprintk("%s: done, ret = %d!\n", __func__, ret);
+       dprintk("%s: ret = %d\n", __func__, ret);
        return ret;
 }
 
@@ -8856,14 +8790,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
        struct nfs4_get_lease_time_data *data =
                        (struct nfs4_get_lease_time_data *)calldata;
 
-       dprintk("--> %s\n", __func__);
        /* just setup sequence, do not trigger session recovery
           since we're invoked within one */
        nfs4_setup_sequence(data->clp,
                        &data->args->la_seq_args,
                        &data->res->lr_seq_res,
                        task);
-       dprintk("<-- %s\n", __func__);
 }
 
 /*
@@ -8875,13 +8807,11 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
        struct nfs4_get_lease_time_data *data =
                        (struct nfs4_get_lease_time_data *)calldata;
 
-       dprintk("--> %s\n", __func__);
        if (!nfs4_sequence_done(task, &data->res->lr_seq_res))
                return;
        switch (task->tk_status) {
        case -NFS4ERR_DELAY:
        case -NFS4ERR_GRACE:
-               dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
                rpc_delay(task, NFS4_POLL_RETRY_MIN);
                task->tk_status = 0;
                fallthrough;
@@ -8889,7 +8819,6 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
                rpc_restart_call_prepare(task);
                return;
        }
-       dprintk("<-- %s\n", __func__);
 }
 
 static const struct rpc_call_ops nfs4_get_lease_time_ops = {
@@ -9121,7 +9050,6 @@ int nfs4_proc_create_session(struct nfs_client *clp, const struct cred *cred)
        dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
                clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
 out:
-       dprintk("<-- %s\n", __func__);
        return status;
 }
 
@@ -9139,8 +9067,6 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
        };
        int status = 0;
 
-       dprintk("--> nfs4_proc_destroy_session\n");
-
        /* session is still being setup */
        if (!test_and_clear_bit(NFS4_SESSION_ESTABLISHED, &session->session_state))
                return 0;
@@ -9152,8 +9078,6 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
        if (status)
                dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
                        "Session has been destroyed regardless...\n", status);
-
-       dprintk("<-- nfs4_proc_destroy_session\n");
        return status;
 }
 
@@ -9201,7 +9125,7 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
        if (task->tk_status < 0) {
                dprintk("%s ERROR %d\n", __func__, task->tk_status);
                if (refcount_read(&clp->cl_count) == 1)
-                       goto out;
+                       return;
 
                if (nfs41_sequence_handle_errors(task, clp) == -EAGAIN) {
                        rpc_restart_call_prepare(task);
@@ -9209,8 +9133,6 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
                }
        }
        dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
-out:
-       dprintk("<-- %s\n", __func__);
 }
 
 static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
@@ -9357,7 +9279,6 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
        struct nfs_client *clp = calldata->clp;
        struct nfs4_sequence_res *res = &calldata->res.seq_res;
 
-       dprintk("--> %s\n", __func__);
        if (!nfs41_sequence_done(task, res))
                return;
 
@@ -9366,7 +9287,6 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
                rpc_restart_call_prepare(task);
                return;
        }
-       dprintk("<-- %s\n", __func__);
 }
 
 static void nfs4_free_reclaim_complete_data(void *data)
@@ -9401,7 +9321,6 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
        };
        int status = -ENOMEM;
 
-       dprintk("--> %s\n", __func__);
        calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
        if (calldata == NULL)
                goto out;
@@ -9424,19 +9343,15 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
        struct nfs4_layoutget *lgp = calldata;
        struct nfs_server *server = NFS_SERVER(lgp->args.inode);
 
-       dprintk("--> %s\n", __func__);
        nfs4_setup_sequence(server->nfs_client, &lgp->args.seq_args,
                                &lgp->res.seq_res, task);
-       dprintk("<-- %s\n", __func__);
 }
 
 static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
 {
        struct nfs4_layoutget *lgp = calldata;
 
-       dprintk("--> %s\n", __func__);
        nfs41_sequence_process(task, &lgp->res.seq_res);
-       dprintk("<-- %s\n", __func__);
 }
 
 static int
@@ -9525,7 +9440,6 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
                        status = err;
        }
 out:
-       dprintk("<-- %s\n", __func__);
        return status;
 }
 
@@ -9539,10 +9453,8 @@ static void nfs4_layoutget_release(void *calldata)
 {
        struct nfs4_layoutget *lgp = calldata;
 
-       dprintk("--> %s\n", __func__);
        nfs4_sequence_free_slot(&lgp->res.seq_res);
        pnfs_layoutget_free(lgp);
-       dprintk("<-- %s\n", __func__);
 }
 
 static const struct rpc_call_ops nfs4_layoutget_call_ops = {
@@ -9578,8 +9490,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout)
        };
        int status = 0;
 
-       dprintk("--> %s\n", __func__);
-
        nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0);
 
        task = rpc_run_task(&task_setup_data);
@@ -9615,7 +9525,6 @@ nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
 {
        struct nfs4_layoutreturn *lrp = calldata;
 
-       dprintk("--> %s\n", __func__);
        nfs4_setup_sequence(lrp->clp,
                        &lrp->args.seq_args,
                        &lrp->res.seq_res,
@@ -9629,8 +9538,6 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
        struct nfs4_layoutreturn *lrp = calldata;
        struct nfs_server *server;
 
-       dprintk("--> %s\n", __func__);
-
        if (!nfs41_sequence_process(task, &lrp->res.seq_res))
                return;
 
@@ -9661,7 +9568,6 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
                        break;
                goto out_restart;
        }
-       dprintk("<-- %s\n", __func__);
        return;
 out_restart:
        task->tk_status = 0;
@@ -9674,7 +9580,6 @@ static void nfs4_layoutreturn_release(void *calldata)
        struct nfs4_layoutreturn *lrp = calldata;
        struct pnfs_layout_hdr *lo = lrp->args.layout;
 
-       dprintk("--> %s\n", __func__);
        pnfs_layoutreturn_free_lsegs(lo, &lrp->args.stateid, &lrp->args.range,
                        lrp->res.lrs_present ? &lrp->res.stateid : NULL);
        nfs4_sequence_free_slot(&lrp->res.seq_res);
@@ -9684,7 +9589,6 @@ static void nfs4_layoutreturn_release(void *calldata)
        nfs_iput_and_deactive(lrp->inode);
        put_cred(lrp->cred);
        kfree(calldata);
-       dprintk("<-- %s\n", __func__);
 }
 
 static const struct rpc_call_ops nfs4_layoutreturn_call_ops = {
@@ -9715,7 +9619,6 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync)
                        NFS_SP4_MACH_CRED_PNFS_CLEANUP,
                        &task_setup_data.rpc_client, &msg);
 
-       dprintk("--> %s\n", __func__);
        lrp->inode = nfs_igrab_and_active(lrp->args.inode);
        if (!sync) {
                if (!lrp->inode) {
@@ -9762,7 +9665,6 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server,
        };
        int status;
 
-       dprintk("--> %s\n", __func__);
        status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
        if (res.notification & ~args.notify_types)
                dprintk("%s: unsupported notification\n", __func__);
@@ -9934,7 +9836,6 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
                msg.rpc_cred = cred;
        }
 
-       dprintk("--> %s\n", __func__);
        nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
        status = nfs4_call_sync_custom(&task_setup);
        dprintk("<-- %s status=%d\n", __func__, status);
@@ -10158,6 +10059,10 @@ static void nfs41_free_stateid_done(struct rpc_task *task, void *calldata)
 
 static void nfs41_free_stateid_release(void *calldata)
 {
+       struct nfs_free_stateid_data *data = calldata;
+       struct nfs_client *clp = data->server->nfs_client;
+
+       nfs_put_client(clp);
        kfree(calldata);
 }
 
@@ -10194,6 +10099,10 @@ static int nfs41_free_stateid(struct nfs_server *server,
        };
        struct nfs_free_stateid_data *data;
        struct rpc_task *task;
+       struct nfs_client *clp = server->nfs_client;
+
+       if (!refcount_inc_not_zero(&clp->cl_count))
+               return -EIO;
 
        nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
                &task_setup.rpc_client, &msg);
index 4145a01..5db4604 100644 (file)
@@ -511,12 +511,16 @@ void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
                struct nfs4_slot *slot,
                struct nfs4_sequence_res *res)
 {
+       u32 target_highest_slotid = min(res->sr_target_highest_slotid,
+                                       NFS4_MAX_SLOTID);
+       u32 highest_slotid = min(res->sr_highest_slotid, NFS4_MAX_SLOTID);
+
        spin_lock(&tbl->slot_tbl_lock);
-       if (!nfs41_is_outlier_target_slotid(tbl, res->sr_target_highest_slotid))
-               nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid);
+       if (!nfs41_is_outlier_target_slotid(tbl, target_highest_slotid))
+               nfs41_set_target_slotid_locked(tbl, target_highest_slotid);
        if (tbl->generation == slot->generation)
-               nfs41_set_server_slotid_locked(tbl, res->sr_highest_slotid);
-       nfs41_set_max_slotid_locked(tbl, res->sr_target_highest_slotid);
+               nfs41_set_server_slotid_locked(tbl, highest_slotid);
+       nfs41_set_max_slotid_locked(tbl, target_highest_slotid);
        spin_unlock(&tbl->slot_tbl_lock);
 }
 
index 3de425f..351616c 100644 (file)
@@ -12,6 +12,7 @@
 #define NFS4_DEF_SLOT_TABLE_SIZE (64U)
 #define NFS4_DEF_CB_SLOT_TABLE_SIZE (16U)
 #define NFS4_MAX_SLOT_TABLE (1024U)
+#define NFS4_MAX_SLOTID (NFS4_MAX_SLOT_TABLE - 1U)
 #define NFS4_NO_SLOT ((u32)-1)
 
 #if IS_ENABLED(CONFIG_NFS_V4)
index f22818a..ecc4594 100644 (file)
@@ -1194,10 +1194,7 @@ static int nfs4_run_state_manager(void *);
 
 static void nfs4_clear_state_manager_bit(struct nfs_client *clp)
 {
-       smp_mb__before_atomic();
-       clear_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
-       smp_mb__after_atomic();
-       wake_up_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING);
+       clear_and_wake_up_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
        rpc_wake_up(&clp->cl_rpcwaitq);
 }
 
index 7a2567a..6ee6ad3 100644 (file)
 #define _TRACE_NFS4_H
 
 #include <linux/tracepoint.h>
+#include <trace/events/sunrpc_base.h>
 
-TRACE_DEFINE_ENUM(EPERM);
-TRACE_DEFINE_ENUM(ENOENT);
-TRACE_DEFINE_ENUM(EIO);
-TRACE_DEFINE_ENUM(ENXIO);
-TRACE_DEFINE_ENUM(EACCES);
-TRACE_DEFINE_ENUM(EEXIST);
-TRACE_DEFINE_ENUM(EXDEV);
-TRACE_DEFINE_ENUM(ENOTDIR);
-TRACE_DEFINE_ENUM(EISDIR);
-TRACE_DEFINE_ENUM(EFBIG);
-TRACE_DEFINE_ENUM(ENOSPC);
-TRACE_DEFINE_ENUM(EROFS);
-TRACE_DEFINE_ENUM(EMLINK);
-TRACE_DEFINE_ENUM(ENAMETOOLONG);
-TRACE_DEFINE_ENUM(ENOTEMPTY);
-TRACE_DEFINE_ENUM(EDQUOT);
-TRACE_DEFINE_ENUM(ESTALE);
-TRACE_DEFINE_ENUM(EBADHANDLE);
-TRACE_DEFINE_ENUM(EBADCOOKIE);
-TRACE_DEFINE_ENUM(ENOTSUPP);
-TRACE_DEFINE_ENUM(ETOOSMALL);
-TRACE_DEFINE_ENUM(EREMOTEIO);
-TRACE_DEFINE_ENUM(EBADTYPE);
-TRACE_DEFINE_ENUM(EAGAIN);
-TRACE_DEFINE_ENUM(ELOOP);
-TRACE_DEFINE_ENUM(EOPNOTSUPP);
-TRACE_DEFINE_ENUM(EDEADLK);
-TRACE_DEFINE_ENUM(ENOMEM);
-TRACE_DEFINE_ENUM(EKEYEXPIRED);
-TRACE_DEFINE_ENUM(ETIMEDOUT);
-TRACE_DEFINE_ENUM(ERESTARTSYS);
-TRACE_DEFINE_ENUM(ECONNREFUSED);
-TRACE_DEFINE_ENUM(ECONNRESET);
-TRACE_DEFINE_ENUM(ENETUNREACH);
-TRACE_DEFINE_ENUM(EHOSTUNREACH);
-TRACE_DEFINE_ENUM(EHOSTDOWN);
-TRACE_DEFINE_ENUM(EPIPE);
-TRACE_DEFINE_ENUM(EPFNOSUPPORT);
-TRACE_DEFINE_ENUM(EPROTONOSUPPORT);
-
-TRACE_DEFINE_ENUM(NFS4_OK);
-TRACE_DEFINE_ENUM(NFS4ERR_ACCESS);
-TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED);
-TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY);
-TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR);
-TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE);
-TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE);
-TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT);
-TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL);
-TRACE_DEFINE_ENUM(NFS4ERR_BADNAME);
-TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER);
-TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT);
-TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE);
-TRACE_DEFINE_ENUM(NFS4ERR_BADXDR);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST);
-TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID);
-TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN);
-TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE);
-TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY);
-TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY);
-TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK);
-TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_DELAY);
-TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED);
-TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED);
-TRACE_DEFINE_ENUM(NFS4ERR_DENIED);
-TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL);
-TRACE_DEFINE_ENUM(NFS4ERR_DQUOT);
-TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_EXIST);
-TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED);
-TRACE_DEFINE_ENUM(NFS4ERR_FBIG);
-TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED);
-TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN);
-TRACE_DEFINE_ENUM(NFS4ERR_GRACE);
-TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_INVAL);
-TRACE_DEFINE_ENUM(NFS4ERR_IO);
-TRACE_DEFINE_ENUM(NFS4ERR_ISDIR);
-TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER);
-TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE);
-TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED);
-TRACE_DEFINE_ENUM(NFS4ERR_LOCKED);
-TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD);
-TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE);
-TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH);
-TRACE_DEFINE_ENUM(NFS4ERR_MLINK);
-TRACE_DEFINE_ENUM(NFS4ERR_MOVED);
-TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG);
-TRACE_DEFINE_ENUM(NFS4ERR_NOENT);
-TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE);
-TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT);
-TRACE_DEFINE_ENUM(NFS4ERR_NOSPC);
-TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR);
-TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY);
-TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP);
-TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP);
-TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME);
-TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE);
-TRACE_DEFINE_ENUM(NFS4ERR_NXIO);
-TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID);
-TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE);
-TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL);
-TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION);
-TRACE_DEFINE_ENUM(NFS4ERR_PERM);
-TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE);
-TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT);
-TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT);
-TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD);
-TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT);
-TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG);
-TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG);
-TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE);
-TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG);
-TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE);
-TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH);
-TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP);
-TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT);
-TRACE_DEFINE_ENUM(NFS4ERR_ROFS);
-TRACE_DEFINE_ENUM(NFS4ERR_SAME);
-TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED);
-TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS);
-TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY);
-TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED);
-TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT);
-TRACE_DEFINE_ENUM(NFS4ERR_STALE);
-TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID);
-TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID);
-TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK);
-TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL);
-TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS);
-TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE);
-TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND);
-TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC);
-TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED);
-TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE);
-TRACE_DEFINE_ENUM(NFS4ERR_XDEV);
-
-TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS);
-TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS);
-
-#define show_nfsv4_errors(error) \
-       __print_symbolic(error, \
-               { NFS4_OK, "OK" }, \
-               /* Mapped by nfs4_stat_to_errno() */ \
-               { EPERM, "EPERM" }, \
-               { ENOENT, "ENOENT" }, \
-               { EIO, "EIO" }, \
-               { ENXIO, "ENXIO" }, \
-               { EACCES, "EACCES" }, \
-               { EEXIST, "EEXIST" }, \
-               { EXDEV, "EXDEV" }, \
-               { ENOTDIR, "ENOTDIR" }, \
-               { EISDIR, "EISDIR" }, \
-               { EFBIG, "EFBIG" }, \
-               { ENOSPC, "ENOSPC" }, \
-               { EROFS, "EROFS" }, \
-               { EMLINK, "EMLINK" }, \
-               { ENAMETOOLONG, "ENAMETOOLONG" }, \
-               { ENOTEMPTY, "ENOTEMPTY" }, \
-               { EDQUOT, "EDQUOT" }, \
-               { ESTALE, "ESTALE" }, \
-               { EBADHANDLE, "EBADHANDLE" }, \
-               { EBADCOOKIE, "EBADCOOKIE" }, \
-               { ENOTSUPP, "ENOTSUPP" }, \
-               { ETOOSMALL, "ETOOSMALL" }, \
-               { EREMOTEIO, "EREMOTEIO" }, \
-               { EBADTYPE, "EBADTYPE" }, \
-               { EAGAIN, "EAGAIN" }, \
-               { ELOOP, "ELOOP" }, \
-               { EOPNOTSUPP, "EOPNOTSUPP" }, \
-               { EDEADLK, "EDEADLK" }, \
-               /* RPC errors */ \
-               { ENOMEM, "ENOMEM" }, \
-               { EKEYEXPIRED, "EKEYEXPIRED" }, \
-               { ETIMEDOUT, "ETIMEDOUT" }, \
-               { ERESTARTSYS, "ERESTARTSYS" }, \
-               { ECONNREFUSED, "ECONNREFUSED" }, \
-               { ECONNRESET, "ECONNRESET" }, \
-               { ENETUNREACH, "ENETUNREACH" }, \
-               { EHOSTUNREACH, "EHOSTUNREACH" }, \
-               { EHOSTDOWN, "EHOSTDOWN" }, \
-               { EPIPE, "EPIPE" }, \
-               { EPFNOSUPPORT, "EPFNOSUPPORT" }, \
-               { EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \
-               /* NFSv4 native errors */ \
-               { NFS4ERR_ACCESS, "ACCESS" }, \
-               { NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \
-               { NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \
-               { NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \
-               { NFS4ERR_BADCHAR, "BADCHAR" }, \
-               { NFS4ERR_BADHANDLE, "BADHANDLE" }, \
-               { NFS4ERR_BADIOMODE, "BADIOMODE" }, \
-               { NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \
-               { NFS4ERR_BADLABEL, "BADLABEL" }, \
-               { NFS4ERR_BADNAME, "BADNAME" }, \
-               { NFS4ERR_BADOWNER, "BADOWNER" }, \
-               { NFS4ERR_BADSESSION, "BADSESSION" }, \
-               { NFS4ERR_BADSLOT, "BADSLOT" }, \
-               { NFS4ERR_BADTYPE, "BADTYPE" }, \
-               { NFS4ERR_BADXDR, "BADXDR" }, \
-               { NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \
-               { NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \
-               { NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \
-               { NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \
-               { NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \
-               { NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \
-               { NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
-               { NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \
-               { NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \
-               { NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \
-               { NFS4ERR_CONN_NOT_BOUND_TO_SESSION, \
-                       "CONN_NOT_BOUND_TO_SESSION" }, \
-               { NFS4ERR_DEADLOCK, "DEADLOCK" }, \
-               { NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \
-               { NFS4ERR_DELAY, "DELAY" }, \
-               { NFS4ERR_DELEG_ALREADY_WANTED, \
-                       "DELEG_ALREADY_WANTED" }, \
-               { NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \
-               { NFS4ERR_DENIED, "DENIED" }, \
-               { NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \
-               { NFS4ERR_DQUOT, "DQUOT" }, \
-               { NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \
-               { NFS4ERR_EXIST, "EXIST" }, \
-               { NFS4ERR_EXPIRED, "EXPIRED" }, \
-               { NFS4ERR_FBIG, "FBIG" }, \
-               { NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \
-               { NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \
-               { NFS4ERR_GRACE, "GRACE" }, \
-               { NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \
-               { NFS4ERR_INVAL, "INVAL" }, \
-               { NFS4ERR_IO, "IO" }, \
-               { NFS4ERR_ISDIR, "ISDIR" }, \
-               { NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \
-               { NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \
-               { NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \
-               { NFS4ERR_LOCKED, "LOCKED" }, \
-               { NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \
-               { NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \
-               { NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \
-               { NFS4ERR_MLINK, "MLINK" }, \
-               { NFS4ERR_MOVED, "MOVED" }, \
-               { NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \
-               { NFS4ERR_NOENT, "NOENT" }, \
-               { NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \
-               { NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \
-               { NFS4ERR_NOSPC, "NOSPC" }, \
-               { NFS4ERR_NOTDIR, "NOTDIR" }, \
-               { NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \
-               { NFS4ERR_NOTSUPP, "NOTSUPP" }, \
-               { NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \
-               { NFS4ERR_NOT_SAME, "NOT_SAME" }, \
-               { NFS4ERR_NO_GRACE, "NO_GRACE" }, \
-               { NFS4ERR_NXIO, "NXIO" }, \
-               { NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \
-               { NFS4ERR_OPENMODE, "OPENMODE" }, \
-               { NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \
-               { NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \
-               { NFS4ERR_PERM, "PERM" }, \
-               { NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \
-               { NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \
-               { NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \
-               { NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \
-               { NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \
-               { NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \
-               { NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \
-               { NFS4ERR_REP_TOO_BIG_TO_CACHE, \
-                       "REP_TOO_BIG_TO_CACHE" }, \
-               { NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \
-               { NFS4ERR_RESOURCE, "RESOURCE" }, \
-               { NFS4ERR_RESTOREFH, "RESTOREFH" }, \
-               { NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \
-               { NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \
-               { NFS4ERR_ROFS, "ROFS" }, \
-               { NFS4ERR_SAME, "SAME" }, \
-               { NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \
-               { NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \
-               { NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \
-               { NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \
-               { NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \
-               { NFS4ERR_STALE, "STALE" }, \
-               { NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \
-               { NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \
-               { NFS4ERR_SYMLINK, "SYMLINK" }, \
-               { NFS4ERR_TOOSMALL, "TOOSMALL" }, \
-               { NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \
-               { NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \
-               { NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \
-               { NFS4ERR_WRONGSEC, "WRONGSEC" }, \
-               { NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \
-               { NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \
-               { NFS4ERR_XDEV, "XDEV" }, \
-               /* ***** Internal to Linux NFS client ***** */ \
-               { NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \
-               { NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" })
-
-#define show_open_flags(flags) \
-       __print_flags(flags, "|", \
-               { O_CREAT, "O_CREAT" }, \
-               { O_EXCL, "O_EXCL" }, \
-               { O_TRUNC, "O_TRUNC" }, \
-               { O_DIRECT, "O_DIRECT" })
-
-#define show_fmode_flags(mode) \
-       __print_flags(mode, "|", \
-               { ((__force unsigned long)FMODE_READ), "READ" }, \
-               { ((__force unsigned long)FMODE_WRITE), "WRITE" }, \
-               { ((__force unsigned long)FMODE_EXEC), "EXEC" })
+#include <trace/events/fs.h>
+#include <trace/events/nfs.h>
 
 #define show_nfs_fattr_flags(valid) \
        __print_flags((unsigned long)valid, "|", \
@@ -365,7 +53,7 @@ DECLARE_EVENT_CLASS(nfs4_clientid_event,
                TP_printk(
                        "error=%ld (%s) dstaddr=%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        __get_str(dstaddr)
                )
 );
@@ -389,29 +77,6 @@ DEFINE_NFS4_CLIENTID_EVENT(nfs4_bind_conn_to_session);
 DEFINE_NFS4_CLIENTID_EVENT(nfs4_sequence);
 DEFINE_NFS4_CLIENTID_EVENT(nfs4_reclaim_complete);
 
-#define show_nfs4_sequence_status_flags(status) \
-       __print_flags((unsigned long)status, "|", \
-               { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \
-               { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, \
-                       "CB_GSS_CONTEXTS_EXPIRING" }, \
-               { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, \
-                       "CB_GSS_CONTEXTS_EXPIRED" }, \
-               { SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, \
-                       "EXPIRED_ALL_STATE_REVOKED" }, \
-               { SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, \
-                       "EXPIRED_SOME_STATE_REVOKED" }, \
-               { SEQ4_STATUS_ADMIN_STATE_REVOKED, \
-                       "ADMIN_STATE_REVOKED" }, \
-               { SEQ4_STATUS_RECALLABLE_STATE_REVOKED,  \
-                       "RECALLABLE_STATE_REVOKED" }, \
-               { SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \
-               { SEQ4_STATUS_RESTART_RECLAIM_NEEDED, \
-                       "RESTART_RECLAIM_NEEDED" }, \
-               { SEQ4_STATUS_CB_PATH_DOWN_SESSION, \
-                       "CB_PATH_DOWN_SESSION" }, \
-               { SEQ4_STATUS_BACKCHANNEL_FAULT, \
-                       "BACKCHANNEL_FAULT" })
-
 TRACE_EVENT(nfs4_sequence_done,
                TP_PROTO(
                        const struct nfs4_session *session,
@@ -425,7 +90,7 @@ TRACE_EVENT(nfs4_sequence_done,
                        __field(unsigned int, seq_nr)
                        __field(unsigned int, highest_slotid)
                        __field(unsigned int, target_highest_slotid)
-                       __field(unsigned int, status_flags)
+                       __field(unsigned long, status_flags)
                        __field(unsigned long, error)
                ),
 
@@ -444,16 +109,16 @@ TRACE_EVENT(nfs4_sequence_done,
                TP_printk(
                        "error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "
                        "highest_slotid=%u target_highest_slotid=%u "
-                       "status_flags=%u (%s)",
+                       "status_flags=0x%lx (%s)",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        __entry->session,
                        __entry->slot_nr,
                        __entry->seq_nr,
                        __entry->highest_slotid,
                        __entry->target_highest_slotid,
                        __entry->status_flags,
-                       show_nfs4_sequence_status_flags(__entry->status_flags)
+                       show_nfs4_seq4_status(__entry->status_flags)
                )
 );
 
@@ -490,7 +155,7 @@ TRACE_EVENT(nfs4_cb_sequence,
                        "error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "
                        "highest_slotid=%u",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        __entry->session,
                        __entry->slot_nr,
                        __entry->seq_nr,
@@ -527,7 +192,7 @@ TRACE_EVENT(nfs4_cb_seqid_err,
                        "error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "
                        "highest_slotid=%u",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        __entry->session,
                        __entry->slot_nr,
                        __entry->seq_nr,
@@ -535,6 +200,49 @@ TRACE_EVENT(nfs4_cb_seqid_err,
                )
 );
 
+TRACE_EVENT(nfs4_cb_offload,
+               TP_PROTO(
+                       const struct nfs_fh *cb_fh,
+                       const nfs4_stateid *cb_stateid,
+                       uint64_t cb_count,
+                       int cb_error,
+                       int cb_how_stable
+               ),
+
+               TP_ARGS(cb_fh, cb_stateid, cb_count, cb_error,
+                       cb_how_stable),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(u32, fhandle)
+                       __field(loff_t, cb_count)
+                       __field(int, cb_how)
+                       __field(int, cb_stateid_seq)
+                       __field(u32, cb_stateid_hash)
+               ),
+
+               TP_fast_assign(
+                       __entry->error = cb_error < 0 ? -cb_error : 0;
+                       __entry->fhandle = nfs_fhandle_hash(cb_fh);
+                       __entry->cb_stateid_seq =
+                               be32_to_cpu(cb_stateid->seqid);
+                       __entry->cb_stateid_hash =
+                               nfs_stateid_hash(cb_stateid);
+                       __entry->cb_count = cb_count;
+                       __entry->cb_how = cb_how_stable;
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fhandle=0x%08x cb_stateid=%d:0x%08x "
+                       "cb_count=%llu cb_how=%s",
+                       -__entry->error,
+                       show_nfs4_status(__entry->error),
+                       __entry->fhandle,
+                       __entry->cb_stateid_seq, __entry->cb_stateid_hash,
+                       __entry->cb_count,
+                       show_nfs_stable_how(__entry->cb_how)
+               )
+);
 #endif /* CONFIG_NFS_V4_1 */
 
 TRACE_EVENT(nfs4_setup_sequence,
@@ -661,7 +369,7 @@ TRACE_EVENT(nfs4_state_mgr_failed,
                        "hostname=%s clp state=%s error=%ld (%s) section=%s",
                        __get_str(hostname),
                        show_nfs4_clp_state(__entry->state), -__entry->error,
-                       show_nfsv4_errors(__entry->error), __get_str(section)
+                       show_nfs4_status(__entry->error), __get_str(section)
 
                )
 )
@@ -694,8 +402,8 @@ TRACE_EVENT(nfs4_xdr_bad_operation,
                        __entry->expected = expected;
                ),
 
-               TP_printk(
-                       "task:%u@%d xid=0x%08x operation=%u, expected=%u",
+               TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                         " xid=0x%08x operation=%u, expected=%u",
                        __entry->task_id, __entry->client_id, __entry->xid,
                        __entry->op, __entry->expected
                )
@@ -729,10 +437,10 @@ DECLARE_EVENT_CLASS(nfs4_xdr_event,
                        __entry->error = error;
                ),
 
-               TP_printk(
-                       "task:%u@%d xid=0x%08x error=%ld (%s) operation=%u",
+               TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                         " xid=0x%08x error=%ld (%s) operation=%u",
                        __entry->task_id, __entry->client_id, __entry->xid,
-                       -__entry->error, show_nfsv4_errors(__entry->error),
+                       -__entry->error, show_nfs4_status(__entry->error),
                        __entry->op
                )
 );
@@ -793,8 +501,8 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
 
                TP_STRUCT__entry(
                        __field(unsigned long, error)
-                       __field(unsigned int, flags)
-                       __field(unsigned int, fmode)
+                       __field(unsigned long, flags)
+                       __field(unsigned long, fmode)
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
@@ -812,7 +520,7 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
 
                        __entry->error = -error;
                        __entry->flags = flags;
-                       __entry->fmode = (__force unsigned int)ctx->mode;
+                       __entry->fmode = (__force unsigned long)ctx->mode;
                        __entry->dev = ctx->dentry->d_sb->s_dev;
                        if (!IS_ERR_OR_NULL(state)) {
                                inode = state->inode;
@@ -842,15 +550,15 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
                ),
 
                TP_printk(
-                       "error=%ld (%s) flags=%d (%s) fmode=%s "
+                       "error=%ld (%s) flags=%lu (%s) fmode=%s "
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "name=%02x:%02x:%llu/%s stateid=%d:0x%08x "
                        "openstateid=%d:0x%08x",
                         -__entry->error,
-                        show_nfsv4_errors(__entry->error),
+                        show_nfs4_status(__entry->error),
                         __entry->flags,
-                        show_open_flags(__entry->flags),
-                        show_fmode_flags(__entry->fmode),
+                        show_fs_fcntl_open_flags(__entry->flags),
+                        show_fs_fmode_flags(__entry->fmode),
                         MAJOR(__entry->dev), MINOR(__entry->dev),
                         (unsigned long long)__entry->fileid,
                         __entry->fhandle,
@@ -904,7 +612,7 @@ TRACE_EVENT(nfs4_cached_open,
                TP_printk(
                        "fmode=%s fileid=%02x:%02x:%llu "
                        "fhandle=0x%08x stateid=%d:0x%08x",
-                       __entry->fmode ?  show_fmode_flags(__entry->fmode) :
+                       __entry->fmode ?  show_fs_fmode_flags(__entry->fmode) :
                                          "closed",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
@@ -951,8 +659,8 @@ TRACE_EVENT(nfs4_close,
                        "error=%ld (%s) fmode=%s fileid=%02x:%02x:%llu "
                        "fhandle=0x%08x openstateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
-                       __entry->fmode ?  show_fmode_flags(__entry->fmode) :
+                       show_nfs4_status(__entry->error),
+                       __entry->fmode ?  show_fs_fmode_flags(__entry->fmode) :
                                          "closed",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
@@ -961,24 +669,6 @@ TRACE_EVENT(nfs4_close,
                )
 );
 
-TRACE_DEFINE_ENUM(F_GETLK);
-TRACE_DEFINE_ENUM(F_SETLK);
-TRACE_DEFINE_ENUM(F_SETLKW);
-TRACE_DEFINE_ENUM(F_RDLCK);
-TRACE_DEFINE_ENUM(F_WRLCK);
-TRACE_DEFINE_ENUM(F_UNLCK);
-
-#define show_lock_cmd(type) \
-       __print_symbolic((int)type, \
-               { F_GETLK, "GETLK" }, \
-               { F_SETLK, "SETLK" }, \
-               { F_SETLKW, "SETLKW" })
-#define show_lock_type(type) \
-       __print_symbolic((int)type, \
-               { F_RDLCK, "RDLCK" }, \
-               { F_WRLCK, "WRLCK" }, \
-               { F_UNLCK, "UNLCK" })
-
 DECLARE_EVENT_CLASS(nfs4_lock_event,
                TP_PROTO(
                        const struct file_lock *request,
@@ -991,8 +681,8 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,
 
                TP_STRUCT__entry(
                        __field(unsigned long, error)
-                       __field(int, cmd)
-                       __field(char, type)
+                       __field(unsigned long, cmd)
+                       __field(unsigned long, type)
                        __field(loff_t, start)
                        __field(loff_t, end)
                        __field(dev_t, dev)
@@ -1024,9 +714,9 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "stateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
-                       show_lock_cmd(__entry->cmd),
-                       show_lock_type(__entry->type),
+                       show_nfs4_status(__entry->error),
+                       show_fs_fcntl_cmd(__entry->cmd),
+                       show_fs_fcntl_lock_type(__entry->type),
                        (long long)__entry->start,
                        (long long)__entry->end,
                        MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -1061,8 +751,8 @@ TRACE_EVENT(nfs4_set_lock,
 
                TP_STRUCT__entry(
                        __field(unsigned long, error)
-                       __field(int, cmd)
-                       __field(char, type)
+                       __field(unsigned long, cmd)
+                       __field(unsigned long, type)
                        __field(loff_t, start)
                        __field(loff_t, end)
                        __field(dev_t, dev)
@@ -1100,9 +790,9 @@ TRACE_EVENT(nfs4_set_lock,
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "stateid=%d:0x%08x lockstateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
-                       show_lock_cmd(__entry->cmd),
-                       show_lock_type(__entry->type),
+                       show_nfs4_status(__entry->error),
+                       show_fs_fcntl_cmd(__entry->cmd),
+                       show_fs_fcntl_lock_type(__entry->type),
                        (long long)__entry->start,
                        (long long)__entry->end,
                        MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -1219,7 +909,7 @@ DECLARE_EVENT_CLASS(nfs4_set_delegation_event,
 
                TP_printk(
                        "fmode=%s fileid=%02x:%02x:%llu fhandle=0x%08x",
-                       show_fmode_flags(__entry->fmode),
+                       show_fs_fmode_flags(__entry->fmode),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle
@@ -1266,7 +956,7 @@ TRACE_EVENT(nfs4_delegreturn_exit,
                        "error=%ld (%s) dev=%02x:%02x fhandle=0x%08x "
                        "stateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        __entry->fhandle,
                        __entry->stateid_seq, __entry->stateid_hash
@@ -1309,7 +999,7 @@ DECLARE_EVENT_CLASS(nfs4_test_stateid_event,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "stateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1356,7 +1046,7 @@ DECLARE_EVENT_CLASS(nfs4_lookup_event,
                TP_printk(
                        "error=%ld (%s) name=%02x:%02x:%llu/%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -1403,7 +1093,7 @@ TRACE_EVENT(nfs4_lookupp,
                TP_printk(
                        "error=%ld (%s) inode=%02x:%02x:%llu",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->ino
                )
@@ -1442,7 +1132,7 @@ TRACE_EVENT(nfs4_rename,
                        "error=%ld (%s) oldname=%02x:%02x:%llu/%s "
                        "newname=%02x:%02x:%llu/%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->olddir,
                        __get_str(oldname),
@@ -1477,7 +1167,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_event,
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle
@@ -1535,7 +1225,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_event,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "stateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1588,7 +1278,7 @@ DECLARE_EVENT_CLASS(nfs4_getattr_event,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "valid=%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1644,7 +1334,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_callback_event,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "dstaddr=%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1705,7 +1395,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_callback_event,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "stateid=%d:0x%08x dstaddr=%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1754,7 +1444,7 @@ DECLARE_EVENT_CLASS(nfs4_idmap_event,
 
                TP_printk(
                        "error=%ld (%s) id=%u name=%s",
-                       -__entry->error, show_nfsv4_errors(__entry->error),
+                       -__entry->error, show_nfs4_status(__entry->error),
                        __entry->id,
                        __get_str(name)
                )
@@ -1832,7 +1522,7 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
                        "offset=%lld count=%u res=%u stateid=%d:0x%08x "
                        "layoutstateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1906,7 +1596,7 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
                        "offset=%lld count=%u res=%u stateid=%d:0x%08x "
                        "layoutstateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1970,7 +1660,7 @@ DECLARE_EVENT_CLASS(nfs4_commit_event,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "offset=%lld count=%u layoutstateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -1990,16 +1680,6 @@ DEFINE_NFS4_COMMIT_EVENT(nfs4_commit);
 #ifdef CONFIG_NFS_V4_1
 DEFINE_NFS4_COMMIT_EVENT(nfs4_pnfs_commit_ds);
 
-TRACE_DEFINE_ENUM(IOMODE_READ);
-TRACE_DEFINE_ENUM(IOMODE_RW);
-TRACE_DEFINE_ENUM(IOMODE_ANY);
-
-#define show_pnfs_iomode(iomode) \
-       __print_symbolic(iomode, \
-               { IOMODE_READ, "READ" }, \
-               { IOMODE_RW, "RW" }, \
-               { IOMODE_ANY, "ANY" })
-
 TRACE_EVENT(nfs4_layoutget,
                TP_PROTO(
                        const struct nfs_open_context *ctx,
@@ -2055,11 +1735,11 @@ TRACE_EVENT(nfs4_layoutget,
                        "iomode=%s offset=%llu count=%llu stateid=%d:0x%08x "
                        "layoutstateid=%d:0x%08x",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       show_pnfs_iomode(__entry->iomode),
+                       show_pnfs_layout_iomode(__entry->iomode),
                        (unsigned long long)__entry->offset,
                        (unsigned long long)__entry->count,
                        __entry->stateid_seq, __entry->stateid_hash,
@@ -2153,7 +1833,7 @@ TRACE_EVENT(pnfs_update_layout,
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       show_pnfs_iomode(__entry->iomode),
+                       show_pnfs_layout_iomode(__entry->iomode),
                        (unsigned long long)__entry->pos,
                        (unsigned long long)__entry->count,
                        __entry->layoutstateid_seq, __entry->layoutstateid_hash,
@@ -2207,7 +1887,7 @@ DECLARE_EVENT_CLASS(pnfs_layout_event,
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       show_pnfs_iomode(__entry->iomode),
+                       show_pnfs_layout_iomode(__entry->iomode),
                        (unsigned long long)__entry->pos,
                        (unsigned long long)__entry->count,
                        __entry->layoutstateid_seq, __entry->layoutstateid_hash,
@@ -2352,7 +2032,7 @@ DECLARE_EVENT_CLASS(nfs4_flexfiles_io_event,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "offset=%llu count=%u stateid=%d:0x%08x dstaddr=%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -2408,7 +2088,7 @@ TRACE_EVENT(ff_layout_commit_error,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "offset=%llu count=%u dstaddr=%s",
                        -__entry->error,
-                       show_nfsv4_errors(__entry->error),
+                       show_nfs4_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
@@ -2417,6 +2097,406 @@ TRACE_EVENT(ff_layout_commit_error,
                )
 );
 
+TRACE_DEFINE_ENUM(NFS4_CONTENT_DATA);
+TRACE_DEFINE_ENUM(NFS4_CONTENT_HOLE);
+
+#define show_llseek_mode(what)                 \
+       __print_symbolic(what,                  \
+               { NFS4_CONTENT_DATA, "DATA" },          \
+               { NFS4_CONTENT_HOLE, "HOLE" })
+
+#ifdef CONFIG_NFS_V4_2
+TRACE_EVENT(nfs4_llseek,
+               TP_PROTO(
+                       const struct inode *inode,
+                       const struct nfs42_seek_args *args,
+                       const struct nfs42_seek_res *res,
+                       int error
+               ),
+
+               TP_ARGS(inode, args, res, error),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(u32, fhandle)
+                       __field(u32, fileid)
+                       __field(dev_t, dev)
+                       __field(int, stateid_seq)
+                       __field(u32, stateid_hash)
+                       __field(loff_t, offset_s)
+                       __field(u32, what)
+                       __field(loff_t, offset_r)
+                       __field(u32, eof)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = args->sa_fh;
+
+                       __entry->fileid = nfsi->fileid;
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fhandle = nfs_fhandle_hash(fh);
+                       __entry->offset_s = args->sa_offset;
+                       __entry->stateid_seq =
+                               be32_to_cpu(args->sa_stateid.seqid);
+                       __entry->stateid_hash =
+                               nfs_stateid_hash(&args->sa_stateid);
+                       __entry->what = args->sa_what;
+                       if (error) {
+                               __entry->error = -error;
+                               __entry->offset_r = 0;
+                               __entry->eof = 0;
+                       } else {
+                               __entry->error = 0;
+                               __entry->offset_r = res->sr_offset;
+                               __entry->eof = res->sr_eof;
+                       }
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
+                       "stateid=%d:0x%08x offset_s=%llu what=%s "
+                       "offset_r=%llu eof=%u",
+                       -__entry->error,
+                       show_nfs4_status(__entry->error),
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle,
+                       __entry->stateid_seq, __entry->stateid_hash,
+                       __entry->offset_s,
+                       show_llseek_mode(__entry->what),
+                       __entry->offset_r,
+                       __entry->eof
+               )
+);
+
+DECLARE_EVENT_CLASS(nfs4_sparse_event,
+               TP_PROTO(
+                       const struct inode *inode,
+                       const struct nfs42_falloc_args *args,
+                       int error
+               ),
+
+               TP_ARGS(inode, args, error),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(loff_t, offset)
+                       __field(loff_t, len)
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(int, stateid_seq)
+                       __field(u32, stateid_hash)
+               ),
+
+               TP_fast_assign(
+                       __entry->error = error < 0 ? -error : 0;
+                       __entry->offset = args->falloc_offset;
+                       __entry->len = args->falloc_length;
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = NFS_FILEID(inode);
+                       __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
+                       __entry->stateid_seq =
+                               be32_to_cpu(args->falloc_stateid.seqid);
+                       __entry->stateid_hash =
+                               nfs_stateid_hash(&args->falloc_stateid);
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
+                       "stateid=%d:0x%08x offset=%llu len=%llu",
+                       -__entry->error,
+                       show_nfs4_status(__entry->error),
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle,
+                       __entry->stateid_seq, __entry->stateid_hash,
+                       (long long)__entry->offset,
+                       (long long)__entry->len
+               )
+);
+#define DEFINE_NFS4_SPARSE_EVENT(name) \
+       DEFINE_EVENT(nfs4_sparse_event, name, \
+                       TP_PROTO( \
+                               const struct inode *inode, \
+                               const struct nfs42_falloc_args *args, \
+                               int error \
+                       ), \
+                       TP_ARGS(inode, args, error))
+DEFINE_NFS4_SPARSE_EVENT(nfs4_fallocate);
+DEFINE_NFS4_SPARSE_EVENT(nfs4_deallocate);
+
+TRACE_EVENT(nfs4_copy,
+               TP_PROTO(
+                       const struct inode *src_inode,
+                       const struct inode *dst_inode,
+                       const struct nfs42_copy_args *args,
+                       const struct nfs42_copy_res *res,
+                       const struct nl4_server *nss,
+                       int error
+               ),
+
+               TP_ARGS(src_inode, dst_inode, args, res, nss, error),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(u32, src_fhandle)
+                       __field(u32, src_fileid)
+                       __field(u32, dst_fhandle)
+                       __field(u32, dst_fileid)
+                       __field(dev_t, src_dev)
+                       __field(dev_t, dst_dev)
+                       __field(int, src_stateid_seq)
+                       __field(u32, src_stateid_hash)
+                       __field(int, dst_stateid_seq)
+                       __field(u32, dst_stateid_hash)
+                       __field(loff_t, src_offset)
+                       __field(loff_t, dst_offset)
+                       __field(bool, sync)
+                       __field(loff_t, len)
+                       __field(int, res_stateid_seq)
+                       __field(u32, res_stateid_hash)
+                       __field(loff_t, res_count)
+                       __field(bool, res_sync)
+                       __field(bool, res_cons)
+                       __field(bool, intra)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *src_nfsi = NFS_I(src_inode);
+                       const struct nfs_inode *dst_nfsi = NFS_I(dst_inode);
+
+                       __entry->src_fileid = src_nfsi->fileid;
+                       __entry->src_dev = src_inode->i_sb->s_dev;
+                       __entry->src_fhandle = nfs_fhandle_hash(args->src_fh);
+                       __entry->src_offset = args->src_pos;
+                       __entry->dst_fileid = dst_nfsi->fileid;
+                       __entry->dst_dev = dst_inode->i_sb->s_dev;
+                       __entry->dst_fhandle = nfs_fhandle_hash(args->dst_fh);
+                       __entry->dst_offset = args->dst_pos;
+                       __entry->len = args->count;
+                       __entry->sync = args->sync;
+                       __entry->src_stateid_seq =
+                               be32_to_cpu(args->src_stateid.seqid);
+                       __entry->src_stateid_hash =
+                               nfs_stateid_hash(&args->src_stateid);
+                       __entry->dst_stateid_seq =
+                               be32_to_cpu(args->dst_stateid.seqid);
+                       __entry->dst_stateid_hash =
+                               nfs_stateid_hash(&args->dst_stateid);
+                       __entry->intra = nss ? 0 : 1;
+                       if (error) {
+                               __entry->error = -error;
+                               __entry->res_stateid_seq = 0;
+                               __entry->res_stateid_hash = 0;
+                               __entry->res_count = 0;
+                               __entry->res_sync = 0;
+                               __entry->res_cons = 0;
+                       } else {
+                               __entry->error = 0;
+                               __entry->res_stateid_seq =
+                                       be32_to_cpu(res->write_res.stateid.seqid);
+                               __entry->res_stateid_hash =
+                                       nfs_stateid_hash(&res->write_res.stateid);
+                               __entry->res_count = res->write_res.count;
+                               __entry->res_sync = res->synchronous;
+                               __entry->res_cons = res->consecutive;
+                       }
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) intra=%d src_fileid=%02x:%02x:%llu "
+                       "src_fhandle=0x%08x dst_fileid=%02x:%02x:%llu "
+                       "dst_fhandle=0x%08x src_stateid=%d:0x%08x "
+                       "dst_stateid=%d:0x%08x src_offset=%llu dst_offset=%llu "
+                       "len=%llu sync=%d cb_stateid=%d:0x%08x res_sync=%d "
+                       "res_cons=%d res_count=%llu",
+                       -__entry->error,
+                       show_nfs4_status(__entry->error),
+                       __entry->intra,
+                       MAJOR(__entry->src_dev), MINOR(__entry->src_dev),
+                       (unsigned long long)__entry->src_fileid,
+                       __entry->src_fhandle,
+                       MAJOR(__entry->dst_dev), MINOR(__entry->dst_dev),
+                       (unsigned long long)__entry->dst_fileid,
+                       __entry->dst_fhandle,
+                       __entry->src_stateid_seq, __entry->src_stateid_hash,
+                       __entry->dst_stateid_seq, __entry->dst_stateid_hash,
+                       __entry->src_offset,
+                       __entry->dst_offset,
+                       __entry->len,
+                       __entry->sync,
+                       __entry->res_stateid_seq, __entry->res_stateid_hash,
+                       __entry->res_sync,
+                       __entry->res_cons,
+                       __entry->res_count
+               )
+);
+
+TRACE_EVENT(nfs4_clone,
+               TP_PROTO(
+                       const struct inode *src_inode,
+                       const struct inode *dst_inode,
+                       const struct nfs42_clone_args *args,
+                       int error
+               ),
+
+               TP_ARGS(src_inode, dst_inode, args, error),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(u32, src_fhandle)
+                       __field(u32, src_fileid)
+                       __field(u32, dst_fhandle)
+                       __field(u32, dst_fileid)
+                       __field(dev_t, src_dev)
+                       __field(dev_t, dst_dev)
+                       __field(loff_t, src_offset)
+                       __field(loff_t, dst_offset)
+                       __field(int, src_stateid_seq)
+                       __field(u32, src_stateid_hash)
+                       __field(int, dst_stateid_seq)
+                       __field(u32, dst_stateid_hash)
+                       __field(loff_t, len)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *src_nfsi = NFS_I(src_inode);
+                       const struct nfs_inode *dst_nfsi = NFS_I(dst_inode);
+
+                       __entry->src_fileid = src_nfsi->fileid;
+                       __entry->src_dev = src_inode->i_sb->s_dev;
+                       __entry->src_fhandle = nfs_fhandle_hash(args->src_fh);
+                       __entry->src_offset = args->src_offset;
+                       __entry->dst_fileid = dst_nfsi->fileid;
+                       __entry->dst_dev = dst_inode->i_sb->s_dev;
+                       __entry->dst_fhandle = nfs_fhandle_hash(args->dst_fh);
+                       __entry->dst_offset = args->dst_offset;
+                       __entry->len = args->count;
+                       __entry->error = error < 0 ? -error : 0;
+                       __entry->src_stateid_seq =
+                               be32_to_cpu(args->src_stateid.seqid);
+                       __entry->src_stateid_hash =
+                               nfs_stateid_hash(&args->src_stateid);
+                       __entry->dst_stateid_seq =
+                               be32_to_cpu(args->dst_stateid.seqid);
+                       __entry->dst_stateid_hash =
+                               nfs_stateid_hash(&args->dst_stateid);
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) src_fileid=%02x:%02x:%llu "
+                       "src_fhandle=0x%08x dst_fileid=%02x:%02x:%llu "
+                       "dst_fhandle=0x%08x src_stateid=%d:0x%08x "
+                       "dst_stateid=%d:0x%08x src_offset=%llu "
+                       "dst_offset=%llu len=%llu",
+                       -__entry->error,
+                       show_nfs4_status(__entry->error),
+                       MAJOR(__entry->src_dev), MINOR(__entry->src_dev),
+                       (unsigned long long)__entry->src_fileid,
+                       __entry->src_fhandle,
+                       MAJOR(__entry->dst_dev), MINOR(__entry->dst_dev),
+                       (unsigned long long)__entry->dst_fileid,
+                       __entry->dst_fhandle,
+                       __entry->src_stateid_seq, __entry->src_stateid_hash,
+                       __entry->dst_stateid_seq, __entry->dst_stateid_hash,
+                       __entry->src_offset,
+                       __entry->dst_offset,
+                       __entry->len
+               )
+);
+
+TRACE_EVENT(nfs4_copy_notify,
+               TP_PROTO(
+                       const struct inode *inode,
+                       const struct nfs42_copy_notify_args *args,
+                       const struct nfs42_copy_notify_res *res,
+                       int error
+               ),
+
+               TP_ARGS(inode, args, res, error),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(u32, fhandle)
+                       __field(u32, fileid)
+                       __field(dev_t, dev)
+                       __field(int, stateid_seq)
+                       __field(u32, stateid_hash)
+                       __field(int, res_stateid_seq)
+                       __field(u32, res_stateid_hash)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+
+                       __entry->fileid = nfsi->fileid;
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fhandle = nfs_fhandle_hash(args->cna_src_fh);
+                       __entry->stateid_seq =
+                               be32_to_cpu(args->cna_src_stateid.seqid);
+                       __entry->stateid_hash =
+                               nfs_stateid_hash(&args->cna_src_stateid);
+                       if (error) {
+                               __entry->error = -error;
+                               __entry->res_stateid_seq = 0;
+                               __entry->res_stateid_hash = 0;
+                       } else {
+                               __entry->error = 0;
+                               __entry->res_stateid_seq =
+                                       be32_to_cpu(res->cnr_stateid.seqid);
+                               __entry->res_stateid_hash =
+                                       nfs_stateid_hash(&res->cnr_stateid);
+                       }
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
+                       "stateid=%d:0x%08x res_stateid=%d:0x%08x",
+                       -__entry->error,
+                       show_nfs4_status(__entry->error),
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle,
+                       __entry->stateid_seq, __entry->stateid_hash,
+                       __entry->res_stateid_seq, __entry->res_stateid_hash
+               )
+);
+
+TRACE_EVENT(nfs4_offload_cancel,
+               TP_PROTO(
+                       const struct nfs42_offload_status_args *args,
+                       int error
+               ),
+
+               TP_ARGS(args, error),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(u32, fhandle)
+                       __field(int, stateid_seq)
+                       __field(u32, stateid_hash)
+               ),
+
+               TP_fast_assign(
+                       __entry->fhandle = nfs_fhandle_hash(args->osa_src_fh);
+                       __entry->error = error < 0 ? -error : 0;
+                       __entry->stateid_seq =
+                               be32_to_cpu(args->osa_stateid.seqid);
+                       __entry->stateid_hash =
+                               nfs_stateid_hash(&args->osa_stateid);
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fhandle=0x%08x stateid=%d:0x%08x",
+                       -__entry->error,
+                       show_nfs4_status(__entry->error),
+                       __entry->fhandle,
+                       __entry->stateid_seq, __entry->stateid_hash
+               )
+);
+#endif /* CONFIG_NFS_V4_2 */
 
 #endif /* CONFIG_NFS_V4_1 */
 
index a8cff19..69862bf 100644 (file)
@@ -3168,20 +3168,23 @@ static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char
 
 static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
 {
-       __be32 *p;
+       ssize_t ret;
+       void *ptr;
+       u32 tmp;
 
-       p = xdr_inline_decode(xdr, 8);
-       if (unlikely(!p))
+       if (xdr_stream_decode_u32(xdr, &tmp) < 0)
                return -EIO;
-       hdr->status = be32_to_cpup(p++);
-       hdr->taglen = be32_to_cpup(p);
+       hdr->status = tmp;
 
-       p = xdr_inline_decode(xdr, hdr->taglen + 4);
-       if (unlikely(!p))
+       ret = xdr_stream_decode_opaque_inline(xdr, &ptr, NFS4_OPAQUE_LIMIT);
+       if (ret < 0)
+               return -EIO;
+       hdr->taglen = ret;
+       hdr->tag = ptr;
+
+       if (xdr_stream_decode_u32(xdr, &tmp) < 0)
                return -EIO;
-       hdr->tag = (char *)p;
-       p += XDR_QUADLEN(hdr->taglen);
-       hdr->nops = be32_to_cpup(p);
+       hdr->nops = tmp;
        if (unlikely(hdr->nops < 1))
                return nfs4_stat_to_errno(hdr->status);
        return 0;
@@ -4582,8 +4585,7 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr,
 
 static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
                struct nfs_fattr *fattr, struct nfs_fh *fh,
-               struct nfs4_fs_locations *fs_loc, struct nfs4_label *label,
-               const struct nfs_server *server)
+               struct nfs4_fs_locations *fs_loc, const struct nfs_server *server)
 {
        int status;
        umode_t fmode = 0;
@@ -4698,8 +4700,8 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
        if (status < 0)
                goto xdr_error;
 
-       if (label) {
-               status = decode_attr_security_label(xdr, bitmap, label);
+       if (fattr->label) {
+               status = decode_attr_security_label(xdr, bitmap, fattr->label);
                if (status < 0)
                        goto xdr_error;
                fattr->valid |= status;
@@ -4712,7 +4714,7 @@ xdr_error:
 
 static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
                struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc,
-               struct nfs4_label *label, const struct nfs_server *server)
+               const struct nfs_server *server)
 {
        unsigned int savep;
        uint32_t attrlen,
@@ -4731,8 +4733,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
        if (status < 0)
                goto xdr_error;
 
-       status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc,
-                                       label, server);
+       status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, server);
        if (status < 0)
                goto xdr_error;
 
@@ -4742,16 +4743,10 @@ xdr_error:
        return status;
 }
 
-static int decode_getfattr_label(struct xdr_stream *xdr, struct nfs_fattr *fattr,
-               struct nfs4_label *label, const struct nfs_server *server)
-{
-       return decode_getfattr_generic(xdr, fattr, NULL, NULL, label, server);
-}
-
 static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
                const struct nfs_server *server)
 {
-       return decode_getfattr_generic(xdr, fattr, NULL, NULL, NULL, server);
+       return decode_getfattr_generic(xdr, fattr, NULL, NULL, server);
 }
 
 /*
@@ -5572,20 +5567,9 @@ static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_re
 
 static int decode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map)
 {
-       __be32 *p;
-       uint32_t bitmap_words;
-       unsigned int i;
-
-       p = xdr_inline_decode(xdr, 4);
-       if (!p)
-               return -EIO;
-       bitmap_words = be32_to_cpup(p++);
-       if (bitmap_words > NFS4_OP_MAP_NUM_WORDS)
+       if (xdr_stream_decode_uint32_array(xdr, op_map->u.words,
+                                          ARRAY_SIZE(op_map->u.words)) < 0)
                return -EIO;
-       p = xdr_inline_decode(xdr, 4 * bitmap_words);
-       for (i = 0; i < bitmap_words; i++)
-               op_map->u.words[i] = be32_to_cpup(p++);
-
        return 0;
 }
 
@@ -6179,7 +6163,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
        status = decode_getfh(xdr, res->fh);
        if (status)
                goto out;
-       status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+       status = decode_getfattr(xdr, res->fattr, res->server);
 out:
        return status;
 }
@@ -6209,7 +6193,7 @@ static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
        status = decode_getfh(xdr, res->fh);
        if (status)
                goto out;
-       status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+       status = decode_getfattr(xdr, res->fattr, res->server);
 out:
        return status;
 }
@@ -6236,8 +6220,7 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
                goto out;
        status = decode_getfh(xdr, res->fh);
        if (status == 0)
-               status = decode_getfattr_label(xdr, res->fattr,
-                                               res->label, res->server);
+               status = decode_getfattr(xdr, res->fattr, res->server);
 out:
        return status;
 }
@@ -6331,7 +6314,7 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
        status = decode_restorefh(xdr);
        if (status)
                goto out;
-       decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+       decode_getfattr(xdr, res->fattr, res->server);
 out:
        return status;
 }
@@ -6361,7 +6344,7 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
        status = decode_getfh(xdr, res->fh);
        if (status)
                goto out;
-       decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+       decode_getfattr(xdr, res->fattr, res->server);
 out:
        return status;
 }
@@ -6394,7 +6377,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
        status = decode_putfh(xdr);
        if (status)
                goto out;
-       status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+       status = decode_getfattr(xdr, res->fattr, res->server);
 out:
        return status;
 }
@@ -6532,7 +6515,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
                goto out;
        if (res->access_request)
                decode_access(xdr, &res->access_supported, &res->access_result);
-       decode_getfattr_label(xdr, res->f_attr, res->f_label, res->server);
+       decode_getfattr(xdr, res->f_attr, res->server);
        if (res->lg_res)
                decode_layoutget(xdr, rqstp, res->lg_res);
 out:
@@ -6616,7 +6599,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp,
        status = decode_setattr(xdr);
        if (status)
                goto out;
-       decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+       decode_getfattr(xdr, res->fattr, res->server);
 out:
        return status;
 }
@@ -7031,7 +7014,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
                status = decode_getfattr_generic(xdr,
                                        &res->fs_locations->fattr,
                                         NULL, res->fs_locations,
-                                        NULL, res->fs_locations->server);
+                                        res->fs_locations->server);
                if (status)
                        goto out;
                if (res->renew)
@@ -7044,7 +7027,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
                status = decode_getfattr_generic(xdr,
                                        &res->fs_locations->fattr,
                                         NULL, res->fs_locations,
-                                        NULL, res->fs_locations->server);
+                                        res->fs_locations->server);
        }
 out:
        return status;
@@ -7475,7 +7458,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
                return -EAGAIN;
 
        if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
-                       NULL, entry->label, entry->server) < 0)
+                       NULL, entry->server) < 0)
                return -EAGAIN;
        if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
                entry->ino = entry->fattr->mounted_on_fileid;
index 8a22487..21dac84 100644 (file)
 #include <linux/tracepoint.h>
 #include <linux/iversion.h>
 
-TRACE_DEFINE_ENUM(DT_UNKNOWN);
-TRACE_DEFINE_ENUM(DT_FIFO);
-TRACE_DEFINE_ENUM(DT_CHR);
-TRACE_DEFINE_ENUM(DT_DIR);
-TRACE_DEFINE_ENUM(DT_BLK);
-TRACE_DEFINE_ENUM(DT_REG);
-TRACE_DEFINE_ENUM(DT_LNK);
-TRACE_DEFINE_ENUM(DT_SOCK);
-TRACE_DEFINE_ENUM(DT_WHT);
-
-#define nfs_show_file_type(ftype) \
-       __print_symbolic(ftype, \
-                       { DT_UNKNOWN, "UNKNOWN" }, \
-                       { DT_FIFO, "FIFO" }, \
-                       { DT_CHR, "CHR" }, \
-                       { DT_DIR, "DIR" }, \
-                       { DT_BLK, "BLK" }, \
-                       { DT_REG, "REG" }, \
-                       { DT_LNK, "LNK" }, \
-                       { DT_SOCK, "SOCK" }, \
-                       { DT_WHT, "WHT" })
-
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_DATA);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_ATIME);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_ACCESS);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_ACL);
-TRACE_DEFINE_ENUM(NFS_INO_REVAL_PAGECACHE);
-TRACE_DEFINE_ENUM(NFS_INO_REVAL_FORCED);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_LABEL);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_CHANGE);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_CTIME);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_MTIME);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_SIZE);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER);
-TRACE_DEFINE_ENUM(NFS_INO_DATA_INVAL_DEFER);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_BLOCKS);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_NLINK);
-TRACE_DEFINE_ENUM(NFS_INO_INVALID_MODE);
+#include <trace/events/fs.h>
+#include <trace/events/nfs.h>
+#include <trace/events/sunrpc_base.h>
 
 #define nfs_show_cache_validity(v) \
        __print_flags(v, "|", \
@@ -71,17 +35,6 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_MODE);
                        { NFS_INO_INVALID_NLINK, "INVALID_NLINK" }, \
                        { NFS_INO_INVALID_MODE, "INVALID_MODE" })
 
-TRACE_DEFINE_ENUM(NFS_INO_ADVISE_RDPLUS);
-TRACE_DEFINE_ENUM(NFS_INO_STALE);
-TRACE_DEFINE_ENUM(NFS_INO_ACL_LRU_SET);
-TRACE_DEFINE_ENUM(NFS_INO_INVALIDATING);
-TRACE_DEFINE_ENUM(NFS_INO_FSCACHE);
-TRACE_DEFINE_ENUM(NFS_INO_FSCACHE_LOCK);
-TRACE_DEFINE_ENUM(NFS_INO_LAYOUTCOMMIT);
-TRACE_DEFINE_ENUM(NFS_INO_LAYOUTCOMMITTING);
-TRACE_DEFINE_ENUM(NFS_INO_LAYOUTSTATS);
-TRACE_DEFINE_ENUM(NFS_INO_ODIRECT);
-
 #define nfs_show_nfsi_flags(v) \
        __print_flags(v, "|", \
                        { BIT(NFS_INO_ADVISE_RDPLUS), "ADVISE_RDPLUS" }, \
@@ -163,12 +116,12 @@ DECLARE_EVENT_CLASS(nfs_inode_event_done,
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
                        "type=%u (%s) version=%llu size=%lld "
                        "cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s)",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
                        __entry->type,
-                       nfs_show_file_type(__entry->type),
+                       show_fs_dirent_type(__entry->type),
                        (unsigned long long)__entry->version,
                        (long long)__entry->size,
                        __entry->cache_validity,
@@ -254,12 +207,12 @@ TRACE_EVENT(nfs_access_exit,
                        "type=%u (%s) version=%llu size=%lld "
                        "cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s) "
                        "mask=0x%x permitted=0x%x",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
                        __entry->type,
-                       nfs_show_file_type(__entry->type),
+                       show_fs_dirent_type(__entry->type),
                        (unsigned long long)__entry->version,
                        (long long)__entry->size,
                        __entry->cache_validity,
@@ -270,33 +223,55 @@ TRACE_EVENT(nfs_access_exit,
                )
 );
 
-TRACE_DEFINE_ENUM(LOOKUP_FOLLOW);
-TRACE_DEFINE_ENUM(LOOKUP_DIRECTORY);
-TRACE_DEFINE_ENUM(LOOKUP_AUTOMOUNT);
-TRACE_DEFINE_ENUM(LOOKUP_PARENT);
-TRACE_DEFINE_ENUM(LOOKUP_REVAL);
-TRACE_DEFINE_ENUM(LOOKUP_RCU);
-TRACE_DEFINE_ENUM(LOOKUP_OPEN);
-TRACE_DEFINE_ENUM(LOOKUP_CREATE);
-TRACE_DEFINE_ENUM(LOOKUP_EXCL);
-TRACE_DEFINE_ENUM(LOOKUP_RENAME_TARGET);
-TRACE_DEFINE_ENUM(LOOKUP_EMPTY);
-TRACE_DEFINE_ENUM(LOOKUP_DOWN);
-
-#define show_lookup_flags(flags) \
-       __print_flags(flags, "|", \
-                       { LOOKUP_FOLLOW, "FOLLOW" }, \
-                       { LOOKUP_DIRECTORY, "DIRECTORY" }, \
-                       { LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \
-                       { LOOKUP_PARENT, "PARENT" }, \
-                       { LOOKUP_REVAL, "REVAL" }, \
-                       { LOOKUP_RCU, "RCU" }, \
-                       { LOOKUP_OPEN, "OPEN" }, \
-                       { LOOKUP_CREATE, "CREATE" }, \
-                       { LOOKUP_EXCL, "EXCL" }, \
-                       { LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \
-                       { LOOKUP_EMPTY, "EMPTY" }, \
-                       { LOOKUP_DOWN, "DOWN" })
+DECLARE_EVENT_CLASS(nfs_update_size_class,
+               TP_PROTO(
+                       const struct inode *inode,
+                       loff_t new_size
+               ),
+
+               TP_ARGS(inode, new_size),
+
+               TP_STRUCT__entry(
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(u64, version)
+                       __field(loff_t, cur_size)
+                       __field(loff_t, new_size)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->fileid = nfsi->fileid;
+                       __entry->version = inode_peek_iversion_raw(inode);
+                       __entry->cur_size = i_size_read(inode);
+                       __entry->new_size = new_size;
+               ),
+
+               TP_printk(
+                       "fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu cursize=%lld newsize=%lld",
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle, __entry->version,
+                       __entry->cur_size, __entry->new_size
+               )
+);
+
+#define DEFINE_NFS_UPDATE_SIZE_EVENT(name) \
+       DEFINE_EVENT(nfs_update_size_class, nfs_size_##name, \
+                       TP_PROTO( \
+                               const struct inode *inode, \
+                               loff_t new_size \
+                       ), \
+                       TP_ARGS(inode, new_size))
+
+DEFINE_NFS_UPDATE_SIZE_EVENT(truncate);
+DEFINE_NFS_UPDATE_SIZE_EVENT(wcc);
+DEFINE_NFS_UPDATE_SIZE_EVENT(update);
+DEFINE_NFS_UPDATE_SIZE_EVENT(grow);
 
 DECLARE_EVENT_CLASS(nfs_lookup_event,
                TP_PROTO(
@@ -324,7 +299,7 @@ DECLARE_EVENT_CLASS(nfs_lookup_event,
                TP_printk(
                        "flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
                        __entry->flags,
-                       show_lookup_flags(__entry->flags),
+                       show_fs_lookup_flags(__entry->flags),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -368,9 +343,9 @@ DECLARE_EVENT_CLASS(nfs_lookup_event_done,
 
                TP_printk(
                        "error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        __entry->flags,
-                       show_lookup_flags(__entry->flags),
+                       show_fs_lookup_flags(__entry->flags),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -392,46 +367,6 @@ DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_exit);
 DEFINE_NFS_LOOKUP_EVENT(nfs_lookup_revalidate_enter);
 DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_revalidate_exit);
 
-TRACE_DEFINE_ENUM(O_WRONLY);
-TRACE_DEFINE_ENUM(O_RDWR);
-TRACE_DEFINE_ENUM(O_CREAT);
-TRACE_DEFINE_ENUM(O_EXCL);
-TRACE_DEFINE_ENUM(O_NOCTTY);
-TRACE_DEFINE_ENUM(O_TRUNC);
-TRACE_DEFINE_ENUM(O_APPEND);
-TRACE_DEFINE_ENUM(O_NONBLOCK);
-TRACE_DEFINE_ENUM(O_DSYNC);
-TRACE_DEFINE_ENUM(O_DIRECT);
-TRACE_DEFINE_ENUM(O_LARGEFILE);
-TRACE_DEFINE_ENUM(O_DIRECTORY);
-TRACE_DEFINE_ENUM(O_NOFOLLOW);
-TRACE_DEFINE_ENUM(O_NOATIME);
-TRACE_DEFINE_ENUM(O_CLOEXEC);
-
-#define show_open_flags(flags) \
-       __print_flags(flags, "|", \
-               { O_WRONLY, "O_WRONLY" }, \
-               { O_RDWR, "O_RDWR" }, \
-               { O_CREAT, "O_CREAT" }, \
-               { O_EXCL, "O_EXCL" }, \
-               { O_NOCTTY, "O_NOCTTY" }, \
-               { O_TRUNC, "O_TRUNC" }, \
-               { O_APPEND, "O_APPEND" }, \
-               { O_NONBLOCK, "O_NONBLOCK" }, \
-               { O_DSYNC, "O_DSYNC" }, \
-               { O_DIRECT, "O_DIRECT" }, \
-               { O_LARGEFILE, "O_LARGEFILE" }, \
-               { O_DIRECTORY, "O_DIRECTORY" }, \
-               { O_NOFOLLOW, "O_NOFOLLOW" }, \
-               { O_NOATIME, "O_NOATIME" }, \
-               { O_CLOEXEC, "O_CLOEXEC" })
-
-#define show_fmode_flags(mode) \
-       __print_flags(mode, "|", \
-               { ((__force unsigned long)FMODE_READ), "READ" }, \
-               { ((__force unsigned long)FMODE_WRITE), "WRITE" }, \
-               { ((__force unsigned long)FMODE_EXEC), "EXEC" })
-
 TRACE_EVENT(nfs_atomic_open_enter,
                TP_PROTO(
                        const struct inode *dir,
@@ -443,7 +378,7 @@ TRACE_EVENT(nfs_atomic_open_enter,
 
                TP_STRUCT__entry(
                        __field(unsigned long, flags)
-                       __field(unsigned int, fmode)
+                       __field(unsigned long, fmode)
                        __field(dev_t, dev)
                        __field(u64, dir)
                        __string(name, ctx->dentry->d_name.name)
@@ -453,15 +388,15 @@ TRACE_EVENT(nfs_atomic_open_enter,
                        __entry->dev = dir->i_sb->s_dev;
                        __entry->dir = NFS_FILEID(dir);
                        __entry->flags = flags;
-                       __entry->fmode = (__force unsigned int)ctx->mode;
+                       __entry->fmode = (__force unsigned long)ctx->mode;
                        __assign_str(name, ctx->dentry->d_name.name);
                ),
 
                TP_printk(
                        "flags=0x%lx (%s) fmode=%s name=%02x:%02x:%llu/%s",
                        __entry->flags,
-                       show_open_flags(__entry->flags),
-                       show_fmode_flags(__entry->fmode),
+                       show_fs_fcntl_open_flags(__entry->flags),
+                       show_fs_fmode_flags(__entry->fmode),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -481,7 +416,7 @@ TRACE_EVENT(nfs_atomic_open_exit,
                TP_STRUCT__entry(
                        __field(unsigned long, error)
                        __field(unsigned long, flags)
-                       __field(unsigned int, fmode)
+                       __field(unsigned long, fmode)
                        __field(dev_t, dev)
                        __field(u64, dir)
                        __string(name, ctx->dentry->d_name.name)
@@ -492,17 +427,17 @@ TRACE_EVENT(nfs_atomic_open_exit,
                        __entry->dev = dir->i_sb->s_dev;
                        __entry->dir = NFS_FILEID(dir);
                        __entry->flags = flags;
-                       __entry->fmode = (__force unsigned int)ctx->mode;
+                       __entry->fmode = (__force unsigned long)ctx->mode;
                        __assign_str(name, ctx->dentry->d_name.name);
                ),
 
                TP_printk(
                        "error=%ld (%s) flags=0x%lx (%s) fmode=%s "
                        "name=%02x:%02x:%llu/%s",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        __entry->flags,
-                       show_open_flags(__entry->flags),
-                       show_fmode_flags(__entry->fmode),
+                       show_fs_fcntl_open_flags(__entry->flags),
+                       show_fs_fmode_flags(__entry->fmode),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -535,7 +470,7 @@ TRACE_EVENT(nfs_create_enter,
                TP_printk(
                        "flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
                        __entry->flags,
-                       show_open_flags(__entry->flags),
+                       show_fs_fcntl_open_flags(__entry->flags),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -570,9 +505,9 @@ TRACE_EVENT(nfs_create_exit,
 
                TP_printk(
                        "error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        __entry->flags,
-                       show_open_flags(__entry->flags),
+                       show_fs_fcntl_open_flags(__entry->flags),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -640,7 +575,7 @@ DECLARE_EVENT_CLASS(nfs_directory_event_done,
 
                TP_printk(
                        "error=%ld (%s) name=%02x:%02x:%llu/%s",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
@@ -730,7 +665,7 @@ TRACE_EVENT(nfs_link_exit,
 
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu name=%02x:%02x:%llu/%s",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        __entry->fileid,
                        MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -817,7 +752,7 @@ DECLARE_EVENT_CLASS(nfs_rename_event_done,
                TP_printk(
                        "error=%ld (%s) old_name=%02x:%02x:%llu/%s "
                        "new_name=%02x:%02x:%llu/%s",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->old_dir,
                        __get_str(old_name),
@@ -871,13 +806,163 @@ TRACE_EVENT(nfs_sillyrename_unlink,
 
                TP_printk(
                        "error=%ld (%s) name=%02x:%02x:%llu/%s",
-                       -__entry->error, nfs_show_status(__entry->error),
+                       -__entry->error, show_nfs_status(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->dir,
                        __get_str(name)
                )
 );
 
+TRACE_EVENT(nfs_aop_readpage,
+               TP_PROTO(
+                       const struct inode *inode,
+                       struct page *page
+               ),
+
+               TP_ARGS(inode, page),
+
+               TP_STRUCT__entry(
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(u64, version)
+                       __field(loff_t, offset)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->version = inode_peek_iversion_raw(inode);
+                       __entry->offset = page_index(page) << PAGE_SHIFT;
+               ),
+
+               TP_printk(
+                       "fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu offset=%lld",
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle, __entry->version,
+                       __entry->offset
+               )
+);
+
+TRACE_EVENT(nfs_aop_readpage_done,
+               TP_PROTO(
+                       const struct inode *inode,
+                       struct page *page,
+                       int ret
+               ),
+
+               TP_ARGS(inode, page, ret),
+
+               TP_STRUCT__entry(
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(int, ret)
+                       __field(u64, fileid)
+                       __field(u64, version)
+                       __field(loff_t, offset)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->version = inode_peek_iversion_raw(inode);
+                       __entry->offset = page_index(page) << PAGE_SHIFT;
+                       __entry->ret = ret;
+               ),
+
+               TP_printk(
+                       "fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu offset=%lld ret=%d",
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle, __entry->version,
+                       __entry->offset, __entry->ret
+               )
+);
+
+TRACE_EVENT(nfs_aop_readahead,
+               TP_PROTO(
+                       const struct inode *inode,
+                       struct page *page,
+                       unsigned int nr_pages
+               ),
+
+               TP_ARGS(inode, page, nr_pages),
+
+               TP_STRUCT__entry(
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(u64, version)
+                       __field(loff_t, offset)
+                       __field(unsigned int, nr_pages)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->version = inode_peek_iversion_raw(inode);
+                       __entry->offset = page_index(page) << PAGE_SHIFT;
+                       __entry->nr_pages = nr_pages;
+               ),
+
+               TP_printk(
+                       "fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu offset=%lld nr_pages=%u",
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle, __entry->version,
+                       __entry->offset, __entry->nr_pages
+               )
+);
+
+TRACE_EVENT(nfs_aop_readahead_done,
+               TP_PROTO(
+                       const struct inode *inode,
+                       unsigned int nr_pages,
+                       int ret
+               ),
+
+               TP_ARGS(inode, nr_pages, ret),
+
+               TP_STRUCT__entry(
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(int, ret)
+                       __field(u64, fileid)
+                       __field(u64, version)
+                       __field(loff_t, offset)
+                       __field(unsigned int, nr_pages)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->version = inode_peek_iversion_raw(inode);
+                       __entry->nr_pages = nr_pages;
+                       __entry->ret = ret;
+               ),
+
+               TP_printk(
+                       "fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu nr_pages=%u ret=%d",
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle, __entry->version,
+                       __entry->nr_pages, __entry->ret
+               )
+);
+
 TRACE_EVENT(nfs_initiate_read,
                TP_PROTO(
                        const struct nfs_pgio_header *hdr
@@ -1054,16 +1139,6 @@ TRACE_EVENT(nfs_pgio_error,
        )
 );
 
-TRACE_DEFINE_ENUM(NFS_UNSTABLE);
-TRACE_DEFINE_ENUM(NFS_DATA_SYNC);
-TRACE_DEFINE_ENUM(NFS_FILE_SYNC);
-
-#define nfs_show_stable(stable) \
-       __print_symbolic(stable, \
-                       { NFS_UNSTABLE, "UNSTABLE" }, \
-                       { NFS_DATA_SYNC, "DATA_SYNC" }, \
-                       { NFS_FILE_SYNC, "FILE_SYNC" })
-
 TRACE_EVENT(nfs_initiate_write,
                TP_PROTO(
                        const struct nfs_pgio_header *hdr
@@ -1077,7 +1152,7 @@ TRACE_EVENT(nfs_initiate_write,
                        __field(u64, fileid)
                        __field(loff_t, offset)
                        __field(u32, count)
-                       __field(enum nfs3_stable_how, stable)
+                       __field(unsigned long, stable)
                ),
 
                TP_fast_assign(
@@ -1101,7 +1176,7 @@ TRACE_EVENT(nfs_initiate_write,
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
                        (long long)__entry->offset, __entry->count,
-                       nfs_show_stable(__entry->stable)
+                       show_nfs_stable_how(__entry->stable)
                )
 );
 
@@ -1121,7 +1196,7 @@ TRACE_EVENT(nfs_writeback_done,
                        __field(u32, arg_count)
                        __field(u32, res_count)
                        __field(int, status)
-                       __field(enum nfs3_stable_how, stable)
+                       __field(unsigned long, stable)
                        __array(char, verifier, NFS4_VERIFIER_SIZE)
                ),
 
@@ -1154,8 +1229,8 @@ TRACE_EVENT(nfs_writeback_done,
                        __entry->fhandle,
                        (long long)__entry->offset, __entry->arg_count,
                        __entry->res_count, __entry->status,
-                       nfs_show_stable(__entry->stable),
-                       __print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE)
+                       show_nfs_stable_how(__entry->stable),
+                       show_nfs4_verifier(__entry->verifier)
                )
 );
 
@@ -1256,7 +1331,7 @@ TRACE_EVENT(nfs_commit_done,
                        __field(u64, fileid)
                        __field(loff_t, offset)
                        __field(int, status)
-                       __field(enum nfs3_stable_how, stable)
+                       __field(unsigned long, stable)
                        __array(char, verifier, NFS4_VERIFIER_SIZE)
                ),
 
@@ -1285,8 +1360,8 @@ TRACE_EVENT(nfs_commit_done,
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
                        (long long)__entry->offset, __entry->status,
-                       nfs_show_stable(__entry->stable),
-                       __print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE)
+                       show_nfs_stable_how(__entry->stable),
+                       show_nfs4_verifier(__entry->verifier)
                )
 );
 
@@ -1323,76 +1398,6 @@ TRACE_EVENT(nfs_fh_to_dentry,
                )
 );
 
-TRACE_DEFINE_ENUM(NFS_OK);
-TRACE_DEFINE_ENUM(NFSERR_PERM);
-TRACE_DEFINE_ENUM(NFSERR_NOENT);
-TRACE_DEFINE_ENUM(NFSERR_IO);
-TRACE_DEFINE_ENUM(NFSERR_NXIO);
-TRACE_DEFINE_ENUM(ECHILD);
-TRACE_DEFINE_ENUM(NFSERR_EAGAIN);
-TRACE_DEFINE_ENUM(NFSERR_ACCES);
-TRACE_DEFINE_ENUM(NFSERR_EXIST);
-TRACE_DEFINE_ENUM(NFSERR_XDEV);
-TRACE_DEFINE_ENUM(NFSERR_NODEV);
-TRACE_DEFINE_ENUM(NFSERR_NOTDIR);
-TRACE_DEFINE_ENUM(NFSERR_ISDIR);
-TRACE_DEFINE_ENUM(NFSERR_INVAL);
-TRACE_DEFINE_ENUM(NFSERR_FBIG);
-TRACE_DEFINE_ENUM(NFSERR_NOSPC);
-TRACE_DEFINE_ENUM(NFSERR_ROFS);
-TRACE_DEFINE_ENUM(NFSERR_MLINK);
-TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP);
-TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);
-TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);
-TRACE_DEFINE_ENUM(NFSERR_DQUOT);
-TRACE_DEFINE_ENUM(NFSERR_STALE);
-TRACE_DEFINE_ENUM(NFSERR_REMOTE);
-TRACE_DEFINE_ENUM(NFSERR_WFLUSH);
-TRACE_DEFINE_ENUM(NFSERR_BADHANDLE);
-TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC);
-TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE);
-TRACE_DEFINE_ENUM(NFSERR_NOTSUPP);
-TRACE_DEFINE_ENUM(NFSERR_TOOSMALL);
-TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT);
-TRACE_DEFINE_ENUM(NFSERR_BADTYPE);
-TRACE_DEFINE_ENUM(NFSERR_JUKEBOX);
-
-#define nfs_show_status(x) \
-       __print_symbolic(x, \
-                       { NFS_OK, "OK" }, \
-                       { NFSERR_PERM, "PERM" }, \
-                       { NFSERR_NOENT, "NOENT" }, \
-                       { NFSERR_IO, "IO" }, \
-                       { NFSERR_NXIO, "NXIO" }, \
-                       { ECHILD, "CHILD" }, \
-                       { NFSERR_EAGAIN, "AGAIN" }, \
-                       { NFSERR_ACCES, "ACCES" }, \
-                       { NFSERR_EXIST, "EXIST" }, \
-                       { NFSERR_XDEV, "XDEV" }, \
-                       { NFSERR_NODEV, "NODEV" }, \
-                       { NFSERR_NOTDIR, "NOTDIR" }, \
-                       { NFSERR_ISDIR, "ISDIR" }, \
-                       { NFSERR_INVAL, "INVAL" }, \
-                       { NFSERR_FBIG, "FBIG" }, \
-                       { NFSERR_NOSPC, "NOSPC" }, \
-                       { NFSERR_ROFS, "ROFS" }, \
-                       { NFSERR_MLINK, "MLINK" }, \
-                       { NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \
-                       { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \
-                       { NFSERR_NOTEMPTY, "NOTEMPTY" }, \
-                       { NFSERR_DQUOT, "DQUOT" }, \
-                       { NFSERR_STALE, "STALE" }, \
-                       { NFSERR_REMOTE, "REMOTE" }, \
-                       { NFSERR_WFLUSH, "WFLUSH" }, \
-                       { NFSERR_BADHANDLE, "BADHANDLE" }, \
-                       { NFSERR_NOT_SYNC, "NOTSYNC" }, \
-                       { NFSERR_BAD_COOKIE, "BADCOOKIE" }, \
-                       { NFSERR_NOTSUPP, "NOTSUPP" }, \
-                       { NFSERR_TOOSMALL, "TOOSMALL" }, \
-                       { NFSERR_SERVERFAULT, "REMOTEIO" }, \
-                       { NFSERR_BADTYPE, "BADTYPE" }, \
-                       { NFSERR_JUKEBOX, "JUKEBOX" })
-
 DECLARE_EVENT_CLASS(nfs_xdr_event,
                TP_PROTO(
                        const struct xdr_stream *xdr,
@@ -1427,12 +1432,12 @@ DECLARE_EVENT_CLASS(nfs_xdr_event,
                        __assign_str(procedure, task->tk_msg.rpc_proc->p_name);
                ),
 
-               TP_printk(
-                       "task:%u@%d xid=0x%08x %sv%d %s error=%ld (%s)",
+               TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                         " xid=0x%08x %sv%d %s error=%ld (%s)",
                        __entry->task_id, __entry->client_id, __entry->xid,
                        __get_str(program), __entry->version,
                        __get_str(procedure), -__entry->error,
-                       nfs_show_status(__entry->error)
+                       show_nfs_status(__entry->error)
                )
 );
 #define DEFINE_NFS_XDR_EVENT(name) \
index cc232d1..ad7f83d 100644 (file)
@@ -271,8 +271,7 @@ nfs_page_set_headlock(struct nfs_page *req)
 void
 nfs_page_clear_headlock(struct nfs_page *req)
 {
-       smp_mb__before_atomic();
-       clear_bit(PG_HEADLOCK, &req->wb_flags);
+       clear_bit_unlock(PG_HEADLOCK, &req->wb_flags);
        smp_mb__after_atomic();
        if (!test_bit(PG_CONTENDED1, &req->wb_flags))
                return;
@@ -525,12 +524,7 @@ nfs_create_subreq(struct nfs_page *req,
  */
 void nfs_unlock_request(struct nfs_page *req)
 {
-       if (!NFS_WBACK_BUSY(req)) {
-               printk(KERN_ERR "NFS: Invalid unlock attempted\n");
-               BUG();
-       }
-       smp_mb__before_atomic();
-       clear_bit(PG_BUSY, &req->wb_flags);
+       clear_bit_unlock(PG_BUSY, &req->wb_flags);
        smp_mb__after_atomic();
        if (!test_bit(PG_CONTENDED2, &req->wb_flags))
                return;
@@ -870,9 +864,6 @@ static void nfs_pgio_result(struct rpc_task *task, void *calldata)
        struct nfs_pgio_header *hdr = calldata;
        struct inode *inode = hdr->inode;
 
-       dprintk("NFS: %s: %5u, (status %d)\n", __func__,
-               task->tk_pid, task->tk_status);
-
        if (hdr->rw_ops->rw_done(task, hdr, inode) != 0)
                return;
        if (task->tk_status < 0)
index d810ae6..f4d7548 100644 (file)
@@ -82,10 +82,6 @@ enum pnfs_try_status {
        PNFS_TRY_AGAIN     = 2,
 };
 
-/* error codes for internal use */
-#define NFS4ERR_RESET_TO_MDS   12001
-#define NFS4ERR_RESET_TO_PNFS  12002
-
 #ifdef CONFIG_NFS_V4_1
 
 #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
@@ -517,7 +513,7 @@ pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
 {
        struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
 
-       if (!lseg || !fl_cinfo->ops->mark_request_commit)
+       if (!lseg || !fl_cinfo->ops || !fl_cinfo->ops->mark_request_commit)
                return false;
        fl_cinfo->ops->mark_request_commit(req, lseg, cinfo, ds_commit_idx);
        return true;
index cf19914..316f68f 100644 (file)
@@ -468,7 +468,6 @@ pnfs_bucket_alloc_ds_commits(struct list_head *list,
                                goto out_error;
                        data->ds_commit_index = i;
                        list_add_tail(&data->list, list);
-                       atomic_inc(&cinfo->mds->rpcs_out);
                        nreq++;
                }
                mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
@@ -520,7 +519,6 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
                data->ds_commit_index = -1;
                list_splice_init(mds_pages, &data->pages);
                list_add_tail(&data->list, &list);
-               atomic_inc(&cinfo->mds->rpcs_out);
                nreq++;
        }
 
@@ -895,7 +893,7 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
        }
 
        smp_wmb();
-       ds->ds_clp = clp;
+       WRITE_ONCE(ds->ds_clp, clp);
        dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
 out:
        return status;
@@ -973,7 +971,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
        }
 
        smp_wmb();
-       ds->ds_clp = clp;
+       WRITE_ONCE(ds->ds_clp, clp);
        dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
 out:
        return status;
index ea19dbf..73dcaa9 100644 (file)
@@ -91,7 +91,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
        info->dtpref = fsinfo.tsize;
        info->maxfilesize = 0x7FFFFFFF;
        info->lease_time = 0;
-       info->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
+       info->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
        return 0;
 }
 
@@ -100,8 +100,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  */
 static int
 nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
-               struct nfs_fattr *fattr, struct nfs4_label *label,
-               struct inode *inode)
+               struct nfs_fattr *fattr, struct inode *inode)
 {
        struct rpc_message msg = {
                .rpc_proc       = &nfs_procedures[NFSPROC_GETATTR],
@@ -154,8 +153,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
 static int
 nfs_proc_lookup(struct inode *dir, struct dentry *dentry,
-               struct nfs_fh *fhandle, struct nfs_fattr *fattr,
-               struct nfs4_label *label)
+               struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
        struct nfs_diropargs    arg = {
                .fh             = NFS_FH(dir),
@@ -257,7 +255,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        nfs_mark_for_revalidate(dir);
        if (status == 0)
-               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
+               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
        nfs_free_createdata(data);
 out:
        dprintk("NFS reply create: %d\n", status);
@@ -304,7 +302,7 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        }
        if (status == 0)
-               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
+               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
        nfs_free_createdata(data);
 out:
        dprintk("NFS reply mknod: %d\n", status);
@@ -436,7 +434,7 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
         * should fill in the data with a LOOKUP call on the wire.
         */
        if (status == 0)
-               status = nfs_instantiate(dentry, fh, fattr, NULL);
+               status = nfs_instantiate(dentry, fh, fattr);
 
 out_free:
        nfs_free_fattr(fattr);
@@ -465,7 +463,7 @@ nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        nfs_mark_for_revalidate(dir);
        if (status == 0)
-               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
+               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
        nfs_free_createdata(data);
 out:
        dprintk("NFS reply mkdir: %d\n", status);
index 08d6cc5..d11af2a 100644 (file)
@@ -337,8 +337,7 @@ int nfs_readpage(struct file *file, struct page *page)
        struct inode *inode = page_file_mapping(page)->host;
        int ret;
 
-       dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
-               page, PAGE_SIZE, page_index(page));
+       trace_nfs_aop_readpage(inode, page);
        nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
 
        /*
@@ -390,9 +389,11 @@ out_wait:
        }
 out:
        put_nfs_open_context(desc.ctx);
+       trace_nfs_aop_readpage_done(inode, page, ret);
        return ret;
 out_unlock:
        unlock_page(page);
+       trace_nfs_aop_readpage_done(inode, page, ret);
        return ret;
 }
 
@@ -403,10 +404,7 @@ int nfs_readpages(struct file *file, struct address_space *mapping,
        struct inode *inode = mapping->host;
        int ret;
 
-       dprintk("NFS: nfs_readpages (%s/%Lu %d)\n",
-                       inode->i_sb->s_id,
-                       (unsigned long long)NFS_FILEID(inode),
-                       nr_pages);
+       trace_nfs_aop_readahead(inode, lru_to_page(pages), nr_pages);
        nfs_inc_stats(inode, NFSIOS_VFSREADPAGES);
 
        ret = -ESTALE;
@@ -439,6 +437,7 @@ int nfs_readpages(struct file *file, struct address_space *mapping,
 read_complete:
        put_nfs_open_context(desc.ctx);
 out:
+       trace_nfs_aop_readahead_done(inode, nr_pages, ret);
        return ret;
 }
 
index e65c834..3aced40 100644 (file)
@@ -1004,6 +1004,7 @@ int nfs_reconfigure(struct fs_context *fc)
        struct nfs_fs_context *ctx = nfs_fc2context(fc);
        struct super_block *sb = fc->root->d_sb;
        struct nfs_server *nfss = sb->s_fs_info;
+       int ret;
 
        sync_filesystem(sb);
 
@@ -1028,7 +1029,11 @@ int nfs_reconfigure(struct fs_context *fc)
        }
 
        /* compare new mount options with old ones */
-       return nfs_compare_remount_data(nfss, ctx);
+       ret = nfs_compare_remount_data(nfss, ctx);
+       if (ret)
+               return ret;
+
+       return nfs_probe_server(nfss, NFS_FH(d_inode(fc->root)));
 }
 EXPORT_SYMBOL_GPL(nfs_reconfigure);
 
index eae9bf1..9b7619c 100644 (file)
@@ -288,6 +288,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c
        end = page_file_offset(page) + ((loff_t)offset+count);
        if (i_size >= end)
                goto out;
+       trace_nfs_size_grow(inode, end);
        i_size_write(inode, end);
        NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE;
        nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
@@ -1038,25 +1039,11 @@ nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
        struct nfs_page *req, *tmp;
        int ret = 0;
 
-restart:
        list_for_each_entry_safe(req, tmp, src, wb_list) {
                kref_get(&req->wb_kref);
                if (!nfs_lock_request(req)) {
-                       int status;
-
-                       /* Prevent deadlock with nfs_lock_and_join_requests */
-                       if (!list_empty(dst)) {
-                               nfs_release_request(req);
-                               continue;
-                       }
-                       /* Ensure we make progress to prevent livelock */
-                       mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
-                       status = nfs_wait_on_request(req);
                        nfs_release_request(req);
-                       mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
-                       if (status < 0)
-                               break;
-                       goto restart;
+                       continue;
                }
                nfs_request_remove_commit_list(req, cinfo);
                clear_bit(PG_COMMIT_TO_DS, &req->wb_flags);
@@ -1246,7 +1233,7 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
        struct nfs_open_context *ctx = nfs_file_open_context(filp);
 
        if (nfs_ctx_key_to_expire(ctx, inode) &&
-           !ctx->ll_cred)
+           !rcu_access_pointer(ctx->ll_cred))
                /* Already expired! */
                return -EACCES;
        return 0;
@@ -1258,23 +1245,38 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
 bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode)
 {
        struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
-       struct rpc_cred *cred = ctx->ll_cred;
+       struct rpc_cred *cred, *new, *old = NULL;
        struct auth_cred acred = {
                .cred = ctx->cred,
        };
+       bool ret = false;
 
-       if (cred && !cred->cr_ops->crmatch(&acred, cred, 0)) {
-               put_rpccred(cred);
-               ctx->ll_cred = NULL;
-               cred = NULL;
-       }
-       if (!cred)
-               cred = auth->au_ops->lookup_cred(auth, &acred, 0);
-       if (!cred || IS_ERR(cred))
+       rcu_read_lock();
+       cred = rcu_dereference(ctx->ll_cred);
+       if (cred && !(cred->cr_ops->crkey_timeout &&
+                     cred->cr_ops->crkey_timeout(cred)))
+               goto out;
+       rcu_read_unlock();
+
+       new = auth->au_ops->lookup_cred(auth, &acred, 0);
+       if (new == cred) {
+               put_rpccred(new);
                return true;
-       ctx->ll_cred = cred;
-       return !!(cred->cr_ops->crkey_timeout &&
-                 cred->cr_ops->crkey_timeout(cred));
+       }
+       if (IS_ERR_OR_NULL(new)) {
+               new = NULL;
+               ret = true;
+       } else if (new->cr_ops->crkey_timeout &&
+                  new->cr_ops->crkey_timeout(new))
+               ret = true;
+
+       rcu_read_lock();
+       old = rcu_dereference_protected(xchg(&ctx->ll_cred,
+                                            RCU_INITIALIZER(new)), 1);
+out:
+       rcu_read_unlock();
+       put_rpccred(old);
+       return ret;
 }
 
 /*
@@ -1382,8 +1384,6 @@ int nfs_updatepage(struct file *file, struct page *page,
        status = nfs_writepage_setup(ctx, page, offset, count);
        if (status < 0)
                nfs_set_pageerror(mapping);
-       else
-               __set_page_dirty_nobuffers(page);
 out:
        dprintk("NFS:       nfs_updatepage returns %d (isize %lld)\n",
                        status, (long long)i_size_read(inode));
@@ -1671,10 +1671,13 @@ static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
        atomic_inc(&cinfo->rpcs_out);
 }
 
-static void nfs_commit_end(struct nfs_mds_commit_info *cinfo)
+bool nfs_commit_end(struct nfs_mds_commit_info *cinfo)
 {
-       if (atomic_dec_and_test(&cinfo->rpcs_out))
+       if (atomic_dec_and_test(&cinfo->rpcs_out)) {
                wake_up_var(&cinfo->rpcs_out);
+               return true;
+       }
+       return false;
 }
 
 void nfs_commitdata_release(struct nfs_commit_data *data)
@@ -1774,6 +1777,7 @@ void nfs_init_commit(struct nfs_commit_data *data,
        data->res.fattr   = &data->fattr;
        data->res.verf    = &data->verf;
        nfs_fattr_init(&data->fattr);
+       nfs_commit_begin(cinfo->mds);
 }
 EXPORT_SYMBOL_GPL(nfs_init_commit);
 
@@ -1820,7 +1824,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
 
        /* Set up the argument struct */
        nfs_init_commit(data, head, NULL, cinfo);
-       atomic_inc(&cinfo->mds->rpcs_out);
        if (NFS_SERVER(inode)->nfs_client->cl_minorversion)
                task_flags = RPC_TASK_MOVEABLE;
        return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode),
@@ -1835,9 +1838,6 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
 {
        struct nfs_commit_data  *data = calldata;
 
-        dprintk("NFS: %5u nfs_commit_done (status %d)\n",
-                                task->tk_pid, task->tk_status);
-
        /* Call the NFS version-specific code */
        NFS_PROTO(data->inode)->commit_done(task, data);
        trace_nfs_commit_done(task, data);
@@ -1936,6 +1936,7 @@ static int __nfs_commit_inode(struct inode *inode, int how,
        int may_wait = how & FLUSH_SYNC;
        int ret, nscan;
 
+       how &= ~FLUSH_SYNC;
        nfs_init_cinfo_from_inode(&cinfo, inode);
        nfs_commit_begin(cinfo.mds);
        for (;;) {
index 5385209..f1e0d3c 100644 (file)
@@ -9,6 +9,7 @@
 #define _NFSD_TRACE_H
 
 #include <linux/tracepoint.h>
+
 #include "export.h"
 #include "nfsfh.h"
 
index 15004c4..5662d8b 100644 (file)
@@ -292,6 +292,10 @@ enum nfsstat4 {
        NFS4ERR_XATTR2BIG      = 10096,
 };
 
+/* error codes for internal client use */
+#define NFS4ERR_RESET_TO_MDS   12001
+#define NFS4ERR_RESET_TO_PNFS  12002
+
 static inline bool seqid_mutating_err(u32 err)
 {
        /* See RFC 7530, section 9.1.7 */
index b9a8b92..05f249f 100644 (file)
@@ -81,7 +81,7 @@ struct nfs_open_context {
        fl_owner_t flock_owner;
        struct dentry *dentry;
        const struct cred *cred;
-       struct rpc_cred *ll_cred;       /* low-level cred - use to check for expiry */
+       struct rpc_cred __rcu *ll_cred; /* low-level cred - use to check for expiry */
        struct nfs4_state *state;
        fmode_t mode;
 
@@ -103,6 +103,7 @@ struct nfs_open_dir_context {
        __be32  verf[NFS_DIR_VERIFIER_SIZE];
        __u64 dir_cookie;
        __u64 dup_cookie;
+       pgoff_t page_index;
        signed char duped;
 };
 
@@ -154,36 +155,39 @@ struct nfs_inode {
        unsigned long           attrtimeo_timestamp;
 
        unsigned long           attr_gencount;
-       /* "Generation counter" for the attribute cache. This is
-        * bumped whenever we update the metadata on the
-        * server.
-        */
-       unsigned long           cache_change_attribute;
 
        struct rb_root          access_cache;
        struct list_head        access_cache_entry_lru;
        struct list_head        access_cache_inode_lru;
 
-       /*
-        * This is the cookie verifier used for NFSv3 readdir
-        * operations
-        */
-       __be32                  cookieverf[NFS_DIR_VERIFIER_SIZE];
-
-       atomic_long_t           nrequests;
-       struct nfs_mds_commit_info commit_info;
+       union {
+               /* Directory */
+               struct {
+                       /* "Generation counter" for the attribute cache.
+                        * This is bumped whenever we update the metadata
+                        * on the server.
+                        */
+                       unsigned long   cache_change_attribute;
+                       /*
+                        * This is the cookie verifier used for NFSv3 readdir
+                        * operations
+                        */
+                       __be32          cookieverf[NFS_DIR_VERIFIER_SIZE];
+                       /* Readers: in-flight sillydelete RPC calls */
+                       /* Writers: rmdir */
+                       struct rw_semaphore     rmdir_sem;
+               };
+               /* Regular file */
+               struct {
+                       atomic_long_t   nrequests;
+                       struct nfs_mds_commit_info commit_info;
+                       struct mutex    commit_mutex;
+               };
+       };
 
        /* Open contexts for shared mmap writes */
        struct list_head        open_files;
 
-       /* Readers: in-flight sillydelete RPC calls */
-       /* Writers: rmdir */
-       struct rw_semaphore     rmdir_sem;
-       struct mutex            commit_mutex;
-
-       /* track last access to cached pages */
-       unsigned long           page_index;
-
 #if IS_ENABLED(CONFIG_NFS_V4)
        struct nfs4_cached_acl  *nfs4_acl;
         /* NFSv4 state */
@@ -272,6 +276,7 @@ struct nfs4_copy_state {
 #define NFS_INO_INVALIDATING   (3)             /* inode is being invalidated */
 #define NFS_INO_FSCACHE                (5)             /* inode can be cached by FS-Cache */
 #define NFS_INO_FSCACHE_LOCK   (6)             /* FS-Cache cookie management lock */
+#define NFS_INO_FORCE_READDIR  (7)             /* force readdirplus */
 #define NFS_INO_LAYOUTCOMMIT   (9)             /* layoutcommit required */
 #define NFS_INO_LAYOUTCOMMITTING (10)          /* layoutcommit inflight */
 #define NFS_INO_LAYOUTSTATS    (11)            /* layoutstats inflight */
@@ -383,7 +388,7 @@ extern void nfs_zap_caches(struct inode *);
 extern void nfs_set_inode_stale(struct inode *inode);
 extern void nfs_invalidate_atime(struct inode *);
 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
-                               struct nfs_fattr *, struct nfs4_label *);
+                               struct nfs_fattr *);
 struct inode *nfs_ilookup(struct super_block *sb, struct nfs_fattr *, struct nfs_fh *);
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
@@ -404,8 +409,7 @@ extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *map
 extern int nfs_revalidate_mapping_rcu(struct inode *inode);
 extern int nfs_setattr(struct user_namespace *, struct dentry *, struct iattr *);
 extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
-extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
-                               struct nfs4_label *label);
+extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr);
 extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
 extern void put_nfs_open_context(struct nfs_open_context *ctx);
 extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode);
@@ -421,9 +425,22 @@ extern void nfs_fattr_set_barrier(struct nfs_fattr *fattr);
 extern unsigned long nfs_inc_attr_generation_counter(void);
 
 extern struct nfs_fattr *nfs_alloc_fattr(void);
+extern struct nfs_fattr *nfs_alloc_fattr_with_label(struct nfs_server *server);
+
+static inline void nfs4_label_free(struct nfs4_label *label)
+{
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+       if (label) {
+               kfree(label->label);
+               kfree(label);
+       }
+#endif
+}
 
 static inline void nfs_free_fattr(const struct nfs_fattr *fattr)
 {
+       if (fattr)
+               nfs4_label_free(fattr->label);
        kfree(fattr);
 }
 
@@ -511,10 +528,9 @@ extern void nfs_set_verifier(struct dentry * dentry, unsigned long verf);
 extern void nfs_clear_verifier_delegated(struct inode *inode);
 #endif /* IS_ENABLED(CONFIG_NFS_V4) */
 extern struct dentry *nfs_add_or_obtain(struct dentry *dentry,
-                       struct nfs_fh *fh, struct nfs_fattr *fattr,
-                       struct nfs4_label *label);
+                       struct nfs_fh *fh, struct nfs_fattr *fattr);
 extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
-                       struct nfs_fattr *fattr, struct nfs4_label *label);
+                       struct nfs_fattr *fattr);
 extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags);
 extern void nfs_access_zap_cache(struct inode *inode);
 extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res,
@@ -569,11 +585,14 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
 extern int  nfs_commit_inode(struct inode *, int);
 extern struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail);
 extern void nfs_commit_free(struct nfs_commit_data *data);
+bool nfs_commit_end(struct nfs_mds_commit_info *cinfo);
 
 static inline int
 nfs_have_writebacks(struct inode *inode)
 {
-       return atomic_long_read(&NFS_I(inode)->nrequests) != 0;
+       if (S_ISREG(inode->i_mode))
+               return atomic_long_read(&NFS_I(inode)->nrequests) != 0;
+       return 0;
 }
 
 /*
index e9698b6..967a009 100644 (file)
@@ -488,7 +488,6 @@ struct nfs_openres {
        struct nfs4_change_info cinfo;
        __u32                   rflags;
        struct nfs_fattr *      f_attr;
-       struct nfs4_label       *f_label;
        struct nfs_seqid *      seqid;
        const struct nfs_server *server;
        fmode_t                 delegation_type;
@@ -753,7 +752,6 @@ struct nfs_entry {
        int                     eof;
        struct nfs_fh *         fh;
        struct nfs_fattr *      fattr;
-       struct nfs4_label  *label;
        unsigned char           d_type;
        struct nfs_server *     server;
 };
@@ -834,7 +832,6 @@ struct nfs_getaclres {
 struct nfs_setattrres {
        struct nfs4_sequence_res        seq_res;
        struct nfs_fattr *              fattr;
-       struct nfs4_label               *label;
        const struct nfs_server *       server;
 };
 
@@ -1041,7 +1038,6 @@ struct nfs4_create_res {
        const struct nfs_server *       server;
        struct nfs_fh *                 fh;
        struct nfs_fattr *              fattr;
-       struct nfs4_label               *label;
        struct nfs4_change_info         dir_cinfo;
 };
 
@@ -1066,7 +1062,6 @@ struct nfs4_getattr_res {
        struct nfs4_sequence_res        seq_res;
        const struct nfs_server *       server;
        struct nfs_fattr *              fattr;
-       struct nfs4_label               *label;
 };
 
 struct nfs4_link_arg {
@@ -1081,7 +1076,6 @@ struct nfs4_link_res {
        struct nfs4_sequence_res        seq_res;
        const struct nfs_server *       server;
        struct nfs_fattr *              fattr;
-       struct nfs4_label               *label;
        struct nfs4_change_info         cinfo;
        struct nfs_fattr *              dir_attr;
 };
@@ -1098,7 +1092,6 @@ struct nfs4_lookup_res {
        const struct nfs_server *       server;
        struct nfs_fattr *              fattr;
        struct nfs_fh *                 fh;
-       struct nfs4_label               *label;
 };
 
 struct nfs4_lookupp_arg {
@@ -1112,7 +1105,6 @@ struct nfs4_lookupp_res {
        const struct nfs_server         *server;
        struct nfs_fattr                *fattr;
        struct nfs_fh                   *fh;
-       struct nfs4_label               *label;
 };
 
 struct nfs4_lookup_root_arg {
@@ -1738,15 +1730,13 @@ struct nfs_rpc_ops {
        int     (*submount) (struct fs_context *, struct nfs_server *);
        int     (*try_get_tree) (struct fs_context *);
        int     (*getattr) (struct nfs_server *, struct nfs_fh *,
-                           struct nfs_fattr *, struct nfs4_label *,
-                           struct inode *);
+                           struct nfs_fattr *, struct inode *);
        int     (*setattr) (struct dentry *, struct nfs_fattr *,
                            struct iattr *);
        int     (*lookup)  (struct inode *, struct dentry *,
-                           struct nfs_fh *, struct nfs_fattr *,
-                           struct nfs4_label *);
+                           struct nfs_fh *, struct nfs_fattr *);
        int     (*lookupp) (struct inode *, struct nfs_fh *,
-                           struct nfs_fattr *, struct nfs4_label *);
+                           struct nfs_fattr *);
        int     (*access)  (struct inode *, struct nfs_access_entry *);
        int     (*readlink)(struct inode *, struct page *, unsigned int,
                            unsigned int);
diff --git a/include/linux/pnfs_osd_xdr.h b/include/linux/pnfs_osd_xdr.h
deleted file mode 100644 (file)
index 17d7d0d..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- *  pNFS-osd on-the-wire data structures
- *
- *  Copyright (C) 2007 Panasas Inc. [year of first publication]
- *  All rights reserved.
- *
- *  Benny Halevy <bhalevy@panasas.com>
- *  Boaz Harrosh <ooo@electrozaur.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2
- *  See the file COPYING included with this distribution for more details.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions
- *  are met:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *  3. Neither the name of the Panasas company nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __PNFS_OSD_XDR_H__
-#define __PNFS_OSD_XDR_H__
-
-#include <linux/nfs_fs.h>
-
-/*
- * draft-ietf-nfsv4-minorversion-22
- * draft-ietf-nfsv4-pnfs-obj-12
- */
-
-/* Layout Structure */
-
-enum pnfs_osd_raid_algorithm4 {
-       PNFS_OSD_RAID_0         = 1,
-       PNFS_OSD_RAID_4         = 2,
-       PNFS_OSD_RAID_5         = 3,
-       PNFS_OSD_RAID_PQ        = 4     /* Reed-Solomon P+Q */
-};
-
-/*   struct pnfs_osd_data_map4 {
- *       uint32_t                    odm_num_comps;
- *       length4                     odm_stripe_unit;
- *       uint32_t                    odm_group_width;
- *       uint32_t                    odm_group_depth;
- *       uint32_t                    odm_mirror_cnt;
- *       pnfs_osd_raid_algorithm4    odm_raid_algorithm;
- *   };
- */
-struct pnfs_osd_data_map {
-       u32     odm_num_comps;
-       u64     odm_stripe_unit;
-       u32     odm_group_width;
-       u32     odm_group_depth;
-       u32     odm_mirror_cnt;
-       u32     odm_raid_algorithm;
-};
-
-/*   struct pnfs_osd_objid4 {
- *       deviceid4       oid_device_id;
- *       uint64_t        oid_partition_id;
- *       uint64_t        oid_object_id;
- *   };
- */
-struct pnfs_osd_objid {
-       struct nfs4_deviceid    oid_device_id;
-       u64                     oid_partition_id;
-       u64                     oid_object_id;
-};
-
-/* For printout. I use:
- * kprint("dev(%llx:%llx)", _DEVID_LO(pointer), _DEVID_HI(pointer));
- * BE style
- */
-#define _DEVID_LO(oid_device_id) \
-       (unsigned long long)be64_to_cpup((__be64 *)(oid_device_id)->data)
-
-#define _DEVID_HI(oid_device_id) \
-       (unsigned long long)be64_to_cpup(((__be64 *)(oid_device_id)->data) + 1)
-
-enum pnfs_osd_version {
-       PNFS_OSD_MISSING              = 0,
-       PNFS_OSD_VERSION_1            = 1,
-       PNFS_OSD_VERSION_2            = 2
-};
-
-struct pnfs_osd_opaque_cred {
-       u32 cred_len;
-       void *cred;
-};
-
-enum pnfs_osd_cap_key_sec {
-       PNFS_OSD_CAP_KEY_SEC_NONE     = 0,
-       PNFS_OSD_CAP_KEY_SEC_SSV      = 1,
-};
-
-/*   struct pnfs_osd_object_cred4 {
- *       pnfs_osd_objid4         oc_object_id;
- *       pnfs_osd_version4       oc_osd_version;
- *       pnfs_osd_cap_key_sec4   oc_cap_key_sec;
- *       opaque                  oc_capability_key<>;
- *       opaque                  oc_capability<>;
- *   };
- */
-struct pnfs_osd_object_cred {
-       struct pnfs_osd_objid           oc_object_id;
-       u32                             oc_osd_version;
-       u32                             oc_cap_key_sec;
-       struct pnfs_osd_opaque_cred     oc_cap_key;
-       struct pnfs_osd_opaque_cred     oc_cap;
-};
-
-/*   struct pnfs_osd_layout4 {
- *       pnfs_osd_data_map4      olo_map;
- *       uint32_t                olo_comps_index;
- *       pnfs_osd_object_cred4   olo_components<>;
- *   };
- */
-struct pnfs_osd_layout {
-       struct pnfs_osd_data_map        olo_map;
-       u32                             olo_comps_index;
-       u32                             olo_num_comps;
-       struct pnfs_osd_object_cred     *olo_comps;
-};
-
-/* Device Address */
-enum pnfs_osd_targetid_type {
-       OBJ_TARGET_ANON = 1,
-       OBJ_TARGET_SCSI_NAME = 2,
-       OBJ_TARGET_SCSI_DEVICE_ID = 3,
-};
-
-/*   union pnfs_osd_targetid4 switch (pnfs_osd_targetid_type4 oti_type) {
- *       case OBJ_TARGET_SCSI_NAME:
- *           string              oti_scsi_name<>;
- *
- *       case OBJ_TARGET_SCSI_DEVICE_ID:
- *           opaque              oti_scsi_device_id<>;
- *
- *       default:
- *           void;
- *   };
- *
- *   union pnfs_osd_targetaddr4 switch (bool ota_available) {
- *       case TRUE:
- *           netaddr4            ota_netaddr;
- *       case FALSE:
- *           void;
- *   };
- *
- *   struct pnfs_osd_deviceaddr4 {
- *       pnfs_osd_targetid4      oda_targetid;
- *       pnfs_osd_targetaddr4    oda_targetaddr;
- *       uint64_t                oda_lun;
- *       opaque                  oda_systemid<>;
- *       pnfs_osd_object_cred4   oda_root_obj_cred;
- *       opaque                  oda_osdname<>;
- *   };
- */
-struct pnfs_osd_targetid {
-       u32                             oti_type;
-       struct nfs4_string              oti_scsi_device_id;
-};
-
-/*   struct netaddr4 {
- *       // see struct rpcb in RFC1833
- *       string r_netid<>;    // network id
- *       string r_addr<>;     // universal address
- *   };
- */
-struct pnfs_osd_net_addr {
-       struct nfs4_string      r_netid;
-       struct nfs4_string      r_addr;
-};
-
-struct pnfs_osd_targetaddr {
-       u32                             ota_available;
-       struct pnfs_osd_net_addr        ota_netaddr;
-};
-
-struct pnfs_osd_deviceaddr {
-       struct pnfs_osd_targetid        oda_targetid;
-       struct pnfs_osd_targetaddr      oda_targetaddr;
-       u8                              oda_lun[8];
-       struct nfs4_string              oda_systemid;
-       struct pnfs_osd_object_cred     oda_root_obj_cred;
-       struct nfs4_string              oda_osdname;
-};
-
-/* LAYOUTCOMMIT: layoutupdate */
-
-/*   union pnfs_osd_deltaspaceused4 switch (bool dsu_valid) {
- *       case TRUE:
- *           int64_t     dsu_delta;
- *       case FALSE:
- *           void;
- *   };
- *
- *   struct pnfs_osd_layoutupdate4 {
- *       pnfs_osd_deltaspaceused4    olu_delta_space_used;
- *       bool                        olu_ioerr_flag;
- *   };
- */
-struct pnfs_osd_layoutupdate {
-       u32     dsu_valid;
-       s64     dsu_delta;
-       u32     olu_ioerr_flag;
-};
-
-/* LAYOUTRETURN: I/O Rrror Report */
-
-enum pnfs_osd_errno {
-       PNFS_OSD_ERR_EIO                = 1,
-       PNFS_OSD_ERR_NOT_FOUND          = 2,
-       PNFS_OSD_ERR_NO_SPACE           = 3,
-       PNFS_OSD_ERR_BAD_CRED           = 4,
-       PNFS_OSD_ERR_NO_ACCESS          = 5,
-       PNFS_OSD_ERR_UNREACHABLE        = 6,
-       PNFS_OSD_ERR_RESOURCE           = 7
-};
-
-/*   struct pnfs_osd_ioerr4 {
- *       pnfs_osd_objid4     oer_component;
- *       length4             oer_comp_offset;
- *       length4             oer_comp_length;
- *       bool                oer_iswrite;
- *       pnfs_osd_errno4     oer_errno;
- *   };
- */
-struct pnfs_osd_ioerr {
-       struct pnfs_osd_objid   oer_component;
-       u64                     oer_comp_offset;
-       u64                     oer_comp_length;
-       u32                     oer_iswrite;
-       u32                     oer_errno;
-};
-
-/* OSD XDR Client API */
-/* Layout helpers */
-/* Layout decoding is done in two parts:
- * 1. First Call pnfs_osd_xdr_decode_layout_map to read in only the header part
- *    of the layout. @iter members need not be initialized.
- *    Returned:
- *             @layout members are set. (@layout->olo_comps set to NULL).
- *
- *             Zero on success, or negative error if passed xdr is broken.
- *
- * 2. 2nd Call pnfs_osd_xdr_decode_layout_comp() in a loop until it returns
- *    false, to decode the next component.
- *    Returned:
- *       true if there is more to decode or false if we are done or error.
- *
- * Example:
- *     struct pnfs_osd_xdr_decode_layout_iter iter;
- *     struct pnfs_osd_layout layout;
- *     struct pnfs_osd_object_cred comp;
- *     int status;
- *
- *     status = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr);
- *     if (unlikely(status))
- *             goto err;
- *     while(pnfs_osd_xdr_decode_layout_comp(&comp, &iter, xdr, &status)) {
- *             // All of @comp strings point to inside the xdr_buffer
- *             // or scrach buffer. Copy them out to user memory eg.
- *             copy_single_comp(dest_comp++, &comp);
- *     }
- *     if (unlikely(status))
- *             goto err;
- */
-
-struct pnfs_osd_xdr_decode_layout_iter {
-       unsigned total_comps;
-       unsigned decoded_comps;
-};
-
-extern int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout,
-       struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr);
-
-extern bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp,
-       struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr,
-       int *err);
-
-/* Device Info helpers */
-
-/* Note: All strings inside @deviceaddr point to space inside @p.
- * @p should stay valid while @deviceaddr is in use.
- */
-extern void pnfs_osd_xdr_decode_deviceaddr(
-       struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p);
-
-/* layoutupdate (layout_commit) xdr helpers */
-extern int
-pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr,
-                                struct pnfs_osd_layoutupdate *lou);
-
-/* osd_ioerror encoding (layout_return) */
-extern __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr);
-extern void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr);
-
-#endif /* __PNFS_OSD_XDR_H__ */
index a466164..267b7ae 100644 (file)
@@ -40,6 +40,7 @@ struct rpc_clnt {
        unsigned int            cl_clid;        /* client id */
        struct list_head        cl_clients;     /* Global list of clients */
        struct list_head        cl_tasks;       /* List of tasks */
+       atomic_t                cl_pid;         /* task PID counter */
        spinlock_t              cl_lock;        /* spinlock */
        struct rpc_xprt __rcu * cl_xprt;        /* transport */
        const struct rpc_procinfo *cl_procinfo; /* procedure info */
index a237b8d..db964bb 100644 (file)
@@ -150,25 +150,13 @@ struct rpc_task_setup {
 #define RPC_TASK_MSG_PIN_WAIT  5
 #define RPC_TASK_SIGNALLED     6
 
-#define RPC_IS_RUNNING(t)      test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
-#define rpc_set_running(t)     set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
 #define rpc_test_and_set_running(t) \
                                test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
-#define rpc_clear_running(t)   \
-       do { \
-               smp_mb__before_atomic(); \
-               clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate); \
-               smp_mb__after_atomic(); \
-       } while (0)
+#define rpc_clear_running(t)   clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
 
 #define RPC_IS_QUEUED(t)       test_bit(RPC_TASK_QUEUED, &(t)->tk_runstate)
 #define rpc_set_queued(t)      set_bit(RPC_TASK_QUEUED, &(t)->tk_runstate)
-#define rpc_clear_queued(t)    \
-       do { \
-               smp_mb__before_atomic(); \
-               clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate); \
-               smp_mb__after_atomic(); \
-       } while (0)
+#define rpc_clear_queued(t)    clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate)
 
 #define RPC_IS_ACTIVATED(t)    test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)
 
diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h
new file mode 100644 (file)
index 0000000..738b97f
--- /dev/null
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Display helpers for generic filesystem items
+ *
+ * Author: Chuck Lever <chuck.lever@oracle.com>
+ *
+ * Copyright (c) 2020, Oracle and/or its affiliates.
+ */
+
+#include <linux/fs.h>
+
+#define show_fs_dirent_type(x) \
+       __print_symbolic(x, \
+               { DT_UNKNOWN,           "UNKNOWN" }, \
+               { DT_FIFO,              "FIFO" }, \
+               { DT_CHR,               "CHR" }, \
+               { DT_DIR,               "DIR" }, \
+               { DT_BLK,               "BLK" }, \
+               { DT_REG,               "REG" }, \
+               { DT_LNK,               "LNK" }, \
+               { DT_SOCK,              "SOCK" }, \
+               { DT_WHT,               "WHT" })
+
+#define show_fs_fcntl_open_flags(x) \
+       __print_flags(x, "|", \
+               { O_WRONLY,             "O_WRONLY" }, \
+               { O_RDWR,               "O_RDWR" }, \
+               { O_CREAT,              "O_CREAT" }, \
+               { O_EXCL,               "O_EXCL" }, \
+               { O_NOCTTY,             "O_NOCTTY" }, \
+               { O_TRUNC,              "O_TRUNC" }, \
+               { O_APPEND,             "O_APPEND" }, \
+               { O_NONBLOCK,           "O_NONBLOCK" }, \
+               { O_DSYNC,              "O_DSYNC" }, \
+               { O_DIRECT,             "O_DIRECT" }, \
+               { O_LARGEFILE,          "O_LARGEFILE" }, \
+               { O_DIRECTORY,          "O_DIRECTORY" }, \
+               { O_NOFOLLOW,           "O_NOFOLLOW" }, \
+               { O_NOATIME,            "O_NOATIME" }, \
+               { O_CLOEXEC,            "O_CLOEXEC" })
+
+#define __fmode_flag(x)        { (__force unsigned long)FMODE_##x, #x }
+#define show_fs_fmode_flags(x) \
+       __print_flags(x, "|", \
+               __fmode_flag(READ), \
+               __fmode_flag(WRITE), \
+               __fmode_flag(EXEC))
+
+#ifdef CONFIG_64BIT
+#define show_fs_fcntl_cmd(x) \
+       __print_symbolic(x, \
+               { F_DUPFD,              "DUPFD" }, \
+               { F_GETFD,              "GETFD" }, \
+               { F_SETFD,              "SETFD" }, \
+               { F_GETFL,              "GETFL" }, \
+               { F_SETFL,              "SETFL" }, \
+               { F_GETLK,              "GETLK" }, \
+               { F_SETLK,              "SETLK" }, \
+               { F_SETLKW,             "SETLKW" }, \
+               { F_SETOWN,             "SETOWN" }, \
+               { F_GETOWN,             "GETOWN" }, \
+               { F_SETSIG,             "SETSIG" }, \
+               { F_GETSIG,             "GETSIG" }, \
+               { F_SETOWN_EX,          "SETOWN_EX" }, \
+               { F_GETOWN_EX,          "GETOWN_EX" }, \
+               { F_GETOWNER_UIDS,      "GETOWNER_UIDS" }, \
+               { F_OFD_GETLK,          "OFD_GETLK" }, \
+               { F_OFD_SETLK,          "OFD_SETLK" }, \
+               { F_OFD_SETLKW,         "OFD_SETLKW" })
+#else /* CONFIG_64BIT */
+#define show_fs_fcntl_cmd(x) \
+       __print_symbolic(x, \
+               { F_DUPFD,              "DUPFD" }, \
+               { F_GETFD,              "GETFD" }, \
+               { F_SETFD,              "SETFD" }, \
+               { F_GETFL,              "GETFL" }, \
+               { F_SETFL,              "SETFL" }, \
+               { F_GETLK,              "GETLK" }, \
+               { F_SETLK,              "SETLK" }, \
+               { F_SETLKW,             "SETLKW" }, \
+               { F_SETOWN,             "SETOWN" }, \
+               { F_GETOWN,             "GETOWN" }, \
+               { F_SETSIG,             "SETSIG" }, \
+               { F_GETSIG,             "GETSIG" }, \
+               { F_GETLK64,            "GETLK64" }, \
+               { F_SETLK64,            "SETLK64" }, \
+               { F_SETLKW64,           "SETLKW64" }, \
+               { F_SETOWN_EX,          "SETOWN_EX" }, \
+               { F_GETOWN_EX,          "GETOWN_EX" }, \
+               { F_GETOWNER_UIDS,      "GETOWNER_UIDS" }, \
+               { F_OFD_GETLK,          "OFD_GETLK" }, \
+               { F_OFD_SETLK,          "OFD_SETLK" }, \
+               { F_OFD_SETLKW,         "OFD_SETLKW" })
+#endif /* CONFIG_64BIT */
+
+#define show_fs_fcntl_lock_type(x) \
+       __print_symbolic(x, \
+               { F_RDLCK,              "RDLCK" }, \
+               { F_WRLCK,              "WRLCK" }, \
+               { F_UNLCK,              "UNLCK" })
+
+#define show_fs_lookup_flags(flags) \
+       __print_flags(flags, "|", \
+               { LOOKUP_FOLLOW,        "FOLLOW" }, \
+               { LOOKUP_DIRECTORY,     "DIRECTORY" }, \
+               { LOOKUP_AUTOMOUNT,     "AUTOMOUNT" }, \
+               { LOOKUP_EMPTY,         "EMPTY" }, \
+               { LOOKUP_DOWN,          "DOWN" }, \
+               { LOOKUP_MOUNTPOINT,    "MOUNTPOINT" }, \
+               { LOOKUP_REVAL,         "REVAL" }, \
+               { LOOKUP_RCU,           "RCU" }, \
+               { LOOKUP_OPEN,          "OPEN" }, \
+               { LOOKUP_CREATE,        "CREATE" }, \
+               { LOOKUP_EXCL,          "EXCL" }, \
+               { LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \
+               { LOOKUP_PARENT,        "PARENT" }, \
+               { LOOKUP_NO_SYMLINKS,   "NO_SYMLINKS" }, \
+               { LOOKUP_NO_MAGICLINKS, "NO_MAGICLINKS" }, \
+               { LOOKUP_NO_XDEV,       "NO_XDEV" }, \
+               { LOOKUP_BENEATH,       "BENEATH" }, \
+               { LOOKUP_IN_ROOT,       "IN_ROOT" }, \
+               { LOOKUP_CACHED,        "CACHED" })
diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h
new file mode 100644 (file)
index 0000000..09ffdbb
--- /dev/null
@@ -0,0 +1,375 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Display helpers for NFS protocol elements
+ *
+ * Author: Chuck Lever <chuck.lever@oracle.com>
+ *
+ * Copyright (c) 2020, Oracle and/or its affiliates.
+ */
+
+#include <linux/nfs.h>
+#include <linux/nfs4.h>
+#include <uapi/linux/nfs.h>
+
+TRACE_DEFINE_ENUM(NFS_OK);
+TRACE_DEFINE_ENUM(NFSERR_PERM);
+TRACE_DEFINE_ENUM(NFSERR_NOENT);
+TRACE_DEFINE_ENUM(NFSERR_IO);
+TRACE_DEFINE_ENUM(NFSERR_NXIO);
+TRACE_DEFINE_ENUM(NFSERR_EAGAIN);
+TRACE_DEFINE_ENUM(NFSERR_ACCES);
+TRACE_DEFINE_ENUM(NFSERR_EXIST);
+TRACE_DEFINE_ENUM(NFSERR_XDEV);
+TRACE_DEFINE_ENUM(NFSERR_NODEV);
+TRACE_DEFINE_ENUM(NFSERR_NOTDIR);
+TRACE_DEFINE_ENUM(NFSERR_ISDIR);
+TRACE_DEFINE_ENUM(NFSERR_INVAL);
+TRACE_DEFINE_ENUM(NFSERR_FBIG);
+TRACE_DEFINE_ENUM(NFSERR_NOSPC);
+TRACE_DEFINE_ENUM(NFSERR_ROFS);
+TRACE_DEFINE_ENUM(NFSERR_MLINK);
+TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP);
+TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG);
+TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY);
+TRACE_DEFINE_ENUM(NFSERR_DQUOT);
+TRACE_DEFINE_ENUM(NFSERR_STALE);
+TRACE_DEFINE_ENUM(NFSERR_REMOTE);
+TRACE_DEFINE_ENUM(NFSERR_WFLUSH);
+TRACE_DEFINE_ENUM(NFSERR_BADHANDLE);
+TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC);
+TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE);
+TRACE_DEFINE_ENUM(NFSERR_NOTSUPP);
+TRACE_DEFINE_ENUM(NFSERR_TOOSMALL);
+TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT);
+TRACE_DEFINE_ENUM(NFSERR_BADTYPE);
+TRACE_DEFINE_ENUM(NFSERR_JUKEBOX);
+
+#define show_nfs_status(x) \
+       __print_symbolic(x, \
+               { NFS_OK,                       "OK" }, \
+               { NFSERR_PERM,                  "PERM" }, \
+               { NFSERR_NOENT,                 "NOENT" }, \
+               { NFSERR_IO,                    "IO" }, \
+               { NFSERR_NXIO,                  "NXIO" }, \
+               { ECHILD,                       "CHILD" }, \
+               { NFSERR_EAGAIN,                "AGAIN" }, \
+               { NFSERR_ACCES,                 "ACCES" }, \
+               { NFSERR_EXIST,                 "EXIST" }, \
+               { NFSERR_XDEV,                  "XDEV" }, \
+               { NFSERR_NODEV,                 "NODEV" }, \
+               { NFSERR_NOTDIR,                "NOTDIR" }, \
+               { NFSERR_ISDIR,                 "ISDIR" }, \
+               { NFSERR_INVAL,                 "INVAL" }, \
+               { NFSERR_FBIG,                  "FBIG" }, \
+               { NFSERR_NOSPC,                 "NOSPC" }, \
+               { NFSERR_ROFS,                  "ROFS" }, \
+               { NFSERR_MLINK,                 "MLINK" }, \
+               { NFSERR_OPNOTSUPP,             "OPNOTSUPP" }, \
+               { NFSERR_NAMETOOLONG,           "NAMETOOLONG" }, \
+               { NFSERR_NOTEMPTY,              "NOTEMPTY" }, \
+               { NFSERR_DQUOT,                 "DQUOT" }, \
+               { NFSERR_STALE,                 "STALE" }, \
+               { NFSERR_REMOTE,                "REMOTE" }, \
+               { NFSERR_WFLUSH,                "WFLUSH" }, \
+               { NFSERR_BADHANDLE,             "BADHANDLE" }, \
+               { NFSERR_NOT_SYNC,              "NOTSYNC" }, \
+               { NFSERR_BAD_COOKIE,            "BADCOOKIE" }, \
+               { NFSERR_NOTSUPP,               "NOTSUPP" }, \
+               { NFSERR_TOOSMALL,              "TOOSMALL" }, \
+               { NFSERR_SERVERFAULT,           "REMOTEIO" }, \
+               { NFSERR_BADTYPE,               "BADTYPE" }, \
+               { NFSERR_JUKEBOX,               "JUKEBOX" })
+
+TRACE_DEFINE_ENUM(NFS_UNSTABLE);
+TRACE_DEFINE_ENUM(NFS_DATA_SYNC);
+TRACE_DEFINE_ENUM(NFS_FILE_SYNC);
+
+#define show_nfs_stable_how(x) \
+       __print_symbolic(x, \
+               { NFS_UNSTABLE,                 "UNSTABLE" }, \
+               { NFS_DATA_SYNC,                "DATA_SYNC" }, \
+               { NFS_FILE_SYNC,                "FILE_SYNC" })
+
+TRACE_DEFINE_ENUM(NFS4_OK);
+TRACE_DEFINE_ENUM(NFS4ERR_ACCESS);
+TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED);
+TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY);
+TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR);
+TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE);
+TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE);
+TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT);
+TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL);
+TRACE_DEFINE_ENUM(NFS4ERR_BADNAME);
+TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER);
+TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT);
+TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE);
+TRACE_DEFINE_ENUM(NFS4ERR_BADXDR);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST);
+TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID);
+TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN);
+TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE);
+TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY);
+TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY);
+TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK);
+TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_DELAY);
+TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED);
+TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED);
+TRACE_DEFINE_ENUM(NFS4ERR_DENIED);
+TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL);
+TRACE_DEFINE_ENUM(NFS4ERR_DQUOT);
+TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_EXIST);
+TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED);
+TRACE_DEFINE_ENUM(NFS4ERR_FBIG);
+TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED);
+TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN);
+TRACE_DEFINE_ENUM(NFS4ERR_GRACE);
+TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_INVAL);
+TRACE_DEFINE_ENUM(NFS4ERR_IO);
+TRACE_DEFINE_ENUM(NFS4ERR_ISDIR);
+TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER);
+TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE);
+TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED);
+TRACE_DEFINE_ENUM(NFS4ERR_LOCKED);
+TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD);
+TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE);
+TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH);
+TRACE_DEFINE_ENUM(NFS4ERR_MLINK);
+TRACE_DEFINE_ENUM(NFS4ERR_MOVED);
+TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG);
+TRACE_DEFINE_ENUM(NFS4ERR_NOENT);
+TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE);
+TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT);
+TRACE_DEFINE_ENUM(NFS4ERR_NOSPC);
+TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR);
+TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY);
+TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP);
+TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP);
+TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME);
+TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE);
+TRACE_DEFINE_ENUM(NFS4ERR_NXIO);
+TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID);
+TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE);
+TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL);
+TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION);
+TRACE_DEFINE_ENUM(NFS4ERR_PERM);
+TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE);
+TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT);
+TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT);
+TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD);
+TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT);
+TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG);
+TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG);
+TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE);
+TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG);
+TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE);
+TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH);
+TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP);
+TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT);
+TRACE_DEFINE_ENUM(NFS4ERR_ROFS);
+TRACE_DEFINE_ENUM(NFS4ERR_SAME);
+TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED);
+TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS);
+TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY);
+TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED);
+TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT);
+TRACE_DEFINE_ENUM(NFS4ERR_STALE);
+TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID);
+TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID);
+TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK);
+TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL);
+TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS);
+TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE);
+TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND);
+TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC);
+TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED);
+TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE);
+TRACE_DEFINE_ENUM(NFS4ERR_XDEV);
+
+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS);
+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS);
+
+#define show_nfs4_status(x) \
+       __print_symbolic(x, \
+               { NFS4_OK,                      "OK" }, \
+               { EPERM,                        "EPERM" }, \
+               { ENOENT,                       "ENOENT" }, \
+               { EIO,                          "EIO" }, \
+               { ENXIO,                        "ENXIO" }, \
+               { EACCES,                       "EACCES" }, \
+               { EEXIST,                       "EEXIST" }, \
+               { EXDEV,                        "EXDEV" }, \
+               { ENOTDIR,                      "ENOTDIR" }, \
+               { EISDIR,                       "EISDIR" }, \
+               { EFBIG,                        "EFBIG" }, \
+               { ENOSPC,                       "ENOSPC" }, \
+               { EROFS,                        "EROFS" }, \
+               { EMLINK,                       "EMLINK" }, \
+               { ENAMETOOLONG,                 "ENAMETOOLONG" }, \
+               { ENOTEMPTY,                    "ENOTEMPTY" }, \
+               { EDQUOT,                       "EDQUOT" }, \
+               { ESTALE,                       "ESTALE" }, \
+               { EBADHANDLE,                   "EBADHANDLE" }, \
+               { EBADCOOKIE,                   "EBADCOOKIE" }, \
+               { ENOTSUPP,                     "ENOTSUPP" }, \
+               { ETOOSMALL,                    "ETOOSMALL" }, \
+               { EREMOTEIO,                    "EREMOTEIO" }, \
+               { EBADTYPE,                     "EBADTYPE" }, \
+               { EAGAIN,                       "EAGAIN" }, \
+               { ELOOP,                        "ELOOP" }, \
+               { EOPNOTSUPP,                   "EOPNOTSUPP" }, \
+               { EDEADLK,                      "EDEADLK" }, \
+               { ENOMEM,                       "ENOMEM" }, \
+               { EKEYEXPIRED,                  "EKEYEXPIRED" }, \
+               { ETIMEDOUT,                    "ETIMEDOUT" }, \
+               { ERESTARTSYS,                  "ERESTARTSYS" }, \
+               { ECONNREFUSED,                 "ECONNREFUSED" }, \
+               { ECONNRESET,                   "ECONNRESET" }, \
+               { ENETUNREACH,                  "ENETUNREACH" }, \
+               { EHOSTUNREACH,                 "EHOSTUNREACH" }, \
+               { EHOSTDOWN,                    "EHOSTDOWN" }, \
+               { EPIPE,                        "EPIPE" }, \
+               { EPFNOSUPPORT,                 "EPFNOSUPPORT" }, \
+               { EPROTONOSUPPORT,              "EPROTONOSUPPORT" }, \
+               { NFS4ERR_ACCESS,               "ACCESS" }, \
+               { NFS4ERR_ATTRNOTSUPP,          "ATTRNOTSUPP" }, \
+               { NFS4ERR_ADMIN_REVOKED,        "ADMIN_REVOKED" }, \
+               { NFS4ERR_BACK_CHAN_BUSY,       "BACK_CHAN_BUSY" }, \
+               { NFS4ERR_BADCHAR,              "BADCHAR" }, \
+               { NFS4ERR_BADHANDLE,            "BADHANDLE" }, \
+               { NFS4ERR_BADIOMODE,            "BADIOMODE" }, \
+               { NFS4ERR_BADLAYOUT,            "BADLAYOUT" }, \
+               { NFS4ERR_BADLABEL,             "BADLABEL" }, \
+               { NFS4ERR_BADNAME,              "BADNAME" }, \
+               { NFS4ERR_BADOWNER,             "BADOWNER" }, \
+               { NFS4ERR_BADSESSION,           "BADSESSION" }, \
+               { NFS4ERR_BADSLOT,              "BADSLOT" }, \
+               { NFS4ERR_BADTYPE,              "BADTYPE" }, \
+               { NFS4ERR_BADXDR,               "BADXDR" }, \
+               { NFS4ERR_BAD_COOKIE,           "BAD_COOKIE" }, \
+               { NFS4ERR_BAD_HIGH_SLOT,        "BAD_HIGH_SLOT" }, \
+               { NFS4ERR_BAD_RANGE,            "BAD_RANGE" }, \
+               { NFS4ERR_BAD_SEQID,            "BAD_SEQID" }, \
+               { NFS4ERR_BAD_SESSION_DIGEST,   "BAD_SESSION_DIGEST" }, \
+               { NFS4ERR_BAD_STATEID,          "BAD_STATEID" }, \
+               { NFS4ERR_CB_PATH_DOWN,         "CB_PATH_DOWN" }, \
+               { NFS4ERR_CLID_INUSE,           "CLID_INUSE" }, \
+               { NFS4ERR_CLIENTID_BUSY,        "CLIENTID_BUSY" }, \
+               { NFS4ERR_COMPLETE_ALREADY,     "COMPLETE_ALREADY" }, \
+               { NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "CONN_NOT_BOUND_TO_SESSION" }, \
+               { NFS4ERR_DEADLOCK,             "DEADLOCK" }, \
+               { NFS4ERR_DEADSESSION,          "DEAD_SESSION" }, \
+               { NFS4ERR_DELAY,                "DELAY" }, \
+               { NFS4ERR_DELEG_ALREADY_WANTED, "DELEG_ALREADY_WANTED" }, \
+               { NFS4ERR_DELEG_REVOKED,        "DELEG_REVOKED" }, \
+               { NFS4ERR_DENIED,               "DENIED" }, \
+               { NFS4ERR_DIRDELEG_UNAVAIL,     "DIRDELEG_UNAVAIL" }, \
+               { NFS4ERR_DQUOT,                "DQUOT" }, \
+               { NFS4ERR_ENCR_ALG_UNSUPP,      "ENCR_ALG_UNSUPP" }, \
+               { NFS4ERR_EXIST,                "EXIST" }, \
+               { NFS4ERR_EXPIRED,              "EXPIRED" }, \
+               { NFS4ERR_FBIG,                 "FBIG" }, \
+               { NFS4ERR_FHEXPIRED,            "FHEXPIRED" }, \
+               { NFS4ERR_FILE_OPEN,            "FILE_OPEN" }, \
+               { NFS4ERR_GRACE,                "GRACE" }, \
+               { NFS4ERR_HASH_ALG_UNSUPP,      "HASH_ALG_UNSUPP" }, \
+               { NFS4ERR_INVAL,                "INVAL" }, \
+               { NFS4ERR_IO,                   "IO" }, \
+               { NFS4ERR_ISDIR,                "ISDIR" }, \
+               { NFS4ERR_LAYOUTTRYLATER,       "LAYOUTTRYLATER" }, \
+               { NFS4ERR_LAYOUTUNAVAILABLE,    "LAYOUTUNAVAILABLE" }, \
+               { NFS4ERR_LEASE_MOVED,          "LEASE_MOVED" }, \
+               { NFS4ERR_LOCKED,               "LOCKED" }, \
+               { NFS4ERR_LOCKS_HELD,           "LOCKS_HELD" }, \
+               { NFS4ERR_LOCK_RANGE,           "LOCK_RANGE" }, \
+               { NFS4ERR_MINOR_VERS_MISMATCH,  "MINOR_VERS_MISMATCH" }, \
+               { NFS4ERR_MLINK,                "MLINK" }, \
+               { NFS4ERR_MOVED,                "MOVED" }, \
+               { NFS4ERR_NAMETOOLONG,          "NAMETOOLONG" }, \
+               { NFS4ERR_NOENT,                "NOENT" }, \
+               { NFS4ERR_NOFILEHANDLE,         "NOFILEHANDLE" }, \
+               { NFS4ERR_NOMATCHING_LAYOUT,    "NOMATCHING_LAYOUT" }, \
+               { NFS4ERR_NOSPC,                "NOSPC" }, \
+               { NFS4ERR_NOTDIR,               "NOTDIR" }, \
+               { NFS4ERR_NOTEMPTY,             "NOTEMPTY" }, \
+               { NFS4ERR_NOTSUPP,              "NOTSUPP" }, \
+               { NFS4ERR_NOT_ONLY_OP,          "NOT_ONLY_OP" }, \
+               { NFS4ERR_NOT_SAME,             "NOT_SAME" }, \
+               { NFS4ERR_NO_GRACE,             "NO_GRACE" }, \
+               { NFS4ERR_NXIO,                 "NXIO" }, \
+               { NFS4ERR_OLD_STATEID,          "OLD_STATEID" }, \
+               { NFS4ERR_OPENMODE,             "OPENMODE" }, \
+               { NFS4ERR_OP_ILLEGAL,           "OP_ILLEGAL" }, \
+               { NFS4ERR_OP_NOT_IN_SESSION,    "OP_NOT_IN_SESSION" }, \
+               { NFS4ERR_PERM,                 "PERM" }, \
+               { NFS4ERR_PNFS_IO_HOLE,         "PNFS_IO_HOLE" }, \
+               { NFS4ERR_PNFS_NO_LAYOUT,       "PNFS_NO_LAYOUT" }, \
+               { NFS4ERR_RECALLCONFLICT,       "RECALLCONFLICT" }, \
+               { NFS4ERR_RECLAIM_BAD,          "RECLAIM_BAD" }, \
+               { NFS4ERR_RECLAIM_CONFLICT,     "RECLAIM_CONFLICT" }, \
+               { NFS4ERR_REJECT_DELEG,         "REJECT_DELEG" }, \
+               { NFS4ERR_REP_TOO_BIG,          "REP_TOO_BIG" }, \
+               { NFS4ERR_REP_TOO_BIG_TO_CACHE, "REP_TOO_BIG_TO_CACHE" }, \
+               { NFS4ERR_REQ_TOO_BIG,          "REQ_TOO_BIG" }, \
+               { NFS4ERR_RESOURCE,             "RESOURCE" }, \
+               { NFS4ERR_RESTOREFH,            "RESTOREFH" }, \
+               { NFS4ERR_RETRY_UNCACHED_REP,   "RETRY_UNCACHED_REP" }, \
+               { NFS4ERR_RETURNCONFLICT,       "RETURNCONFLICT" }, \
+               { NFS4ERR_ROFS,                 "ROFS" }, \
+               { NFS4ERR_SAME,                 "SAME" }, \
+               { NFS4ERR_SHARE_DENIED,         "SHARE_DENIED" }, \
+               { NFS4ERR_SEQUENCE_POS,         "SEQUENCE_POS" }, \
+               { NFS4ERR_SEQ_FALSE_RETRY,      "SEQ_FALSE_RETRY" }, \
+               { NFS4ERR_SEQ_MISORDERED,       "SEQ_MISORDERED" }, \
+               { NFS4ERR_SERVERFAULT,          "SERVERFAULT" }, \
+               { NFS4ERR_STALE,                "STALE" }, \
+               { NFS4ERR_STALE_CLIENTID,       "STALE_CLIENTID" }, \
+               { NFS4ERR_STALE_STATEID,        "STALE_STATEID" }, \
+               { NFS4ERR_SYMLINK,              "SYMLINK" }, \
+               { NFS4ERR_TOOSMALL,             "TOOSMALL" }, \
+               { NFS4ERR_TOO_MANY_OPS,         "TOO_MANY_OPS" }, \
+               { NFS4ERR_UNKNOWN_LAYOUTTYPE,   "UNKNOWN_LAYOUTTYPE" }, \
+               { NFS4ERR_UNSAFE_COMPOUND,      "UNSAFE_COMPOUND" }, \
+               { NFS4ERR_WRONGSEC,             "WRONGSEC" }, \
+               { NFS4ERR_WRONG_CRED,           "WRONG_CRED" }, \
+               { NFS4ERR_WRONG_TYPE,           "WRONG_TYPE" }, \
+               { NFS4ERR_XDEV,                 "XDEV" }, \
+               /* ***** Internal to Linux NFS client ***** */ \
+               { NFS4ERR_RESET_TO_MDS,         "RESET_TO_MDS" }, \
+               { NFS4ERR_RESET_TO_PNFS,        "RESET_TO_PNFS" })
+
+#define show_nfs4_verifier(x) \
+       __print_hex_str(x, NFS4_VERIFIER_SIZE)
+
+TRACE_DEFINE_ENUM(IOMODE_READ);
+TRACE_DEFINE_ENUM(IOMODE_RW);
+TRACE_DEFINE_ENUM(IOMODE_ANY);
+
+#define show_pnfs_layout_iomode(x) \
+       __print_symbolic(x, \
+               { IOMODE_READ,                  "READ" }, \
+               { IOMODE_RW,                    "RW" }, \
+               { IOMODE_ANY,                   "ANY" })
+
+#define show_nfs4_seq4_status(x) \
+       __print_flags(x, "|", \
+               { SEQ4_STATUS_CB_PATH_DOWN,             "CB_PATH_DOWN" }, \
+               { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, "CB_GSS_CONTEXTS_EXPIRING" }, \
+               { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED,  "CB_GSS_CONTEXTS_EXPIRED" }, \
+               { SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, "EXPIRED_ALL_STATE_REVOKED" }, \
+               { SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, "EXPIRED_SOME_STATE_REVOKED" }, \
+               { SEQ4_STATUS_ADMIN_STATE_REVOKED,      "ADMIN_STATE_REVOKED" }, \
+               { SEQ4_STATUS_RECALLABLE_STATE_REVOKED, "RECALLABLE_STATE_REVOKED" }, \
+               { SEQ4_STATUS_LEASE_MOVED,              "LEASE_MOVED" }, \
+               { SEQ4_STATUS_RESTART_RECLAIM_NEEDED,   "RESTART_RECLAIM_NEEDED" }, \
+               { SEQ4_STATUS_CB_PATH_DOWN_SESSION,     "CB_PATH_DOWN_SESSION" }, \
+               { SEQ4_STATUS_BACKCHANNEL_FAULT,        "BACKCHANNEL_FAULT" })
index b2a2672..3ba6331 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <linux/tracepoint.h>
 
+#include <trace/events/sunrpc_base.h>
+
 /**
  ** GSS-API related trace events
  **/
@@ -99,7 +101,7 @@ DECLARE_EVENT_CLASS(rpcgss_gssapi_event,
                __entry->maj_stat = maj_stat;
        ),
 
-       TP_printk("task:%u@%u maj_stat=%s",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " maj_stat=%s",
                __entry->task_id, __entry->client_id,
                __entry->maj_stat == 0 ?
                "GSS_S_COMPLETE" : show_gss_status(__entry->maj_stat))
@@ -332,7 +334,8 @@ TRACE_EVENT(rpcgss_unwrap_failed,
                __entry->client_id = task->tk_client->cl_clid;
        ),
 
-       TP_printk("task:%u@%u", __entry->task_id, __entry->client_id)
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER,
+               __entry->task_id, __entry->client_id)
 );
 
 TRACE_EVENT(rpcgss_bad_seqno,
@@ -358,7 +361,8 @@ TRACE_EVENT(rpcgss_bad_seqno,
                __entry->received = received;
        ),
 
-       TP_printk("task:%u@%u expected seqno %u, received seqno %u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " expected seqno %u, received seqno %u",
                __entry->task_id, __entry->client_id,
                __entry->expected, __entry->received)
 );
@@ -386,7 +390,7 @@ TRACE_EVENT(rpcgss_seqno,
                __entry->seqno = rqst->rq_seqno;
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x seqno=%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x seqno=%u",
                __entry->task_id, __entry->client_id,
                __entry->xid, __entry->seqno)
 );
@@ -418,7 +422,8 @@ TRACE_EVENT(rpcgss_need_reencode,
                __entry->ret = ret;
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x rq_seqno=%u seq_xmit=%u reencode %sneeded",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " xid=0x%08x rq_seqno=%u seq_xmit=%u reencode %sneeded",
                __entry->task_id, __entry->client_id,
                __entry->xid, __entry->seqno, __entry->seq_xmit,
                __entry->ret ? "" : "un")
@@ -452,7 +457,8 @@ TRACE_EVENT(rpcgss_update_slack,
                __entry->verfsize = auth->au_verfsize;
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x auth=%p rslack=%u ralign=%u verfsize=%u\n",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " xid=0x%08x auth=%p rslack=%u ralign=%u verfsize=%u\n",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->auth, __entry->rslack, __entry->ralign,
                __entry->verfsize)
index de41954..7f46ef6 100644 (file)
@@ -14,7 +14,9 @@
 #include <linux/sunrpc/rpc_rdma_cid.h>
 #include <linux/tracepoint.h>
 #include <rdma/ib_cm.h>
+
 #include <trace/events/rdma.h>
+#include <trace/events/sunrpc_base.h>
 
 /**
  ** Event classes
@@ -279,7 +281,8 @@ DECLARE_EVENT_CLASS(xprtrdma_rdch_event,
                __entry->nsegs = nsegs;
        ),
 
-       TP_printk("task:%u@%u pos=%u %u@0x%016llx:0x%08x (%s)",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " pos=%u %u@0x%016llx:0x%08x (%s)",
                __entry->task_id, __entry->client_id,
                __entry->pos, __entry->length,
                (unsigned long long)__entry->offset, __entry->handle,
@@ -326,7 +329,8 @@ DECLARE_EVENT_CLASS(xprtrdma_wrch_event,
                __entry->nsegs = nsegs;
        ),
 
-       TP_printk("task:%u@%u %u@0x%016llx:0x%08x (%s)",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " %u@0x%016llx:0x%08x (%s)",
                __entry->task_id, __entry->client_id,
                __entry->length, (unsigned long long)__entry->offset,
                __entry->handle,
@@ -375,10 +379,16 @@ DECLARE_EVENT_CLASS(xprtrdma_mr_class,
 
        TP_fast_assign(
                const struct rpcrdma_req *req = mr->mr_req;
-               const struct rpc_task *task = req->rl_slot.rq_task;
 
-               __entry->task_id = task->tk_pid;
-               __entry->client_id = task->tk_client->cl_clid;
+               if (req) {
+                       const struct rpc_task *task = req->rl_slot.rq_task;
+
+                       __entry->task_id = task->tk_pid;
+                       __entry->client_id = task->tk_client->cl_clid;
+               } else {
+                       __entry->task_id = 0;
+                       __entry->client_id = -1;
+               }
                __entry->mr_id  = mr->mr_ibmr->res.id;
                __entry->nents  = mr->mr_nents;
                __entry->handle = mr->mr_handle;
@@ -387,7 +397,8 @@ DECLARE_EVENT_CLASS(xprtrdma_mr_class,
                __entry->dir    = mr->mr_dir;
        ),
 
-       TP_printk("task:%u@%u mr.id=%u nents=%d %u@0x%016llx:0x%08x (%s)",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " mr.id=%u nents=%d %u@0x%016llx:0x%08x (%s)",
                __entry->task_id, __entry->client_id,
                __entry->mr_id, __entry->nents, __entry->length,
                (unsigned long long)__entry->offset, __entry->handle,
@@ -630,15 +641,16 @@ TRACE_EVENT(xprtrdma_nomrs_err,
                __assign_str(port, rpcrdma_portstr(r_xprt));
        ),
 
-       TP_printk("peer=[%s]:%s task:%u@%u",
-               __get_str(addr), __get_str(port),
-               __entry->task_id, __entry->client_id
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " peer=[%s]:%s",
+               __entry->task_id, __entry->client_id,
+               __get_str(addr), __get_str(port)
        )
 );
 
 DEFINE_RDCH_EVENT(read);
 DEFINE_WRCH_EVENT(write);
 DEFINE_WRCH_EVENT(reply);
+DEFINE_WRCH_EVENT(wp);
 
 TRACE_DEFINE_ENUM(rpcrdma_noch);
 TRACE_DEFINE_ENUM(rpcrdma_noch_pullup);
@@ -693,7 +705,8 @@ TRACE_EVENT(xprtrdma_marshal,
                __entry->wtype = wtype;
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x: hdr=%u xdr=%u/%u/%u %s/%s",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " xid=0x%08x hdr=%u xdr=%u/%u/%u %s/%s",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->hdrlen,
                __entry->headlen, __entry->pagelen, __entry->taillen,
@@ -723,7 +736,7 @@ TRACE_EVENT(xprtrdma_marshal_failed,
                __entry->ret = ret;
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x: ret=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x ret=%d",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->ret
        )
@@ -750,7 +763,7 @@ TRACE_EVENT(xprtrdma_prepsend_failed,
                __entry->ret = ret;
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x: ret=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x ret=%d",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->ret
        )
@@ -785,7 +798,7 @@ TRACE_EVENT(xprtrdma_post_send,
                __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED;
        ),
 
-       TP_printk("task:%u@%u cq.id=%u cid=%d (%d SGE%s) %s",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " cq.id=%u cid=%d (%d SGE%s) %s",
                __entry->task_id, __entry->client_id,
                __entry->cq_id, __entry->completion_id,
                __entry->num_sge, (__entry->num_sge == 1 ? "" : "s"),
@@ -820,7 +833,7 @@ TRACE_EVENT(xprtrdma_post_send_err,
                __entry->rc = rc;
        ),
 
-       TP_printk("task:%u@%u cq.id=%u rc=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " cq.id=%u rc=%d",
                __entry->task_id, __entry->client_id,
                __entry->cq_id, __entry->rc
        )
@@ -932,7 +945,7 @@ TRACE_EVENT(xprtrdma_post_linv_err,
                __entry->status = status;
        ),
 
-       TP_printk("task:%u@%u status=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " status=%d",
                __entry->task_id, __entry->client_id, __entry->status
        )
 );
@@ -1120,7 +1133,7 @@ TRACE_EVENT(xprtrdma_reply,
                __entry->credits = credits;
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x credits=%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x credits=%u",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->credits
        )
@@ -1156,7 +1169,7 @@ TRACE_EVENT(xprtrdma_err_vers,
                __entry->max = be32_to_cpup(max);
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x versions=[%u, %u]",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x versions=[%u, %u]",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->min, __entry->max
        )
@@ -1181,7 +1194,7 @@ TRACE_EVENT(xprtrdma_err_chunk,
                __entry->xid = be32_to_cpu(rqst->rq_xid);
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x",
                __entry->task_id, __entry->client_id, __entry->xid
        )
 );
@@ -1207,7 +1220,7 @@ TRACE_EVENT(xprtrdma_err_unrecognized,
                __entry->procedure = be32_to_cpup(procedure);
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x procedure=%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x procedure=%u",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->procedure
        )
@@ -1239,7 +1252,7 @@ TRACE_EVENT(xprtrdma_fixup,
                __entry->taillen = rqst->rq_rcv_buf.tail[0].iov_len;
        ),
 
-       TP_printk("task:%u@%u fixup=%lu xdr=%zu/%u/%zu",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " fixup=%lu xdr=%zu/%u/%zu",
                __entry->task_id, __entry->client_id, __entry->fixup,
                __entry->headlen, __entry->pagelen, __entry->taillen
        )
@@ -1289,7 +1302,7 @@ TRACE_EVENT(xprtrdma_mrs_zap,
                __entry->client_id = task->tk_client->cl_clid;
        ),
 
-       TP_printk("task:%u@%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER,
                __entry->task_id, __entry->client_id
        )
 );
index 2d04eb9..dc922e6 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/net.h>
 #include <linux/tracepoint.h>
 
+#include <trace/events/sunrpc_base.h>
+
 TRACE_DEFINE_ENUM(SOCK_STREAM);
 TRACE_DEFINE_ENUM(SOCK_DGRAM);
 TRACE_DEFINE_ENUM(SOCK_RAW);
@@ -78,7 +80,8 @@ DECLARE_EVENT_CLASS(rpc_xdr_buf_class,
                __entry->msg_len = xdr->len;
        ),
 
-       TP_printk("task:%u@%u head=[%p,%zu] page=%u tail=[%p,%zu] len=%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " head=[%p,%zu] page=%u tail=[%p,%zu] len=%u",
                __entry->task_id, __entry->client_id,
                __entry->head_base, __entry->head_len, __entry->page_len,
                __entry->tail_base, __entry->tail_len, __entry->msg_len
@@ -114,7 +117,7 @@ DECLARE_EVENT_CLASS(rpc_clnt_class,
                __entry->client_id = clnt->cl_clid;
        ),
 
-       TP_printk("clid=%u", __entry->client_id)
+       TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER, __entry->client_id)
 );
 
 #define DEFINE_RPC_CLNT_EVENT(name)                                    \
@@ -158,7 +161,8 @@ TRACE_EVENT(rpc_clnt_new,
                __assign_str(server, server);
        ),
 
-       TP_printk("client=%u peer=[%s]:%s program=%s server=%s",
+       TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER
+                 " peer=[%s]:%s program=%s server=%s",
                __entry->client_id, __get_str(addr), __get_str(port),
                __get_str(program), __get_str(server))
 );
@@ -206,7 +210,8 @@ TRACE_EVENT(rpc_clnt_clone_err,
                __entry->error = error;
        ),
 
-       TP_printk("client=%u error=%d", __entry->client_id, __entry->error)
+       TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER " error=%d",
+               __entry->client_id, __entry->error)
 );
 
 
@@ -248,7 +253,7 @@ DECLARE_EVENT_CLASS(rpc_task_status,
                __entry->status = task->tk_status;
        ),
 
-       TP_printk("task:%u@%u status=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " status=%d",
                __entry->task_id, __entry->client_id,
                __entry->status)
 );
@@ -288,7 +293,7 @@ TRACE_EVENT(rpc_request,
                __assign_str(procname, rpc_proc_name(task));
        ),
 
-       TP_printk("task:%u@%u %sv%d %s (%ssync)",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " %sv%d %s (%ssync)",
                __entry->task_id, __entry->client_id,
                __get_str(progname), __entry->version,
                __get_str(procname), __entry->async ? "a": ""
@@ -348,7 +353,8 @@ DECLARE_EVENT_CLASS(rpc_task_running,
                __entry->flags = task->tk_flags;
                ),
 
-       TP_printk("task:%u@%d flags=%s runstate=%s status=%d action=%ps",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " flags=%s runstate=%s status=%d action=%ps",
                __entry->task_id, __entry->client_id,
                rpc_show_task_flags(__entry->flags),
                rpc_show_runstate(__entry->runstate),
@@ -372,6 +378,7 @@ DEFINE_RPC_RUNNING_EVENT(complete);
 DEFINE_RPC_RUNNING_EVENT(timeout);
 DEFINE_RPC_RUNNING_EVENT(signalled);
 DEFINE_RPC_RUNNING_EVENT(end);
+DEFINE_RPC_RUNNING_EVENT(call_done);
 
 DECLARE_EVENT_CLASS(rpc_task_queued,
 
@@ -400,7 +407,8 @@ DECLARE_EVENT_CLASS(rpc_task_queued,
                __assign_str(q_name, rpc_qname(q));
                ),
 
-       TP_printk("task:%u@%d flags=%s runstate=%s status=%d timeout=%lu queue=%s",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " flags=%s runstate=%s status=%d timeout=%lu queue=%s",
                __entry->task_id, __entry->client_id,
                rpc_show_task_flags(__entry->flags),
                rpc_show_runstate(__entry->runstate),
@@ -436,7 +444,7 @@ DECLARE_EVENT_CLASS(rpc_failure,
                __entry->client_id = task->tk_client->cl_clid;
        ),
 
-       TP_printk("task:%u@%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER,
                __entry->task_id, __entry->client_id)
 );
 
@@ -478,7 +486,8 @@ DECLARE_EVENT_CLASS(rpc_reply_event,
                __assign_str(servername, task->tk_xprt->servername);
        ),
 
-       TP_printk("task:%u@%d server=%s xid=0x%08x %sv%d %s",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " server=%s xid=0x%08x %sv%d %s",
                __entry->task_id, __entry->client_id, __get_str(servername),
                __entry->xid, __get_str(progname), __entry->version,
                __get_str(procname))
@@ -538,7 +547,8 @@ TRACE_EVENT(rpc_buf_alloc,
                __entry->status = status;
        ),
 
-       TP_printk("task:%u@%u callsize=%zu recvsize=%zu status=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " callsize=%zu recvsize=%zu status=%d",
                __entry->task_id, __entry->client_id,
                __entry->callsize, __entry->recvsize, __entry->status
        )
@@ -567,7 +577,8 @@ TRACE_EVENT(rpc_call_rpcerror,
                __entry->rpc_status = rpc_status;
        ),
 
-       TP_printk("task:%u@%u tk_status=%d rpc_status=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " tk_status=%d rpc_status=%d",
                __entry->task_id, __entry->client_id,
                __entry->tk_status, __entry->rpc_status)
 );
@@ -607,7 +618,8 @@ TRACE_EVENT(rpc_stats_latency,
                __entry->execute = ktime_to_us(execute);
        ),
 
-       TP_printk("task:%u@%d xid=0x%08x %sv%d %s backlog=%lu rtt=%lu execute=%lu",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " xid=0x%08x %sv%d %s backlog=%lu rtt=%lu execute=%lu",
                __entry->task_id, __entry->client_id, __entry->xid,
                __get_str(progname), __entry->version, __get_str(procname),
                __entry->backlog, __entry->rtt, __entry->execute)
@@ -651,8 +663,8 @@ TRACE_EVENT(rpc_xdr_overflow,
                        __entry->version = task->tk_client->cl_vers;
                        __assign_str(procedure, task->tk_msg.rpc_proc->p_name);
                } else {
-                       __entry->task_id = 0;
-                       __entry->client_id = 0;
+                       __entry->task_id = -1;
+                       __entry->client_id = -1;
                        __assign_str(progname, "unknown");
                        __entry->version = 0;
                        __assign_str(procedure, "unknown");
@@ -668,8 +680,8 @@ TRACE_EVENT(rpc_xdr_overflow,
                __entry->len = xdr->buf->len;
        ),
 
-       TP_printk(
-               "task:%u@%u %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u\n",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u\n",
                __entry->task_id, __entry->client_id,
                __get_str(progname), __entry->version, __get_str(procedure),
                __entry->requested, __entry->p, __entry->end,
@@ -727,8 +739,8 @@ TRACE_EVENT(rpc_xdr_alignment,
                __entry->len = xdr->buf->len;
        ),
 
-       TP_printk(
-               "task:%u@%u %sv%d %s offset=%zu copied=%u xdr=[%p,%zu]/%u/[%p,%zu]/%u\n",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " %sv%d %s offset=%zu copied=%u xdr=[%p,%zu]/%u/[%p,%zu]/%u\n",
                __entry->task_id, __entry->client_id,
                __get_str(progname), __entry->version, __get_str(procedure),
                __entry->offset, __entry->copied,
@@ -917,7 +929,8 @@ TRACE_EVENT(rpc_socket_nospace,
                __entry->remaining = rqst->rq_slen - transport->xmit.offset;
        ),
 
-       TP_printk("task:%u@%u total=%u remaining=%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " total=%u remaining=%u",
                __entry->task_id, __entry->client_id,
                __entry->total, __entry->remaining
        )
@@ -925,18 +938,18 @@ TRACE_EVENT(rpc_socket_nospace,
 
 #define rpc_show_xprt_state(x)                                         \
        __print_flags(x, "|",                                           \
-               { (1UL << XPRT_LOCKED),         "LOCKED"},              \
-               { (1UL << XPRT_CONNECTED),      "CONNECTED"},           \
-               { (1UL << XPRT_CONNECTING),     "CONNECTING"},          \
-               { (1UL << XPRT_CLOSE_WAIT),     "CLOSE_WAIT"},          \
-               { (1UL << XPRT_BOUND),          "BOUND"},               \
-               { (1UL << XPRT_BINDING),        "BINDING"},             \
-               { (1UL << XPRT_CLOSING),        "CLOSING"},             \
-               { (1UL << XPRT_OFFLINE),        "OFFLINE"},             \
-               { (1UL << XPRT_REMOVE),         "REMOVE"},              \
-               { (1UL << XPRT_CONGESTED),      "CONGESTED"},           \
-               { (1UL << XPRT_CWND_WAIT),      "CWND_WAIT"},           \
-               { (1UL << XPRT_WRITE_SPACE),    "WRITE_SPACE"})
+               { BIT(XPRT_LOCKED),             "LOCKED" },             \
+               { BIT(XPRT_CONNECTED),          "CONNECTED" },          \
+               { BIT(XPRT_CONNECTING),         "CONNECTING" },         \
+               { BIT(XPRT_CLOSE_WAIT),         "CLOSE_WAIT" },         \
+               { BIT(XPRT_BOUND),              "BOUND" },              \
+               { BIT(XPRT_BINDING),            "BINDING" },            \
+               { BIT(XPRT_CLOSING),            "CLOSING" },            \
+               { BIT(XPRT_OFFLINE),            "OFFLINE" },            \
+               { BIT(XPRT_REMOVE),             "REMOVE" },             \
+               { BIT(XPRT_CONGESTED),          "CONGESTED" },          \
+               { BIT(XPRT_CWND_WAIT),          "CWND_WAIT" },          \
+               { BIT(XPRT_WRITE_SPACE),        "WRITE_SPACE" })
 
 DECLARE_EVENT_CLASS(rpc_xprt_lifetime_class,
        TP_PROTO(
@@ -1042,8 +1055,8 @@ TRACE_EVENT(xprt_transmit,
                __entry->status = status;
        ),
 
-       TP_printk(
-               "task:%u@%u xid=0x%08x seqno=%u status=%d",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " xid=0x%08x seqno=%u status=%d",
                __entry->task_id, __entry->client_id, __entry->xid,
                __entry->seqno, __entry->status)
 );
@@ -1082,8 +1095,8 @@ TRACE_EVENT(xprt_retransmit,
                __assign_str(procname, rpc_proc_name(task));
        ),
 
-       TP_printk(
-               "task:%u@%u xid=0x%08x %sv%d %s ntrans=%d timeout=%lu",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " xid=0x%08x %sv%d %s ntrans=%d timeout=%lu",
                __entry->task_id, __entry->client_id, __entry->xid,
                __get_str(progname), __entry->version, __get_str(procname),
                __entry->ntrans, __entry->timeout
@@ -1137,7 +1150,8 @@ DECLARE_EVENT_CLASS(xprt_writelock_event,
                                        xprt->snd_task->tk_pid : -1;
        ),
 
-       TP_printk("task:%u@%u snd_task:%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " snd_task:" SUNRPC_TRACE_PID_SPECIFIER,
                        __entry->task_id, __entry->client_id,
                        __entry->snd_task_id)
 );
@@ -1185,7 +1199,9 @@ DECLARE_EVENT_CLASS(xprt_cong_event,
                __entry->wait = test_bit(XPRT_CWND_WAIT, &xprt->state);
        ),
 
-       TP_printk("task:%u@%u snd_task:%u cong=%lu cwnd=%lu%s",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " snd_task:" SUNRPC_TRACE_PID_SPECIFIER
+                 " cong=%lu cwnd=%lu%s",
                        __entry->task_id, __entry->client_id,
                        __entry->snd_task_id, __entry->cong, __entry->cwnd,
                        __entry->wait ? " (wait)" : "")
@@ -1223,7 +1239,7 @@ TRACE_EVENT(xprt_reserve,
                __entry->xid = be32_to_cpu(rqst->rq_xid);
        ),
 
-       TP_printk("task:%u@%u xid=0x%08x",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x",
                __entry->task_id, __entry->client_id, __entry->xid
        )
 );
@@ -1312,7 +1328,8 @@ TRACE_EVENT(rpcb_getport,
                __assign_str(servername, task->tk_xprt->servername);
        ),
 
-       TP_printk("task:%u@%u server=%s program=%u version=%u protocol=%d bind_version=%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
+                 " server=%s program=%u version=%u protocol=%d bind_version=%u",
                __entry->task_id, __entry->client_id, __get_str(servername),
                __entry->program, __entry->version, __entry->protocol,
                __entry->bind_version
@@ -1342,7 +1359,7 @@ TRACE_EVENT(rpcb_setport,
                __entry->port = port;
        ),
 
-       TP_printk("task:%u@%u status=%d port=%u",
+       TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " status=%d port=%u",
                __entry->task_id, __entry->client_id,
                __entry->status, __entry->port
        )
diff --git a/include/trace/events/sunrpc_base.h b/include/trace/events/sunrpc_base.h
new file mode 100644 (file)
index 0000000..588557d
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates.
+ *
+ * Common types and format specifiers for sunrpc.
+ */
+
+#if !defined(_TRACE_SUNRPC_BASE_H)
+#define _TRACE_SUNRPC_BASE_H
+
+#include <linux/tracepoint.h>
+
+#define SUNRPC_TRACE_PID_SPECIFIER     "%08x"
+#define SUNRPC_TRACE_CLID_SPECIFIER    "%08x"
+#define SUNRPC_TRACE_TASK_SPECIFIER \
+       "task:" SUNRPC_TRACE_PID_SPECIFIER "@" SUNRPC_TRACE_CLID_SPECIFIER
+
+#endif /* _TRACE_SUNRPC_BASE_H */
index f056ff9..a312ea2 100644 (file)
@@ -1076,24 +1076,21 @@ void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
 static
 void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
 {
-
-       if (clnt != NULL) {
-               rpc_task_set_transport(task, clnt);
-               task->tk_client = clnt;
-               refcount_inc(&clnt->cl_count);
-               if (clnt->cl_softrtry)
-                       task->tk_flags |= RPC_TASK_SOFT;
-               if (clnt->cl_softerr)
-                       task->tk_flags |= RPC_TASK_TIMEOUT;
-               if (clnt->cl_noretranstimeo)
-                       task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT;
-               if (atomic_read(&clnt->cl_swapper))
-                       task->tk_flags |= RPC_TASK_SWAPPER;
-               /* Add to the client's list of all tasks */
-               spin_lock(&clnt->cl_lock);
-               list_add_tail(&task->tk_task, &clnt->cl_tasks);
-               spin_unlock(&clnt->cl_lock);
-       }
+       rpc_task_set_transport(task, clnt);
+       task->tk_client = clnt;
+       refcount_inc(&clnt->cl_count);
+       if (clnt->cl_softrtry)
+               task->tk_flags |= RPC_TASK_SOFT;
+       if (clnt->cl_softerr)
+               task->tk_flags |= RPC_TASK_TIMEOUT;
+       if (clnt->cl_noretranstimeo)
+               task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT;
+       if (atomic_read(&clnt->cl_swapper))
+               task->tk_flags |= RPC_TASK_SWAPPER;
+       /* Add to the client's list of all tasks */
+       spin_lock(&clnt->cl_lock);
+       list_add_tail(&task->tk_task, &clnt->cl_tasks);
+       spin_unlock(&clnt->cl_lock);
 }
 
 static void
index c045f63..e2c8354 100644 (file)
@@ -277,9 +277,17 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key, int mode)
 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)
 static void rpc_task_set_debuginfo(struct rpc_task *task)
 {
-       static atomic_t rpc_pid;
+       struct rpc_clnt *clnt = task->tk_client;
 
-       task->tk_pid = atomic_inc_return(&rpc_pid);
+       /* Might be a task carrying a reverse-direction operation */
+       if (!clnt) {
+               static atomic_t rpc_pid;
+
+               task->tk_pid = atomic_inc_return(&rpc_pid);
+               return;
+       }
+
+       task->tk_pid = atomic_inc_return(&clnt->cl_pid);
 }
 #else
 static inline void rpc_task_set_debuginfo(struct rpc_task *task)
@@ -829,6 +837,7 @@ void rpc_exit_task(struct rpc_task *task)
        else if (task->tk_client)
                rpc_count_iostats(task, task->tk_client->cl_metrics);
        if (task->tk_ops->rpc_call_done != NULL) {
+               trace_rpc_task_call_done(task, task->tk_ops->rpc_call_done);
                task->tk_ops->rpc_call_done(task, task->tk_calldata);
                if (task->tk_action != NULL) {
                        /* Always release the RPC slot and buffer memory */
@@ -903,8 +912,10 @@ static void __rpc_execute(struct rpc_task *task)
                /*
                 * Lockless check for whether task is sleeping or not.
                 */
-               if (!RPC_IS_QUEUED(task))
+               if (!RPC_IS_QUEUED(task)) {
+                       cond_resched();
                        continue;
+               }
 
                /*
                 * Signalled tasks should exit rather than sleep.
@@ -1230,8 +1241,7 @@ static int rpciod_start(void)
        if (!wq)
                goto out_failed;
        rpciod_workqueue = wq;
-       /* Note: highpri because network receive is latency sensitive */
-       wq = alloc_workqueue("xprtiod", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_HIGHPRI, 0);
+       wq = alloc_workqueue("xprtiod", WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
        if (!wq)
                goto free_rpciod;
        xprtiod_workqueue = wq;
index 9a6f17e..2766dd2 100644 (file)
@@ -109,8 +109,10 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,
        struct sock_xprt *sock;
        ssize_t ret = -1;
 
-       if (!xprt)
-               return 0;
+       if (!xprt || !xprt_connected(xprt)) {
+               xprt_put(xprt);
+               return -ENOTCONN;
+       }
 
        sock = container_of(xprt, struct sock_xprt, xprt);
        if (kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0)
@@ -129,8 +131,10 @@ static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj,
        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
        ssize_t ret;
 
-       if (!xprt)
-               return 0;
+       if (!xprt || !xprt_connected(xprt)) {
+               xprt_put(xprt);
+               return -ENOTCONN;
+       }
 
        ret = sprintf(buf, "last_used=%lu\ncur_cong=%lu\ncong_win=%lu\n"
                       "max_num_slots=%u\nmin_num_slots=%u\nnum_reqs=%u\n"
index cfd6817..a02de2b 100644 (file)
@@ -246,11 +246,9 @@ EXPORT_SYMBOL_GPL(xprt_find_transport_ident);
 static void xprt_clear_locked(struct rpc_xprt *xprt)
 {
        xprt->snd_task = NULL;
-       if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state)) {
-               smp_mb__before_atomic();
-               clear_bit(XPRT_LOCKED, &xprt->state);
-               smp_mb__after_atomic();
-       } else
+       if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state))
+               clear_bit_unlock(XPRT_LOCKED, &xprt->state);
+       else
                queue_work(xprtiod_workqueue, &xprt->task_cleanup);
 }
 
@@ -737,6 +735,8 @@ static void xprt_autoclose(struct work_struct *work)
        unsigned int pflags = memalloc_nofs_save();
 
        trace_xprt_disconnect_auto(xprt);
+       xprt->connect_cookie++;
+       smp_mb__before_atomic();
        clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
        xprt->ops->close(xprt);
        xprt_release_write(xprt, NULL);
@@ -767,7 +767,8 @@ EXPORT_SYMBOL_GPL(xprt_disconnect_done);
  */
 static void xprt_schedule_autoclose_locked(struct rpc_xprt *xprt)
 {
-       set_bit(XPRT_CLOSE_WAIT, &xprt->state);
+       if (test_and_set_bit(XPRT_CLOSE_WAIT, &xprt->state))
+               return;
        if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
                queue_work(xprtiod_workqueue, &xprt->task_cleanup);
        else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state))
@@ -1603,15 +1604,14 @@ xprt_transmit(struct rpc_task *task)
 {
        struct rpc_rqst *next, *req = task->tk_rqstp;
        struct rpc_xprt *xprt = req->rq_xprt;
-       int counter, status;
+       int status;
 
        spin_lock(&xprt->queue_lock);
-       counter = 0;
-       while (!list_empty(&xprt->xmit_queue)) {
-               if (++counter == 20)
+       for (;;) {
+               next = list_first_entry_or_null(&xprt->xmit_queue,
+                                               struct rpc_rqst, rq_xmit);
+               if (!next)
                        break;
-               next = list_first_entry(&xprt->xmit_queue,
-                               struct rpc_rqst, rq_xmit);
                xprt_pin_rqst(next);
                spin_unlock(&xprt->queue_lock);
                status = xprt_request_transmit(next, task);
@@ -1619,13 +1619,16 @@ xprt_transmit(struct rpc_task *task)
                        status = 0;
                spin_lock(&xprt->queue_lock);
                xprt_unpin_rqst(next);
-               if (status == 0) {
-                       if (!xprt_request_data_received(task) ||
-                           test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
-                               continue;
-               } else if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
-                       task->tk_status = status;
-               break;
+               if (status < 0) {
+                       if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
+                               task->tk_status = status;
+                       break;
+               }
+               /* Was @task transmitted, and has it received a reply? */
+               if (xprt_request_data_received(task) &&
+                   !test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
+                       break;
+               cond_resched_lock(&xprt->queue_lock);
        }
        spin_unlock(&xprt->queue_lock);
 }
index f700b34..ff69930 100644 (file)
@@ -515,8 +515,8 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         * a single ib_post_send() call.
         */
        prev = &first;
-       while ((mr = rpcrdma_mr_pop(&req->rl_registered))) {
-
+       mr = rpcrdma_mr_pop(&req->rl_registered);
+       do {
                trace_xprtrdma_mr_localinv(mr);
                r_xprt->rx_stats.local_inv_needed++;
 
@@ -533,7 +533,8 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
 
                *prev = last;
                prev = &last->next;
-       }
+       } while ((mr = rpcrdma_mr_pop(&req->rl_registered)));
+
        mr = container_of(last, struct rpcrdma_mr, mr_invwr);
 
        /* Strong send queue ordering guarantees that when the
@@ -617,8 +618,8 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         * a single ib_post_send() call.
         */
        prev = &first;
-       while ((mr = rpcrdma_mr_pop(&req->rl_registered))) {
-
+       mr = rpcrdma_mr_pop(&req->rl_registered);
+       do {
                trace_xprtrdma_mr_localinv(mr);
                r_xprt->rx_stats.local_inv_needed++;
 
@@ -635,7 +636,7 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
 
                *prev = last;
                prev = &last->next;
-       }
+       } while ((mr = rpcrdma_mr_pop(&req->rl_registered)));
 
        /* Strong send queue ordering guarantees that when the
         * last WR in the chain completes, all WRs in the chain
@@ -666,3 +667,38 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         */
        rpcrdma_force_disconnect(ep);
 }
+
+/**
+ * frwr_wp_create - Create an MR for padding Write chunks
+ * @r_xprt: transport resources to use
+ *
+ * Return 0 on success, negative errno on failure.
+ */
+int frwr_wp_create(struct rpcrdma_xprt *r_xprt)
+{
+       struct rpcrdma_ep *ep = r_xprt->rx_ep;
+       struct rpcrdma_mr_seg seg;
+       struct rpcrdma_mr *mr;
+
+       mr = rpcrdma_mr_get(r_xprt);
+       if (!mr)
+               return -EAGAIN;
+       mr->mr_req = NULL;
+       ep->re_write_pad_mr = mr;
+
+       seg.mr_len = XDR_UNIT;
+       seg.mr_page = virt_to_page(ep->re_write_pad);
+       seg.mr_offset = offset_in_page(ep->re_write_pad);
+       if (IS_ERR(frwr_map(r_xprt, &seg, 1, true, xdr_zero, mr)))
+               return -EIO;
+       trace_xprtrdma_mr_fastreg(mr);
+
+       mr->mr_cqe.done = frwr_wc_fastreg;
+       mr->mr_regwr.wr.next = NULL;
+       mr->mr_regwr.wr.wr_cqe = &mr->mr_cqe;
+       mr->mr_regwr.wr.num_sge = 0;
+       mr->mr_regwr.wr.opcode = IB_WR_REG_MR;
+       mr->mr_regwr.wr.send_flags = 0;
+
+       return ib_post_send(ep->re_id->qp, &mr->mr_regwr.wr, NULL);
+}
index c335c13..8035a98 100644 (file)
@@ -255,15 +255,7 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt *r_xprt, struct xdr_buf *xdrbuf,
                page_base = 0;
        }
 
-       if (type == rpcrdma_readch)
-               goto out;
-
-       /* When encoding a Write chunk, some servers need to see an
-        * extra segment for non-XDR-aligned Write chunks. The upper
-        * layer provides space in the tail iovec that may be used
-        * for this purpose.
-        */
-       if (type == rpcrdma_writech && r_xprt->rx_ep->re_implicit_roundup)
+       if (type == rpcrdma_readch || type == rpcrdma_writech)
                goto out;
 
        if (xdrbuf->tail[0].iov_len)
@@ -405,6 +397,7 @@ static int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt,
                                     enum rpcrdma_chunktype wtype)
 {
        struct xdr_stream *xdr = &req->rl_stream;
+       struct rpcrdma_ep *ep = r_xprt->rx_ep;
        struct rpcrdma_mr_seg *seg;
        struct rpcrdma_mr *mr;
        int nsegs, nchunks;
@@ -443,6 +436,18 @@ static int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt,
                nsegs -= mr->mr_nents;
        } while (nsegs);
 
+       if (xdr_pad_size(rqst->rq_rcv_buf.page_len)) {
+               if (encode_rdma_segment(xdr, ep->re_write_pad_mr) < 0)
+                       return -EMSGSIZE;
+
+               trace_xprtrdma_chunk_wp(rqst->rq_task, ep->re_write_pad_mr,
+                                       nsegs);
+               r_xprt->rx_stats.write_chunk_count++;
+               r_xprt->rx_stats.total_rdma_request += mr->mr_length;
+               nchunks++;
+               nsegs -= mr->mr_nents;
+       }
+
        /* Update count of segments in this Write chunk */
        *segcount = cpu_to_be32(nchunks);
 
index aaec3c9..3d3673b 100644 (file)
@@ -205,14 +205,12 @@ static void rpcrdma_update_cm_private(struct rpcrdma_ep *ep,
        unsigned int rsize, wsize;
 
        /* Default settings for RPC-over-RDMA Version One */
-       ep->re_implicit_roundup = xprt_rdma_pad_optimize;
        rsize = RPCRDMA_V1_DEF_INLINE_SIZE;
        wsize = RPCRDMA_V1_DEF_INLINE_SIZE;
 
        if (pmsg &&
            pmsg->cp_magic == rpcrdma_cmp_magic &&
            pmsg->cp_version == RPCRDMA_CMP_VERSION) {
-               ep->re_implicit_roundup = true;
                rsize = rpcrdma_decode_buffer_size(pmsg->cp_send_size);
                wsize = rpcrdma_decode_buffer_size(pmsg->cp_recv_size);
        }
@@ -551,6 +549,7 @@ int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt)
                goto out;
        }
        rpcrdma_mrs_create(r_xprt);
+       frwr_wp_create(r_xprt);
 
 out:
        trace_xprtrdma_connect(r_xprt, rc);
index d91f54e..c79f92e 100644 (file)
 /*
  * RDMA Endpoint -- connection endpoint details
  */
+struct rpcrdma_mr;
 struct rpcrdma_ep {
        struct kref             re_kref;
        struct rdma_cm_id       *re_id;
        struct ib_pd            *re_pd;
        unsigned int            re_max_rdma_segs;
        unsigned int            re_max_fr_depth;
-       bool                    re_implicit_roundup;
+       struct rpcrdma_mr       *re_write_pad_mr;
        enum ib_mr_type         re_mrtype;
        struct completion       re_done;
        unsigned int            re_send_count;
@@ -97,6 +98,8 @@ struct rpcrdma_ep {
        unsigned int            re_inline_recv; /* negotiated */
 
        atomic_t                re_completion_ids;
+
+       char                    re_write_pad[XDR_UNIT];
 };
 
 /* Pre-allocate extra Work Requests for handling reverse-direction
@@ -535,6 +538,7 @@ int frwr_send(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);
 void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs);
 void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);
 void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);
+int frwr_wp_create(struct rpcrdma_xprt *r_xprt);
 
 /*
  * RPC/RDMA protocol calls - xprtrdma/rpc_rdma.c
index 04f1b78..ae48c9c 100644 (file)
@@ -1134,6 +1134,7 @@ static void xs_run_error_worker(struct sock_xprt *transport, unsigned int nr)
 
 static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
 {
+       xprt->connect_cookie++;
        smp_mb__before_atomic();
        clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
        clear_bit(XPRT_CLOSING, &xprt->state);
@@ -1153,14 +1154,13 @@ static void xs_error_report(struct sock *sk)
        struct sock_xprt *transport;
        struct rpc_xprt *xprt;
 
-       read_lock_bh(&sk->sk_callback_lock);
        if (!(xprt = xprt_from_sock(sk)))
-               goto out;
+               return;
 
        transport = container_of(xprt, struct sock_xprt, xprt);
        transport->xprt_err = -sk->sk_err;
        if (transport->xprt_err == 0)
-               goto out;
+               return;
        dprintk("RPC:       xs_error_report client %p, error=%d...\n",
                        xprt, -transport->xprt_err);
        trace_rpc_socket_error(xprt, sk->sk_socket, transport->xprt_err);
@@ -1168,8 +1168,6 @@ static void xs_error_report(struct sock *sk)
        /* barrier ensures xprt_err is set before XPRT_SOCK_WAKE_ERROR */
        smp_mb__before_atomic();
        xs_run_error_worker(transport, XPRT_SOCK_WAKE_ERROR);
- out:
-       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static void xs_reset_transport(struct sock_xprt *transport)
@@ -1188,7 +1186,7 @@ static void xs_reset_transport(struct sock_xprt *transport)
        kernel_sock_shutdown(sock, SHUT_RDWR);
 
        mutex_lock(&transport->recv_mutex);
-       write_lock_bh(&sk->sk_callback_lock);
+       lock_sock(sk);
        transport->inet = NULL;
        transport->sock = NULL;
        transport->file = NULL;
@@ -1197,10 +1195,10 @@ static void xs_reset_transport(struct sock_xprt *transport)
 
        xs_restore_old_callbacks(transport, sk);
        xprt_clear_connected(xprt);
-       write_unlock_bh(&sk->sk_callback_lock);
        xs_sock_reset_connection_flags(xprt);
        /* Reset stream record info */
        xs_stream_reset_connect(transport);
+       release_sock(sk);
        mutex_unlock(&transport->recv_mutex);
 
        trace_rpc_socket_close(xprt, sock);
@@ -1364,7 +1362,6 @@ static void xs_data_ready(struct sock *sk)
 {
        struct rpc_xprt *xprt;
 
-       read_lock_bh(&sk->sk_callback_lock);
        dprintk("RPC:       xs_data_ready...\n");
        xprt = xprt_from_sock(sk);
        if (xprt != NULL) {
@@ -1379,7 +1376,6 @@ static void xs_data_ready(struct sock *sk)
                if (!test_and_set_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))
                        queue_work(xprtiod_workqueue, &transport->recv_worker);
        }
-       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /*
@@ -1408,9 +1404,8 @@ static void xs_tcp_state_change(struct sock *sk)
        struct rpc_xprt *xprt;
        struct sock_xprt *transport;
 
-       read_lock_bh(&sk->sk_callback_lock);
        if (!(xprt = xprt_from_sock(sk)))
-               goto out;
+               return;
        dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);
        dprintk("RPC:       state %x conn %d dead %d zapped %d sk_shutdown %d\n",
                        sk->sk_state, xprt_connected(xprt),
@@ -1471,8 +1466,6 @@ static void xs_tcp_state_change(struct sock *sk)
                /* Trigger the socket release */
                xs_run_error_worker(transport, XPRT_SOCK_WAKE_DISCONNECT);
        }
- out:
-       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static void xs_write_space(struct sock *sk)
@@ -1511,13 +1504,9 @@ out:
  */
 static void xs_udp_write_space(struct sock *sk)
 {
-       read_lock_bh(&sk->sk_callback_lock);
-
        /* from net/core/sock.c:sock_def_write_space */
        if (sock_writeable(sk))
                xs_write_space(sk);
-
-       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /**
@@ -1532,13 +1521,9 @@ static void xs_udp_write_space(struct sock *sk)
  */
 static void xs_tcp_write_space(struct sock *sk)
 {
-       read_lock_bh(&sk->sk_callback_lock);
-
        /* from net/core/stream.c:sk_stream_write_space */
        if (sk_stream_is_writeable(sk))
                xs_write_space(sk);
-
-       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
@@ -1833,7 +1818,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
        if (!transport->inet) {
                struct sock *sk = sock->sk;
 
-               write_lock_bh(&sk->sk_callback_lock);
+               lock_sock(sk);
 
                xs_save_old_callbacks(transport, sk);
 
@@ -1849,7 +1834,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
                transport->sock = sock;
                transport->inet = sk;
 
-               write_unlock_bh(&sk->sk_callback_lock);
+               release_sock(sk);
        }
 
        xs_stream_start_connect(transport);
@@ -2031,7 +2016,7 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
        if (!transport->inet) {
                struct sock *sk = sock->sk;
 
-               write_lock_bh(&sk->sk_callback_lock);
+               lock_sock(sk);
 
                xs_save_old_callbacks(transport, sk);
 
@@ -2048,7 +2033,7 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
 
                xs_set_memalloc(xprt);
 
-               write_unlock_bh(&sk->sk_callback_lock);
+               release_sock(sk);
        }
        xs_udp_do_set_buffer_size(xprt);
 
@@ -2174,7 +2159,6 @@ static void xs_tcp_set_connect_timeout(struct rpc_xprt *xprt,
 static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
 {
        struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
-       int ret = -ENOTCONN;
 
        if (!transport->inet) {
                struct sock *sk = sock->sk;
@@ -2194,7 +2178,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
                xs_tcp_set_socket_timeouts(xprt, sock);
                tcp_sock_set_nodelay(sk);
 
-               write_lock_bh(&sk->sk_callback_lock);
+               lock_sock(sk);
 
                xs_save_old_callbacks(transport, sk);
 
@@ -2214,11 +2198,11 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
                transport->sock = sock;
                transport->inet = sk;
 
-               write_unlock_bh(&sk->sk_callback_lock);
+               release_sock(sk);
        }
 
        if (!xprt_bound(xprt))
-               goto out;
+               return -ENOTCONN;
 
        xs_set_memalloc(xprt);
 
@@ -2226,22 +2210,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
 
        /* Tell the socket layer to start connecting... */
        set_bit(XPRT_SOCK_CONNECTING, &transport->sock_state);
-       ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK);
-       switch (ret) {
-       case 0:
-               xs_set_srcport(transport, sock);
-               fallthrough;
-       case -EINPROGRESS:
-               /* SYN_SENT! */
-               if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
-                       xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
-               break;
-       case -EADDRNOTAVAIL:
-               /* Source port number is unavailable. Try a new one! */
-               transport->srcport = 0;
-       }
-out:
-       return ret;
+       return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK);
 }
 
 /**
@@ -2256,14 +2225,14 @@ static void xs_tcp_setup_socket(struct work_struct *work)
                container_of(work, struct sock_xprt, connect_worker.work);
        struct socket *sock = transport->sock;
        struct rpc_xprt *xprt = &transport->xprt;
-       int status = -EIO;
+       int status;
 
        if (!sock) {
                sock = xs_create_sock(xprt, transport,
                                xs_addr(xprt)->sa_family, SOCK_STREAM,
                                IPPROTO_TCP, true);
                if (IS_ERR(sock)) {
-                       status = PTR_ERR(sock);
+                       xprt_wake_pending_tasks(xprt, PTR_ERR(sock));
                        goto out;
                }
        }
@@ -2280,21 +2249,21 @@ static void xs_tcp_setup_socket(struct work_struct *work)
                        xprt, -status, xprt_connected(xprt),
                        sock->sk->sk_state);
        switch (status) {
-       default:
-               printk("%s: connect returned unhandled error %d\n",
-                       __func__, status);
-               fallthrough;
-       case -EADDRNOTAVAIL:
-               /* We're probably in TIME_WAIT. Get rid of existing socket,
-                * and retry
-                */
-               xs_tcp_force_close(xprt);
-               break;
        case 0:
+               xs_set_srcport(transport, sock);
+               fallthrough;
        case -EINPROGRESS:
+               /* SYN_SENT! */
+               if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
+                       xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
+               fallthrough;
        case -EALREADY:
-               xprt_unlock_connect(xprt, transport);
-               return;
+               goto out_unlock;
+       case -EADDRNOTAVAIL:
+               /* Source port number is unavailable. Try a new one! */
+               transport->srcport = 0;
+               status = -EAGAIN;
+               break;
        case -EINVAL:
                /* Happens, for instance, if the user specified a link
                 * local IPv6 address without a scope-id.
@@ -2306,18 +2275,22 @@ static void xs_tcp_setup_socket(struct work_struct *work)
        case -EHOSTUNREACH:
        case -EADDRINUSE:
        case -ENOBUFS:
-               /* xs_tcp_force_close() wakes tasks with a fixed error code.
-                * We need to wake them first to ensure the correct error code.
-                */
-               xprt_wake_pending_tasks(xprt, status);
-               xs_tcp_force_close(xprt);
-               goto out;
+               break;
+       default:
+               printk("%s: connect returned unhandled error %d\n",
+                       __func__, status);
+               status = -EAGAIN;
        }
-       status = -EAGAIN;
+
+       /* xs_tcp_force_close() wakes tasks with a fixed error code.
+        * We need to wake them first to ensure the correct error code.
+        */
+       xprt_wake_pending_tasks(xprt, status);
+       xs_tcp_force_close(xprt);
 out:
        xprt_clear_connecting(xprt);
+out_unlock:
        xprt_unlock_connect(xprt, transport);
-       xprt_wake_pending_tasks(xprt, status);
 }
 
 /**
@@ -2341,7 +2314,7 @@ static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
 
        WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport));
 
-       if (transport->sock != NULL) {
+       if (transport->sock != NULL && !xprt_connecting(xprt)) {
                dprintk("RPC:       xs_connect delayed xprt %p for %lu "
                                "seconds\n",
                                xprt, xprt->reestablish_timeout / HZ);