Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 27 Jun 2010 16:04:02 +0000 (09:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 27 Jun 2010 16:04:02 +0000 (09:04 -0700)
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  NFSv4: Fix an embarassing typo in encode_attrs()
  NFSv4: Ensure that /proc/self/mountinfo displays the minor version number
  NFSv4.1: Ensure that we initialise the session when following a referral
  SUNRPC: Fix a re-entrancy bug in xs_tcp_read_calldir()
  nfs4 use mandatory attribute file type in nfs4_get_root

fs/nfs/client.c
fs/nfs/getroot.c
fs/nfs/nfs4xdr.c
fs/nfs/super.c
net/sunrpc/xprtsock.c

index 7ec9b34a59f8df96f376a60a13a3750e96ca766c..d25b5257b7a1a38380457804333a384cf47f3939 100644 (file)
@@ -1286,6 +1286,55 @@ static void nfs4_session_set_rwsize(struct nfs_server *server)
 #endif /* CONFIG_NFS_V4_1 */
 }
 
+static int nfs4_server_common_setup(struct nfs_server *server,
+               struct nfs_fh *mntfh)
+{
+       struct nfs_fattr *fattr;
+       int error;
+
+       BUG_ON(!server->nfs_client);
+       BUG_ON(!server->nfs_client->rpc_ops);
+       BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               return -ENOMEM;
+
+       /* We must ensure the session is initialised first */
+       error = nfs4_init_session(server);
+       if (error < 0)
+               goto out;
+
+       /* Probe the root fh to retrieve its FSID and filehandle */
+       error = nfs4_get_rootfh(server, mntfh);
+       if (error < 0)
+               goto out;
+
+       dprintk("Server FSID: %llx:%llx\n",
+                       (unsigned long long) server->fsid.major,
+                       (unsigned long long) server->fsid.minor);
+       dprintk("Mount FH: %d\n", mntfh->size);
+
+       nfs4_session_set_rwsize(server);
+
+       error = nfs_probe_fsinfo(server, mntfh, fattr);
+       if (error < 0)
+               goto out;
+
+       if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
+               server->namelen = NFS4_MAXNAMLEN;
+
+       spin_lock(&nfs_client_lock);
+       list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
+       list_add_tail(&server->master_link, &nfs_volume_list);
+       spin_unlock(&nfs_client_lock);
+
+       server->mount_time = jiffies;
+out:
+       nfs_free_fattr(fattr);
+       return error;
+}
+
 /*
  * Create a version 4 volume record
  */
@@ -1346,7 +1395,6 @@ error:
 struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
                                      struct nfs_fh *mntfh)
 {
-       struct nfs_fattr *fattr;
        struct nfs_server *server;
        int error;
 
@@ -1356,55 +1404,19 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
        if (!server)
                return ERR_PTR(-ENOMEM);
 
-       error = -ENOMEM;
-       fattr = nfs_alloc_fattr();
-       if (fattr == NULL)
-               goto error;
-
        /* set up the general RPC client */
        error = nfs4_init_server(server, data);
        if (error < 0)
                goto error;
 
-       BUG_ON(!server->nfs_client);
-       BUG_ON(!server->nfs_client->rpc_ops);
-       BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
-
-       error = nfs4_init_session(server);
-       if (error < 0)
-               goto error;
-
-       /* Probe the root fh to retrieve its FSID */
-       error = nfs4_get_rootfh(server, mntfh);
+       error = nfs4_server_common_setup(server, mntfh);
        if (error < 0)
                goto error;
 
-       dprintk("Server FSID: %llx:%llx\n",
-               (unsigned long long) server->fsid.major,
-               (unsigned long long) server->fsid.minor);
-       dprintk("Mount FH: %d\n", mntfh->size);
-
-       nfs4_session_set_rwsize(server);
-
-       error = nfs_probe_fsinfo(server, mntfh, fattr);
-       if (error < 0)
-               goto error;
-
-       if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
-               server->namelen = NFS4_MAXNAMLEN;
-
-       spin_lock(&nfs_client_lock);
-       list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
-       list_add_tail(&server->master_link, &nfs_volume_list);
-       spin_unlock(&nfs_client_lock);
-
-       server->mount_time = jiffies;
        dprintk("<-- nfs4_create_server() = %p\n", server);
-       nfs_free_fattr(fattr);
        return server;
 
 error:
-       nfs_free_fattr(fattr);
        nfs_free_server(server);
        dprintk("<-- nfs4_create_server() = error %d\n", error);
        return ERR_PTR(error);
@@ -1418,7 +1430,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 {
        struct nfs_client *parent_client;
        struct nfs_server *server, *parent_server;
-       struct nfs_fattr *fattr;
        int error;
 
        dprintk("--> nfs4_create_referral_server()\n");
@@ -1427,11 +1438,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        if (!server)
                return ERR_PTR(-ENOMEM);
 
-       error = -ENOMEM;
-       fattr = nfs_alloc_fattr();
-       if (fattr == NULL)
-               goto error;
-
        parent_server = NFS_SB(data->sb);
        parent_client = parent_server->nfs_client;
 
@@ -1456,40 +1462,14 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        if (error < 0)
                goto error;
 
-       BUG_ON(!server->nfs_client);
-       BUG_ON(!server->nfs_client->rpc_ops);
-       BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
-
-       /* Probe the root fh to retrieve its FSID and filehandle */
-       error = nfs4_get_rootfh(server, mntfh);
-       if (error < 0)
-               goto error;
-
-       /* probe the filesystem info for this server filesystem */
-       error = nfs_probe_fsinfo(server, mntfh, fattr);
+       error = nfs4_server_common_setup(server, mntfh);
        if (error < 0)
                goto error;
 
-       if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
-               server->namelen = NFS4_MAXNAMLEN;
-
-       dprintk("Referral FSID: %llx:%llx\n",
-               (unsigned long long) server->fsid.major,
-               (unsigned long long) server->fsid.minor);
-
-       spin_lock(&nfs_client_lock);
-       list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
-       list_add_tail(&server->master_link, &nfs_volume_list);
-       spin_unlock(&nfs_client_lock);
-
-       server->mount_time = jiffies;
-
-       nfs_free_fattr(fattr);
        dprintk("<-- nfs_create_referral_server() = %p\n", server);
        return server;
 
 error:
-       nfs_free_fattr(fattr);
        nfs_free_server(server);
        dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
        return ERR_PTR(error);
index 7428f7d6273bf2bd512c03e4419487e6deffc6fb..a70e446e1605fa43fb1b23b96418d8296773109f 100644 (file)
@@ -146,7 +146,7 @@ int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh)
                goto out;
        }
 
-       if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_MODE)
+       if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_TYPE)
                        || !S_ISDIR(fsinfo.fattr->mode)) {
                printk(KERN_ERR "nfs4_get_rootfh:"
                       " getroot encountered non-directory\n");
index 6bdef28efa33ff07561da0f92f492bc1b5d78046..65c8dae4b267f5622fb936dbaeb61f1f448c41a5 100644 (file)
@@ -862,8 +862,8 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
                bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
                *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
                *p++ = cpu_to_be32(0);
-               *p++ = cpu_to_be32(iap->ia_mtime.tv_sec);
-               *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
+               *p++ = cpu_to_be32(iap->ia_atime.tv_sec);
+               *p++ = cpu_to_be32(iap->ia_atime.tv_nsec);
        }
        else if (iap->ia_valid & ATTR_ATIME) {
                bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
index 04214fc5c30457ea290a2a15e0f87a5f184aea65..f9df16de4a56b84e18ddb3288f9606bd2cd2cd49 100644 (file)
@@ -570,6 +570,22 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
        nfs_show_mountd_netid(m, nfss, showdefaults);
 }
 
+#ifdef CONFIG_NFS_V4
+static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
+                                   int showdefaults)
+{
+       struct nfs_client *clp = nfss->nfs_client;
+
+       seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
+       seq_printf(m, ",minorversion=%u", clp->cl_minorversion);
+}
+#else
+static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
+                                   int showdefaults)
+{
+}
+#endif
+
 /*
  * Describe the mount options in force on this server representation
  */
@@ -631,11 +647,9 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
 
        if (version != 4)
                nfs_show_mountd_options(m, nfss, showdefaults);
+       else
+               nfs_show_nfsv4_options(m, nfss, showdefaults);
 
-#ifdef CONFIG_NFS_V4
-       if (clp->rpc_ops->version == 4)
-               seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
-#endif
        if (nfss->options & NFS_OPTION_FSCACHE)
                seq_printf(m, ",fsc");
 }
index 2a9675136c68e487adcf02849c54680ed7fd0e98..7ca65c7005ea5d2445ddddd617017ab3e6539f29 100644 (file)
@@ -210,7 +210,8 @@ struct sock_xprt {
         * State of TCP reply receive
         */
        __be32                  tcp_fraghdr,
-                               tcp_xid;
+                               tcp_xid,
+                               tcp_calldir;
 
        u32                     tcp_offset,
                                tcp_reclen;
@@ -927,7 +928,7 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport,
 {
        size_t len, used;
        u32 offset;
-       __be32  calldir;
+       char *p;
 
        /*
         * We want transport->tcp_offset to be 8 at the end of this routine
@@ -936,26 +937,33 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport,
         * transport->tcp_offset is 4 (after having already read the xid).
         */
        offset = transport->tcp_offset - sizeof(transport->tcp_xid);
-       len = sizeof(calldir) - offset;
+       len = sizeof(transport->tcp_calldir) - offset;
        dprintk("RPC:       reading CALL/REPLY flag (%Zu bytes)\n", len);
-       used = xdr_skb_read_bits(desc, &calldir, len);
+       p = ((char *) &transport->tcp_calldir) + offset;
+       used = xdr_skb_read_bits(desc, p, len);
        transport->tcp_offset += used;
        if (used != len)
                return;
        transport->tcp_flags &= ~TCP_RCV_READ_CALLDIR;
-       transport->tcp_flags |= TCP_RCV_COPY_CALLDIR;
-       transport->tcp_flags |= TCP_RCV_COPY_DATA;
        /*
         * We don't yet have the XDR buffer, so we will write the calldir
         * out after we get the buffer from the 'struct rpc_rqst'
         */
-       if (ntohl(calldir) == RPC_REPLY)
+       switch (ntohl(transport->tcp_calldir)) {
+       case RPC_REPLY:
+               transport->tcp_flags |= TCP_RCV_COPY_CALLDIR;
+               transport->tcp_flags |= TCP_RCV_COPY_DATA;
                transport->tcp_flags |= TCP_RPC_REPLY;
-       else
+               break;
+       case RPC_CALL:
+               transport->tcp_flags |= TCP_RCV_COPY_CALLDIR;
+               transport->tcp_flags |= TCP_RCV_COPY_DATA;
                transport->tcp_flags &= ~TCP_RPC_REPLY;
-       dprintk("RPC:       reading %s CALL/REPLY flag %08x\n",
-                       (transport->tcp_flags & TCP_RPC_REPLY) ?
-                               "reply for" : "request with", calldir);
+               break;
+       default:
+               dprintk("RPC:       invalid request message type\n");
+               xprt_force_disconnect(&transport->xprt);
+       }
        xs_tcp_check_fraghdr(transport);
 }
 
@@ -975,12 +983,10 @@ static inline void xs_tcp_read_common(struct rpc_xprt *xprt,
                /*
                 * Save the RPC direction in the XDR buffer
                 */
-               __be32  calldir = transport->tcp_flags & TCP_RPC_REPLY ?
-                                       htonl(RPC_REPLY) : 0;
-
                memcpy(rcvbuf->head[0].iov_base + transport->tcp_copied,
-                       &calldir, sizeof(calldir));
-               transport->tcp_copied += sizeof(calldir);
+                       &transport->tcp_calldir,
+                       sizeof(transport->tcp_calldir));
+               transport->tcp_copied += sizeof(transport->tcp_calldir);
                transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR;
        }