Commit f1d1c9fa authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'nfs-for-2.6.40' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* 'nfs-for-2.6.40' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  SUNRPC: Support for RPC over AF_LOCAL transports
  SUNRPC: Remove obsolete comment
  SUNRPC: Use AF_LOCAL for rpcbind upcalls
  SUNRPC: Clean up use of curly braces in switch cases
  NFS: Revert NFSROOT default mount options
  SUNRPC: Rename xs_encode_tcp_fragment_header()
  nfs,rcu: convert call_rcu(nfs_free_delegation_callback) to kfree_rcu()
  nfs41: Correct offset for LAYOUTCOMMIT
  NFS: nfs_update_inode: print current and new inode size in debug output
  NFSv4.1: Fix the handling of NFS4ERR_SEQ_MISORDERED errors
  NFSv4: Handle expired stateids when the lease is still valid
  SUNRPC: Deal with the lack of a SYN_SENT sk->sk_state_change callback...
parents 2ff55e98 176e21ee
...@@ -21,25 +21,13 @@ ...@@ -21,25 +21,13 @@
#include "delegation.h" #include "delegation.h"
#include "internal.h" #include "internal.h"
static void nfs_do_free_delegation(struct nfs_delegation *delegation)
{
kfree(delegation);
}
static void nfs_free_delegation_callback(struct rcu_head *head)
{
struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
nfs_do_free_delegation(delegation);
}
static void nfs_free_delegation(struct nfs_delegation *delegation) static void nfs_free_delegation(struct nfs_delegation *delegation)
{ {
if (delegation->cred) { if (delegation->cred) {
put_rpccred(delegation->cred); put_rpccred(delegation->cred);
delegation->cred = NULL; delegation->cred = NULL;
} }
call_rcu(&delegation->rcu, nfs_free_delegation_callback); kfree_rcu(delegation, rcu);
} }
/** /**
......
...@@ -1298,8 +1298,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1298,8 +1298,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
i_size_write(inode, new_isize); i_size_write(inode, new_isize);
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
} }
dprintk("NFS: isize change on server for file %s/%ld\n", dprintk("NFS: isize change on server for file %s/%ld "
inode->i_sb->s_id, inode->i_ino); "(%Ld to %Ld)\n",
inode->i_sb->s_id,
inode->i_ino,
(long long)cur_isize,
(long long)new_isize);
} }
} else } else
invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
......
...@@ -267,9 +267,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc ...@@ -267,9 +267,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
break; break;
nfs4_schedule_stateid_recovery(server, state); nfs4_schedule_stateid_recovery(server, state);
goto wait_on_recovery; goto wait_on_recovery;
case -NFS4ERR_EXPIRED:
if (state != NULL)
nfs4_schedule_stateid_recovery(server, state);
case -NFS4ERR_STALE_STATEID: case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_EXPIRED:
nfs4_schedule_lease_recovery(clp); nfs4_schedule_lease_recovery(clp);
goto wait_on_recovery; goto wait_on_recovery;
#if defined(CONFIG_NFS_V4_1) #if defined(CONFIG_NFS_V4_1)
...@@ -3670,9 +3672,11 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, ...@@ -3670,9 +3672,11 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
break; break;
nfs4_schedule_stateid_recovery(server, state); nfs4_schedule_stateid_recovery(server, state);
goto wait_on_recovery; goto wait_on_recovery;
case -NFS4ERR_EXPIRED:
if (state != NULL)
nfs4_schedule_stateid_recovery(server, state);
case -NFS4ERR_STALE_STATEID: case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_EXPIRED:
nfs4_schedule_lease_recovery(clp); nfs4_schedule_lease_recovery(clp);
goto wait_on_recovery; goto wait_on_recovery;
#if defined(CONFIG_NFS_V4_1) #if defined(CONFIG_NFS_V4_1)
...@@ -4543,6 +4547,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) ...@@ -4543,6 +4547,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
case -ESTALE: case -ESTALE:
goto out; goto out;
case -NFS4ERR_EXPIRED: case -NFS4ERR_EXPIRED:
nfs4_schedule_stateid_recovery(server, state);
case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_STALE_STATEID: case -NFS4ERR_STALE_STATEID:
nfs4_schedule_lease_recovery(server->nfs_client); nfs4_schedule_lease_recovery(server->nfs_client);
......
...@@ -1466,7 +1466,10 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) ...@@ -1466,7 +1466,10 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
#ifdef CONFIG_NFS_V4_1 #ifdef CONFIG_NFS_V4_1
void nfs4_schedule_session_recovery(struct nfs4_session *session) void nfs4_schedule_session_recovery(struct nfs4_session *session)
{ {
nfs4_schedule_lease_recovery(session->clp); struct nfs_client *clp = session->clp;
set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
nfs4_schedule_lease_recovery(clp);
} }
EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery); EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery);
...@@ -1549,6 +1552,7 @@ static int nfs4_reset_session(struct nfs_client *clp) ...@@ -1549,6 +1552,7 @@ static int nfs4_reset_session(struct nfs_client *clp)
status = nfs4_recovery_handle_error(clp, status); status = nfs4_recovery_handle_error(clp, status);
goto out; goto out;
} }
clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
/* create_session negotiated new slot table */ /* create_session negotiated new slot table */
clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
......
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
#define NFS_ROOT "/tftpboot/%s" #define NFS_ROOT "/tftpboot/%s"
/* Default NFSROOT mount options. */ /* Default NFSROOT mount options. */
#define NFS_DEF_OPTIONS "udp" #define NFS_DEF_OPTIONS "vers=2,udp,rsize=4096,wsize=4096"
/* Parameters passed from the kernel command line */ /* Parameters passed from the kernel command line */
static char nfs_root_parms[256] __initdata = ""; static char nfs_root_parms[256] __initdata = "";
......
...@@ -1009,7 +1009,7 @@ void ...@@ -1009,7 +1009,7 @@ void
pnfs_set_layoutcommit(struct nfs_write_data *wdata) pnfs_set_layoutcommit(struct nfs_write_data *wdata)
{ {
struct nfs_inode *nfsi = NFS_I(wdata->inode); struct nfs_inode *nfsi = NFS_I(wdata->inode);
loff_t end_pos = wdata->args.offset + wdata->res.count; loff_t end_pos = wdata->mds_offset + wdata->res.count;
bool mark_as_dirty = false; bool mark_as_dirty = false;
spin_lock(&nfsi->vfs_inode.i_lock); spin_lock(&nfsi->vfs_inode.i_lock);
......
...@@ -145,6 +145,7 @@ typedef __be32 rpc_fraghdr; ...@@ -145,6 +145,7 @@ typedef __be32 rpc_fraghdr;
#define RPCBIND_NETID_TCP "tcp" #define RPCBIND_NETID_TCP "tcp"
#define RPCBIND_NETID_UDP6 "udp6" #define RPCBIND_NETID_UDP6 "udp6"
#define RPCBIND_NETID_TCP6 "tcp6" #define RPCBIND_NETID_TCP6 "tcp6"
#define RPCBIND_NETID_LOCAL "local"
/* /*
* Note that RFC 1833 does not put any size restrictions on the * Note that RFC 1833 does not put any size restrictions on the
......
...@@ -141,7 +141,8 @@ enum xprt_transports { ...@@ -141,7 +141,8 @@ enum xprt_transports {
XPRT_TRANSPORT_UDP = IPPROTO_UDP, XPRT_TRANSPORT_UDP = IPPROTO_UDP,
XPRT_TRANSPORT_TCP = IPPROTO_TCP, XPRT_TRANSPORT_TCP = IPPROTO_TCP,
XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC, XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC,
XPRT_TRANSPORT_RDMA = 256 XPRT_TRANSPORT_RDMA = 256,
XPRT_TRANSPORT_LOCAL = 257,
}; };
struct rpc_xprt { struct rpc_xprt {
......
...@@ -13,10 +13,6 @@ ...@@ -13,10 +13,6 @@
* and need to be refreshed, or when a packet was damaged in transit. * and need to be refreshed, or when a packet was damaged in transit.
* This may be have to be moved to the VFS layer. * This may be have to be moved to the VFS layer.
* *
* NB: BSD uses a more intelligent approach to guessing when a request
* or reply has been lost by keeping the RTO estimate for each procedure.
* We currently make do with a constant timeout value.
*
* Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> * Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com>
* Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de>
*/ */
...@@ -32,7 +28,9 @@ ...@@ -32,7 +28,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/in.h>
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/un.h>
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/rpc_pipe_fs.h> #include <linux/sunrpc/rpc_pipe_fs.h>
...@@ -298,22 +296,27 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) ...@@ -298,22 +296,27 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
* up a string representation of the passed-in address. * up a string representation of the passed-in address.
*/ */
if (args->servername == NULL) { if (args->servername == NULL) {
servername[0] = '\0'; struct sockaddr_un *sun =
switch (args->address->sa_family) { (struct sockaddr_un *)args->address;
case AF_INET: {
struct sockaddr_in *sin = struct sockaddr_in *sin =
(struct sockaddr_in *)args->address; (struct sockaddr_in *)args->address;
struct sockaddr_in6 *sin6 =
(struct sockaddr_in6 *)args->address;
servername[0] = '\0';
switch (args->address->sa_family) {
case AF_LOCAL:
snprintf(servername, sizeof(servername), "%s",
sun->sun_path);
break;
case AF_INET:
snprintf(servername, sizeof(servername), "%pI4", snprintf(servername, sizeof(servername), "%pI4",
&sin->sin_addr.s_addr); &sin->sin_addr.s_addr);
break; break;
} case AF_INET6:
case AF_INET6: {
struct sockaddr_in6 *sin =
(struct sockaddr_in6 *)args->address;
snprintf(servername, sizeof(servername), "%pI6", snprintf(servername, sizeof(servername), "%pI6",
&sin->sin6_addr); &sin6->sin6_addr);
break; break;
}
default: default:
/* caller wants default server name, but /* caller wants default server name, but
* address family isn't recognized. */ * address family isn't recognized. */
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/un.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -32,6 +33,8 @@ ...@@ -32,6 +33,8 @@
# define RPCDBG_FACILITY RPCDBG_BIND # define RPCDBG_FACILITY RPCDBG_BIND
#endif #endif
#define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock"
#define RPCBIND_PROGRAM (100000u) #define RPCBIND_PROGRAM (100000u)
#define RPCBIND_PORT (111u) #define RPCBIND_PORT (111u)
...@@ -158,20 +161,69 @@ static void rpcb_map_release(void *data) ...@@ -158,20 +161,69 @@ static void rpcb_map_release(void *data)
kfree(map); kfree(map);
} }
static const struct sockaddr_in rpcb_inaddr_loopback = { /*
.sin_family = AF_INET, * Returns zero on success, otherwise a negative errno value
.sin_addr.s_addr = htonl(INADDR_LOOPBACK), * is returned.
.sin_port = htons(RPCBIND_PORT), */
}; static int rpcb_create_local_unix(void)
{
static const struct sockaddr_un rpcb_localaddr_rpcbind = {
.sun_family = AF_LOCAL,
.sun_path = RPCBIND_SOCK_PATHNAME,
};
struct rpc_create_args args = {
.net = &init_net,
.protocol = XPRT_TRANSPORT_LOCAL,
.address = (struct sockaddr *)&rpcb_localaddr_rpcbind,
.addrsize = sizeof(rpcb_localaddr_rpcbind),
.servername = "localhost",
.program = &rpcb_program,
.version = RPCBVERS_2,
.authflavor = RPC_AUTH_NULL,
};
struct rpc_clnt *clnt, *clnt4;
int result = 0;
/*
* Because we requested an RPC PING at transport creation time,
* this works only if the user space portmapper is rpcbind, and
* it's listening on AF_LOCAL on the named socket.
*/
clnt = rpc_create(&args);
if (IS_ERR(clnt)) {
dprintk("RPC: failed to create AF_LOCAL rpcbind "
"client (errno %ld).\n", PTR_ERR(clnt));
result = -PTR_ERR(clnt);
goto out;
}
clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
if (IS_ERR(clnt4)) {
dprintk("RPC: failed to bind second program to "
"rpcbind v4 client (errno %ld).\n",
PTR_ERR(clnt4));
clnt4 = NULL;
}
/* Protected by rpcb_create_local_mutex */
rpcb_local_clnt = clnt;
rpcb_local_clnt4 = clnt4;
static DEFINE_MUTEX(rpcb_create_local_mutex); out:
return result;
}
/* /*
* Returns zero on success, otherwise a negative errno value * Returns zero on success, otherwise a negative errno value
* is returned. * is returned.
*/ */
static int rpcb_create_local(void) static int rpcb_create_local_net(void)
{ {
static const struct sockaddr_in rpcb_inaddr_loopback = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
.sin_port = htons(RPCBIND_PORT),
};
struct rpc_create_args args = { struct rpc_create_args args = {
.net = &init_net, .net = &init_net,
.protocol = XPRT_TRANSPORT_TCP, .protocol = XPRT_TRANSPORT_TCP,
...@@ -186,13 +238,6 @@ static int rpcb_create_local(void) ...@@ -186,13 +238,6 @@ static int rpcb_create_local(void)
struct rpc_clnt *clnt, *clnt4; struct rpc_clnt *clnt, *clnt4;
int result = 0; int result = 0;
if (rpcb_local_clnt)
return result;
mutex_lock(&rpcb_create_local_mutex);
if (rpcb_local_clnt)
goto out;
clnt = rpc_create(&args); clnt = rpc_create(&args);
if (IS_ERR(clnt)) { if (IS_ERR(clnt)) {
dprintk("RPC: failed to create local rpcbind " dprintk("RPC: failed to create local rpcbind "
...@@ -214,9 +259,33 @@ static int rpcb_create_local(void) ...@@ -214,9 +259,33 @@ static int rpcb_create_local(void)
clnt4 = NULL; clnt4 = NULL;
} }
/* Protected by rpcb_create_local_mutex */
rpcb_local_clnt = clnt; rpcb_local_clnt = clnt;
rpcb_local_clnt4 = clnt4; rpcb_local_clnt4 = clnt4;
out:
return result;
}
/*
* Returns zero on success, otherwise a negative errno value
* is returned.
*/
static int rpcb_create_local(void)
{
static DEFINE_MUTEX(rpcb_create_local_mutex);
int result = 0;
if (rpcb_local_clnt)
return result;
mutex_lock(&rpcb_create_local_mutex);
if (rpcb_local_clnt)
goto out;
if (rpcb_create_local_unix() != 0)
result = rpcb_create_local_net();
out: out:
mutex_unlock(&rpcb_create_local_mutex); mutex_unlock(&rpcb_create_local_mutex);
return result; return result;
......
...@@ -942,6 +942,8 @@ static void svc_unregister(const struct svc_serv *serv) ...@@ -942,6 +942,8 @@ static void svc_unregister(const struct svc_serv *serv)
if (progp->pg_vers[i]->vs_hidden) if (progp->pg_vers[i]->vs_hidden)
continue; continue;
dprintk("svc: attempting to unregister %sv%u\n",
progp->pg_name, i);
__svc_unregister(progp->pg_prog, i, progp->pg_name); __svc_unregister(progp->pg_prog, i, progp->pg_name);
} }
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment