]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Aug 2010 22:45:23 +0000 (15:45 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Aug 2010 22:45:23 +0000 (15:45 -0700)
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  NFS: Fix an Oops in the NFSv4 atomic open code
  NFS: Fix the selection of security flavours in Kconfig
  NFS: fix the return value of nfs_file_fsync()
  rpcrdma: Fix SQ size calculation when memreg is FRMR
  xprtrdma: Do not truncate iova_start values in frmr registrations.
  nfs: Remove redundant NULL check upon kfree()
  nfs: Add "lookupcache" to displayed mount options
  NFS: allow close-to-open cache semantics to apply to root of NFS filesystem
  SUNRPC: fix NFS client over TCP hangs due to packet loss (Bug 16494)

fs/nfs/Kconfig
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/nfs4proc.c
fs/nfs/super.c
fs/nfsd/Kconfig
net/sunrpc/Kconfig
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtsock.c

index 26a510a7be0908023eaa5848002eced097f6e9dc..6c2aad49d7318054b57c22b58c6b4eaa0be50178 100644 (file)
@@ -63,7 +63,6 @@ config NFS_V3_ACL
 config NFS_V4
        bool "NFS client support for NFS version 4"
        depends on NFS_FS
-       select RPCSEC_GSS_KRB5
        help
          This option enables support for version 4 of the NFS protocol
          (RFC 3530) in the kernel's NFS client.
index 29539ceeb745f8d19fa57816127eceed2c5d989d..e257172d438c08afe374c99fe0e7c80af51efe6c 100644 (file)
@@ -140,6 +140,13 @@ nfs_opendir(struct inode *inode, struct file *filp)
 
        /* Call generic open code in order to cache credentials */
        res = nfs_open(inode, filp);
+       if (filp->f_path.dentry == filp->f_path.mnt->mnt_root) {
+               /* This is a mountpoint, so d_revalidate will never
+                * have been called, so we need to refresh the
+                * inode (for close-open consistency) ourselves.
+                */
+               __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+       }
        return res;
 }
 
@@ -1103,7 +1110,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
        if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
                goto no_open_dput;
        /* We can't create new files, or truncate existing ones here */
-       openflags &= ~(O_CREAT|O_TRUNC);
+       openflags &= ~(O_CREAT|O_EXCL|O_TRUNC);
 
        /*
         * Note: we're not holding inode->i_mutex and so may be racing with
index 2d141a74ae82ec722d1efb799de168824b593722..eb51bd6201da0cd361d8265b4c6b0e3edee50ec9 100644 (file)
@@ -323,7 +323,7 @@ nfs_file_fsync(struct file *file, int datasync)
        have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
        if (have_error)
                ret = xchg(&ctx->error, 0);
-       if (!ret)
+       if (!ret && status < 0)
                ret = status;
        return ret;
 }
index 7ffbb98ddec34c405bde993b0df16873162e21b6..089da5b5d20a1621b1142dbf75f415251ea4cb4b 100644 (file)
@@ -2036,7 +2036,8 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        struct rpc_cred *cred;
        struct nfs4_state *state;
        struct dentry *res;
-       fmode_t fmode = nd->intent.open.flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
+       int open_flags = nd->intent.open.flags;
+       fmode_t fmode = open_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
 
        if (nd->flags & LOOKUP_CREATE) {
                attr.ia_mode = nd->intent.open.create_mode;
@@ -2044,8 +2045,9 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
                if (!IS_POSIXACL(dir))
                        attr.ia_mode &= ~current_umask();
        } else {
+               open_flags &= ~O_EXCL;
                attr.ia_valid = 0;
-               BUG_ON(nd->intent.open.flags & O_CREAT);
+               BUG_ON(open_flags & O_CREAT);
        }
 
        cred = rpc_lookup_cred();
@@ -2054,7 +2056,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        parent = dentry->d_parent;
        /* Protect against concurrent sillydeletes */
        nfs_block_sillyrename(parent);
-       state = nfs4_do_open(dir, &path, fmode, nd->intent.open.flags, &attr, cred);
+       state = nfs4_do_open(dir, &path, fmode, open_flags, &attr, cred);
        put_rpccred(cred);
        if (IS_ERR(state)) {
                if (PTR_ERR(state) == -ENOENT) {
@@ -2273,8 +2275,7 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct
 out:
        if (page)
                __free_page(page);
-       if (locations)
-               kfree(locations);
+       kfree(locations);
        return status;
 }
 
index ee26316ad1f44eaf276299740c2a579635682fac..ec3966e4706b2f70d8709199f86456392a6e6584 100644 (file)
@@ -655,6 +655,13 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
 
        if (nfss->options & NFS_OPTION_FSCACHE)
                seq_printf(m, ",fsc");
+
+       if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) {
+               if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
+                       seq_printf(m, ",lookupcache=none");
+               else
+                       seq_printf(m, ",lookupcache=pos");
+       }
 }
 
 /*
index 503b9da159a3d3def44ca3cb5d752d1020eb1e50..95932f523aef2b2b7ef4686b8bb4a18383b4a395 100644 (file)
@@ -69,7 +69,6 @@ config NFSD_V4
        depends on NFSD && PROC_FS && EXPERIMENTAL
        select NFSD_V3
        select FS_POSIX_ACL
-       select RPCSEC_GSS_KRB5
        help
          This option enables support in your system's NFS server for
          version 4 of the NFS protocol (RFC 3530).
index 443c161eb8bdd0dd4c988a9bab0d6d387fe2f0e3..3376d7657185324adf2afef79984369bd16984ff 100644 (file)
@@ -18,10 +18,11 @@ config SUNRPC_XPRT_RDMA
          If unsure, say N.
 
 config RPCSEC_GSS_KRB5
-       tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
-       depends on SUNRPC && EXPERIMENTAL
+       tristate
+       depends on SUNRPC && CRYPTO
+       prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4)
+       default y
        select SUNRPC_GSS
-       select CRYPTO
        select CRYPTO_MD5
        select CRYPTO_DES
        select CRYPTO_CBC
@@ -34,7 +35,7 @@ config RPCSEC_GSS_KRB5
          available from http://linux-nfs.org/.  In addition, user-space
          Kerberos support should be installed.
 
-         If unsure, say N.
+         If unsure, say Y.
 
 config RPCSEC_GSS_SPKM3
        tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)"
index e5e28d1946a41a852a558caa83ca49c68265bed7..2ac3f6e8adffaf74a7480961997bb9fb97201e98 100644 (file)
@@ -249,6 +249,8 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
        req->rl_nchunks = nchunks;
 
        BUG_ON(nchunks == 0);
+       BUG_ON((r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
+              && (nchunks > 3));
 
        /*
         * finish off header. If write, marshal discrim and nchunks.
index 27015c6d8eb58311ed88264e86313fc3879ad0c2..5f4c7b3bc7114c597703c2739a427815c3be741c 100644 (file)
@@ -650,10 +650,22 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
        ep->rep_attr.cap.max_send_wr = cdata->max_requests;
        switch (ia->ri_memreg_strategy) {
        case RPCRDMA_FRMR:
-               /* Add room for frmr register and invalidate WRs */
-               ep->rep_attr.cap.max_send_wr *= 3;
-               if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
-                       return -EINVAL;
+               /* Add room for frmr register and invalidate WRs.
+                * 1. FRMR reg WR for head
+                * 2. FRMR invalidate WR for head
+                * 3. FRMR reg WR for pagelist
+                * 4. FRMR invalidate WR for pagelist
+                * 5. FRMR reg WR for tail
+                * 6. FRMR invalidate WR for tail
+                * 7. The RDMA_SEND WR
+                */
+               ep->rep_attr.cap.max_send_wr *= 7;
+               if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr) {
+                       cdata->max_requests = devattr.max_qp_wr / 7;
+                       if (!cdata->max_requests)
+                               return -EINVAL;
+                       ep->rep_attr.cap.max_send_wr = cdata->max_requests * 7;
+               }
                break;
        case RPCRDMA_MEMWINDOWS_ASYNC:
        case RPCRDMA_MEMWINDOWS:
@@ -1490,7 +1502,7 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
        memset(&frmr_wr, 0, sizeof frmr_wr);
        frmr_wr.opcode = IB_WR_FAST_REG_MR;
        frmr_wr.send_flags = 0;                 /* unsignaled */
-       frmr_wr.wr.fast_reg.iova_start = (unsigned long)seg1->mr_dma;
+       frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma;
        frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
        frmr_wr.wr.fast_reg.page_list_len = i;
        frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
index 49a62f0c4b87dc7f5a92223a7ecf67699e246e37..b6309db5622689deaf1c76a6acb1f6a09a02602c 100644 (file)
@@ -1305,10 +1305,11 @@ static void xs_tcp_state_change(struct sock *sk)
        if (!(xprt = xprt_from_sock(sk)))
                goto out;
        dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);
-       dprintk("RPC:       state %x conn %d dead %d zapped %d\n",
+       dprintk("RPC:       state %x conn %d dead %d zapped %d sk_shutdown %d\n",
                        sk->sk_state, xprt_connected(xprt),
                        sock_flag(sk, SOCK_DEAD),
-                       sock_flag(sk, SOCK_ZAPPED));
+                       sock_flag(sk, SOCK_ZAPPED),
+                       sk->sk_shutdown);
 
        switch (sk->sk_state) {
        case TCP_ESTABLISHED:
@@ -1779,10 +1780,25 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *tra
 {
        unsigned int state = transport->inet->sk_state;
 
-       if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED)
-               return;
-       if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT))
-               return;
+       if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) {
+               /* we don't need to abort the connection if the socket
+                * hasn't undergone a shutdown
+                */
+               if (transport->inet->sk_shutdown == 0)
+                       return;
+               dprintk("RPC:       %s: TCP_CLOSEd and sk_shutdown set to %d\n",
+                               __func__, transport->inet->sk_shutdown);
+       }
+       if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) {
+               /* we don't need to abort the connection if the socket
+                * hasn't undergone a shutdown
+                */
+               if (transport->inet->sk_shutdown == 0)
+                       return;
+               dprintk("RPC:       %s: ESTABLISHED/SYN_SENT "
+                               "sk_shutdown set to %d\n",
+                               __func__, transport->inet->sk_shutdown);
+       }
        xs_abort_connection(xprt, transport);
 }