Skip to content

Commit

Permalink
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/n…
Browse files Browse the repository at this point in the history
…fs-2.6

* '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
  • Loading branch information
Linus Torvalds committed Jun 27, 2010
2 parents bf29376 + d3f6baa commit e7865c2
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 94 deletions.
122 changes: 51 additions & 71 deletions fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -1346,7 +1395,6 @@ static int nfs4_init_server(struct nfs_server *server,
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;

Expand All @@ -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);
Expand All @@ -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");
Expand All @@ -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;

Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/getroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions fs/nfs/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 18 additions & 4 deletions fs/nfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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");
}
Expand Down
38 changes: 22 additions & 16 deletions net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
}

Expand All @@ -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;
}

Expand Down

0 comments on commit e7865c2

Please sign in to comment.