2013-03-22 12:57:16

by Jeff Layton

[permalink] [raw]
Subject: [PATCH] nfsd: remove support for nfsdcld

...as advertised for 3.10.

Cc: Stanislav Kinsbursky <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
---
fs/nfsd/nfs4recover.c | 492 +----------------------------------------
fs/nfsd/nfsctl.c | 8 +-
fs/nfsd/nfsd.h | 5 -
include/uapi/linux/nfsd/Kbuild | 1 -
include/uapi/linux/nfsd/cld.h | 56 -----
5 files changed, 6 insertions(+), 556 deletions(-)
delete mode 100644 include/uapi/linux/nfsd/cld.h

diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 899ca26..4e7f47e 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -42,7 +42,6 @@
#include <net/net_namespace.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
#include <linux/sunrpc/clnt.h>
-#include <linux/nfsd/cld.h>

#include "nfsd.h"
#include "state.h"
@@ -625,426 +624,6 @@ static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
.grace_done = nfsd4_recdir_purge_old,
};

-/* Globals */
-#define NFSD_PIPE_DIR "nfsd"
-#define NFSD_CLD_PIPE "cld"
-
-/* per-net-ns structure for holding cld upcall info */
-struct cld_net {
- struct rpc_pipe *cn_pipe;
- spinlock_t cn_lock;
- struct list_head cn_list;
- unsigned int cn_xid;
-};
-
-struct cld_upcall {
- struct list_head cu_list;
- struct cld_net *cu_net;
- struct task_struct *cu_task;
- struct cld_msg cu_msg;
-};
-
-static int
-__cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
-{
- int ret;
- struct rpc_pipe_msg msg;
-
- memset(&msg, 0, sizeof(msg));
- msg.data = cmsg;
- msg.len = sizeof(*cmsg);
-
- /*
- * Set task state before we queue the upcall. That prevents
- * wake_up_process in the downcall from racing with schedule.
- */
- set_current_state(TASK_UNINTERRUPTIBLE);
- ret = rpc_queue_upcall(pipe, &msg);
- if (ret < 0) {
- set_current_state(TASK_RUNNING);
- goto out;
- }
-
- schedule();
- set_current_state(TASK_RUNNING);
-
- if (msg.errno < 0)
- ret = msg.errno;
-out:
- return ret;
-}
-
-static int
-cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
-{
- int ret;
-
- /*
- * -EAGAIN occurs when pipe is closed and reopened while there are
- * upcalls queued.
- */
- do {
- ret = __cld_pipe_upcall(pipe, cmsg);
- } while (ret == -EAGAIN);
-
- return ret;
-}
-
-static ssize_t
-cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
-{
- struct cld_upcall *tmp, *cup;
- struct cld_msg __user *cmsg = (struct cld_msg __user *)src;
- uint32_t xid;
- struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info,
- nfsd_net_id);
- struct cld_net *cn = nn->cld_net;
-
- if (mlen != sizeof(*cmsg)) {
- dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
- sizeof(*cmsg));
- return -EINVAL;
- }
-
- /* copy just the xid so we can try to find that */
- if (copy_from_user(&xid, &cmsg->cm_xid, sizeof(xid)) != 0) {
- dprintk("%s: error when copying xid from userspace", __func__);
- return -EFAULT;
- }
-
- /* walk the list and find corresponding xid */
- cup = NULL;
- spin_lock(&cn->cn_lock);
- list_for_each_entry(tmp, &cn->cn_list, cu_list) {
- if (get_unaligned(&tmp->cu_msg.cm_xid) == xid) {
- cup = tmp;
- list_del_init(&cup->cu_list);
- break;
- }
- }
- spin_unlock(&cn->cn_lock);
-
- /* couldn't find upcall? */
- if (!cup) {
- dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid);
- return -EINVAL;
- }
-
- if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
- return -EFAULT;
-
- wake_up_process(cup->cu_task);
- return mlen;
-}
-
-static void
-cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
-{
- struct cld_msg *cmsg = msg->data;
- struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
- cu_msg);
-
- /* errno >= 0 means we got a downcall */
- if (msg->errno >= 0)
- return;
-
- wake_up_process(cup->cu_task);
-}
-
-static const struct rpc_pipe_ops cld_upcall_ops = {
- .upcall = rpc_pipe_generic_upcall,
- .downcall = cld_pipe_downcall,
- .destroy_msg = cld_pipe_destroy_msg,
-};
-
-static struct dentry *
-nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
-{
- struct dentry *dir, *dentry;
-
- dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
- if (dir == NULL)
- return ERR_PTR(-ENOENT);
- dentry = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
- dput(dir);
- return dentry;
-}
-
-static void
-nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
-{
- if (pipe->dentry)
- rpc_unlink(pipe->dentry);
-}
-
-static struct dentry *
-nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
-{
- struct super_block *sb;
- struct dentry *dentry;
-
- sb = rpc_get_sb_net(net);
- if (!sb)
- return NULL;
- dentry = nfsd4_cld_register_sb(sb, pipe);
- rpc_put_sb_net(net);
- return dentry;
-}
-
-static void
-nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
-{
- struct super_block *sb;
-
- sb = rpc_get_sb_net(net);
- if (sb) {
- nfsd4_cld_unregister_sb(pipe);
- rpc_put_sb_net(net);
- }
-}
-
-/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
-static int
-nfsd4_init_cld_pipe(struct net *net)
-{
- int ret;
- struct dentry *dentry;
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
- struct cld_net *cn;
-
- if (nn->cld_net)
- return 0;
-
- cn = kzalloc(sizeof(*cn), GFP_KERNEL);
- if (!cn) {
- ret = -ENOMEM;
- goto err;
- }
-
- cn->cn_pipe = rpc_mkpipe_data(&cld_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
- if (IS_ERR(cn->cn_pipe)) {
- ret = PTR_ERR(cn->cn_pipe);
- goto err;
- }
- spin_lock_init(&cn->cn_lock);
- INIT_LIST_HEAD(&cn->cn_list);
-
- dentry = nfsd4_cld_register_net(net, cn->cn_pipe);
- if (IS_ERR(dentry)) {
- ret = PTR_ERR(dentry);
- goto err_destroy_data;
- }
-
- cn->cn_pipe->dentry = dentry;
- nn->cld_net = cn;
- return 0;
-
-err_destroy_data:
- rpc_destroy_pipe_data(cn->cn_pipe);
-err:
- kfree(cn);
- printk(KERN_ERR "NFSD: unable to create nfsdcld upcall pipe (%d)\n",
- ret);
- return ret;
-}
-
-static void
-nfsd4_remove_cld_pipe(struct net *net)
-{
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
- struct cld_net *cn = nn->cld_net;
-
- nfsd4_cld_unregister_net(net, cn->cn_pipe);
- rpc_destroy_pipe_data(cn->cn_pipe);
- kfree(nn->cld_net);
- nn->cld_net = NULL;
-}
-
-static struct cld_upcall *
-alloc_cld_upcall(struct cld_net *cn)
-{
- struct cld_upcall *new, *tmp;
-
- new = kzalloc(sizeof(*new), GFP_KERNEL);
- if (!new)
- return new;
-
- /* FIXME: hard cap on number in flight? */
-restart_search:
- spin_lock(&cn->cn_lock);
- list_for_each_entry(tmp, &cn->cn_list, cu_list) {
- if (tmp->cu_msg.cm_xid == cn->cn_xid) {
- cn->cn_xid++;
- spin_unlock(&cn->cn_lock);
- goto restart_search;
- }
- }
- new->cu_task = current;
- new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
- put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
- new->cu_net = cn;
- list_add(&new->cu_list, &cn->cn_list);
- spin_unlock(&cn->cn_lock);
-
- dprintk("%s: allocated xid %u\n", __func__, new->cu_msg.cm_xid);
-
- return new;
-}
-
-static void
-free_cld_upcall(struct cld_upcall *victim)
-{
- struct cld_net *cn = victim->cu_net;
-
- spin_lock(&cn->cn_lock);
- list_del(&victim->cu_list);
- spin_unlock(&cn->cn_lock);
- kfree(victim);
-}
-
-/* Ask daemon to create a new record */
-static void
-nfsd4_cld_create(struct nfs4_client *clp)
-{
- int ret;
- struct cld_upcall *cup;
- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
- struct cld_net *cn = nn->cld_net;
-
- /* Don't upcall if it's already stored */
- if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
- return;
-
- cup = alloc_cld_upcall(cn);
- if (!cup) {
- ret = -ENOMEM;
- goto out_err;
- }
-
- cup->cu_msg.cm_cmd = Cld_Create;
- cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
- memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
- clp->cl_name.len);
-
- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
- if (!ret) {
- ret = cup->cu_msg.cm_status;
- set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
- }
-
- free_cld_upcall(cup);
-out_err:
- if (ret)
- printk(KERN_ERR "NFSD: Unable to create client "
- "record on stable storage: %d\n", ret);
-}
-
-/* Ask daemon to create a new record */
-static void
-nfsd4_cld_remove(struct nfs4_client *clp)
-{
- int ret;
- struct cld_upcall *cup;
- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
- struct cld_net *cn = nn->cld_net;
-
- /* Don't upcall if it's already removed */
- if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
- return;
-
- cup = alloc_cld_upcall(cn);
- if (!cup) {
- ret = -ENOMEM;
- goto out_err;
- }
-
- cup->cu_msg.cm_cmd = Cld_Remove;
- cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
- memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
- clp->cl_name.len);
-
- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
- if (!ret) {
- ret = cup->cu_msg.cm_status;
- clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
- }
-
- free_cld_upcall(cup);
-out_err:
- if (ret)
- printk(KERN_ERR "NFSD: Unable to remove client "
- "record from stable storage: %d\n", ret);
-}
-
-/* Check for presence of a record, and update its timestamp */
-static int
-nfsd4_cld_check(struct nfs4_client *clp)
-{
- int ret;
- struct cld_upcall *cup;
- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
- struct cld_net *cn = nn->cld_net;
-
- /* Don't upcall if one was already stored during this grace pd */
- if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
- return 0;
-
- cup = alloc_cld_upcall(cn);
- if (!cup) {
- printk(KERN_ERR "NFSD: Unable to check client record on "
- "stable storage: %d\n", -ENOMEM);
- return -ENOMEM;
- }
-
- cup->cu_msg.cm_cmd = Cld_Check;
- cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
- memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
- clp->cl_name.len);
-
- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
- if (!ret) {
- ret = cup->cu_msg.cm_status;
- set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
- }
-
- free_cld_upcall(cup);
- return ret;
-}
-
-static void
-nfsd4_cld_grace_done(struct nfsd_net *nn, time_t boot_time)
-{
- int ret;
- struct cld_upcall *cup;
- struct cld_net *cn = nn->cld_net;
-
- cup = alloc_cld_upcall(cn);
- if (!cup) {
- ret = -ENOMEM;
- goto out_err;
- }
-
- cup->cu_msg.cm_cmd = Cld_GraceDone;
- cup->cu_msg.cm_u.cm_gracetime = (int64_t)boot_time;
- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
- if (!ret)
- ret = cup->cu_msg.cm_status;
-
- free_cld_upcall(cup);
-out_err:
- if (ret)
- printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
-}
-
-static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
- .init = nfsd4_init_cld_pipe,
- .exit = nfsd4_remove_cld_pipe,
- .create = nfsd4_cld_create,
- .remove = nfsd4_cld_remove,
- .check = nfsd4_cld_check,
- .grace_done = nfsd4_cld_grace_done,
-};
-
/* upcall via usermodehelper */
static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
@@ -1287,21 +866,14 @@ nfsd4_client_tracking_init(struct net *net)
* then use the legacy ops.
*/
nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
- status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
- if (!status) {
- status = S_ISDIR(path.dentry->d_inode->i_mode);
- path_put(&path);
- if (status)
- goto do_init;
- }
+ status = kern_path(nfs4_recoverydir(),
+ LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
+ if (status)
+ goto out_err;

- /* Finally, try to use nfsdcld */
- nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
- printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be "
- "removed in 3.10. Please transition to using "
- "nfsdcltrack.\n");
do_init:
status = nn->client_tracking_ops->init(net);
+out_err:
if (status) {
printk(KERN_WARNING "NFSD: Unable to initialize client "
"recovery tracking! (%d)\n", status);
@@ -1358,57 +930,3 @@ nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time)
nn->client_tracking_ops->grace_done(nn, boot_time);
}

-static int
-rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
-{
- struct super_block *sb = ptr;
- struct net *net = sb->s_fs_info;
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
- struct cld_net *cn = nn->cld_net;
- struct dentry *dentry;
- int ret = 0;
-
- if (!try_module_get(THIS_MODULE))
- return 0;
-
- if (!cn) {
- module_put(THIS_MODULE);
- return 0;
- }
-
- switch (event) {
- case RPC_PIPEFS_MOUNT:
- dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe);
- if (IS_ERR(dentry)) {
- ret = PTR_ERR(dentry);
- break;
- }
- cn->cn_pipe->dentry = dentry;
- break;
- case RPC_PIPEFS_UMOUNT:
- if (cn->cn_pipe->dentry)
- nfsd4_cld_unregister_sb(cn->cn_pipe);
- break;
- default:
- ret = -ENOTSUPP;
- break;
- }
- module_put(THIS_MODULE);
- return ret;
-}
-
-static struct notifier_block nfsd4_cld_block = {
- .notifier_call = rpc_pipefs_event,
-};
-
-int
-register_cld_notifier(void)
-{
- return rpc_pipefs_notifier_register(&nfsd4_cld_block);
-}
-
-void
-unregister_cld_notifier(void)
-{
- rpc_pipefs_notifier_unregister(&nfsd4_cld_block);
-}
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index a830f33..f0aeb93 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1163,12 +1163,9 @@ static int __init init_nfsd(void)
int retval;
printk(KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n");

- retval = register_cld_notifier();
- if (retval)
- return retval;
retval = register_pernet_subsys(&nfsd_net_ops);
if (retval < 0)
- goto out_unregister_notifier;
+ return retval;
retval = nfsd4_init_slabs();
if (retval)
goto out_unregister_pernet;
@@ -1201,8 +1198,6 @@ out_free_slabs:
nfsd4_free_slabs();
out_unregister_pernet:
unregister_pernet_subsys(&nfsd_net_ops);
-out_unregister_notifier:
- unregister_cld_notifier();
return retval;
}

@@ -1217,7 +1212,6 @@ static void __exit exit_nfsd(void)
nfsd_fault_inject_cleanup();
unregister_filesystem(&nfsd_fs_type);
unregister_pernet_subsys(&nfsd_net_ops);
- unregister_cld_notifier();
}

MODULE_AUTHOR("Olaf Kirch <[email protected]>");
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 07a473f..8eb2aac 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -365,17 +365,12 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
NFSD_WRITEABLE_ATTRS_WORD2

extern int nfsd4_is_junction(struct dentry *dentry);
-extern int register_cld_notifier(void);
-extern void unregister_cld_notifier(void);
#else /* CONFIG_NFSD_V4 */
static inline int nfsd4_is_junction(struct dentry *dentry)
{
return 0;
}

-#define register_cld_notifier() 0
-#define unregister_cld_notifier() do { } while(0)
-
#endif /* CONFIG_NFSD_V4 */

#endif /* LINUX_NFSD_NFSD_H */
diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
index c11bc40..88589ac 100644
--- a/include/uapi/linux/nfsd/Kbuild
+++ b/include/uapi/linux/nfsd/Kbuild
@@ -1,5 +1,4 @@
# UAPI Header export list
-header-y += cld.h
header-y += debug.h
header-y += export.h
header-y += nfsfh.h
diff --git a/include/uapi/linux/nfsd/cld.h b/include/uapi/linux/nfsd/cld.h
deleted file mode 100644
index f14a9ab..0000000
--- a/include/uapi/linux/nfsd/cld.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Upcall description for nfsdcld communication
- *
- * Copyright (c) 2012 Red Hat, Inc.
- * Author(s): Jeff Layton <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _NFSD_CLD_H
-#define _NFSD_CLD_H
-
-/* latest upcall version available */
-#define CLD_UPCALL_VERSION 1
-
-/* defined by RFC3530 */
-#define NFS4_OPAQUE_LIMIT 1024
-
-enum cld_command {
- Cld_Create, /* create a record for this cm_id */
- Cld_Remove, /* remove record of this cm_id */
- Cld_Check, /* is this cm_id allowed? */
- Cld_GraceDone, /* grace period is complete */
-};
-
-/* representation of long-form NFSv4 client ID */
-struct cld_name {
- uint16_t cn_len; /* length of cm_id */
- unsigned char cn_id[NFS4_OPAQUE_LIMIT]; /* client-provided */
-} __attribute__((packed));
-
-/* message struct for communication with userspace */
-struct cld_msg {
- uint8_t cm_vers; /* upcall version */
- uint8_t cm_cmd; /* upcall command */
- int16_t cm_status; /* return code */
- uint32_t cm_xid; /* transaction id */
- union {
- int64_t cm_gracetime; /* grace period start time */
- struct cld_name cm_name;
- } __attribute__((packed)) cm_u;
-} __attribute__((packed));
-
-#endif /* !_NFSD_CLD_H */
--
1.7.11.7



2013-04-01 07:55:36

by Stanislav Kinsbursky

[permalink] [raw]
Subject: Re: [PATCH] nfsd: remove support for nfsdcld

22.03.2013 16:57, Jeff Layton ?????:
> ...as advertised for 3.10.
>

It looks like UMH should be containerised as fast as possible, doesn't it?
Bruce, don't you know, how much time left before 3.10 merge window?

> Cc: Stanislav Kinsbursky <[email protected]>
> Signed-off-by: Jeff Layton <[email protected]>
> ---
> fs/nfsd/nfs4recover.c | 492 +----------------------------------------
> fs/nfsd/nfsctl.c | 8 +-
> fs/nfsd/nfsd.h | 5 -
> include/uapi/linux/nfsd/Kbuild | 1 -
> include/uapi/linux/nfsd/cld.h | 56 -----
> 5 files changed, 6 insertions(+), 556 deletions(-)
> delete mode 100644 include/uapi/linux/nfsd/cld.h
>
> diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
> index 899ca26..4e7f47e 100644
> --- a/fs/nfsd/nfs4recover.c
> +++ b/fs/nfsd/nfs4recover.c
> @@ -42,7 +42,6 @@
> #include <net/net_namespace.h>
> #include <linux/sunrpc/rpc_pipe_fs.h>
> #include <linux/sunrpc/clnt.h>
> -#include <linux/nfsd/cld.h>
>
> #include "nfsd.h"
> #include "state.h"
> @@ -625,426 +624,6 @@ static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
> .grace_done = nfsd4_recdir_purge_old,
> };
>
> -/* Globals */
> -#define NFSD_PIPE_DIR "nfsd"
> -#define NFSD_CLD_PIPE "cld"
> -
> -/* per-net-ns structure for holding cld upcall info */
> -struct cld_net {
> - struct rpc_pipe *cn_pipe;
> - spinlock_t cn_lock;
> - struct list_head cn_list;
> - unsigned int cn_xid;
> -};
> -
> -struct cld_upcall {
> - struct list_head cu_list;
> - struct cld_net *cu_net;
> - struct task_struct *cu_task;
> - struct cld_msg cu_msg;
> -};
> -
> -static int
> -__cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
> -{
> - int ret;
> - struct rpc_pipe_msg msg;
> -
> - memset(&msg, 0, sizeof(msg));
> - msg.data = cmsg;
> - msg.len = sizeof(*cmsg);
> -
> - /*
> - * Set task state before we queue the upcall. That prevents
> - * wake_up_process in the downcall from racing with schedule.
> - */
> - set_current_state(TASK_UNINTERRUPTIBLE);
> - ret = rpc_queue_upcall(pipe, &msg);
> - if (ret < 0) {
> - set_current_state(TASK_RUNNING);
> - goto out;
> - }
> -
> - schedule();
> - set_current_state(TASK_RUNNING);
> -
> - if (msg.errno < 0)
> - ret = msg.errno;
> -out:
> - return ret;
> -}
> -
> -static int
> -cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
> -{
> - int ret;
> -
> - /*
> - * -EAGAIN occurs when pipe is closed and reopened while there are
> - * upcalls queued.
> - */
> - do {
> - ret = __cld_pipe_upcall(pipe, cmsg);
> - } while (ret == -EAGAIN);
> -
> - return ret;
> -}
> -
> -static ssize_t
> -cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
> -{
> - struct cld_upcall *tmp, *cup;
> - struct cld_msg __user *cmsg = (struct cld_msg __user *)src;
> - uint32_t xid;
> - struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info,
> - nfsd_net_id);
> - struct cld_net *cn = nn->cld_net;
> -
> - if (mlen != sizeof(*cmsg)) {
> - dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
> - sizeof(*cmsg));
> - return -EINVAL;
> - }
> -
> - /* copy just the xid so we can try to find that */
> - if (copy_from_user(&xid, &cmsg->cm_xid, sizeof(xid)) != 0) {
> - dprintk("%s: error when copying xid from userspace", __func__);
> - return -EFAULT;
> - }
> -
> - /* walk the list and find corresponding xid */
> - cup = NULL;
> - spin_lock(&cn->cn_lock);
> - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
> - if (get_unaligned(&tmp->cu_msg.cm_xid) == xid) {
> - cup = tmp;
> - list_del_init(&cup->cu_list);
> - break;
> - }
> - }
> - spin_unlock(&cn->cn_lock);
> -
> - /* couldn't find upcall? */
> - if (!cup) {
> - dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid);
> - return -EINVAL;
> - }
> -
> - if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
> - return -EFAULT;
> -
> - wake_up_process(cup->cu_task);
> - return mlen;
> -}
> -
> -static void
> -cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
> -{
> - struct cld_msg *cmsg = msg->data;
> - struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
> - cu_msg);
> -
> - /* errno >= 0 means we got a downcall */
> - if (msg->errno >= 0)
> - return;
> -
> - wake_up_process(cup->cu_task);
> -}
> -
> -static const struct rpc_pipe_ops cld_upcall_ops = {
> - .upcall = rpc_pipe_generic_upcall,
> - .downcall = cld_pipe_downcall,
> - .destroy_msg = cld_pipe_destroy_msg,
> -};
> -
> -static struct dentry *
> -nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
> -{
> - struct dentry *dir, *dentry;
> -
> - dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
> - if (dir == NULL)
> - return ERR_PTR(-ENOENT);
> - dentry = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
> - dput(dir);
> - return dentry;
> -}
> -
> -static void
> -nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
> -{
> - if (pipe->dentry)
> - rpc_unlink(pipe->dentry);
> -}
> -
> -static struct dentry *
> -nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
> -{
> - struct super_block *sb;
> - struct dentry *dentry;
> -
> - sb = rpc_get_sb_net(net);
> - if (!sb)
> - return NULL;
> - dentry = nfsd4_cld_register_sb(sb, pipe);
> - rpc_put_sb_net(net);
> - return dentry;
> -}
> -
> -static void
> -nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
> -{
> - struct super_block *sb;
> -
> - sb = rpc_get_sb_net(net);
> - if (sb) {
> - nfsd4_cld_unregister_sb(pipe);
> - rpc_put_sb_net(net);
> - }
> -}
> -
> -/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
> -static int
> -nfsd4_init_cld_pipe(struct net *net)
> -{
> - int ret;
> - struct dentry *dentry;
> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> - struct cld_net *cn;
> -
> - if (nn->cld_net)
> - return 0;
> -
> - cn = kzalloc(sizeof(*cn), GFP_KERNEL);
> - if (!cn) {
> - ret = -ENOMEM;
> - goto err;
> - }
> -
> - cn->cn_pipe = rpc_mkpipe_data(&cld_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
> - if (IS_ERR(cn->cn_pipe)) {
> - ret = PTR_ERR(cn->cn_pipe);
> - goto err;
> - }
> - spin_lock_init(&cn->cn_lock);
> - INIT_LIST_HEAD(&cn->cn_list);
> -
> - dentry = nfsd4_cld_register_net(net, cn->cn_pipe);
> - if (IS_ERR(dentry)) {
> - ret = PTR_ERR(dentry);
> - goto err_destroy_data;
> - }
> -
> - cn->cn_pipe->dentry = dentry;
> - nn->cld_net = cn;
> - return 0;
> -
> -err_destroy_data:
> - rpc_destroy_pipe_data(cn->cn_pipe);
> -err:
> - kfree(cn);
> - printk(KERN_ERR "NFSD: unable to create nfsdcld upcall pipe (%d)\n",
> - ret);
> - return ret;
> -}
> -
> -static void
> -nfsd4_remove_cld_pipe(struct net *net)
> -{
> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> - struct cld_net *cn = nn->cld_net;
> -
> - nfsd4_cld_unregister_net(net, cn->cn_pipe);
> - rpc_destroy_pipe_data(cn->cn_pipe);
> - kfree(nn->cld_net);
> - nn->cld_net = NULL;
> -}
> -
> -static struct cld_upcall *
> -alloc_cld_upcall(struct cld_net *cn)
> -{
> - struct cld_upcall *new, *tmp;
> -
> - new = kzalloc(sizeof(*new), GFP_KERNEL);
> - if (!new)
> - return new;
> -
> - /* FIXME: hard cap on number in flight? */
> -restart_search:
> - spin_lock(&cn->cn_lock);
> - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
> - if (tmp->cu_msg.cm_xid == cn->cn_xid) {
> - cn->cn_xid++;
> - spin_unlock(&cn->cn_lock);
> - goto restart_search;
> - }
> - }
> - new->cu_task = current;
> - new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
> - put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
> - new->cu_net = cn;
> - list_add(&new->cu_list, &cn->cn_list);
> - spin_unlock(&cn->cn_lock);
> -
> - dprintk("%s: allocated xid %u\n", __func__, new->cu_msg.cm_xid);
> -
> - return new;
> -}
> -
> -static void
> -free_cld_upcall(struct cld_upcall *victim)
> -{
> - struct cld_net *cn = victim->cu_net;
> -
> - spin_lock(&cn->cn_lock);
> - list_del(&victim->cu_list);
> - spin_unlock(&cn->cn_lock);
> - kfree(victim);
> -}
> -
> -/* Ask daemon to create a new record */
> -static void
> -nfsd4_cld_create(struct nfs4_client *clp)
> -{
> - int ret;
> - struct cld_upcall *cup;
> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> - struct cld_net *cn = nn->cld_net;
> -
> - /* Don't upcall if it's already stored */
> - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> - return;
> -
> - cup = alloc_cld_upcall(cn);
> - if (!cup) {
> - ret = -ENOMEM;
> - goto out_err;
> - }
> -
> - cup->cu_msg.cm_cmd = Cld_Create;
> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> - clp->cl_name.len);
> -
> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> - if (!ret) {
> - ret = cup->cu_msg.cm_status;
> - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> - }
> -
> - free_cld_upcall(cup);
> -out_err:
> - if (ret)
> - printk(KERN_ERR "NFSD: Unable to create client "
> - "record on stable storage: %d\n", ret);
> -}
> -
> -/* Ask daemon to create a new record */
> -static void
> -nfsd4_cld_remove(struct nfs4_client *clp)
> -{
> - int ret;
> - struct cld_upcall *cup;
> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> - struct cld_net *cn = nn->cld_net;
> -
> - /* Don't upcall if it's already removed */
> - if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> - return;
> -
> - cup = alloc_cld_upcall(cn);
> - if (!cup) {
> - ret = -ENOMEM;
> - goto out_err;
> - }
> -
> - cup->cu_msg.cm_cmd = Cld_Remove;
> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> - clp->cl_name.len);
> -
> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> - if (!ret) {
> - ret = cup->cu_msg.cm_status;
> - clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> - }
> -
> - free_cld_upcall(cup);
> -out_err:
> - if (ret)
> - printk(KERN_ERR "NFSD: Unable to remove client "
> - "record from stable storage: %d\n", ret);
> -}
> -
> -/* Check for presence of a record, and update its timestamp */
> -static int
> -nfsd4_cld_check(struct nfs4_client *clp)
> -{
> - int ret;
> - struct cld_upcall *cup;
> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> - struct cld_net *cn = nn->cld_net;
> -
> - /* Don't upcall if one was already stored during this grace pd */
> - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> - return 0;
> -
> - cup = alloc_cld_upcall(cn);
> - if (!cup) {
> - printk(KERN_ERR "NFSD: Unable to check client record on "
> - "stable storage: %d\n", -ENOMEM);
> - return -ENOMEM;
> - }
> -
> - cup->cu_msg.cm_cmd = Cld_Check;
> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> - clp->cl_name.len);
> -
> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> - if (!ret) {
> - ret = cup->cu_msg.cm_status;
> - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> - }
> -
> - free_cld_upcall(cup);
> - return ret;
> -}
> -
> -static void
> -nfsd4_cld_grace_done(struct nfsd_net *nn, time_t boot_time)
> -{
> - int ret;
> - struct cld_upcall *cup;
> - struct cld_net *cn = nn->cld_net;
> -
> - cup = alloc_cld_upcall(cn);
> - if (!cup) {
> - ret = -ENOMEM;
> - goto out_err;
> - }
> -
> - cup->cu_msg.cm_cmd = Cld_GraceDone;
> - cup->cu_msg.cm_u.cm_gracetime = (int64_t)boot_time;
> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> - if (!ret)
> - ret = cup->cu_msg.cm_status;
> -
> - free_cld_upcall(cup);
> -out_err:
> - if (ret)
> - printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
> -}
> -
> -static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
> - .init = nfsd4_init_cld_pipe,
> - .exit = nfsd4_remove_cld_pipe,
> - .create = nfsd4_cld_create,
> - .remove = nfsd4_cld_remove,
> - .check = nfsd4_cld_check,
> - .grace_done = nfsd4_cld_grace_done,
> -};
> -
> /* upcall via usermodehelper */
> static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
> module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
> @@ -1287,21 +866,14 @@ nfsd4_client_tracking_init(struct net *net)
> * then use the legacy ops.
> */
> nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
> - status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
> - if (!status) {
> - status = S_ISDIR(path.dentry->d_inode->i_mode);
> - path_put(&path);
> - if (status)
> - goto do_init;
> - }
> + status = kern_path(nfs4_recoverydir(),
> + LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
> + if (status)
> + goto out_err;
>
> - /* Finally, try to use nfsdcld */
> - nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
> - printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be "
> - "removed in 3.10. Please transition to using "
> - "nfsdcltrack.\n");
> do_init:
> status = nn->client_tracking_ops->init(net);
> +out_err:
> if (status) {
> printk(KERN_WARNING "NFSD: Unable to initialize client "
> "recovery tracking! (%d)\n", status);
> @@ -1358,57 +930,3 @@ nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time)
> nn->client_tracking_ops->grace_done(nn, boot_time);
> }
>
> -static int
> -rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
> -{
> - struct super_block *sb = ptr;
> - struct net *net = sb->s_fs_info;
> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> - struct cld_net *cn = nn->cld_net;
> - struct dentry *dentry;
> - int ret = 0;
> -
> - if (!try_module_get(THIS_MODULE))
> - return 0;
> -
> - if (!cn) {
> - module_put(THIS_MODULE);
> - return 0;
> - }
> -
> - switch (event) {
> - case RPC_PIPEFS_MOUNT:
> - dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe);
> - if (IS_ERR(dentry)) {
> - ret = PTR_ERR(dentry);
> - break;
> - }
> - cn->cn_pipe->dentry = dentry;
> - break;
> - case RPC_PIPEFS_UMOUNT:
> - if (cn->cn_pipe->dentry)
> - nfsd4_cld_unregister_sb(cn->cn_pipe);
> - break;
> - default:
> - ret = -ENOTSUPP;
> - break;
> - }
> - module_put(THIS_MODULE);
> - return ret;
> -}
> -
> -static struct notifier_block nfsd4_cld_block = {
> - .notifier_call = rpc_pipefs_event,
> -};
> -
> -int
> -register_cld_notifier(void)
> -{
> - return rpc_pipefs_notifier_register(&nfsd4_cld_block);
> -}
> -
> -void
> -unregister_cld_notifier(void)
> -{
> - rpc_pipefs_notifier_unregister(&nfsd4_cld_block);
> -}
> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> index a830f33..f0aeb93 100644
> --- a/fs/nfsd/nfsctl.c
> +++ b/fs/nfsd/nfsctl.c
> @@ -1163,12 +1163,9 @@ static int __init init_nfsd(void)
> int retval;
> printk(KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n");
>
> - retval = register_cld_notifier();
> - if (retval)
> - return retval;
> retval = register_pernet_subsys(&nfsd_net_ops);
> if (retval < 0)
> - goto out_unregister_notifier;
> + return retval;
> retval = nfsd4_init_slabs();
> if (retval)
> goto out_unregister_pernet;
> @@ -1201,8 +1198,6 @@ out_free_slabs:
> nfsd4_free_slabs();
> out_unregister_pernet:
> unregister_pernet_subsys(&nfsd_net_ops);
> -out_unregister_notifier:
> - unregister_cld_notifier();
> return retval;
> }
>
> @@ -1217,7 +1212,6 @@ static void __exit exit_nfsd(void)
> nfsd_fault_inject_cleanup();
> unregister_filesystem(&nfsd_fs_type);
> unregister_pernet_subsys(&nfsd_net_ops);
> - unregister_cld_notifier();
> }
>
> MODULE_AUTHOR("Olaf Kirch <[email protected]>");
> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
> index 07a473f..8eb2aac 100644
> --- a/fs/nfsd/nfsd.h
> +++ b/fs/nfsd/nfsd.h
> @@ -365,17 +365,12 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
> NFSD_WRITEABLE_ATTRS_WORD2
>
> extern int nfsd4_is_junction(struct dentry *dentry);
> -extern int register_cld_notifier(void);
> -extern void unregister_cld_notifier(void);
> #else /* CONFIG_NFSD_V4 */
> static inline int nfsd4_is_junction(struct dentry *dentry)
> {
> return 0;
> }
>
> -#define register_cld_notifier() 0
> -#define unregister_cld_notifier() do { } while(0)
> -
> #endif /* CONFIG_NFSD_V4 */
>
> #endif /* LINUX_NFSD_NFSD_H */
> diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
> index c11bc40..88589ac 100644
> --- a/include/uapi/linux/nfsd/Kbuild
> +++ b/include/uapi/linux/nfsd/Kbuild
> @@ -1,5 +1,4 @@
> # UAPI Header export list
> -header-y += cld.h
> header-y += debug.h
> header-y += export.h
> header-y += nfsfh.h
> diff --git a/include/uapi/linux/nfsd/cld.h b/include/uapi/linux/nfsd/cld.h
> deleted file mode 100644
> index f14a9ab..0000000
> --- a/include/uapi/linux/nfsd/cld.h
> +++ /dev/null
> @@ -1,56 +0,0 @@
> -/*
> - * Upcall description for nfsdcld communication
> - *
> - * Copyright (c) 2012 Red Hat, Inc.
> - * Author(s): Jeff Layton <[email protected]>
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> - */
> -
> -#ifndef _NFSD_CLD_H
> -#define _NFSD_CLD_H
> -
> -/* latest upcall version available */
> -#define CLD_UPCALL_VERSION 1
> -
> -/* defined by RFC3530 */
> -#define NFS4_OPAQUE_LIMIT 1024
> -
> -enum cld_command {
> - Cld_Create, /* create a record for this cm_id */
> - Cld_Remove, /* remove record of this cm_id */
> - Cld_Check, /* is this cm_id allowed? */
> - Cld_GraceDone, /* grace period is complete */
> -};
> -
> -/* representation of long-form NFSv4 client ID */
> -struct cld_name {
> - uint16_t cn_len; /* length of cm_id */
> - unsigned char cn_id[NFS4_OPAQUE_LIMIT]; /* client-provided */
> -} __attribute__((packed));
> -
> -/* message struct for communication with userspace */
> -struct cld_msg {
> - uint8_t cm_vers; /* upcall version */
> - uint8_t cm_cmd; /* upcall command */
> - int16_t cm_status; /* return code */
> - uint32_t cm_xid; /* transaction id */
> - union {
> - int64_t cm_gracetime; /* grace period start time */
> - struct cld_name cm_name;
> - } __attribute__((packed)) cm_u;
> -} __attribute__((packed));
> -
> -#endif /* !_NFSD_CLD_H */
>


--
Best regards,
Stanislav Kinsbursky

2013-04-01 11:51:15

by Stanislav Kinsbursky

[permalink] [raw]
Subject: Re: [PATCH] nfsd: remove support for nfsdcld

01.04.2013 15:41, Jeff Layton ?????:
> On Mon, 1 Apr 2013 11:53:53 +0400
> Stanislav Kinsbursky <[email protected]> wrote:
>
>> 22.03.2013 16:57, Jeff Layton ?????:
>>> ...as advertised for 3.10.
>>>
>>
>> It looks like UMH should be containerised as fast as possible, doesn't it?
>> Bruce, don't you know, how much time left before 3.10 merge window?
>>
>
> Yes, that would be ideal. I'd estimate that we have about a month or so?
>
> Just from a quick look it doesn't look too hard to do this:
>
> Use call_usermodehelper_fns with an "init" function that changes the
> namespace(s) of the process before the do_execve call. The namespace
> info could be passed in via the "data" parm to call_usermodehelper_fns.
> Alternately, I guess you could add some namespace fields to struct
> subprocess_info...
>
> That said, I'm not clear on how you have to go about changing the
> namespace once the new process has been spawned...
>

Thanks, Jeff.

>
>>> Cc: Stanislav Kinsbursky <[email protected]>
>>> Signed-off-by: Jeff Layton <[email protected]>
>>> ---
>>> fs/nfsd/nfs4recover.c | 492 +----------------------------------------
>>> fs/nfsd/nfsctl.c | 8 +-
>>> fs/nfsd/nfsd.h | 5 -
>>> include/uapi/linux/nfsd/Kbuild | 1 -
>>> include/uapi/linux/nfsd/cld.h | 56 -----
>>> 5 files changed, 6 insertions(+), 556 deletions(-)
>>> delete mode 100644 include/uapi/linux/nfsd/cld.h
>>>
>>> diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
>>> index 899ca26..4e7f47e 100644
>>> --- a/fs/nfsd/nfs4recover.c
>>> +++ b/fs/nfsd/nfs4recover.c
>>> @@ -42,7 +42,6 @@
>>> #include <net/net_namespace.h>
>>> #include <linux/sunrpc/rpc_pipe_fs.h>
>>> #include <linux/sunrpc/clnt.h>
>>> -#include <linux/nfsd/cld.h>
>>>
>>> #include "nfsd.h"
>>> #include "state.h"
>>> @@ -625,426 +624,6 @@ static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
>>> .grace_done = nfsd4_recdir_purge_old,
>>> };
>>>
>>> -/* Globals */
>>> -#define NFSD_PIPE_DIR "nfsd"
>>> -#define NFSD_CLD_PIPE "cld"
>>> -
>>> -/* per-net-ns structure for holding cld upcall info */
>>> -struct cld_net {
>>> - struct rpc_pipe *cn_pipe;
>>> - spinlock_t cn_lock;
>>> - struct list_head cn_list;
>>> - unsigned int cn_xid;
>>> -};
>>> -
>>> -struct cld_upcall {
>>> - struct list_head cu_list;
>>> - struct cld_net *cu_net;
>>> - struct task_struct *cu_task;
>>> - struct cld_msg cu_msg;
>>> -};
>>> -
>>> -static int
>>> -__cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
>>> -{
>>> - int ret;
>>> - struct rpc_pipe_msg msg;
>>> -
>>> - memset(&msg, 0, sizeof(msg));
>>> - msg.data = cmsg;
>>> - msg.len = sizeof(*cmsg);
>>> -
>>> - /*
>>> - * Set task state before we queue the upcall. That prevents
>>> - * wake_up_process in the downcall from racing with schedule.
>>> - */
>>> - set_current_state(TASK_UNINTERRUPTIBLE);
>>> - ret = rpc_queue_upcall(pipe, &msg);
>>> - if (ret < 0) {
>>> - set_current_state(TASK_RUNNING);
>>> - goto out;
>>> - }
>>> -
>>> - schedule();
>>> - set_current_state(TASK_RUNNING);
>>> -
>>> - if (msg.errno < 0)
>>> - ret = msg.errno;
>>> -out:
>>> - return ret;
>>> -}
>>> -
>>> -static int
>>> -cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
>>> -{
>>> - int ret;
>>> -
>>> - /*
>>> - * -EAGAIN occurs when pipe is closed and reopened while there are
>>> - * upcalls queued.
>>> - */
>>> - do {
>>> - ret = __cld_pipe_upcall(pipe, cmsg);
>>> - } while (ret == -EAGAIN);
>>> -
>>> - return ret;
>>> -}
>>> -
>>> -static ssize_t
>>> -cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
>>> -{
>>> - struct cld_upcall *tmp, *cup;
>>> - struct cld_msg __user *cmsg = (struct cld_msg __user *)src;
>>> - uint32_t xid;
>>> - struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info,
>>> - nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - if (mlen != sizeof(*cmsg)) {
>>> - dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
>>> - sizeof(*cmsg));
>>> - return -EINVAL;
>>> - }
>>> -
>>> - /* copy just the xid so we can try to find that */
>>> - if (copy_from_user(&xid, &cmsg->cm_xid, sizeof(xid)) != 0) {
>>> - dprintk("%s: error when copying xid from userspace", __func__);
>>> - return -EFAULT;
>>> - }
>>> -
>>> - /* walk the list and find corresponding xid */
>>> - cup = NULL;
>>> - spin_lock(&cn->cn_lock);
>>> - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
>>> - if (get_unaligned(&tmp->cu_msg.cm_xid) == xid) {
>>> - cup = tmp;
>>> - list_del_init(&cup->cu_list);
>>> - break;
>>> - }
>>> - }
>>> - spin_unlock(&cn->cn_lock);
>>> -
>>> - /* couldn't find upcall? */
>>> - if (!cup) {
>>> - dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid);
>>> - return -EINVAL;
>>> - }
>>> -
>>> - if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
>>> - return -EFAULT;
>>> -
>>> - wake_up_process(cup->cu_task);
>>> - return mlen;
>>> -}
>>> -
>>> -static void
>>> -cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
>>> -{
>>> - struct cld_msg *cmsg = msg->data;
>>> - struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
>>> - cu_msg);
>>> -
>>> - /* errno >= 0 means we got a downcall */
>>> - if (msg->errno >= 0)
>>> - return;
>>> -
>>> - wake_up_process(cup->cu_task);
>>> -}
>>> -
>>> -static const struct rpc_pipe_ops cld_upcall_ops = {
>>> - .upcall = rpc_pipe_generic_upcall,
>>> - .downcall = cld_pipe_downcall,
>>> - .destroy_msg = cld_pipe_destroy_msg,
>>> -};
>>> -
>>> -static struct dentry *
>>> -nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
>>> -{
>>> - struct dentry *dir, *dentry;
>>> -
>>> - dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
>>> - if (dir == NULL)
>>> - return ERR_PTR(-ENOENT);
>>> - dentry = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
>>> - dput(dir);
>>> - return dentry;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
>>> -{
>>> - if (pipe->dentry)
>>> - rpc_unlink(pipe->dentry);
>>> -}
>>> -
>>> -static struct dentry *
>>> -nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
>>> -{
>>> - struct super_block *sb;
>>> - struct dentry *dentry;
>>> -
>>> - sb = rpc_get_sb_net(net);
>>> - if (!sb)
>>> - return NULL;
>>> - dentry = nfsd4_cld_register_sb(sb, pipe);
>>> - rpc_put_sb_net(net);
>>> - return dentry;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
>>> -{
>>> - struct super_block *sb;
>>> -
>>> - sb = rpc_get_sb_net(net);
>>> - if (sb) {
>>> - nfsd4_cld_unregister_sb(pipe);
>>> - rpc_put_sb_net(net);
>>> - }
>>> -}
>>> -
>>> -/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
>>> -static int
>>> -nfsd4_init_cld_pipe(struct net *net)
>>> -{
>>> - int ret;
>>> - struct dentry *dentry;
>>> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>>> - struct cld_net *cn;
>>> -
>>> - if (nn->cld_net)
>>> - return 0;
>>> -
>>> - cn = kzalloc(sizeof(*cn), GFP_KERNEL);
>>> - if (!cn) {
>>> - ret = -ENOMEM;
>>> - goto err;
>>> - }
>>> -
>>> - cn->cn_pipe = rpc_mkpipe_data(&cld_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
>>> - if (IS_ERR(cn->cn_pipe)) {
>>> - ret = PTR_ERR(cn->cn_pipe);
>>> - goto err;
>>> - }
>>> - spin_lock_init(&cn->cn_lock);
>>> - INIT_LIST_HEAD(&cn->cn_list);
>>> -
>>> - dentry = nfsd4_cld_register_net(net, cn->cn_pipe);
>>> - if (IS_ERR(dentry)) {
>>> - ret = PTR_ERR(dentry);
>>> - goto err_destroy_data;
>>> - }
>>> -
>>> - cn->cn_pipe->dentry = dentry;
>>> - nn->cld_net = cn;
>>> - return 0;
>>> -
>>> -err_destroy_data:
>>> - rpc_destroy_pipe_data(cn->cn_pipe);
>>> -err:
>>> - kfree(cn);
>>> - printk(KERN_ERR "NFSD: unable to create nfsdcld upcall pipe (%d)\n",
>>> - ret);
>>> - return ret;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_remove_cld_pipe(struct net *net)
>>> -{
>>> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - nfsd4_cld_unregister_net(net, cn->cn_pipe);
>>> - rpc_destroy_pipe_data(cn->cn_pipe);
>>> - kfree(nn->cld_net);
>>> - nn->cld_net = NULL;
>>> -}
>>> -
>>> -static struct cld_upcall *
>>> -alloc_cld_upcall(struct cld_net *cn)
>>> -{
>>> - struct cld_upcall *new, *tmp;
>>> -
>>> - new = kzalloc(sizeof(*new), GFP_KERNEL);
>>> - if (!new)
>>> - return new;
>>> -
>>> - /* FIXME: hard cap on number in flight? */
>>> -restart_search:
>>> - spin_lock(&cn->cn_lock);
>>> - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
>>> - if (tmp->cu_msg.cm_xid == cn->cn_xid) {
>>> - cn->cn_xid++;
>>> - spin_unlock(&cn->cn_lock);
>>> - goto restart_search;
>>> - }
>>> - }
>>> - new->cu_task = current;
>>> - new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
>>> - put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
>>> - new->cu_net = cn;
>>> - list_add(&new->cu_list, &cn->cn_list);
>>> - spin_unlock(&cn->cn_lock);
>>> -
>>> - dprintk("%s: allocated xid %u\n", __func__, new->cu_msg.cm_xid);
>>> -
>>> - return new;
>>> -}
>>> -
>>> -static void
>>> -free_cld_upcall(struct cld_upcall *victim)
>>> -{
>>> - struct cld_net *cn = victim->cu_net;
>>> -
>>> - spin_lock(&cn->cn_lock);
>>> - list_del(&victim->cu_list);
>>> - spin_unlock(&cn->cn_lock);
>>> - kfree(victim);
>>> -}
>>> -
>>> -/* Ask daemon to create a new record */
>>> -static void
>>> -nfsd4_cld_create(struct nfs4_client *clp)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - /* Don't upcall if it's already stored */
>>> - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
>>> - return;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - ret = -ENOMEM;
>>> - goto out_err;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_Create;
>>> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
>>> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
>>> - clp->cl_name.len);
>>> -
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret) {
>>> - ret = cup->cu_msg.cm_status;
>>> - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
>>> - }
>>> -
>>> - free_cld_upcall(cup);
>>> -out_err:
>>> - if (ret)
>>> - printk(KERN_ERR "NFSD: Unable to create client "
>>> - "record on stable storage: %d\n", ret);
>>> -}
>>> -
>>> -/* Ask daemon to create a new record */
>>> -static void
>>> -nfsd4_cld_remove(struct nfs4_client *clp)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - /* Don't upcall if it's already removed */
>>> - if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
>>> - return;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - ret = -ENOMEM;
>>> - goto out_err;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_Remove;
>>> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
>>> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
>>> - clp->cl_name.len);
>>> -
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret) {
>>> - ret = cup->cu_msg.cm_status;
>>> - clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
>>> - }
>>> -
>>> - free_cld_upcall(cup);
>>> -out_err:
>>> - if (ret)
>>> - printk(KERN_ERR "NFSD: Unable to remove client "
>>> - "record from stable storage: %d\n", ret);
>>> -}
>>> -
>>> -/* Check for presence of a record, and update its timestamp */
>>> -static int
>>> -nfsd4_cld_check(struct nfs4_client *clp)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - /* Don't upcall if one was already stored during this grace pd */
>>> - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
>>> - return 0;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - printk(KERN_ERR "NFSD: Unable to check client record on "
>>> - "stable storage: %d\n", -ENOMEM);
>>> - return -ENOMEM;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_Check;
>>> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
>>> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
>>> - clp->cl_name.len);
>>> -
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret) {
>>> - ret = cup->cu_msg.cm_status;
>>> - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
>>> - }
>>> -
>>> - free_cld_upcall(cup);
>>> - return ret;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_cld_grace_done(struct nfsd_net *nn, time_t boot_time)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - ret = -ENOMEM;
>>> - goto out_err;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_GraceDone;
>>> - cup->cu_msg.cm_u.cm_gracetime = (int64_t)boot_time;
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret)
>>> - ret = cup->cu_msg.cm_status;
>>> -
>>> - free_cld_upcall(cup);
>>> -out_err:
>>> - if (ret)
>>> - printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
>>> -}
>>> -
>>> -static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
>>> - .init = nfsd4_init_cld_pipe,
>>> - .exit = nfsd4_remove_cld_pipe,
>>> - .create = nfsd4_cld_create,
>>> - .remove = nfsd4_cld_remove,
>>> - .check = nfsd4_cld_check,
>>> - .grace_done = nfsd4_cld_grace_done,
>>> -};
>>> -
>>> /* upcall via usermodehelper */
>>> static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
>>> module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
>>> @@ -1287,21 +866,14 @@ nfsd4_client_tracking_init(struct net *net)
>>> * then use the legacy ops.
>>> */
>>> nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
>>> - status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
>>> - if (!status) {
>>> - status = S_ISDIR(path.dentry->d_inode->i_mode);
>>> - path_put(&path);
>>> - if (status)
>>> - goto do_init;
>>> - }
>>> + status = kern_path(nfs4_recoverydir(),
>>> + LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
>>> + if (status)
>>> + goto out_err;
>>>
>>> - /* Finally, try to use nfsdcld */
>>> - nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
>>> - printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be "
>>> - "removed in 3.10. Please transition to using "
>>> - "nfsdcltrack.\n");
>>> do_init:
>>> status = nn->client_tracking_ops->init(net);
>>> +out_err:
>>> if (status) {
>>> printk(KERN_WARNING "NFSD: Unable to initialize client "
>>> "recovery tracking! (%d)\n", status);
>>> @@ -1358,57 +930,3 @@ nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time)
>>> nn->client_tracking_ops->grace_done(nn, boot_time);
>>> }
>>>
>>> -static int
>>> -rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
>>> -{
>>> - struct super_block *sb = ptr;
>>> - struct net *net = sb->s_fs_info;
>>> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> - struct dentry *dentry;
>>> - int ret = 0;
>>> -
>>> - if (!try_module_get(THIS_MODULE))
>>> - return 0;
>>> -
>>> - if (!cn) {
>>> - module_put(THIS_MODULE);
>>> - return 0;
>>> - }
>>> -
>>> - switch (event) {
>>> - case RPC_PIPEFS_MOUNT:
>>> - dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe);
>>> - if (IS_ERR(dentry)) {
>>> - ret = PTR_ERR(dentry);
>>> - break;
>>> - }
>>> - cn->cn_pipe->dentry = dentry;
>>> - break;
>>> - case RPC_PIPEFS_UMOUNT:
>>> - if (cn->cn_pipe->dentry)
>>> - nfsd4_cld_unregister_sb(cn->cn_pipe);
>>> - break;
>>> - default:
>>> - ret = -ENOTSUPP;
>>> - break;
>>> - }
>>> - module_put(THIS_MODULE);
>>> - return ret;
>>> -}
>>> -
>>> -static struct notifier_block nfsd4_cld_block = {
>>> - .notifier_call = rpc_pipefs_event,
>>> -};
>>> -
>>> -int
>>> -register_cld_notifier(void)
>>> -{
>>> - return rpc_pipefs_notifier_register(&nfsd4_cld_block);
>>> -}
>>> -
>>> -void
>>> -unregister_cld_notifier(void)
>>> -{
>>> - rpc_pipefs_notifier_unregister(&nfsd4_cld_block);
>>> -}
>>> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
>>> index a830f33..f0aeb93 100644
>>> --- a/fs/nfsd/nfsctl.c
>>> +++ b/fs/nfsd/nfsctl.c
>>> @@ -1163,12 +1163,9 @@ static int __init init_nfsd(void)
>>> int retval;
>>> printk(KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n");
>>>
>>> - retval = register_cld_notifier();
>>> - if (retval)
>>> - return retval;
>>> retval = register_pernet_subsys(&nfsd_net_ops);
>>> if (retval < 0)
>>> - goto out_unregister_notifier;
>>> + return retval;
>>> retval = nfsd4_init_slabs();
>>> if (retval)
>>> goto out_unregister_pernet;
>>> @@ -1201,8 +1198,6 @@ out_free_slabs:
>>> nfsd4_free_slabs();
>>> out_unregister_pernet:
>>> unregister_pernet_subsys(&nfsd_net_ops);
>>> -out_unregister_notifier:
>>> - unregister_cld_notifier();
>>> return retval;
>>> }
>>>
>>> @@ -1217,7 +1212,6 @@ static void __exit exit_nfsd(void)
>>> nfsd_fault_inject_cleanup();
>>> unregister_filesystem(&nfsd_fs_type);
>>> unregister_pernet_subsys(&nfsd_net_ops);
>>> - unregister_cld_notifier();
>>> }
>>>
>>> MODULE_AUTHOR("Olaf Kirch <[email protected]>");
>>> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
>>> index 07a473f..8eb2aac 100644
>>> --- a/fs/nfsd/nfsd.h
>>> +++ b/fs/nfsd/nfsd.h
>>> @@ -365,17 +365,12 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
>>> NFSD_WRITEABLE_ATTRS_WORD2
>>>
>>> extern int nfsd4_is_junction(struct dentry *dentry);
>>> -extern int register_cld_notifier(void);
>>> -extern void unregister_cld_notifier(void);
>>> #else /* CONFIG_NFSD_V4 */
>>> static inline int nfsd4_is_junction(struct dentry *dentry)
>>> {
>>> return 0;
>>> }
>>>
>>> -#define register_cld_notifier() 0
>>> -#define unregister_cld_notifier() do { } while(0)
>>> -
>>> #endif /* CONFIG_NFSD_V4 */
>>>
>>> #endif /* LINUX_NFSD_NFSD_H */
>>> diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
>>> index c11bc40..88589ac 100644
>>> --- a/include/uapi/linux/nfsd/Kbuild
>>> +++ b/include/uapi/linux/nfsd/Kbuild
>>> @@ -1,5 +1,4 @@
>>> # UAPI Header export list
>>> -header-y += cld.h
>>> header-y += debug.h
>>> header-y += export.h
>>> header-y += nfsfh.h
>>> diff --git a/include/uapi/linux/nfsd/cld.h b/include/uapi/linux/nfsd/cld.h
>>> deleted file mode 100644
>>> index f14a9ab..0000000
>>> --- a/include/uapi/linux/nfsd/cld.h
>>> +++ /dev/null
>>> @@ -1,56 +0,0 @@
>>> -/*
>>> - * Upcall description for nfsdcld communication
>>> - *
>>> - * Copyright (c) 2012 Red Hat, Inc.
>>> - * Author(s): Jeff Layton <[email protected]>
>>> - *
>>> - * This program is free software; you can redistribute it and/or modify
>>> - * it under the terms of the GNU General Public License as published by
>>> - * the Free Software Foundation; either version 2 of the License, or
>>> - * (at your option) any later version.
>>> - *
>>> - * This program is distributed in the hope that it will be useful,
>>> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> - * GNU General Public License for more details.
>>> - *
>>> - * You should have received a copy of the GNU General Public License
>>> - * along with this program; if not, write to the Free Software
>>> - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>>> - */
>>> -
>>> -#ifndef _NFSD_CLD_H
>>> -#define _NFSD_CLD_H
>>> -
>>> -/* latest upcall version available */
>>> -#define CLD_UPCALL_VERSION 1
>>> -
>>> -/* defined by RFC3530 */
>>> -#define NFS4_OPAQUE_LIMIT 1024
>>> -
>>> -enum cld_command {
>>> - Cld_Create, /* create a record for this cm_id */
>>> - Cld_Remove, /* remove record of this cm_id */
>>> - Cld_Check, /* is this cm_id allowed? */
>>> - Cld_GraceDone, /* grace period is complete */
>>> -};
>>> -
>>> -/* representation of long-form NFSv4 client ID */
>>> -struct cld_name {
>>> - uint16_t cn_len; /* length of cm_id */
>>> - unsigned char cn_id[NFS4_OPAQUE_LIMIT]; /* client-provided */
>>> -} __attribute__((packed));
>>> -
>>> -/* message struct for communication with userspace */
>>> -struct cld_msg {
>>> - uint8_t cm_vers; /* upcall version */
>>> - uint8_t cm_cmd; /* upcall command */
>>> - int16_t cm_status; /* return code */
>>> - uint32_t cm_xid; /* transaction id */
>>> - union {
>>> - int64_t cm_gracetime; /* grace period start time */
>>> - struct cld_name cm_name;
>>> - } __attribute__((packed)) cm_u;
>>> -} __attribute__((packed));
>>> -
>>> -#endif /* !_NFSD_CLD_H */
>>>
>>
>>
>
>


--
Best regards,
Stanislav Kinsbursky

2013-04-01 11:41:53

by Jeff Layton

[permalink] [raw]
Subject: Re: [PATCH] nfsd: remove support for nfsdcld

On Mon, 1 Apr 2013 11:53:53 +0400
Stanislav Kinsbursky <[email protected]> wrote:

> 22.03.2013 16:57, Jeff Layton ?????:
> > ...as advertised for 3.10.
> >
>
> It looks like UMH should be containerised as fast as possible, doesn't it?
> Bruce, don't you know, how much time left before 3.10 merge window?
>

Yes, that would be ideal. I'd estimate that we have about a month or so?

Just from a quick look it doesn't look too hard to do this:

Use call_usermodehelper_fns with an "init" function that changes the
namespace(s) of the process before the do_execve call. The namespace
info could be passed in via the "data" parm to call_usermodehelper_fns.
Alternately, I guess you could add some namespace fields to struct
subprocess_info...

That said, I'm not clear on how you have to go about changing the
namespace once the new process has been spawned...


> > Cc: Stanislav Kinsbursky <[email protected]>
> > Signed-off-by: Jeff Layton <[email protected]>
> > ---
> > fs/nfsd/nfs4recover.c | 492 +----------------------------------------
> > fs/nfsd/nfsctl.c | 8 +-
> > fs/nfsd/nfsd.h | 5 -
> > include/uapi/linux/nfsd/Kbuild | 1 -
> > include/uapi/linux/nfsd/cld.h | 56 -----
> > 5 files changed, 6 insertions(+), 556 deletions(-)
> > delete mode 100644 include/uapi/linux/nfsd/cld.h
> >
> > diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
> > index 899ca26..4e7f47e 100644
> > --- a/fs/nfsd/nfs4recover.c
> > +++ b/fs/nfsd/nfs4recover.c
> > @@ -42,7 +42,6 @@
> > #include <net/net_namespace.h>
> > #include <linux/sunrpc/rpc_pipe_fs.h>
> > #include <linux/sunrpc/clnt.h>
> > -#include <linux/nfsd/cld.h>
> >
> > #include "nfsd.h"
> > #include "state.h"
> > @@ -625,426 +624,6 @@ static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
> > .grace_done = nfsd4_recdir_purge_old,
> > };
> >
> > -/* Globals */
> > -#define NFSD_PIPE_DIR "nfsd"
> > -#define NFSD_CLD_PIPE "cld"
> > -
> > -/* per-net-ns structure for holding cld upcall info */
> > -struct cld_net {
> > - struct rpc_pipe *cn_pipe;
> > - spinlock_t cn_lock;
> > - struct list_head cn_list;
> > - unsigned int cn_xid;
> > -};
> > -
> > -struct cld_upcall {
> > - struct list_head cu_list;
> > - struct cld_net *cu_net;
> > - struct task_struct *cu_task;
> > - struct cld_msg cu_msg;
> > -};
> > -
> > -static int
> > -__cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
> > -{
> > - int ret;
> > - struct rpc_pipe_msg msg;
> > -
> > - memset(&msg, 0, sizeof(msg));
> > - msg.data = cmsg;
> > - msg.len = sizeof(*cmsg);
> > -
> > - /*
> > - * Set task state before we queue the upcall. That prevents
> > - * wake_up_process in the downcall from racing with schedule.
> > - */
> > - set_current_state(TASK_UNINTERRUPTIBLE);
> > - ret = rpc_queue_upcall(pipe, &msg);
> > - if (ret < 0) {
> > - set_current_state(TASK_RUNNING);
> > - goto out;
> > - }
> > -
> > - schedule();
> > - set_current_state(TASK_RUNNING);
> > -
> > - if (msg.errno < 0)
> > - ret = msg.errno;
> > -out:
> > - return ret;
> > -}
> > -
> > -static int
> > -cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
> > -{
> > - int ret;
> > -
> > - /*
> > - * -EAGAIN occurs when pipe is closed and reopened while there are
> > - * upcalls queued.
> > - */
> > - do {
> > - ret = __cld_pipe_upcall(pipe, cmsg);
> > - } while (ret == -EAGAIN);
> > -
> > - return ret;
> > -}
> > -
> > -static ssize_t
> > -cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
> > -{
> > - struct cld_upcall *tmp, *cup;
> > - struct cld_msg __user *cmsg = (struct cld_msg __user *)src;
> > - uint32_t xid;
> > - struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info,
> > - nfsd_net_id);
> > - struct cld_net *cn = nn->cld_net;
> > -
> > - if (mlen != sizeof(*cmsg)) {
> > - dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
> > - sizeof(*cmsg));
> > - return -EINVAL;
> > - }
> > -
> > - /* copy just the xid so we can try to find that */
> > - if (copy_from_user(&xid, &cmsg->cm_xid, sizeof(xid)) != 0) {
> > - dprintk("%s: error when copying xid from userspace", __func__);
> > - return -EFAULT;
> > - }
> > -
> > - /* walk the list and find corresponding xid */
> > - cup = NULL;
> > - spin_lock(&cn->cn_lock);
> > - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
> > - if (get_unaligned(&tmp->cu_msg.cm_xid) == xid) {
> > - cup = tmp;
> > - list_del_init(&cup->cu_list);
> > - break;
> > - }
> > - }
> > - spin_unlock(&cn->cn_lock);
> > -
> > - /* couldn't find upcall? */
> > - if (!cup) {
> > - dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid);
> > - return -EINVAL;
> > - }
> > -
> > - if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
> > - return -EFAULT;
> > -
> > - wake_up_process(cup->cu_task);
> > - return mlen;
> > -}
> > -
> > -static void
> > -cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
> > -{
> > - struct cld_msg *cmsg = msg->data;
> > - struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
> > - cu_msg);
> > -
> > - /* errno >= 0 means we got a downcall */
> > - if (msg->errno >= 0)
> > - return;
> > -
> > - wake_up_process(cup->cu_task);
> > -}
> > -
> > -static const struct rpc_pipe_ops cld_upcall_ops = {
> > - .upcall = rpc_pipe_generic_upcall,
> > - .downcall = cld_pipe_downcall,
> > - .destroy_msg = cld_pipe_destroy_msg,
> > -};
> > -
> > -static struct dentry *
> > -nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
> > -{
> > - struct dentry *dir, *dentry;
> > -
> > - dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
> > - if (dir == NULL)
> > - return ERR_PTR(-ENOENT);
> > - dentry = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
> > - dput(dir);
> > - return dentry;
> > -}
> > -
> > -static void
> > -nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
> > -{
> > - if (pipe->dentry)
> > - rpc_unlink(pipe->dentry);
> > -}
> > -
> > -static struct dentry *
> > -nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
> > -{
> > - struct super_block *sb;
> > - struct dentry *dentry;
> > -
> > - sb = rpc_get_sb_net(net);
> > - if (!sb)
> > - return NULL;
> > - dentry = nfsd4_cld_register_sb(sb, pipe);
> > - rpc_put_sb_net(net);
> > - return dentry;
> > -}
> > -
> > -static void
> > -nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
> > -{
> > - struct super_block *sb;
> > -
> > - sb = rpc_get_sb_net(net);
> > - if (sb) {
> > - nfsd4_cld_unregister_sb(pipe);
> > - rpc_put_sb_net(net);
> > - }
> > -}
> > -
> > -/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
> > -static int
> > -nfsd4_init_cld_pipe(struct net *net)
> > -{
> > - int ret;
> > - struct dentry *dentry;
> > - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> > - struct cld_net *cn;
> > -
> > - if (nn->cld_net)
> > - return 0;
> > -
> > - cn = kzalloc(sizeof(*cn), GFP_KERNEL);
> > - if (!cn) {
> > - ret = -ENOMEM;
> > - goto err;
> > - }
> > -
> > - cn->cn_pipe = rpc_mkpipe_data(&cld_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
> > - if (IS_ERR(cn->cn_pipe)) {
> > - ret = PTR_ERR(cn->cn_pipe);
> > - goto err;
> > - }
> > - spin_lock_init(&cn->cn_lock);
> > - INIT_LIST_HEAD(&cn->cn_list);
> > -
> > - dentry = nfsd4_cld_register_net(net, cn->cn_pipe);
> > - if (IS_ERR(dentry)) {
> > - ret = PTR_ERR(dentry);
> > - goto err_destroy_data;
> > - }
> > -
> > - cn->cn_pipe->dentry = dentry;
> > - nn->cld_net = cn;
> > - return 0;
> > -
> > -err_destroy_data:
> > - rpc_destroy_pipe_data(cn->cn_pipe);
> > -err:
> > - kfree(cn);
> > - printk(KERN_ERR "NFSD: unable to create nfsdcld upcall pipe (%d)\n",
> > - ret);
> > - return ret;
> > -}
> > -
> > -static void
> > -nfsd4_remove_cld_pipe(struct net *net)
> > -{
> > - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> > - struct cld_net *cn = nn->cld_net;
> > -
> > - nfsd4_cld_unregister_net(net, cn->cn_pipe);
> > - rpc_destroy_pipe_data(cn->cn_pipe);
> > - kfree(nn->cld_net);
> > - nn->cld_net = NULL;
> > -}
> > -
> > -static struct cld_upcall *
> > -alloc_cld_upcall(struct cld_net *cn)
> > -{
> > - struct cld_upcall *new, *tmp;
> > -
> > - new = kzalloc(sizeof(*new), GFP_KERNEL);
> > - if (!new)
> > - return new;
> > -
> > - /* FIXME: hard cap on number in flight? */
> > -restart_search:
> > - spin_lock(&cn->cn_lock);
> > - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
> > - if (tmp->cu_msg.cm_xid == cn->cn_xid) {
> > - cn->cn_xid++;
> > - spin_unlock(&cn->cn_lock);
> > - goto restart_search;
> > - }
> > - }
> > - new->cu_task = current;
> > - new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
> > - put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
> > - new->cu_net = cn;
> > - list_add(&new->cu_list, &cn->cn_list);
> > - spin_unlock(&cn->cn_lock);
> > -
> > - dprintk("%s: allocated xid %u\n", __func__, new->cu_msg.cm_xid);
> > -
> > - return new;
> > -}
> > -
> > -static void
> > -free_cld_upcall(struct cld_upcall *victim)
> > -{
> > - struct cld_net *cn = victim->cu_net;
> > -
> > - spin_lock(&cn->cn_lock);
> > - list_del(&victim->cu_list);
> > - spin_unlock(&cn->cn_lock);
> > - kfree(victim);
> > -}
> > -
> > -/* Ask daemon to create a new record */
> > -static void
> > -nfsd4_cld_create(struct nfs4_client *clp)
> > -{
> > - int ret;
> > - struct cld_upcall *cup;
> > - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> > - struct cld_net *cn = nn->cld_net;
> > -
> > - /* Don't upcall if it's already stored */
> > - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> > - return;
> > -
> > - cup = alloc_cld_upcall(cn);
> > - if (!cup) {
> > - ret = -ENOMEM;
> > - goto out_err;
> > - }
> > -
> > - cup->cu_msg.cm_cmd = Cld_Create;
> > - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> > - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> > - clp->cl_name.len);
> > -
> > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> > - if (!ret) {
> > - ret = cup->cu_msg.cm_status;
> > - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> > - }
> > -
> > - free_cld_upcall(cup);
> > -out_err:
> > - if (ret)
> > - printk(KERN_ERR "NFSD: Unable to create client "
> > - "record on stable storage: %d\n", ret);
> > -}
> > -
> > -/* Ask daemon to create a new record */
> > -static void
> > -nfsd4_cld_remove(struct nfs4_client *clp)
> > -{
> > - int ret;
> > - struct cld_upcall *cup;
> > - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> > - struct cld_net *cn = nn->cld_net;
> > -
> > - /* Don't upcall if it's already removed */
> > - if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> > - return;
> > -
> > - cup = alloc_cld_upcall(cn);
> > - if (!cup) {
> > - ret = -ENOMEM;
> > - goto out_err;
> > - }
> > -
> > - cup->cu_msg.cm_cmd = Cld_Remove;
> > - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> > - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> > - clp->cl_name.len);
> > -
> > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> > - if (!ret) {
> > - ret = cup->cu_msg.cm_status;
> > - clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> > - }
> > -
> > - free_cld_upcall(cup);
> > -out_err:
> > - if (ret)
> > - printk(KERN_ERR "NFSD: Unable to remove client "
> > - "record from stable storage: %d\n", ret);
> > -}
> > -
> > -/* Check for presence of a record, and update its timestamp */
> > -static int
> > -nfsd4_cld_check(struct nfs4_client *clp)
> > -{
> > - int ret;
> > - struct cld_upcall *cup;
> > - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> > - struct cld_net *cn = nn->cld_net;
> > -
> > - /* Don't upcall if one was already stored during this grace pd */
> > - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> > - return 0;
> > -
> > - cup = alloc_cld_upcall(cn);
> > - if (!cup) {
> > - printk(KERN_ERR "NFSD: Unable to check client record on "
> > - "stable storage: %d\n", -ENOMEM);
> > - return -ENOMEM;
> > - }
> > -
> > - cup->cu_msg.cm_cmd = Cld_Check;
> > - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> > - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> > - clp->cl_name.len);
> > -
> > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> > - if (!ret) {
> > - ret = cup->cu_msg.cm_status;
> > - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> > - }
> > -
> > - free_cld_upcall(cup);
> > - return ret;
> > -}
> > -
> > -static void
> > -nfsd4_cld_grace_done(struct nfsd_net *nn, time_t boot_time)
> > -{
> > - int ret;
> > - struct cld_upcall *cup;
> > - struct cld_net *cn = nn->cld_net;
> > -
> > - cup = alloc_cld_upcall(cn);
> > - if (!cup) {
> > - ret = -ENOMEM;
> > - goto out_err;
> > - }
> > -
> > - cup->cu_msg.cm_cmd = Cld_GraceDone;
> > - cup->cu_msg.cm_u.cm_gracetime = (int64_t)boot_time;
> > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> > - if (!ret)
> > - ret = cup->cu_msg.cm_status;
> > -
> > - free_cld_upcall(cup);
> > -out_err:
> > - if (ret)
> > - printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
> > -}
> > -
> > -static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
> > - .init = nfsd4_init_cld_pipe,
> > - .exit = nfsd4_remove_cld_pipe,
> > - .create = nfsd4_cld_create,
> > - .remove = nfsd4_cld_remove,
> > - .check = nfsd4_cld_check,
> > - .grace_done = nfsd4_cld_grace_done,
> > -};
> > -
> > /* upcall via usermodehelper */
> > static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
> > module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
> > @@ -1287,21 +866,14 @@ nfsd4_client_tracking_init(struct net *net)
> > * then use the legacy ops.
> > */
> > nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
> > - status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
> > - if (!status) {
> > - status = S_ISDIR(path.dentry->d_inode->i_mode);
> > - path_put(&path);
> > - if (status)
> > - goto do_init;
> > - }
> > + status = kern_path(nfs4_recoverydir(),
> > + LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
> > + if (status)
> > + goto out_err;
> >
> > - /* Finally, try to use nfsdcld */
> > - nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
> > - printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be "
> > - "removed in 3.10. Please transition to using "
> > - "nfsdcltrack.\n");
> > do_init:
> > status = nn->client_tracking_ops->init(net);
> > +out_err:
> > if (status) {
> > printk(KERN_WARNING "NFSD: Unable to initialize client "
> > "recovery tracking! (%d)\n", status);
> > @@ -1358,57 +930,3 @@ nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time)
> > nn->client_tracking_ops->grace_done(nn, boot_time);
> > }
> >
> > -static int
> > -rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
> > -{
> > - struct super_block *sb = ptr;
> > - struct net *net = sb->s_fs_info;
> > - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> > - struct cld_net *cn = nn->cld_net;
> > - struct dentry *dentry;
> > - int ret = 0;
> > -
> > - if (!try_module_get(THIS_MODULE))
> > - return 0;
> > -
> > - if (!cn) {
> > - module_put(THIS_MODULE);
> > - return 0;
> > - }
> > -
> > - switch (event) {
> > - case RPC_PIPEFS_MOUNT:
> > - dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe);
> > - if (IS_ERR(dentry)) {
> > - ret = PTR_ERR(dentry);
> > - break;
> > - }
> > - cn->cn_pipe->dentry = dentry;
> > - break;
> > - case RPC_PIPEFS_UMOUNT:
> > - if (cn->cn_pipe->dentry)
> > - nfsd4_cld_unregister_sb(cn->cn_pipe);
> > - break;
> > - default:
> > - ret = -ENOTSUPP;
> > - break;
> > - }
> > - module_put(THIS_MODULE);
> > - return ret;
> > -}
> > -
> > -static struct notifier_block nfsd4_cld_block = {
> > - .notifier_call = rpc_pipefs_event,
> > -};
> > -
> > -int
> > -register_cld_notifier(void)
> > -{
> > - return rpc_pipefs_notifier_register(&nfsd4_cld_block);
> > -}
> > -
> > -void
> > -unregister_cld_notifier(void)
> > -{
> > - rpc_pipefs_notifier_unregister(&nfsd4_cld_block);
> > -}
> > diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> > index a830f33..f0aeb93 100644
> > --- a/fs/nfsd/nfsctl.c
> > +++ b/fs/nfsd/nfsctl.c
> > @@ -1163,12 +1163,9 @@ static int __init init_nfsd(void)
> > int retval;
> > printk(KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n");
> >
> > - retval = register_cld_notifier();
> > - if (retval)
> > - return retval;
> > retval = register_pernet_subsys(&nfsd_net_ops);
> > if (retval < 0)
> > - goto out_unregister_notifier;
> > + return retval;
> > retval = nfsd4_init_slabs();
> > if (retval)
> > goto out_unregister_pernet;
> > @@ -1201,8 +1198,6 @@ out_free_slabs:
> > nfsd4_free_slabs();
> > out_unregister_pernet:
> > unregister_pernet_subsys(&nfsd_net_ops);
> > -out_unregister_notifier:
> > - unregister_cld_notifier();
> > return retval;
> > }
> >
> > @@ -1217,7 +1212,6 @@ static void __exit exit_nfsd(void)
> > nfsd_fault_inject_cleanup();
> > unregister_filesystem(&nfsd_fs_type);
> > unregister_pernet_subsys(&nfsd_net_ops);
> > - unregister_cld_notifier();
> > }
> >
> > MODULE_AUTHOR("Olaf Kirch <[email protected]>");
> > diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
> > index 07a473f..8eb2aac 100644
> > --- a/fs/nfsd/nfsd.h
> > +++ b/fs/nfsd/nfsd.h
> > @@ -365,17 +365,12 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
> > NFSD_WRITEABLE_ATTRS_WORD2
> >
> > extern int nfsd4_is_junction(struct dentry *dentry);
> > -extern int register_cld_notifier(void);
> > -extern void unregister_cld_notifier(void);
> > #else /* CONFIG_NFSD_V4 */
> > static inline int nfsd4_is_junction(struct dentry *dentry)
> > {
> > return 0;
> > }
> >
> > -#define register_cld_notifier() 0
> > -#define unregister_cld_notifier() do { } while(0)
> > -
> > #endif /* CONFIG_NFSD_V4 */
> >
> > #endif /* LINUX_NFSD_NFSD_H */
> > diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
> > index c11bc40..88589ac 100644
> > --- a/include/uapi/linux/nfsd/Kbuild
> > +++ b/include/uapi/linux/nfsd/Kbuild
> > @@ -1,5 +1,4 @@
> > # UAPI Header export list
> > -header-y += cld.h
> > header-y += debug.h
> > header-y += export.h
> > header-y += nfsfh.h
> > diff --git a/include/uapi/linux/nfsd/cld.h b/include/uapi/linux/nfsd/cld.h
> > deleted file mode 100644
> > index f14a9ab..0000000
> > --- a/include/uapi/linux/nfsd/cld.h
> > +++ /dev/null
> > @@ -1,56 +0,0 @@
> > -/*
> > - * Upcall description for nfsdcld communication
> > - *
> > - * Copyright (c) 2012 Red Hat, Inc.
> > - * Author(s): Jeff Layton <[email protected]>
> > - *
> > - * This program is free software; you can redistribute it and/or modify
> > - * it under the terms of the GNU General Public License as published by
> > - * the Free Software Foundation; either version 2 of the License, or
> > - * (at your option) any later version.
> > - *
> > - * This program is distributed in the hope that it will be useful,
> > - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > - * GNU General Public License for more details.
> > - *
> > - * You should have received a copy of the GNU General Public License
> > - * along with this program; if not, write to the Free Software
> > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> > - */
> > -
> > -#ifndef _NFSD_CLD_H
> > -#define _NFSD_CLD_H
> > -
> > -/* latest upcall version available */
> > -#define CLD_UPCALL_VERSION 1
> > -
> > -/* defined by RFC3530 */
> > -#define NFS4_OPAQUE_LIMIT 1024
> > -
> > -enum cld_command {
> > - Cld_Create, /* create a record for this cm_id */
> > - Cld_Remove, /* remove record of this cm_id */
> > - Cld_Check, /* is this cm_id allowed? */
> > - Cld_GraceDone, /* grace period is complete */
> > -};
> > -
> > -/* representation of long-form NFSv4 client ID */
> > -struct cld_name {
> > - uint16_t cn_len; /* length of cm_id */
> > - unsigned char cn_id[NFS4_OPAQUE_LIMIT]; /* client-provided */
> > -} __attribute__((packed));
> > -
> > -/* message struct for communication with userspace */
> > -struct cld_msg {
> > - uint8_t cm_vers; /* upcall version */
> > - uint8_t cm_cmd; /* upcall command */
> > - int16_t cm_status; /* return code */
> > - uint32_t cm_xid; /* transaction id */
> > - union {
> > - int64_t cm_gracetime; /* grace period start time */
> > - struct cld_name cm_name;
> > - } __attribute__((packed)) cm_u;
> > -} __attribute__((packed));
> > -
> > -#endif /* !_NFSD_CLD_H */
> >
>
>


--
Jeff Layton <[email protected]>

2013-04-02 05:02:46

by Stanislav Kinsbursky

[permalink] [raw]
Subject: Re: [PATCH] nfsd: remove support for nfsdcld

01.04.2013 18:50, J. Bruce Fields пишет:
> On Mon, Apr 01, 2013 at 11:53:53AM +0400, Stanislav Kinsbursky wrote:
>> 22.03.2013 16:57, Jeff Layton пишет:
>>> ...as advertised for 3.10.
>>>
>>
>> It looks like UMH should be containerised as fast as possible, doesn't it?
>> Bruce, don't you know, how much time left before 3.10 merge window?
>
> "A few weeks" (http://lwn.net/Articles/545399/), but as usual it's good
> to have everything lined up in -next before then.
>
> Thanks for asking about this, that is indeed my one remaining concern
> before ripping this out....
>

Thanks, Bruce. I'll try to do it as fast as possible.
As Jeff mentioned, the task doesn't look too complicated.

> --b.
>
>>> Cc: Stanislav Kinsbursky <[email protected]>
>>> Signed-off-by: Jeff Layton <[email protected]>
>>> ---
>>> fs/nfsd/nfs4recover.c | 492 +----------------------------------------
>>> fs/nfsd/nfsctl.c | 8 +-
>>> fs/nfsd/nfsd.h | 5 -
>>> include/uapi/linux/nfsd/Kbuild | 1 -
>>> include/uapi/linux/nfsd/cld.h | 56 -----
>>> 5 files changed, 6 insertions(+), 556 deletions(-)
>>> delete mode 100644 include/uapi/linux/nfsd/cld.h
>>>
>>> diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
>>> index 899ca26..4e7f47e 100644
>>> --- a/fs/nfsd/nfs4recover.c
>>> +++ b/fs/nfsd/nfs4recover.c
>>> @@ -42,7 +42,6 @@
>>> #include <net/net_namespace.h>
>>> #include <linux/sunrpc/rpc_pipe_fs.h>
>>> #include <linux/sunrpc/clnt.h>
>>> -#include <linux/nfsd/cld.h>
>>>
>>> #include "nfsd.h"
>>> #include "state.h"
>>> @@ -625,426 +624,6 @@ static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
>>> .grace_done = nfsd4_recdir_purge_old,
>>> };
>>>
>>> -/* Globals */
>>> -#define NFSD_PIPE_DIR "nfsd"
>>> -#define NFSD_CLD_PIPE "cld"
>>> -
>>> -/* per-net-ns structure for holding cld upcall info */
>>> -struct cld_net {
>>> - struct rpc_pipe *cn_pipe;
>>> - spinlock_t cn_lock;
>>> - struct list_head cn_list;
>>> - unsigned int cn_xid;
>>> -};
>>> -
>>> -struct cld_upcall {
>>> - struct list_head cu_list;
>>> - struct cld_net *cu_net;
>>> - struct task_struct *cu_task;
>>> - struct cld_msg cu_msg;
>>> -};
>>> -
>>> -static int
>>> -__cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
>>> -{
>>> - int ret;
>>> - struct rpc_pipe_msg msg;
>>> -
>>> - memset(&msg, 0, sizeof(msg));
>>> - msg.data = cmsg;
>>> - msg.len = sizeof(*cmsg);
>>> -
>>> - /*
>>> - * Set task state before we queue the upcall. That prevents
>>> - * wake_up_process in the downcall from racing with schedule.
>>> - */
>>> - set_current_state(TASK_UNINTERRUPTIBLE);
>>> - ret = rpc_queue_upcall(pipe, &msg);
>>> - if (ret < 0) {
>>> - set_current_state(TASK_RUNNING);
>>> - goto out;
>>> - }
>>> -
>>> - schedule();
>>> - set_current_state(TASK_RUNNING);
>>> -
>>> - if (msg.errno < 0)
>>> - ret = msg.errno;
>>> -out:
>>> - return ret;
>>> -}
>>> -
>>> -static int
>>> -cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
>>> -{
>>> - int ret;
>>> -
>>> - /*
>>> - * -EAGAIN occurs when pipe is closed and reopened while there are
>>> - * upcalls queued.
>>> - */
>>> - do {
>>> - ret = __cld_pipe_upcall(pipe, cmsg);
>>> - } while (ret == -EAGAIN);
>>> -
>>> - return ret;
>>> -}
>>> -
>>> -static ssize_t
>>> -cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
>>> -{
>>> - struct cld_upcall *tmp, *cup;
>>> - struct cld_msg __user *cmsg = (struct cld_msg __user *)src;
>>> - uint32_t xid;
>>> - struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info,
>>> - nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - if (mlen != sizeof(*cmsg)) {
>>> - dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
>>> - sizeof(*cmsg));
>>> - return -EINVAL;
>>> - }
>>> -
>>> - /* copy just the xid so we can try to find that */
>>> - if (copy_from_user(&xid, &cmsg->cm_xid, sizeof(xid)) != 0) {
>>> - dprintk("%s: error when copying xid from userspace", __func__);
>>> - return -EFAULT;
>>> - }
>>> -
>>> - /* walk the list and find corresponding xid */
>>> - cup = NULL;
>>> - spin_lock(&cn->cn_lock);
>>> - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
>>> - if (get_unaligned(&tmp->cu_msg.cm_xid) == xid) {
>>> - cup = tmp;
>>> - list_del_init(&cup->cu_list);
>>> - break;
>>> - }
>>> - }
>>> - spin_unlock(&cn->cn_lock);
>>> -
>>> - /* couldn't find upcall? */
>>> - if (!cup) {
>>> - dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid);
>>> - return -EINVAL;
>>> - }
>>> -
>>> - if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
>>> - return -EFAULT;
>>> -
>>> - wake_up_process(cup->cu_task);
>>> - return mlen;
>>> -}
>>> -
>>> -static void
>>> -cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
>>> -{
>>> - struct cld_msg *cmsg = msg->data;
>>> - struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
>>> - cu_msg);
>>> -
>>> - /* errno >= 0 means we got a downcall */
>>> - if (msg->errno >= 0)
>>> - return;
>>> -
>>> - wake_up_process(cup->cu_task);
>>> -}
>>> -
>>> -static const struct rpc_pipe_ops cld_upcall_ops = {
>>> - .upcall = rpc_pipe_generic_upcall,
>>> - .downcall = cld_pipe_downcall,
>>> - .destroy_msg = cld_pipe_destroy_msg,
>>> -};
>>> -
>>> -static struct dentry *
>>> -nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
>>> -{
>>> - struct dentry *dir, *dentry;
>>> -
>>> - dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
>>> - if (dir == NULL)
>>> - return ERR_PTR(-ENOENT);
>>> - dentry = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
>>> - dput(dir);
>>> - return dentry;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
>>> -{
>>> - if (pipe->dentry)
>>> - rpc_unlink(pipe->dentry);
>>> -}
>>> -
>>> -static struct dentry *
>>> -nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
>>> -{
>>> - struct super_block *sb;
>>> - struct dentry *dentry;
>>> -
>>> - sb = rpc_get_sb_net(net);
>>> - if (!sb)
>>> - return NULL;
>>> - dentry = nfsd4_cld_register_sb(sb, pipe);
>>> - rpc_put_sb_net(net);
>>> - return dentry;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
>>> -{
>>> - struct super_block *sb;
>>> -
>>> - sb = rpc_get_sb_net(net);
>>> - if (sb) {
>>> - nfsd4_cld_unregister_sb(pipe);
>>> - rpc_put_sb_net(net);
>>> - }
>>> -}
>>> -
>>> -/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
>>> -static int
>>> -nfsd4_init_cld_pipe(struct net *net)
>>> -{
>>> - int ret;
>>> - struct dentry *dentry;
>>> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>>> - struct cld_net *cn;
>>> -
>>> - if (nn->cld_net)
>>> - return 0;
>>> -
>>> - cn = kzalloc(sizeof(*cn), GFP_KERNEL);
>>> - if (!cn) {
>>> - ret = -ENOMEM;
>>> - goto err;
>>> - }
>>> -
>>> - cn->cn_pipe = rpc_mkpipe_data(&cld_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
>>> - if (IS_ERR(cn->cn_pipe)) {
>>> - ret = PTR_ERR(cn->cn_pipe);
>>> - goto err;
>>> - }
>>> - spin_lock_init(&cn->cn_lock);
>>> - INIT_LIST_HEAD(&cn->cn_list);
>>> -
>>> - dentry = nfsd4_cld_register_net(net, cn->cn_pipe);
>>> - if (IS_ERR(dentry)) {
>>> - ret = PTR_ERR(dentry);
>>> - goto err_destroy_data;
>>> - }
>>> -
>>> - cn->cn_pipe->dentry = dentry;
>>> - nn->cld_net = cn;
>>> - return 0;
>>> -
>>> -err_destroy_data:
>>> - rpc_destroy_pipe_data(cn->cn_pipe);
>>> -err:
>>> - kfree(cn);
>>> - printk(KERN_ERR "NFSD: unable to create nfsdcld upcall pipe (%d)\n",
>>> - ret);
>>> - return ret;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_remove_cld_pipe(struct net *net)
>>> -{
>>> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - nfsd4_cld_unregister_net(net, cn->cn_pipe);
>>> - rpc_destroy_pipe_data(cn->cn_pipe);
>>> - kfree(nn->cld_net);
>>> - nn->cld_net = NULL;
>>> -}
>>> -
>>> -static struct cld_upcall *
>>> -alloc_cld_upcall(struct cld_net *cn)
>>> -{
>>> - struct cld_upcall *new, *tmp;
>>> -
>>> - new = kzalloc(sizeof(*new), GFP_KERNEL);
>>> - if (!new)
>>> - return new;
>>> -
>>> - /* FIXME: hard cap on number in flight? */
>>> -restart_search:
>>> - spin_lock(&cn->cn_lock);
>>> - list_for_each_entry(tmp, &cn->cn_list, cu_list) {
>>> - if (tmp->cu_msg.cm_xid == cn->cn_xid) {
>>> - cn->cn_xid++;
>>> - spin_unlock(&cn->cn_lock);
>>> - goto restart_search;
>>> - }
>>> - }
>>> - new->cu_task = current;
>>> - new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
>>> - put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
>>> - new->cu_net = cn;
>>> - list_add(&new->cu_list, &cn->cn_list);
>>> - spin_unlock(&cn->cn_lock);
>>> -
>>> - dprintk("%s: allocated xid %u\n", __func__, new->cu_msg.cm_xid);
>>> -
>>> - return new;
>>> -}
>>> -
>>> -static void
>>> -free_cld_upcall(struct cld_upcall *victim)
>>> -{
>>> - struct cld_net *cn = victim->cu_net;
>>> -
>>> - spin_lock(&cn->cn_lock);
>>> - list_del(&victim->cu_list);
>>> - spin_unlock(&cn->cn_lock);
>>> - kfree(victim);
>>> -}
>>> -
>>> -/* Ask daemon to create a new record */
>>> -static void
>>> -nfsd4_cld_create(struct nfs4_client *clp)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - /* Don't upcall if it's already stored */
>>> - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
>>> - return;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - ret = -ENOMEM;
>>> - goto out_err;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_Create;
>>> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
>>> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
>>> - clp->cl_name.len);
>>> -
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret) {
>>> - ret = cup->cu_msg.cm_status;
>>> - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
>>> - }
>>> -
>>> - free_cld_upcall(cup);
>>> -out_err:
>>> - if (ret)
>>> - printk(KERN_ERR "NFSD: Unable to create client "
>>> - "record on stable storage: %d\n", ret);
>>> -}
>>> -
>>> -/* Ask daemon to create a new record */
>>> -static void
>>> -nfsd4_cld_remove(struct nfs4_client *clp)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - /* Don't upcall if it's already removed */
>>> - if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
>>> - return;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - ret = -ENOMEM;
>>> - goto out_err;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_Remove;
>>> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
>>> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
>>> - clp->cl_name.len);
>>> -
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret) {
>>> - ret = cup->cu_msg.cm_status;
>>> - clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
>>> - }
>>> -
>>> - free_cld_upcall(cup);
>>> -out_err:
>>> - if (ret)
>>> - printk(KERN_ERR "NFSD: Unable to remove client "
>>> - "record from stable storage: %d\n", ret);
>>> -}
>>> -
>>> -/* Check for presence of a record, and update its timestamp */
>>> -static int
>>> -nfsd4_cld_check(struct nfs4_client *clp)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - /* Don't upcall if one was already stored during this grace pd */
>>> - if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
>>> - return 0;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - printk(KERN_ERR "NFSD: Unable to check client record on "
>>> - "stable storage: %d\n", -ENOMEM);
>>> - return -ENOMEM;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_Check;
>>> - cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
>>> - memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
>>> - clp->cl_name.len);
>>> -
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret) {
>>> - ret = cup->cu_msg.cm_status;
>>> - set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
>>> - }
>>> -
>>> - free_cld_upcall(cup);
>>> - return ret;
>>> -}
>>> -
>>> -static void
>>> -nfsd4_cld_grace_done(struct nfsd_net *nn, time_t boot_time)
>>> -{
>>> - int ret;
>>> - struct cld_upcall *cup;
>>> - struct cld_net *cn = nn->cld_net;
>>> -
>>> - cup = alloc_cld_upcall(cn);
>>> - if (!cup) {
>>> - ret = -ENOMEM;
>>> - goto out_err;
>>> - }
>>> -
>>> - cup->cu_msg.cm_cmd = Cld_GraceDone;
>>> - cup->cu_msg.cm_u.cm_gracetime = (int64_t)boot_time;
>>> - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
>>> - if (!ret)
>>> - ret = cup->cu_msg.cm_status;
>>> -
>>> - free_cld_upcall(cup);
>>> -out_err:
>>> - if (ret)
>>> - printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
>>> -}
>>> -
>>> -static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
>>> - .init = nfsd4_init_cld_pipe,
>>> - .exit = nfsd4_remove_cld_pipe,
>>> - .create = nfsd4_cld_create,
>>> - .remove = nfsd4_cld_remove,
>>> - .check = nfsd4_cld_check,
>>> - .grace_done = nfsd4_cld_grace_done,
>>> -};
>>> -
>>> /* upcall via usermodehelper */
>>> static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
>>> module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
>>> @@ -1287,21 +866,14 @@ nfsd4_client_tracking_init(struct net *net)
>>> * then use the legacy ops.
>>> */
>>> nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
>>> - status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
>>> - if (!status) {
>>> - status = S_ISDIR(path.dentry->d_inode->i_mode);
>>> - path_put(&path);
>>> - if (status)
>>> - goto do_init;
>>> - }
>>> + status = kern_path(nfs4_recoverydir(),
>>> + LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
>>> + if (status)
>>> + goto out_err;
>>>
>>> - /* Finally, try to use nfsdcld */
>>> - nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
>>> - printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be "
>>> - "removed in 3.10. Please transition to using "
>>> - "nfsdcltrack.\n");
>>> do_init:
>>> status = nn->client_tracking_ops->init(net);
>>> +out_err:
>>> if (status) {
>>> printk(KERN_WARNING "NFSD: Unable to initialize client "
>>> "recovery tracking! (%d)\n", status);
>>> @@ -1358,57 +930,3 @@ nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time)
>>> nn->client_tracking_ops->grace_done(nn, boot_time);
>>> }
>>>
>>> -static int
>>> -rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
>>> -{
>>> - struct super_block *sb = ptr;
>>> - struct net *net = sb->s_fs_info;
>>> - struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>>> - struct cld_net *cn = nn->cld_net;
>>> - struct dentry *dentry;
>>> - int ret = 0;
>>> -
>>> - if (!try_module_get(THIS_MODULE))
>>> - return 0;
>>> -
>>> - if (!cn) {
>>> - module_put(THIS_MODULE);
>>> - return 0;
>>> - }
>>> -
>>> - switch (event) {
>>> - case RPC_PIPEFS_MOUNT:
>>> - dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe);
>>> - if (IS_ERR(dentry)) {
>>> - ret = PTR_ERR(dentry);
>>> - break;
>>> - }
>>> - cn->cn_pipe->dentry = dentry;
>>> - break;
>>> - case RPC_PIPEFS_UMOUNT:
>>> - if (cn->cn_pipe->dentry)
>>> - nfsd4_cld_unregister_sb(cn->cn_pipe);
>>> - break;
>>> - default:
>>> - ret = -ENOTSUPP;
>>> - break;
>>> - }
>>> - module_put(THIS_MODULE);
>>> - return ret;
>>> -}
>>> -
>>> -static struct notifier_block nfsd4_cld_block = {
>>> - .notifier_call = rpc_pipefs_event,
>>> -};
>>> -
>>> -int
>>> -register_cld_notifier(void)
>>> -{
>>> - return rpc_pipefs_notifier_register(&nfsd4_cld_block);
>>> -}
>>> -
>>> -void
>>> -unregister_cld_notifier(void)
>>> -{
>>> - rpc_pipefs_notifier_unregister(&nfsd4_cld_block);
>>> -}
>>> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
>>> index a830f33..f0aeb93 100644
>>> --- a/fs/nfsd/nfsctl.c
>>> +++ b/fs/nfsd/nfsctl.c
>>> @@ -1163,12 +1163,9 @@ static int __init init_nfsd(void)
>>> int retval;
>>> printk(KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n");
>>>
>>> - retval = register_cld_notifier();
>>> - if (retval)
>>> - return retval;
>>> retval = register_pernet_subsys(&nfsd_net_ops);
>>> if (retval < 0)
>>> - goto out_unregister_notifier;
>>> + return retval;
>>> retval = nfsd4_init_slabs();
>>> if (retval)
>>> goto out_unregister_pernet;
>>> @@ -1201,8 +1198,6 @@ out_free_slabs:
>>> nfsd4_free_slabs();
>>> out_unregister_pernet:
>>> unregister_pernet_subsys(&nfsd_net_ops);
>>> -out_unregister_notifier:
>>> - unregister_cld_notifier();
>>> return retval;
>>> }
>>>
>>> @@ -1217,7 +1212,6 @@ static void __exit exit_nfsd(void)
>>> nfsd_fault_inject_cleanup();
>>> unregister_filesystem(&nfsd_fs_type);
>>> unregister_pernet_subsys(&nfsd_net_ops);
>>> - unregister_cld_notifier();
>>> }
>>>
>>> MODULE_AUTHOR("Olaf Kirch <[email protected]>");
>>> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
>>> index 07a473f..8eb2aac 100644
>>> --- a/fs/nfsd/nfsd.h
>>> +++ b/fs/nfsd/nfsd.h
>>> @@ -365,17 +365,12 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
>>> NFSD_WRITEABLE_ATTRS_WORD2
>>>
>>> extern int nfsd4_is_junction(struct dentry *dentry);
>>> -extern int register_cld_notifier(void);
>>> -extern void unregister_cld_notifier(void);
>>> #else /* CONFIG_NFSD_V4 */
>>> static inline int nfsd4_is_junction(struct dentry *dentry)
>>> {
>>> return 0;
>>> }
>>>
>>> -#define register_cld_notifier() 0
>>> -#define unregister_cld_notifier() do { } while(0)
>>> -
>>> #endif /* CONFIG_NFSD_V4 */
>>>
>>> #endif /* LINUX_NFSD_NFSD_H */
>>> diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
>>> index c11bc40..88589ac 100644
>>> --- a/include/uapi/linux/nfsd/Kbuild
>>> +++ b/include/uapi/linux/nfsd/Kbuild
>>> @@ -1,5 +1,4 @@
>>> # UAPI Header export list
>>> -header-y += cld.h
>>> header-y += debug.h
>>> header-y += export.h
>>> header-y += nfsfh.h
>>> diff --git a/include/uapi/linux/nfsd/cld.h b/include/uapi/linux/nfsd/cld.h
>>> deleted file mode 100644
>>> index f14a9ab..0000000
>>> --- a/include/uapi/linux/nfsd/cld.h
>>> +++ /dev/null
>>> @@ -1,56 +0,0 @@
>>> -/*
>>> - * Upcall description for nfsdcld communication
>>> - *
>>> - * Copyright (c) 2012 Red Hat, Inc.
>>> - * Author(s): Jeff Layton <[email protected]>
>>> - *
>>> - * This program is free software; you can redistribute it and/or modify
>>> - * it under the terms of the GNU General Public License as published by
>>> - * the Free Software Foundation; either version 2 of the License, or
>>> - * (at your option) any later version.
>>> - *
>>> - * This program is distributed in the hope that it will be useful,
>>> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> - * GNU General Public License for more details.
>>> - *
>>> - * You should have received a copy of the GNU General Public License
>>> - * along with this program; if not, write to the Free Software
>>> - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>>> - */
>>> -
>>> -#ifndef _NFSD_CLD_H
>>> -#define _NFSD_CLD_H
>>> -
>>> -/* latest upcall version available */
>>> -#define CLD_UPCALL_VERSION 1
>>> -
>>> -/* defined by RFC3530 */
>>> -#define NFS4_OPAQUE_LIMIT 1024
>>> -
>>> -enum cld_command {
>>> - Cld_Create, /* create a record for this cm_id */
>>> - Cld_Remove, /* remove record of this cm_id */
>>> - Cld_Check, /* is this cm_id allowed? */
>>> - Cld_GraceDone, /* grace period is complete */
>>> -};
>>> -
>>> -/* representation of long-form NFSv4 client ID */
>>> -struct cld_name {
>>> - uint16_t cn_len; /* length of cm_id */
>>> - unsigned char cn_id[NFS4_OPAQUE_LIMIT]; /* client-provided */
>>> -} __attribute__((packed));
>>> -
>>> -/* message struct for communication with userspace */
>>> -struct cld_msg {
>>> - uint8_t cm_vers; /* upcall version */
>>> - uint8_t cm_cmd; /* upcall command */
>>> - int16_t cm_status; /* return code */
>>> - uint32_t cm_xid; /* transaction id */
>>> - union {
>>> - int64_t cm_gracetime; /* grace period start time */
>>> - struct cld_name cm_name;
>>> - } __attribute__((packed)) cm_u;
>>> -} __attribute__((packed));
>>> -
>>> -#endif /* !_NFSD_CLD_H */
>>>
>>
>>
>> --
>> Best regards,
>> Stanislav Kinsbursky
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html


--
Best regards,
Stanislav Kinsbursky

2013-04-01 14:51:00

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: remove support for nfsdcld

On Mon, Apr 01, 2013 at 11:53:53AM +0400, Stanislav Kinsbursky wrote:
> 22.03.2013 16:57, Jeff Layton пишет:
> >...as advertised for 3.10.
> >
>
> It looks like UMH should be containerised as fast as possible, doesn't it?
> Bruce, don't you know, how much time left before 3.10 merge window?

"A few weeks" (http://lwn.net/Articles/545399/), but as usual it's good
to have everything lined up in -next before then.

Thanks for asking about this, that is indeed my one remaining concern
before ripping this out....

--b.

> >Cc: Stanislav Kinsbursky <[email protected]>
> >Signed-off-by: Jeff Layton <[email protected]>
> >---
> > fs/nfsd/nfs4recover.c | 492 +----------------------------------------
> > fs/nfsd/nfsctl.c | 8 +-
> > fs/nfsd/nfsd.h | 5 -
> > include/uapi/linux/nfsd/Kbuild | 1 -
> > include/uapi/linux/nfsd/cld.h | 56 -----
> > 5 files changed, 6 insertions(+), 556 deletions(-)
> > delete mode 100644 include/uapi/linux/nfsd/cld.h
> >
> >diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
> >index 899ca26..4e7f47e 100644
> >--- a/fs/nfsd/nfs4recover.c
> >+++ b/fs/nfsd/nfs4recover.c
> >@@ -42,7 +42,6 @@
> > #include <net/net_namespace.h>
> > #include <linux/sunrpc/rpc_pipe_fs.h>
> > #include <linux/sunrpc/clnt.h>
> >-#include <linux/nfsd/cld.h>
> >
> > #include "nfsd.h"
> > #include "state.h"
> >@@ -625,426 +624,6 @@ static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
> > .grace_done = nfsd4_recdir_purge_old,
> > };
> >
> >-/* Globals */
> >-#define NFSD_PIPE_DIR "nfsd"
> >-#define NFSD_CLD_PIPE "cld"
> >-
> >-/* per-net-ns structure for holding cld upcall info */
> >-struct cld_net {
> >- struct rpc_pipe *cn_pipe;
> >- spinlock_t cn_lock;
> >- struct list_head cn_list;
> >- unsigned int cn_xid;
> >-};
> >-
> >-struct cld_upcall {
> >- struct list_head cu_list;
> >- struct cld_net *cu_net;
> >- struct task_struct *cu_task;
> >- struct cld_msg cu_msg;
> >-};
> >-
> >-static int
> >-__cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
> >-{
> >- int ret;
> >- struct rpc_pipe_msg msg;
> >-
> >- memset(&msg, 0, sizeof(msg));
> >- msg.data = cmsg;
> >- msg.len = sizeof(*cmsg);
> >-
> >- /*
> >- * Set task state before we queue the upcall. That prevents
> >- * wake_up_process in the downcall from racing with schedule.
> >- */
> >- set_current_state(TASK_UNINTERRUPTIBLE);
> >- ret = rpc_queue_upcall(pipe, &msg);
> >- if (ret < 0) {
> >- set_current_state(TASK_RUNNING);
> >- goto out;
> >- }
> >-
> >- schedule();
> >- set_current_state(TASK_RUNNING);
> >-
> >- if (msg.errno < 0)
> >- ret = msg.errno;
> >-out:
> >- return ret;
> >-}
> >-
> >-static int
> >-cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
> >-{
> >- int ret;
> >-
> >- /*
> >- * -EAGAIN occurs when pipe is closed and reopened while there are
> >- * upcalls queued.
> >- */
> >- do {
> >- ret = __cld_pipe_upcall(pipe, cmsg);
> >- } while (ret == -EAGAIN);
> >-
> >- return ret;
> >-}
> >-
> >-static ssize_t
> >-cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
> >-{
> >- struct cld_upcall *tmp, *cup;
> >- struct cld_msg __user *cmsg = (struct cld_msg __user *)src;
> >- uint32_t xid;
> >- struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info,
> >- nfsd_net_id);
> >- struct cld_net *cn = nn->cld_net;
> >-
> >- if (mlen != sizeof(*cmsg)) {
> >- dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
> >- sizeof(*cmsg));
> >- return -EINVAL;
> >- }
> >-
> >- /* copy just the xid so we can try to find that */
> >- if (copy_from_user(&xid, &cmsg->cm_xid, sizeof(xid)) != 0) {
> >- dprintk("%s: error when copying xid from userspace", __func__);
> >- return -EFAULT;
> >- }
> >-
> >- /* walk the list and find corresponding xid */
> >- cup = NULL;
> >- spin_lock(&cn->cn_lock);
> >- list_for_each_entry(tmp, &cn->cn_list, cu_list) {
> >- if (get_unaligned(&tmp->cu_msg.cm_xid) == xid) {
> >- cup = tmp;
> >- list_del_init(&cup->cu_list);
> >- break;
> >- }
> >- }
> >- spin_unlock(&cn->cn_lock);
> >-
> >- /* couldn't find upcall? */
> >- if (!cup) {
> >- dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid);
> >- return -EINVAL;
> >- }
> >-
> >- if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
> >- return -EFAULT;
> >-
> >- wake_up_process(cup->cu_task);
> >- return mlen;
> >-}
> >-
> >-static void
> >-cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
> >-{
> >- struct cld_msg *cmsg = msg->data;
> >- struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
> >- cu_msg);
> >-
> >- /* errno >= 0 means we got a downcall */
> >- if (msg->errno >= 0)
> >- return;
> >-
> >- wake_up_process(cup->cu_task);
> >-}
> >-
> >-static const struct rpc_pipe_ops cld_upcall_ops = {
> >- .upcall = rpc_pipe_generic_upcall,
> >- .downcall = cld_pipe_downcall,
> >- .destroy_msg = cld_pipe_destroy_msg,
> >-};
> >-
> >-static struct dentry *
> >-nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
> >-{
> >- struct dentry *dir, *dentry;
> >-
> >- dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
> >- if (dir == NULL)
> >- return ERR_PTR(-ENOENT);
> >- dentry = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
> >- dput(dir);
> >- return dentry;
> >-}
> >-
> >-static void
> >-nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
> >-{
> >- if (pipe->dentry)
> >- rpc_unlink(pipe->dentry);
> >-}
> >-
> >-static struct dentry *
> >-nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
> >-{
> >- struct super_block *sb;
> >- struct dentry *dentry;
> >-
> >- sb = rpc_get_sb_net(net);
> >- if (!sb)
> >- return NULL;
> >- dentry = nfsd4_cld_register_sb(sb, pipe);
> >- rpc_put_sb_net(net);
> >- return dentry;
> >-}
> >-
> >-static void
> >-nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
> >-{
> >- struct super_block *sb;
> >-
> >- sb = rpc_get_sb_net(net);
> >- if (sb) {
> >- nfsd4_cld_unregister_sb(pipe);
> >- rpc_put_sb_net(net);
> >- }
> >-}
> >-
> >-/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
> >-static int
> >-nfsd4_init_cld_pipe(struct net *net)
> >-{
> >- int ret;
> >- struct dentry *dentry;
> >- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> >- struct cld_net *cn;
> >-
> >- if (nn->cld_net)
> >- return 0;
> >-
> >- cn = kzalloc(sizeof(*cn), GFP_KERNEL);
> >- if (!cn) {
> >- ret = -ENOMEM;
> >- goto err;
> >- }
> >-
> >- cn->cn_pipe = rpc_mkpipe_data(&cld_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
> >- if (IS_ERR(cn->cn_pipe)) {
> >- ret = PTR_ERR(cn->cn_pipe);
> >- goto err;
> >- }
> >- spin_lock_init(&cn->cn_lock);
> >- INIT_LIST_HEAD(&cn->cn_list);
> >-
> >- dentry = nfsd4_cld_register_net(net, cn->cn_pipe);
> >- if (IS_ERR(dentry)) {
> >- ret = PTR_ERR(dentry);
> >- goto err_destroy_data;
> >- }
> >-
> >- cn->cn_pipe->dentry = dentry;
> >- nn->cld_net = cn;
> >- return 0;
> >-
> >-err_destroy_data:
> >- rpc_destroy_pipe_data(cn->cn_pipe);
> >-err:
> >- kfree(cn);
> >- printk(KERN_ERR "NFSD: unable to create nfsdcld upcall pipe (%d)\n",
> >- ret);
> >- return ret;
> >-}
> >-
> >-static void
> >-nfsd4_remove_cld_pipe(struct net *net)
> >-{
> >- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> >- struct cld_net *cn = nn->cld_net;
> >-
> >- nfsd4_cld_unregister_net(net, cn->cn_pipe);
> >- rpc_destroy_pipe_data(cn->cn_pipe);
> >- kfree(nn->cld_net);
> >- nn->cld_net = NULL;
> >-}
> >-
> >-static struct cld_upcall *
> >-alloc_cld_upcall(struct cld_net *cn)
> >-{
> >- struct cld_upcall *new, *tmp;
> >-
> >- new = kzalloc(sizeof(*new), GFP_KERNEL);
> >- if (!new)
> >- return new;
> >-
> >- /* FIXME: hard cap on number in flight? */
> >-restart_search:
> >- spin_lock(&cn->cn_lock);
> >- list_for_each_entry(tmp, &cn->cn_list, cu_list) {
> >- if (tmp->cu_msg.cm_xid == cn->cn_xid) {
> >- cn->cn_xid++;
> >- spin_unlock(&cn->cn_lock);
> >- goto restart_search;
> >- }
> >- }
> >- new->cu_task = current;
> >- new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
> >- put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
> >- new->cu_net = cn;
> >- list_add(&new->cu_list, &cn->cn_list);
> >- spin_unlock(&cn->cn_lock);
> >-
> >- dprintk("%s: allocated xid %u\n", __func__, new->cu_msg.cm_xid);
> >-
> >- return new;
> >-}
> >-
> >-static void
> >-free_cld_upcall(struct cld_upcall *victim)
> >-{
> >- struct cld_net *cn = victim->cu_net;
> >-
> >- spin_lock(&cn->cn_lock);
> >- list_del(&victim->cu_list);
> >- spin_unlock(&cn->cn_lock);
> >- kfree(victim);
> >-}
> >-
> >-/* Ask daemon to create a new record */
> >-static void
> >-nfsd4_cld_create(struct nfs4_client *clp)
> >-{
> >- int ret;
> >- struct cld_upcall *cup;
> >- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> >- struct cld_net *cn = nn->cld_net;
> >-
> >- /* Don't upcall if it's already stored */
> >- if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> >- return;
> >-
> >- cup = alloc_cld_upcall(cn);
> >- if (!cup) {
> >- ret = -ENOMEM;
> >- goto out_err;
> >- }
> >-
> >- cup->cu_msg.cm_cmd = Cld_Create;
> >- cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> >- memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> >- clp->cl_name.len);
> >-
> >- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> >- if (!ret) {
> >- ret = cup->cu_msg.cm_status;
> >- set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> >- }
> >-
> >- free_cld_upcall(cup);
> >-out_err:
> >- if (ret)
> >- printk(KERN_ERR "NFSD: Unable to create client "
> >- "record on stable storage: %d\n", ret);
> >-}
> >-
> >-/* Ask daemon to create a new record */
> >-static void
> >-nfsd4_cld_remove(struct nfs4_client *clp)
> >-{
> >- int ret;
> >- struct cld_upcall *cup;
> >- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> >- struct cld_net *cn = nn->cld_net;
> >-
> >- /* Don't upcall if it's already removed */
> >- if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> >- return;
> >-
> >- cup = alloc_cld_upcall(cn);
> >- if (!cup) {
> >- ret = -ENOMEM;
> >- goto out_err;
> >- }
> >-
> >- cup->cu_msg.cm_cmd = Cld_Remove;
> >- cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> >- memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> >- clp->cl_name.len);
> >-
> >- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> >- if (!ret) {
> >- ret = cup->cu_msg.cm_status;
> >- clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> >- }
> >-
> >- free_cld_upcall(cup);
> >-out_err:
> >- if (ret)
> >- printk(KERN_ERR "NFSD: Unable to remove client "
> >- "record from stable storage: %d\n", ret);
> >-}
> >-
> >-/* Check for presence of a record, and update its timestamp */
> >-static int
> >-nfsd4_cld_check(struct nfs4_client *clp)
> >-{
> >- int ret;
> >- struct cld_upcall *cup;
> >- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
> >- struct cld_net *cn = nn->cld_net;
> >-
> >- /* Don't upcall if one was already stored during this grace pd */
> >- if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
> >- return 0;
> >-
> >- cup = alloc_cld_upcall(cn);
> >- if (!cup) {
> >- printk(KERN_ERR "NFSD: Unable to check client record on "
> >- "stable storage: %d\n", -ENOMEM);
> >- return -ENOMEM;
> >- }
> >-
> >- cup->cu_msg.cm_cmd = Cld_Check;
> >- cup->cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
> >- memcpy(cup->cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
> >- clp->cl_name.len);
> >-
> >- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> >- if (!ret) {
> >- ret = cup->cu_msg.cm_status;
> >- set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
> >- }
> >-
> >- free_cld_upcall(cup);
> >- return ret;
> >-}
> >-
> >-static void
> >-nfsd4_cld_grace_done(struct nfsd_net *nn, time_t boot_time)
> >-{
> >- int ret;
> >- struct cld_upcall *cup;
> >- struct cld_net *cn = nn->cld_net;
> >-
> >- cup = alloc_cld_upcall(cn);
> >- if (!cup) {
> >- ret = -ENOMEM;
> >- goto out_err;
> >- }
> >-
> >- cup->cu_msg.cm_cmd = Cld_GraceDone;
> >- cup->cu_msg.cm_u.cm_gracetime = (int64_t)boot_time;
> >- ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_msg);
> >- if (!ret)
> >- ret = cup->cu_msg.cm_status;
> >-
> >- free_cld_upcall(cup);
> >-out_err:
> >- if (ret)
> >- printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
> >-}
> >-
> >-static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
> >- .init = nfsd4_init_cld_pipe,
> >- .exit = nfsd4_remove_cld_pipe,
> >- .create = nfsd4_cld_create,
> >- .remove = nfsd4_cld_remove,
> >- .check = nfsd4_cld_check,
> >- .grace_done = nfsd4_cld_grace_done,
> >-};
> >-
> > /* upcall via usermodehelper */
> > static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
> > module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
> >@@ -1287,21 +866,14 @@ nfsd4_client_tracking_init(struct net *net)
> > * then use the legacy ops.
> > */
> > nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
> >- status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
> >- if (!status) {
> >- status = S_ISDIR(path.dentry->d_inode->i_mode);
> >- path_put(&path);
> >- if (status)
> >- goto do_init;
> >- }
> >+ status = kern_path(nfs4_recoverydir(),
> >+ LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
> >+ if (status)
> >+ goto out_err;
> >
> >- /* Finally, try to use nfsdcld */
> >- nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
> >- printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be "
> >- "removed in 3.10. Please transition to using "
> >- "nfsdcltrack.\n");
> > do_init:
> > status = nn->client_tracking_ops->init(net);
> >+out_err:
> > if (status) {
> > printk(KERN_WARNING "NFSD: Unable to initialize client "
> > "recovery tracking! (%d)\n", status);
> >@@ -1358,57 +930,3 @@ nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time)
> > nn->client_tracking_ops->grace_done(nn, boot_time);
> > }
> >
> >-static int
> >-rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
> >-{
> >- struct super_block *sb = ptr;
> >- struct net *net = sb->s_fs_info;
> >- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
> >- struct cld_net *cn = nn->cld_net;
> >- struct dentry *dentry;
> >- int ret = 0;
> >-
> >- if (!try_module_get(THIS_MODULE))
> >- return 0;
> >-
> >- if (!cn) {
> >- module_put(THIS_MODULE);
> >- return 0;
> >- }
> >-
> >- switch (event) {
> >- case RPC_PIPEFS_MOUNT:
> >- dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe);
> >- if (IS_ERR(dentry)) {
> >- ret = PTR_ERR(dentry);
> >- break;
> >- }
> >- cn->cn_pipe->dentry = dentry;
> >- break;
> >- case RPC_PIPEFS_UMOUNT:
> >- if (cn->cn_pipe->dentry)
> >- nfsd4_cld_unregister_sb(cn->cn_pipe);
> >- break;
> >- default:
> >- ret = -ENOTSUPP;
> >- break;
> >- }
> >- module_put(THIS_MODULE);
> >- return ret;
> >-}
> >-
> >-static struct notifier_block nfsd4_cld_block = {
> >- .notifier_call = rpc_pipefs_event,
> >-};
> >-
> >-int
> >-register_cld_notifier(void)
> >-{
> >- return rpc_pipefs_notifier_register(&nfsd4_cld_block);
> >-}
> >-
> >-void
> >-unregister_cld_notifier(void)
> >-{
> >- rpc_pipefs_notifier_unregister(&nfsd4_cld_block);
> >-}
> >diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> >index a830f33..f0aeb93 100644
> >--- a/fs/nfsd/nfsctl.c
> >+++ b/fs/nfsd/nfsctl.c
> >@@ -1163,12 +1163,9 @@ static int __init init_nfsd(void)
> > int retval;
> > printk(KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n");
> >
> >- retval = register_cld_notifier();
> >- if (retval)
> >- return retval;
> > retval = register_pernet_subsys(&nfsd_net_ops);
> > if (retval < 0)
> >- goto out_unregister_notifier;
> >+ return retval;
> > retval = nfsd4_init_slabs();
> > if (retval)
> > goto out_unregister_pernet;
> >@@ -1201,8 +1198,6 @@ out_free_slabs:
> > nfsd4_free_slabs();
> > out_unregister_pernet:
> > unregister_pernet_subsys(&nfsd_net_ops);
> >-out_unregister_notifier:
> >- unregister_cld_notifier();
> > return retval;
> > }
> >
> >@@ -1217,7 +1212,6 @@ static void __exit exit_nfsd(void)
> > nfsd_fault_inject_cleanup();
> > unregister_filesystem(&nfsd_fs_type);
> > unregister_pernet_subsys(&nfsd_net_ops);
> >- unregister_cld_notifier();
> > }
> >
> > MODULE_AUTHOR("Olaf Kirch <[email protected]>");
> >diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
> >index 07a473f..8eb2aac 100644
> >--- a/fs/nfsd/nfsd.h
> >+++ b/fs/nfsd/nfsd.h
> >@@ -365,17 +365,12 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
> > NFSD_WRITEABLE_ATTRS_WORD2
> >
> > extern int nfsd4_is_junction(struct dentry *dentry);
> >-extern int register_cld_notifier(void);
> >-extern void unregister_cld_notifier(void);
> > #else /* CONFIG_NFSD_V4 */
> > static inline int nfsd4_is_junction(struct dentry *dentry)
> > {
> > return 0;
> > }
> >
> >-#define register_cld_notifier() 0
> >-#define unregister_cld_notifier() do { } while(0)
> >-
> > #endif /* CONFIG_NFSD_V4 */
> >
> > #endif /* LINUX_NFSD_NFSD_H */
> >diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
> >index c11bc40..88589ac 100644
> >--- a/include/uapi/linux/nfsd/Kbuild
> >+++ b/include/uapi/linux/nfsd/Kbuild
> >@@ -1,5 +1,4 @@
> > # UAPI Header export list
> >-header-y += cld.h
> > header-y += debug.h
> > header-y += export.h
> > header-y += nfsfh.h
> >diff --git a/include/uapi/linux/nfsd/cld.h b/include/uapi/linux/nfsd/cld.h
> >deleted file mode 100644
> >index f14a9ab..0000000
> >--- a/include/uapi/linux/nfsd/cld.h
> >+++ /dev/null
> >@@ -1,56 +0,0 @@
> >-/*
> >- * Upcall description for nfsdcld communication
> >- *
> >- * Copyright (c) 2012 Red Hat, Inc.
> >- * Author(s): Jeff Layton <[email protected]>
> >- *
> >- * This program is free software; you can redistribute it and/or modify
> >- * it under the terms of the GNU General Public License as published by
> >- * the Free Software Foundation; either version 2 of the License, or
> >- * (at your option) any later version.
> >- *
> >- * This program is distributed in the hope that it will be useful,
> >- * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> >- * GNU General Public License for more details.
> >- *
> >- * You should have received a copy of the GNU General Public License
> >- * along with this program; if not, write to the Free Software
> >- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> >- */
> >-
> >-#ifndef _NFSD_CLD_H
> >-#define _NFSD_CLD_H
> >-
> >-/* latest upcall version available */
> >-#define CLD_UPCALL_VERSION 1
> >-
> >-/* defined by RFC3530 */
> >-#define NFS4_OPAQUE_LIMIT 1024
> >-
> >-enum cld_command {
> >- Cld_Create, /* create a record for this cm_id */
> >- Cld_Remove, /* remove record of this cm_id */
> >- Cld_Check, /* is this cm_id allowed? */
> >- Cld_GraceDone, /* grace period is complete */
> >-};
> >-
> >-/* representation of long-form NFSv4 client ID */
> >-struct cld_name {
> >- uint16_t cn_len; /* length of cm_id */
> >- unsigned char cn_id[NFS4_OPAQUE_LIMIT]; /* client-provided */
> >-} __attribute__((packed));
> >-
> >-/* message struct for communication with userspace */
> >-struct cld_msg {
> >- uint8_t cm_vers; /* upcall version */
> >- uint8_t cm_cmd; /* upcall command */
> >- int16_t cm_status; /* return code */
> >- uint32_t cm_xid; /* transaction id */
> >- union {
> >- int64_t cm_gracetime; /* grace period start time */
> >- struct cld_name cm_name;
> >- } __attribute__((packed)) cm_u;
> >-} __attribute__((packed));
> >-
> >-#endif /* !_NFSD_CLD_H */
> >
>
>
> --
> Best regards,
> Stanislav Kinsbursky
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html