linux/fs/nfsd/nfs4recover.c

/*
*  Copyright (c) 2004 The Regents of the University of Michigan.
*  Copyright (c) 2012 Jeff Layton <[email protected]>
*  All rights reserved.
*
*  Andy Adamson <[email protected]>
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*  1. Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*  2. Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in the
*     documentation and/or other materials provided with the distribution.
*  3. Neither the name of the University nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
*  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
*  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
*  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
*  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
*  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

#include <crypto/hash.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/module.h>
#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"
#include "vfs.h"
#include "netns.h"

#define NFSDDBG_FACILITY

/* Declarations */
struct nfsd4_client_tracking_ops {};

static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops;
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v2;

#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
/* Globals */
static char user_recovery_dirname[PATH_MAX] =;

static int
nfs4_save_creds(const struct cred **original_creds)
{}

static void
nfs4_reset_creds(const struct cred *original)
{}

static void
md5_to_hex(char *out, char *md5)
{}

static int
nfs4_make_rec_clidname(char *dname, const struct xdr_netobj *clname)
{}

/*
 * If we had an error generating the recdir name for the legacy tracker
 * then warn the admin. If the error doesn't appear to be transient,
 * then disable recovery tracking.
 */
static void
legacy_recdir_name_error(struct nfs4_client *clp, int error)
{}

static void
__nfsd4_create_reclaim_record_grace(struct nfs4_client *clp,
		const char *dname, int len, struct nfsd_net *nn)
{}

static void
nfsd4_create_clid_dir(struct nfs4_client *clp)
{}

recdir_func;

struct name_list {};

struct nfs4_dir_ctx {};

static bool
nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
		loff_t offset, u64 ino, unsigned int d_type)
{}

static int
nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
{}

static int
nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn)
{}

static void
__nfsd4_remove_reclaim_record_grace(const char *dname, int len,
		struct nfsd_net *nn)
{}

static void
nfsd4_remove_clid_dir(struct nfs4_client *clp)
{}

static int
purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
{}

static void
nfsd4_recdir_purge_old(struct nfsd_net *nn)
{}

static int
load_recdir(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
{}

static int
nfsd4_recdir_load(struct net *net) {}

/*
 * Hold reference to the recovery directory.
 */

static int
nfsd4_init_recdir(struct net *net)
{}

static void
nfsd4_shutdown_recdir(struct net *net)
{}

static int
nfs4_legacy_state_init(struct net *net)
{}

static void
nfs4_legacy_state_shutdown(struct net *net)
{}

static int
nfsd4_load_reboot_recovery_data(struct net *net)
{}

static int
nfsd4_legacy_tracking_init(struct net *net)
{}

static void
nfsd4_legacy_tracking_exit(struct net *net)
{}

/*
 * Change the NFSv4 recovery directory to recdir.
 */
int
nfs4_reset_recoverydir(char *recdir)
{}

char *
nfs4_recoverydir(void)
{}

static int
nfsd4_check_legacy_client(struct nfs4_client *clp)
{}

static const struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops =;
#endif /* CONFIG_NFSD_LEGACY_CLIENT_TRACKING */

/* Globals */
#define NFSD_PIPE_DIR
#define NFSD_CLD_PIPE

/* per-net-ns structure for holding cld upcall info */
struct cld_net {};

struct cld_upcall {};

static int
__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
{}

static int
cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
{}

static ssize_t
__cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
		struct nfsd_net *nn)
{}

static ssize_t
cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
{}

static void
cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
{}

static const struct rpc_pipe_ops cld_upcall_ops =;

static struct dentry *
nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
{}

static void
nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
{}

static struct dentry *
nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
{}

static void
nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
{}

/* Initialize rpc_pipefs pipe for communication with client tracking daemon */
static int
__nfsd4_init_cld_pipe(struct net *net)
{}

static int
nfsd4_init_cld_pipe(struct net *net)
{}

static void
nfsd4_remove_cld_pipe(struct net *net)
{}

static struct cld_upcall *
alloc_cld_upcall(struct nfsd_net *nn)
{}

static void
free_cld_upcall(struct cld_upcall *victim)
{}

/* Ask daemon to create a new record */
static void
nfsd4_cld_create(struct nfs4_client *clp)
{}

/* Ask daemon to create a new record */
static void
nfsd4_cld_create_v2(struct nfs4_client *clp)
{}

/* Ask daemon to create a new record */
static void
nfsd4_cld_remove(struct nfs4_client *clp)
{}

/*
 * For older nfsdcld's that do not allow us to "slurp" the clients
 * from the tracking database during startup.
 *
 * Check for presence of a record, and update its timestamp
 */
static int
nfsd4_cld_check_v0(struct nfs4_client *clp)
{}

/*
 * For newer nfsdcld's that allow us to "slurp" the clients
 * from the tracking database during startup.
 *
 * Check for presence of a record in the reclaim_str_hashtbl
 */
static int
nfsd4_cld_check(struct nfs4_client *clp)
{}

static int
nfsd4_cld_check_v2(struct nfs4_client *clp)
{}

static int
nfsd4_cld_grace_start(struct nfsd_net *nn)
{}

/* For older nfsdcld's that need cm_gracetime */
static void
nfsd4_cld_grace_done_v0(struct nfsd_net *nn)
{}

/*
 * For newer nfsdcld's that do not need cm_gracetime.  We also need to call
 * nfs4_release_reclaim() to clear out the reclaim_str_hashtbl.
 */
static void
nfsd4_cld_grace_done(struct nfsd_net *nn)
{}

static int
nfs4_cld_state_init(struct net *net)
{}

static void
nfs4_cld_state_shutdown(struct net *net)
{}

static bool
cld_running(struct nfsd_net *nn)
{}

static int
nfsd4_cld_get_version(struct nfsd_net *nn)
{}

static int
nfsd4_cld_tracking_init(struct net *net)
{}

static void
nfsd4_cld_tracking_exit(struct net *net)
{}

/* For older nfsdcld's */
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v0 =;

/* For newer nfsdcld's */
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops =;

/* v2 create/check ops include the principal, if available */
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v2 =;

#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
/* upcall via usermodehelper */
static char cltrack_prog[PATH_MAX] =;
module_param_string();
MODULE_PARM_DESC();

static bool cltrack_legacy_disable;
module_param(cltrack_legacy_disable, bool, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC();

#define LEGACY_TOPDIR_ENV_PREFIX
#define LEGACY_RECDIR_ENV_PREFIX
#define HAS_SESSION_ENV_PREFIX
#define GRACE_START_ENV_PREFIX

static char *
nfsd4_cltrack_legacy_topdir(void)
{}

static char *
nfsd4_cltrack_legacy_recdir(const struct xdr_netobj *name)
{}

static char *
nfsd4_cltrack_client_has_session(struct nfs4_client *clp)
{}

static char *
nfsd4_cltrack_grace_start(time64_t grace_start)
{}

static int
nfsd4_umh_cltrack_upcall(char *cmd, char *arg, char *env0, char *env1)
{}

static char *
bin_to_hex_dup(const unsigned char *src, int srclen)
{}

static int
nfsd4_umh_cltrack_init(struct net *net)
{}

static void
nfsd4_cltrack_upcall_lock(struct nfs4_client *clp)
{}

static void
nfsd4_cltrack_upcall_unlock(struct nfs4_client *clp)
{}

static void
nfsd4_umh_cltrack_create(struct nfs4_client *clp)
{}

static void
nfsd4_umh_cltrack_remove(struct nfs4_client *clp)
{}

static int
nfsd4_umh_cltrack_check(struct nfs4_client *clp)
{}

static void
nfsd4_umh_cltrack_grace_done(struct nfsd_net *nn)
{}

static const struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops =;

static inline int check_for_legacy_methods(int status, struct net *net)
{}
#else
static inline int check_for_legacy_methods(int status, struct net *net)
{
	return status;
}
#endif /* CONFIG_LEGACY_NFSD_CLIENT_TRACKING */

int
nfsd4_client_tracking_init(struct net *net)
{}

void
nfsd4_client_tracking_exit(struct net *net)
{}

void
nfsd4_client_record_create(struct nfs4_client *clp)
{}

void
nfsd4_client_record_remove(struct nfs4_client *clp)
{}

int
nfsd4_client_record_check(struct nfs4_client *clp)
{}

void
nfsd4_record_grace_done(struct nfsd_net *nn)
{}

static int
rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
{}

static struct notifier_block nfsd4_cld_block =;

int
register_cld_notifier(void)
{}

void
unregister_cld_notifier(void)
{}