Merge tag 'nfsd-4.17' of git://linux-nfs.org/~bfields/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Apr 2018 02:15:29 +0000 (19:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Apr 2018 02:15:29 +0000 (19:15 -0700)
Pull nfsd updates from Bruce Fields:
 "Chuck Lever did a bunch of work on nfsd tracepoints, on RDMA, and on
  server xdr decoding (with an eye towards eliminating a data copy in
  the RDMA case).

  I did some refactoring of the delegation code in preparation for
  eliminating some delegation self-conflicts and implementing write
  delegations"

* tag 'nfsd-4.17' of git://linux-nfs.org/~bfields/linux: (40 commits)
  nfsd: fix incorrect umasks
  sunrpc: remove incorrect HMAC request initialization
  NFSD: Clean up legacy NFS SYMLINK argument XDR decoders
  NFSD: Clean up legacy NFS WRITE argument XDR decoders
  nfsd: Trace NFSv4 COMPOUND execution
  nfsd: Add I/O trace points in the NFSv4 read proc
  nfsd: Add I/O trace points in the NFSv4 write path
  nfsd: Add "nfsd_" to trace point names
  nfsd: Record request byte count, not count of vectors
  nfsd: Fix NFSD trace points
  svc: Report xprt dequeue latency
  sunrpc: Report per-RPC execution stats
  sunrpc: Re-purpose trace_svc_process
  sunrpc: Save remote presentation address in svc_xprt for trace events
  sunrpc: Simplify trace_svc_recv
  sunrpc: Simplify do_enqueue tracing
  sunrpc: Move trace_svc_xprt_dequeue()
  sunrpc: Update show_svc_xprt_flags() to include recently added flags
  svc: Simplify ->xpo_secure_port
  sunrpc: Remove unneeded pointer dereference
  ...

1  2 
net/sunrpc/cache.c
net/sunrpc/svcsock.c

diff --combined net/sunrpc/cache.c
index c536cc24b3d1f6073ac1df3fddf7915f783f24df,26582e27be6a1d8468fe09720efd92d856171880..cdda4744c9b154295cbff961a3f5a71eacb86983
@@@ -1450,8 -1450,8 +1450,8 @@@ static ssize_t write_flush(struct file 
                           struct cache_detail *cd)
  {
        char tbuf[20];
-       char *bp, *ep;
-       time_t then, now;
+       char *ep;
+       time_t now;
  
        if (*ppos || count > sizeof(tbuf)-1)
                return -EINVAL;
        simple_strtoul(tbuf, &ep, 0);
        if (*ep && *ep != '\n')
                return -EINVAL;
+       /* Note that while we check that 'buf' holds a valid number,
+        * we always ignore the value and just flush everything.
+        * Making use of the number leads to races.
+        */
  
-       bp = tbuf;
-       then = get_expiry(&bp);
        now = seconds_since_boot();
-       cd->nextcheck = now;
-       /* Can only set flush_time to 1 second beyond "now", or
-        * possibly 1 second beyond flushtime.  This is because
-        * flush_time never goes backwards so it mustn't get too far
-        * ahead of time.
+       /* Always flush everything, so behave like cache_purge()
+        * Do this by advancing flush_time to the current time,
+        * or by one second if it has already reached the current time.
+        * Newly added cache entries will always have ->last_refresh greater
+        * that ->flush_time, so they don't get flushed prematurely.
         */
-       if (then >= now) {
-               /* Want to flush everything, so behave like cache_purge() */
-               if (cd->flush_time >= now)
-                       now = cd->flush_time + 1;
-               then = now;
-       }
  
-       cd->flush_time = then;
+       if (cd->flush_time >= now)
+               now = cd->flush_time + 1;
+       cd->flush_time = now;
+       cd->nextcheck = now;
        cache_flush();
  
        *ppos += count;
@@@ -1621,20 -1621,20 +1621,20 @@@ static int create_cache_proc_entries(st
        if (cd->procfs == NULL)
                goto out_nomem;
  
 -      p = proc_create_data("flush", S_IFREG|S_IRUSR|S_IWUSR,
 +      p = proc_create_data("flush", S_IFREG | 0600,
                             cd->procfs, &cache_flush_operations_procfs, cd);
        if (p == NULL)
                goto out_nomem;
  
        if (cd->cache_request || cd->cache_parse) {
 -              p = proc_create_data("channel", S_IFREG|S_IRUSR|S_IWUSR,
 -                              cd->procfs, &cache_file_operations_procfs, cd);
 +              p = proc_create_data("channel", S_IFREG | 0600, cd->procfs,
 +                                   &cache_file_operations_procfs, cd);
                if (p == NULL)
                        goto out_nomem;
        }
        if (cd->cache_show) {
 -              p = proc_create_data("content", S_IFREG|S_IRUSR,
 -                              cd->procfs, &content_file_operations_procfs, cd);
 +              p = proc_create_data("content", S_IFREG | 0400, cd->procfs,
 +                                   &content_file_operations_procfs, cd);
                if (p == NULL)
                        goto out_nomem;
        }
diff --combined net/sunrpc/svcsock.c
index 08cd951aaeeae8e1d1cca3cfa90513699496c9bb,4ca1d92b531ace1dd3482bad515eca5c543174e6..5445145e639c9c82f8cc53f80b327da9260b0658
@@@ -391,9 -391,12 +391,12 @@@ static void svc_sock_setbufsize(struct 
        release_sock(sock->sk);
  }
  
- static int svc_sock_secure_port(struct svc_rqst *rqstp)
+ static void svc_sock_secure_port(struct svc_rqst *rqstp)
  {
-       return svc_port_is_privileged(svc_addr(rqstp));
+       if (svc_port_is_privileged(svc_addr(rqstp)))
+               set_bit(RQ_SECURE, &rqstp->rq_flags);
+       else
+               clear_bit(RQ_SECURE, &rqstp->rq_flags);
  }
  
  /*
@@@ -832,13 -835,12 +835,13 @@@ static struct svc_xprt *svc_tcp_accept(
        }
        set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
  
 -      err = kernel_getpeername(newsock, sin, &slen);
 +      err = kernel_getpeername(newsock, sin);
        if (err < 0) {
                net_warn_ratelimited("%s: peername failed (err %d)!\n",
                                     serv->sv_name, -err);
                goto failed;            /* aborted connection or whatever */
        }
 +      slen = err;
  
        /* Ideally, we would want to reject connections from unauthorized
         * hosts here, but when we get encryption, the IP of the host won't
        if (IS_ERR(newsvsk))
                goto failed;
        svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen);
 -      err = kernel_getsockname(newsock, sin, &slen);
 +      err = kernel_getsockname(newsock, sin);
 +      slen = err;
        if (unlikely(err < 0)) {
                dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err);
                slen = offsetof(struct sockaddr, sa_data);
@@@ -1309,6 -1310,7 +1312,7 @@@ static void svc_tcp_init(struct svc_soc
        set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
        if (sk->sk_state == TCP_LISTEN) {
                dprintk("setting up TCP socket for listening\n");
+               strcpy(svsk->sk_xprt.xpt_remotebuf, "listener");
                set_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags);
                sk->sk_data_ready = svc_tcp_listen_data_ready;
                set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
@@@ -1467,8 -1469,7 +1471,8 @@@ int svc_addsock(struct svc_serv *serv, 
                err = PTR_ERR(svsk);
                goto out;
        }
 -      if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0)
 +      salen = kernel_getsockname(svsk->sk_sock, sin);
 +      if (salen >= 0)
                svc_xprt_set_local(&svsk->sk_xprt, sin, salen);
        svc_add_new_perm_xprt(serv, &svsk->sk_xprt);
        return svc_one_sock_name(svsk, name_return, len);
@@@ -1542,10 -1543,10 +1546,10 @@@ static struct svc_xprt *svc_create_sock
        if (error < 0)
                goto bummer;
  
 -      newlen = len;
 -      error = kernel_getsockname(sock, newsin, &newlen);
 +      error = kernel_getsockname(sock, newsin);
        if (error < 0)
                goto bummer;
 +      newlen = error;
  
        if (protocol == IPPROTO_TCP) {
                if ((error = kernel_listen(sock, 64)) < 0)