Merge tag 'nfs-for-5.18-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Apr 2022 17:39:17 +0000 (07:39 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Apr 2022 17:39:17 +0000 (07:39 -1000)
Pull NFS client fixes from Trond Myklebust:
 "Stable fixes:

   - SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()

  Bugfixes:

   - Fix an Oopsable condition due to SLAB_ACCOUNT setting in the
     NFSv4.2 xattr code.

   - Fix for open() using an file open mode of '3' in NFSv4

   - Replace readdir's use of xxhash() with hash_64()

   - Several patches to handle malloc() failure in SUNRPC"

* tag 'nfs-for-5.18-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  SUNRPC: Move the call to xprt_send_pagedata() out of xprt_sock_sendmsg()
  SUNRPC: svc_tcp_sendmsg() should handle errors from xdr_alloc_bvec()
  SUNRPC: Handle allocation failure in rpc_new_task()
  NFS: Ensure rpc_run_task() cannot fail in nfs_async_rename()
  NFSv4/pnfs: Handle RPC allocation errors in nfs4_proc_layoutget
  SUNRPC: Handle low memory situations in call_status()
  SUNRPC: Handle ENOMEM in call_transmit_status()
  NFSv4.2: Fix missing removal of SLAB_ACCOUNT on kmem_cache allocation
  SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()
  NFS: Replace readdir's use of xxhash() with hash_64()
  SUNRPC: handle malloc failure in ->request_prepare
  NFSv4: fix open failure with O_ACCMODE flag
  Revert "NFSv4: Handle the special Linux file open access mode"

1  2 
fs/nfs/inode.c
include/linux/sunrpc/xprt.h
include/trace/events/sunrpc.h
net/sunrpc/xprt.c

diff --combined fs/nfs/inode.c
@@@ -1180,7 -1180,6 +1180,6 @@@ int nfs_open(struct inode *inode, struc
        nfs_fscache_open_file(inode, filp);
        return 0;
  }
- EXPORT_SYMBOL_GPL(nfs_open);
  
  /*
   * This function is called whenever some part of NFS notices that
@@@ -2238,7 -2237,7 +2237,7 @@@ static int nfs_update_inode(struct inod
  struct inode *nfs_alloc_inode(struct super_block *sb)
  {
        struct nfs_inode *nfsi;
 -      nfsi = kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL);
 +      nfsi = alloc_inode_sb(sb, nfs_inode_cachep, GFP_KERNEL);
        if (!nfsi)
                return NULL;
        nfsi->flags = 0UL;
@@@ -144,7 -144,7 +144,7 @@@ struct rpc_xprt_ops 
        unsigned short  (*get_srcport)(struct rpc_xprt *xprt);
        int             (*buf_alloc)(struct rpc_task *task);
        void            (*buf_free)(struct rpc_task *task);
-       void            (*prepare_request)(struct rpc_rqst *req);
+       int             (*prepare_request)(struct rpc_rqst *req);
        int             (*send_request)(struct rpc_rqst *req);
        void            (*wait_for_reply_request)(struct rpc_task *task);
        void            (*timer)(struct rpc_xprt *xprt, struct rpc_task *task);
@@@ -287,7 -287,6 +287,7 @@@ struct rpc_xprt 
        } stat;
  
        struct net              *xprt_net;
 +      netns_tracker           ns_tracker;
        const char              *servername;
        const char              *address_strings[RPC_DISPLAY_MAX];
  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
@@@ -358,10 -357,9 +358,9 @@@ int                       xprt_reserve_xprt_cong(struct rpc
  void                  xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task);
  void                  xprt_free_slot(struct rpc_xprt *xprt,
                                       struct rpc_rqst *req);
- void                  xprt_request_prepare(struct rpc_rqst *req);
  bool                  xprt_prepare_transmit(struct rpc_task *task);
  void                  xprt_request_enqueue_transmit(struct rpc_task *task);
void                  xprt_request_enqueue_receive(struct rpc_task *task);
int                   xprt_request_enqueue_receive(struct rpc_task *task);
  void                  xprt_request_wait_receive(struct rpc_task *task);
  void                  xprt_request_dequeue_xprt(struct rpc_task *task);
  bool                  xprt_request_need_retransmit(struct rpc_task *task);
@@@ -1004,7 -1004,6 +1004,6 @@@ DEFINE_RPC_XPRT_LIFETIME_EVENT(connect)
  DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_auto);
  DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_done);
  DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_force);
- DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_cleanup);
  DEFINE_RPC_XPRT_LIFETIME_EVENT(destroy);
  
  DECLARE_EVENT_CLASS(rpc_xprt_event,
@@@ -1624,53 -1623,26 +1623,53 @@@ TRACE_DEFINE_ENUM(SVC_COMPLETE)
                { SVC_PENDING,  "SVC_PENDING" },        \
                { SVC_COMPLETE, "SVC_COMPLETE" })
  
 +#define SVC_RQST_ENDPOINT_FIELDS(r) \
 +              __sockaddr(server, (r)->rq_xprt->xpt_locallen) \
 +              __sockaddr(client, (r)->rq_xprt->xpt_remotelen) \
 +              __field(unsigned int, netns_ino) \
 +              __field(u32, xid)
 +
 +#define SVC_RQST_ENDPOINT_ASSIGNMENTS(r) \
 +              do { \
 +                      struct svc_xprt *xprt = (r)->rq_xprt; \
 +                      __assign_sockaddr(server, &xprt->xpt_local, \
 +                                        xprt->xpt_locallen); \
 +                      __assign_sockaddr(client, &xprt->xpt_remote, \
 +                                        xprt->xpt_remotelen); \
 +                      __entry->netns_ino = xprt->xpt_net->ns.inum; \
 +                      __entry->xid = be32_to_cpu((r)->rq_xid); \
 +              } while (0)
 +
 +#define SVC_RQST_ENDPOINT_FORMAT \
 +              "xid=0x%08x server=%pISpc client=%pISpc"
 +
 +#define SVC_RQST_ENDPOINT_VARARGS \
 +              __entry->xid, __get_sockaddr(server), __get_sockaddr(client)
 +
  TRACE_EVENT(svc_authenticate,
        TP_PROTO(const struct svc_rqst *rqst, int auth_res),
  
        TP_ARGS(rqst, auth_res),
  
        TP_STRUCT__entry(
 -              __field(u32, xid)
 +              SVC_RQST_ENDPOINT_FIELDS(rqst)
 +
                __field(unsigned long, svc_status)
                __field(unsigned long, auth_stat)
        ),
  
        TP_fast_assign(
 -              __entry->xid = be32_to_cpu(rqst->rq_xid);
 +              SVC_RQST_ENDPOINT_ASSIGNMENTS(rqst);
 +
                __entry->svc_status = auth_res;
                __entry->auth_stat = be32_to_cpu(rqst->rq_auth_stat);
        ),
  
 -      TP_printk("xid=0x%08x auth_res=%s auth_stat=%s",
 -                      __entry->xid, svc_show_status(__entry->svc_status),
 -                      rpc_show_auth_stat(__entry->auth_stat))
 +      TP_printk(SVC_RQST_ENDPOINT_FORMAT
 +              " auth_res=%s auth_stat=%s",
 +              SVC_RQST_ENDPOINT_VARARGS,
 +              svc_show_status(__entry->svc_status),
 +              rpc_show_auth_stat(__entry->auth_stat))
  );
  
  TRACE_EVENT(svc_process,
  );
  
  DECLARE_EVENT_CLASS(svc_rqst_event,
 -
        TP_PROTO(
                const struct svc_rqst *rqst
        ),
        TP_ARGS(rqst),
  
        TP_STRUCT__entry(
 -              __field(u32, xid)
 +              SVC_RQST_ENDPOINT_FIELDS(rqst)
 +
                __field(unsigned long, flags)
 -              __string(addr, rqst->rq_xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 -              __entry->xid = be32_to_cpu(rqst->rq_xid);
 +              SVC_RQST_ENDPOINT_ASSIGNMENTS(rqst);
 +
                __entry->flags = rqst->rq_flags;
 -              __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("addr=%s xid=0x%08x flags=%s",
 -                      __get_str(addr), __entry->xid,
 -                      show_rqstp_flags(__entry->flags))
 +      TP_printk(SVC_RQST_ENDPOINT_FORMAT " flags=%s",
 +              SVC_RQST_ENDPOINT_VARARGS,
 +              show_rqstp_flags(__entry->flags))
  );
  #define DEFINE_SVC_RQST_EVENT(name) \
        DEFINE_EVENT(svc_rqst_event, svc_##name, \
@@@ -1739,63 -1712,34 +1738,63 @@@ DEFINE_SVC_RQST_EVENT(defer)
  DEFINE_SVC_RQST_EVENT(drop);
  
  DECLARE_EVENT_CLASS(svc_rqst_status,
 -
 -      TP_PROTO(struct svc_rqst *rqst, int status),
 +      TP_PROTO(
 +              const struct svc_rqst *rqst,
 +              int status
 +      ),
  
        TP_ARGS(rqst, status),
  
        TP_STRUCT__entry(
 -              __field(u32, xid)
 +              SVC_RQST_ENDPOINT_FIELDS(rqst)
 +
                __field(int, status)
                __field(unsigned long, flags)
 -              __string(addr, rqst->rq_xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 -              __entry->xid = be32_to_cpu(rqst->rq_xid);
 +              SVC_RQST_ENDPOINT_ASSIGNMENTS(rqst);
 +
                __entry->status = status;
                __entry->flags = rqst->rq_flags;
 -              __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("addr=%s xid=0x%08x status=%d flags=%s",
 -                __get_str(addr), __entry->xid,
 -                __entry->status, show_rqstp_flags(__entry->flags))
 +      TP_printk(SVC_RQST_ENDPOINT_FORMAT " status=%d flags=%s",
 +              SVC_RQST_ENDPOINT_VARARGS,
 +              __entry->status, show_rqstp_flags(__entry->flags))
  );
  
  DEFINE_EVENT(svc_rqst_status, svc_send,
 -      TP_PROTO(struct svc_rqst *rqst, int status),
 +      TP_PROTO(const struct svc_rqst *rqst, int status),
        TP_ARGS(rqst, status));
  
 +TRACE_EVENT(svc_stats_latency,
 +      TP_PROTO(
 +              const struct svc_rqst *rqst
 +      ),
 +
 +      TP_ARGS(rqst),
 +
 +      TP_STRUCT__entry(
 +              SVC_RQST_ENDPOINT_FIELDS(rqst)
 +
 +              __field(unsigned long, execute)
 +              __string(procedure, svc_proc_name(rqst))
 +      ),
 +
 +      TP_fast_assign(
 +              SVC_RQST_ENDPOINT_ASSIGNMENTS(rqst);
 +
 +              __entry->execute = ktime_to_us(ktime_sub(ktime_get(),
 +                                                       rqst->rq_stime));
 +              __assign_str(procedure, svc_proc_name(rqst));
 +      ),
 +
 +      TP_printk(SVC_RQST_ENDPOINT_FORMAT " proc=%s execute-us=%lu",
 +              SVC_RQST_ENDPOINT_VARARGS,
 +              __get_str(procedure), __entry->execute)
 +);
 +
  #define show_svc_xprt_flags(flags)                                    \
        __print_flags(flags, "|",                                       \
                { (1UL << XPT_BUSY),            "XPT_BUSY"},            \
@@@ -1828,114 -1772,65 +1827,114 @@@ TRACE_EVENT(svc_xprt_create_err
                __field(long, error)
                __string(program, program)
                __string(protocol, protocol)
 -              __array(unsigned char, addr, sizeof(struct sockaddr_in6))
 +              __sockaddr(addr, salen)
        ),
  
        TP_fast_assign(
                __entry->error = PTR_ERR(xprt);
                __assign_str(program, program);
                __assign_str(protocol, protocol);
 -              memcpy(__entry->addr, sap, min(salen, sizeof(__entry->addr)));
 +              __assign_sockaddr(addr, sap, salen);
        ),
  
        TP_printk("addr=%pISpc program=%s protocol=%s error=%ld",
 -              __entry->addr, __get_str(program), __get_str(protocol),
 +              __get_sockaddr(addr), __get_str(program), __get_str(protocol),
                __entry->error)
  );
  
 +#define SVC_XPRT_ENDPOINT_FIELDS(x) \
 +              __sockaddr(server, (x)->xpt_locallen) \
 +              __sockaddr(client, (x)->xpt_remotelen) \
 +              __field(unsigned long, flags) \
 +              __field(unsigned int, netns_ino)
 +
 +#define SVC_XPRT_ENDPOINT_ASSIGNMENTS(x) \
 +              do { \
 +                      __assign_sockaddr(server, &(x)->xpt_local, \
 +                                        (x)->xpt_locallen); \
 +                      __assign_sockaddr(client, &(x)->xpt_remote, \
 +                                        (x)->xpt_remotelen); \
 +                      __entry->flags = (x)->xpt_flags; \
 +                      __entry->netns_ino = (x)->xpt_net->ns.inum; \
 +              } while (0)
 +
 +#define SVC_XPRT_ENDPOINT_FORMAT \
 +              "server=%pISpc client=%pISpc flags=%s"
 +
 +#define SVC_XPRT_ENDPOINT_VARARGS \
 +              __get_sockaddr(server), __get_sockaddr(client), \
 +              show_svc_xprt_flags(__entry->flags)
 +
  TRACE_EVENT(svc_xprt_enqueue,
 -      TP_PROTO(struct svc_xprt *xprt, struct svc_rqst *rqst),
 +      TP_PROTO(
 +              const struct svc_xprt *xprt,
 +              const struct svc_rqst *rqst
 +      ),
  
        TP_ARGS(xprt, rqst),
  
        TP_STRUCT__entry(
 +              SVC_XPRT_ENDPOINT_FIELDS(xprt)
 +
                __field(int, pid)
 -              __field(unsigned long, flags)
 -              __string(addr, xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 +              SVC_XPRT_ENDPOINT_ASSIGNMENTS(xprt);
 +
                __entry->pid = rqst? rqst->rq_task->pid : 0;
 -              __entry->flags = xprt->xpt_flags;
 -              __assign_str(addr, xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("addr=%s pid=%d flags=%s", __get_str(addr),
 -              __entry->pid, show_svc_xprt_flags(__entry->flags))
 +      TP_printk(SVC_XPRT_ENDPOINT_FORMAT " pid=%d",
 +              SVC_XPRT_ENDPOINT_VARARGS, __entry->pid)
 +);
 +
 +TRACE_EVENT(svc_xprt_dequeue,
 +      TP_PROTO(
 +              const struct svc_rqst *rqst
 +      ),
 +
 +      TP_ARGS(rqst),
 +
 +      TP_STRUCT__entry(
 +              SVC_XPRT_ENDPOINT_FIELDS(rqst->rq_xprt)
 +
 +              __field(unsigned long, wakeup)
 +      ),
 +
 +      TP_fast_assign(
 +              SVC_XPRT_ENDPOINT_ASSIGNMENTS(rqst->rq_xprt);
 +
 +              __entry->wakeup = ktime_to_us(ktime_sub(ktime_get(),
 +                                                      rqst->rq_qtime));
 +      ),
 +
 +      TP_printk(SVC_XPRT_ENDPOINT_FORMAT " wakeup-us=%lu",
 +              SVC_XPRT_ENDPOINT_VARARGS, __entry->wakeup)
  );
  
  DECLARE_EVENT_CLASS(svc_xprt_event,
 -      TP_PROTO(struct svc_xprt *xprt),
 +      TP_PROTO(
 +              const struct svc_xprt *xprt
 +      ),
  
        TP_ARGS(xprt),
  
        TP_STRUCT__entry(
 -              __field(unsigned long, flags)
 -              __string(addr, xprt->xpt_remotebuf)
 +              SVC_XPRT_ENDPOINT_FIELDS(xprt)
        ),
  
        TP_fast_assign(
 -              __entry->flags = xprt->xpt_flags;
 -              __assign_str(addr, xprt->xpt_remotebuf);
 +              SVC_XPRT_ENDPOINT_ASSIGNMENTS(xprt);
        ),
  
 -      TP_printk("addr=%s flags=%s", __get_str(addr),
 -              show_svc_xprt_flags(__entry->flags))
 +      TP_printk(SVC_XPRT_ENDPOINT_FORMAT, SVC_XPRT_ENDPOINT_VARARGS)
  );
  
  #define DEFINE_SVC_XPRT_EVENT(name) \
        DEFINE_EVENT(svc_xprt_event, svc_xprt_##name, \
                        TP_PROTO( \
 -                              struct svc_xprt *xprt \
 +                              const struct svc_xprt *xprt \
                        ), \
                        TP_ARGS(xprt))
  
@@@ -1953,25 -1848,44 +1952,25 @@@ TRACE_EVENT(svc_xprt_accept
        TP_ARGS(xprt, service),
  
        TP_STRUCT__entry(
 -              __string(addr, xprt->xpt_remotebuf)
 +              SVC_XPRT_ENDPOINT_FIELDS(xprt)
 +
                __string(protocol, xprt->xpt_class->xcl_name)
                __string(service, service)
        ),
  
        TP_fast_assign(
 -              __assign_str(addr, xprt->xpt_remotebuf);
 +              SVC_XPRT_ENDPOINT_ASSIGNMENTS(xprt);
 +
                __assign_str(protocol, xprt->xpt_class->xcl_name);
                __assign_str(service, service);
        ),
  
 -      TP_printk("addr=%s protocol=%s service=%s",
 -              __get_str(addr), __get_str(protocol), __get_str(service)
 +      TP_printk(SVC_XPRT_ENDPOINT_FORMAT " protocol=%s service=%s",
 +              SVC_XPRT_ENDPOINT_VARARGS,
 +              __get_str(protocol), __get_str(service)
        )
  );
  
 -TRACE_EVENT(svc_xprt_dequeue,
 -      TP_PROTO(struct svc_rqst *rqst),
 -
 -      TP_ARGS(rqst),
 -
 -      TP_STRUCT__entry(
 -              __field(unsigned long, flags)
 -              __field(unsigned long, wakeup)
 -              __string(addr, rqst->rq_xprt->xpt_remotebuf)
 -      ),
 -
 -      TP_fast_assign(
 -              __entry->flags = rqst->rq_xprt->xpt_flags;
 -              __entry->wakeup = ktime_to_us(ktime_sub(ktime_get(),
 -                                                      rqst->rq_qtime));
 -              __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
 -      ),
 -
 -      TP_printk("addr=%s flags=%s wakeup-us=%lu", __get_str(addr),
 -              show_svc_xprt_flags(__entry->flags), __entry->wakeup)
 -);
 -
  TRACE_EVENT(svc_wake_up,
        TP_PROTO(int pid),
  
@@@ -2006,6 -1920,31 +2005,6 @@@ TRACE_EVENT(svc_alloc_arg_err
        TP_printk("pages=%u", __entry->pages)
  );
  
 -TRACE_EVENT(svc_stats_latency,
 -      TP_PROTO(const struct svc_rqst *rqst),
 -
 -      TP_ARGS(rqst),
 -
 -      TP_STRUCT__entry(
 -              __field(u32, xid)
 -              __field(unsigned long, execute)
 -              __string(procedure, svc_proc_name(rqst))
 -              __string(addr, rqst->rq_xprt->xpt_remotebuf)
 -      ),
 -
 -      TP_fast_assign(
 -              __entry->xid = be32_to_cpu(rqst->rq_xid);
 -              __entry->execute = ktime_to_us(ktime_sub(ktime_get(),
 -                                                       rqst->rq_stime));
 -              __assign_str(procedure, svc_proc_name(rqst));
 -              __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
 -      ),
 -
 -      TP_printk("addr=%s xid=0x%08x proc=%s execute-us=%lu",
 -              __get_str(addr), __entry->xid, __get_str(procedure),
 -              __entry->execute)
 -);
 -
  DECLARE_EVENT_CLASS(svc_deferred_event,
        TP_PROTO(
                const struct svc_deferred_req *dr
diff --combined net/sunrpc/xprt.c
  /*
   * Local functions
   */
- static void    xprt_init(struct rpc_xprt *xprt, struct net *net);
+ static void   xprt_init(struct rpc_xprt *xprt, struct net *net);
  static __be32 xprt_alloc_xid(struct rpc_xprt *xprt);
- static void    xprt_destroy(struct rpc_xprt *xprt);
- static void    xprt_request_init(struct rpc_task *task);
+ static void   xprt_destroy(struct rpc_xprt *xprt);
+ static void   xprt_request_init(struct rpc_task *task);
+ static int    xprt_request_prepare(struct rpc_rqst *req);
  
  static DEFINE_SPINLOCK(xprt_list_lock);
  static LIST_HEAD(xprt_list);
@@@ -929,12 -930,7 +930,7 @@@ void xprt_connect(struct rpc_task *task
        if (!xprt_lock_write(xprt, task))
                return;
  
-       if (test_and_clear_bit(XPRT_CLOSE_WAIT, &xprt->state)) {
-               trace_xprt_disconnect_cleanup(xprt);
-               xprt->ops->close(xprt);
-       }
-       if (!xprt_connected(xprt)) {
+       if (!xprt_connected(xprt) && !test_bit(XPRT_CLOSE_WAIT, &xprt->state)) {
                task->tk_rqstp->rq_connect_cookie = xprt->connect_cookie;
                rpc_sleep_on_timeout(&xprt->pending, task, NULL,
                                xprt_request_timeout(task->tk_rqstp));
@@@ -1143,16 -1139,19 +1139,19 @@@ xprt_request_need_enqueue_receive(struc
   * @task: RPC task
   *
   */
- void
+ int
  xprt_request_enqueue_receive(struct rpc_task *task)
  {
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_xprt *xprt = req->rq_xprt;
+       int ret;
  
        if (!xprt_request_need_enqueue_receive(task, req))
-               return;
+               return 0;
  
-       xprt_request_prepare(task->tk_rqstp);
+       ret = xprt_request_prepare(task->tk_rqstp);
+       if (ret)
+               return ret;
        spin_lock(&xprt->queue_lock);
  
        /* Update the softirq receive buffer */
  
        /* Turn off autodisconnect */
        del_singleshot_timer_sync(&xprt->timer);
+       return 0;
  }
  
  /**
@@@ -1452,14 -1452,16 +1452,16 @@@ xprt_request_dequeue_xprt(struct rpc_ta
   *
   * Calls into the transport layer to do whatever is needed to prepare
   * the request for transmission or receive.
+  * Returns error, or zero.
   */
- void
+ static int
  xprt_request_prepare(struct rpc_rqst *req)
  {
        struct rpc_xprt *xprt = req->rq_xprt;
  
        if (xprt->ops->prepare_request)
-               xprt->ops->prepare_request(req);
+               return xprt->ops->prepare_request(req);
+       return 0;
  }
  
  /**
@@@ -1827,7 -1829,7 +1829,7 @@@ EXPORT_SYMBOL_GPL(xprt_alloc)
  
  void xprt_free(struct rpc_xprt *xprt)
  {
 -      put_net(xprt->xprt_net);
 +      put_net_track(xprt->xprt_net, &xprt->ns_tracker);
        xprt_free_all_slots(xprt);
        xprt_free_id(xprt);
        rpc_sysfs_xprt_destroy(xprt);
@@@ -2019,7 -2021,7 +2021,7 @@@ static void xprt_init(struct rpc_xprt *
  
        xprt_init_xid(xprt);
  
 -      xprt->xprt_net = get_net(net);
 +      xprt->xprt_net = get_net_track(net, &xprt->ns_tracker, GFP_KERNEL);
  }
  
  /**