Skip to content

Commit

Permalink
Merge tag 'nfsd-4.5' of git://linux-nfs.org/~bfields/linux
Browse files Browse the repository at this point in the history
Pull nfsd updates from Bruce Fields:
 "Smaller bugfixes and cleanup, including a fix for a failures of
  kerberized NFSv4.1 mounts, and Scott Mayhew's work addressing ACK
  storms that can affect some high-availability NFS setups"

* tag 'nfsd-4.5' of git://linux-nfs.org/~bfields/linux:
  nfsd: add new io class tracepoint
  nfsd: give up on CB_LAYOUTRECALLs after two lease periods
  nfsd: Fix nfsd leaks sunrpc module references
  lockd: constify nlmsvc_binding structure
  lockd: use to_delayed_work
  nfsd: use to_delayed_work
  Revert "svcrdma: Do not send XDR roundup bytes for a write chunk"
  lockd: Register callbacks on the inetaddr_chain and inet6addr_chain
  nfsd: Register callbacks on the inetaddr_chain and inet6addr_chain
  sunrpc: Add a function to close temporary transports immediately
  nfsd: don't base cl_cb_status on stale information
  nfsd4: fix gss-proxy 4.1 mounts for some AD principals
  nfsd: fix unlikely NULL deref in mach_creds_match
  nfsd: minor consolidation of mach_cred handling code
  nfsd: helper for dup of possibly NULL string
  svcrpc: move some initialization to common code
  nfsd: fix a warning message
  nfsd: constify nfsd4_callback_ops structure
  nfsd: recover: constify nfsd4_client_tracking_ops structures
  svcrdma: Do not send XDR roundup bytes for a write chunk
  • Loading branch information
Linus Torvalds committed Jan 15, 2016
2 parents c7b6c5f + 6e8b50d commit cc80fe0
Show file tree
Hide file tree
Showing 19 changed files with 370 additions and 57 deletions.
79 changes: 74 additions & 5 deletions fs/lockd/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/inetdevice.h>

#include <linux/sunrpc/types.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/svcsock.h>
#include <linux/sunrpc/svc_xprt.h>
#include <net/ip.h>
#include <net/addrconf.h>
#include <net/ipv6.h>
#include <linux/lockd/lockd.h>
#include <linux/nfs.h>

Expand All @@ -44,7 +48,7 @@

static struct svc_program nlmsvc_program;

struct nlmsvc_binding * nlmsvc_ops;
const struct nlmsvc_binding *nlmsvc_ops;
EXPORT_SYMBOL_GPL(nlmsvc_ops);

static DEFINE_MUTEX(nlmsvc_mutex);
Expand Down Expand Up @@ -90,8 +94,7 @@ static unsigned long get_lockd_grace_period(void)

static void grace_ender(struct work_struct *grace)
{
struct delayed_work *dwork = container_of(grace, struct delayed_work,
work);
struct delayed_work *dwork = to_delayed_work(grace);
struct lockd_net *ln = container_of(dwork, struct lockd_net,
grace_period_end);

Expand Down Expand Up @@ -279,6 +282,68 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net)
}
}

static int lockd_inetaddr_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
struct sockaddr_in sin;

if (event != NETDEV_DOWN)
goto out;

if (nlmsvc_rqst) {
dprintk("lockd_inetaddr_event: removed %pI4\n",
&ifa->ifa_local);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ifa->ifa_local;
svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
(struct sockaddr *)&sin);
}

out:
return NOTIFY_DONE;
}

static struct notifier_block lockd_inetaddr_notifier = {
.notifier_call = lockd_inetaddr_event,
};

#if IS_ENABLED(CONFIG_IPV6)
static int lockd_inet6addr_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
struct sockaddr_in6 sin6;

if (event != NETDEV_DOWN)
goto out;

if (nlmsvc_rqst) {
dprintk("lockd_inet6addr_event: removed %pI6\n", &ifa->addr);
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = ifa->addr;
svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
(struct sockaddr *)&sin6);
}

out:
return NOTIFY_DONE;
}

static struct notifier_block lockd_inet6addr_notifier = {
.notifier_call = lockd_inet6addr_event,
};
#endif

static void lockd_svc_exit_thread(void)
{
unregister_inetaddr_notifier(&lockd_inetaddr_notifier);
#if IS_ENABLED(CONFIG_IPV6)
unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
#endif
svc_exit_thread(nlmsvc_rqst);
}

static int lockd_start_svc(struct svc_serv *serv)
{
int error;
Expand Down Expand Up @@ -315,7 +380,7 @@ static int lockd_start_svc(struct svc_serv *serv)
return 0;

out_task:
svc_exit_thread(nlmsvc_rqst);
lockd_svc_exit_thread();
nlmsvc_task = NULL;
out_rqst:
nlmsvc_rqst = NULL;
Expand Down Expand Up @@ -360,6 +425,10 @@ static struct svc_serv *lockd_create_svc(void)
printk(KERN_WARNING "lockd_up: create service failed\n");
return ERR_PTR(-ENOMEM);
}
register_inetaddr_notifier(&lockd_inetaddr_notifier);
#if IS_ENABLED(CONFIG_IPV6)
register_inet6addr_notifier(&lockd_inet6addr_notifier);
#endif
dprintk("lockd_up: service created\n");
return serv;
}
Expand Down Expand Up @@ -428,7 +497,7 @@ lockd_down(struct net *net)
}
kthread_stop(nlmsvc_task);
dprintk("lockd_down: service stopped\n");
svc_exit_thread(nlmsvc_rqst);
lockd_svc_exit_thread();
dprintk("lockd_down: service destroyed\n");
nlmsvc_task = NULL;
nlmsvc_rqst = NULL;
Expand Down
2 changes: 1 addition & 1 deletion fs/nfsd/lockd.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ nlm_fclose(struct file *filp)
fput(filp);
}

static struct nlmsvc_binding nfsd_nlm_ops = {
static const struct nlmsvc_binding nfsd_nlm_ops = {
.fopen = nlm_fopen, /* open file for locking */
.fclose = nlm_fclose, /* close file */
};
Expand Down
2 changes: 1 addition & 1 deletion fs/nfsd/netns.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ struct nfsd_net {

struct file *rec_file;
bool in_grace;
struct nfsd4_client_tracking_ops *client_tracking_ops;
const struct nfsd4_client_tracking_ops *client_tracking_ops;

time_t nfsd4_lease;
time_t nfsd4_grace;
Expand Down
6 changes: 5 additions & 1 deletion fs/nfsd/nfs4callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -792,12 +792,16 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason)

static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
{
if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
return;
clp->cl_cb_state = NFSD4_CB_DOWN;
warn_no_callback_path(clp, reason);
}

static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason)
{
if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
return;
clp->cl_cb_state = NFSD4_CB_FAULT;
warn_no_callback_path(clp, reason);
}
Expand Down Expand Up @@ -1143,7 +1147,7 @@ nfsd4_run_cb_work(struct work_struct *work)
}

void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op)
const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op)
{
cb->cb_clp = clp;
cb->cb_msg.rpc_proc = &nfs4_cb_procedures[op];
Expand Down
39 changes: 27 additions & 12 deletions fs/nfsd/nfs4layouts.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct nfs4_layout {
static struct kmem_cache *nfs4_layout_cache;
static struct kmem_cache *nfs4_layout_stateid_cache;

static struct nfsd4_callback_ops nfsd4_cb_layout_ops;
static const struct nfsd4_callback_ops nfsd4_cb_layout_ops;
static const struct lock_manager_operations nfsd4_layouts_lm_ops;

const struct nfsd4_layout_ops *nfsd4_layout_ops[LAYOUT_TYPE_MAX] = {
Expand Down Expand Up @@ -624,24 +624,39 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
{
struct nfs4_layout_stateid *ls =
container_of(cb, struct nfs4_layout_stateid, ls_recall);
struct nfsd_net *nn;
ktime_t now, cutoff;
LIST_HEAD(reaplist);


switch (task->tk_status) {
case 0:
return 1;
case -NFS4ERR_DELAY:
/*
* Anything left? If not, then call it done. Note that we don't
* take the spinlock since this is an optimization and nothing
* should get added until the cb counter goes to zero.
*/
if (list_empty(&ls->ls_layouts))
return 1;

/* Poll the client until it's done with the layout */
now = ktime_get();
nn = net_generic(ls->ls_stid.sc_client->net, nfsd_net_id);

/* Client gets 2 lease periods to return it */
cutoff = ktime_add_ns(task->tk_start,
nn->nfsd4_lease * NSEC_PER_SEC * 2);

if (ktime_before(now, cutoff)) {
rpc_delay(task, HZ/100); /* 10 mili-seconds */
return 0;
}
/* Fallthrough */
case -NFS4ERR_NOMATCHING_LAYOUT:
trace_layout_recall_done(&ls->ls_stid.sc_stateid);
task->tk_status = 0;
return 1;
case -NFS4ERR_DELAY:
/* Poll the client until it's done with the layout */
/* FIXME: cap number of retries.
* The pnfs standard states that we need to only expire
* the client after at-least "lease time" .eg lease-time * 2
* when failing to communicate a recall
*/
rpc_delay(task, HZ/100); /* 10 mili-seconds */
return 0;
default:
/*
* Unknown error or non-responding client, we'll need to fence.
Expand All @@ -665,7 +680,7 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
nfs4_put_stid(&ls->ls_stid);
}

static struct nfsd4_callback_ops nfsd4_cb_layout_ops = {
static const struct nfsd4_callback_ops nfsd4_cb_layout_ops = {
.prepare = nfsd4_cb_layout_prepare,
.done = nfsd4_cb_layout_done,
.release = nfsd4_cb_layout_release,
Expand Down
6 changes: 3 additions & 3 deletions fs/nfsd/nfs4recover.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
return -ENOENT;
}

static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
static const struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
.init = nfsd4_legacy_tracking_init,
.exit = nfsd4_legacy_tracking_exit,
.create = nfsd4_create_clid_dir,
Expand Down Expand Up @@ -1050,7 +1050,7 @@ nfsd4_cld_grace_done(struct nfsd_net *nn)
printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
}

static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
.init = nfsd4_init_cld_pipe,
.exit = nfsd4_remove_cld_pipe,
.create = nfsd4_cld_create,
Expand Down Expand Up @@ -1394,7 +1394,7 @@ nfsd4_umh_cltrack_grace_done(struct nfsd_net *nn)
kfree(legacy);
}

static struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {
static const struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {
.init = nfsd4_umh_cltrack_init,
.exit = NULL,
.create = nfsd4_umh_cltrack_create,
Expand Down
Loading

0 comments on commit cc80fe0

Please sign in to comment.