// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2014 Christoph Hellwig.
 */
#include <linux/exportfs_block.h>
#include <linux/kmod.h>
#include <linux/file.h>
#include <linux/jhash.h>
#include <linux/sched.h>
#include <linux/sunrpc/addr.h>

#include "pnfs.h"
#include "netns.h"
#include "trace.h"

#define NFSDDBG_FACILITY                NFSDDBG_PNFS

struct nfs4_layout {
	struct list_head		lo_perstate;
	struct nfs4_layout_stateid	*lo_state;
	struct nfsd4_layout_seg		lo_seg;
};

static struct kmem_cache *nfs4_layout_cache;
static struct kmem_cache *nfs4_layout_stateid_cache;

static const struct nfsd4_callback_ops nfsd4_cb_layout_ops;
static const struct lease_manager_operations nfsd4_layouts_lm_ops;

static void nfsd4_layout_fence_worker(struct work_struct *work);

const struct nfsd4_layout_ops *nfsd4_layout_ops[LAYOUT_TYPE_MAX] =  {
#ifdef CONFIG_NFSD_FLEXFILELAYOUT
	[LAYOUT_FLEX_FILES]	= &ff_layout_ops,
#endif
#ifdef CONFIG_NFSD_BLOCKLAYOUT
	[LAYOUT_BLOCK_VOLUME]	= &bl_layout_ops,
#endif
#ifdef CONFIG_NFSD_SCSILAYOUT
	[LAYOUT_SCSI]		= &scsi_layout_ops,
#endif
};

/* pNFS device ID to export fsid mapping */
#define DEVID_HASH_BITS	8
#define DEVID_HASH_SIZE	(1 << DEVID_HASH_BITS)
#define DEVID_HASH_MASK	(DEVID_HASH_SIZE - 1)
static u64 nfsd_devid_seq = 1;
static struct list_head nfsd_devid_hash[DEVID_HASH_SIZE];
static DEFINE_SPINLOCK(nfsd_devid_lock);

static inline u32 devid_hashfn(u64 idx)
{
	return jhash_2words(idx, idx >> 32, 0) & DEVID_HASH_MASK;
}

static void
nfsd4_alloc_devid_map(const struct svc_fh *fhp)
{
	const struct knfsd_fh *fh = &fhp->fh_handle;
	size_t fsid_len = key_len(fh->fh_fsid_type);
	struct nfsd4_deviceid_map *map, *old;
	int i;

	map = kzalloc(sizeof(*map) + fsid_len, GFP_KERNEL);
	if (!map)
		return;

	map->fsid_type = fh->fh_fsid_type;
	memcpy(&map->fsid, fh_fsid(fh), fsid_len);

	spin_lock(&nfsd_devid_lock);
	if (fhp->fh_export->ex_devid_map)
		goto out_unlock;

	for (i = 0; i < DEVID_HASH_SIZE; i++) {
		list_for_each_entry(old, &nfsd_devid_hash[i], hash) {
			if (old->fsid_type != fh->fh_fsid_type)
				continue;
			if (memcmp(old->fsid, fh_fsid(fh),
					key_len(old->fsid_type)))
				continue;

			fhp->fh_export->ex_devid_map = old;
			goto out_unlock;
		}
	}

	map->idx = nfsd_devid_seq++;
	list_add_tail_rcu(&map->hash, &nfsd_devid_hash[devid_hashfn(map->idx)]);
	fhp->fh_export->ex_devid_map = map;
	map = NULL;

out_unlock:
	spin_unlock(&nfsd_devid_lock);
	kfree(map);
}

struct nfsd4_deviceid_map *
nfsd4_find_devid_map(int idx)
{
	struct nfsd4_deviceid_map *map, *ret = NULL;

	rcu_read_lock();
	list_for_each_entry_rcu(map, &nfsd_devid_hash[devid_hashfn(idx)], hash)
		if (map->idx == idx)
			ret = map;
	rcu_read_unlock();

	return ret;
}

int
nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
		u32 device_generation)
{
	if (!fhp->fh_export->ex_devid_map) {
		nfsd4_alloc_devid_map(fhp);
		if (!fhp->fh_export->ex_devid_map)
			return -ENOMEM;
	}

	id->fsid_idx = fhp->fh_export->ex_devid_map->idx;
	id->generation = device_generation;
	return 0;
}

void nfsd4_setup_layout_type(struct svc_export *exp)
{
	struct super_block *sb = exp->ex_path.mnt->mnt_sb;
	expfs_block_layouts_t block_supported = exportfs_layouts_supported(sb);

	if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT))
		exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
	if (IS_ENABLED(CONFIG_NFSD_BLOCKLAYOUT) &&
	    (block_supported & EXPFS_BLOCK_IN_BAND_ID))
		exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
	if (IS_ENABLED(CONFIG_NFSD_SCSILAYOUT) &&
	    (block_supported & EXPFS_BLOCK_OUT_OF_BAND_ID))
		exp->ex_layout_types |= 1 << LAYOUT_SCSI;
}

void nfsd4_close_layout(struct nfs4_layout_stateid *ls)
{
	struct nfsd_file *fl;

	spin_lock(&ls->ls_stid.sc_file->fi_lock);
	fl = ls->ls_file;
	ls->ls_file = NULL;
	spin_unlock(&ls->ls_stid.sc_file->fi_lock);

	if (fl) {
		if (!nfsd4_layout_ops[ls->ls_layout_type]->disable_recalls)
			kernel_setlease(fl->nf_file, F_UNLCK, NULL,
					(void **)&ls);
		nfsd_file_put(fl);
	}
}

static void
nfsd4_free_layout_stateid(struct nfs4_stid *stid)
{
	struct nfs4_layout_stateid *ls = layoutstateid(stid);
	struct nfs4_client *clp = ls->ls_stid.sc_client;
	struct nfs4_file *fp = ls->ls_stid.sc_file;

	trace_nfsd_layoutstate_free(&ls->ls_stid.sc_stateid);

	spin_lock(&ls->ls_lock);
	if (delayed_work_pending(&ls->ls_fence_work)) {
		spin_unlock(&ls->ls_lock);
		cancel_delayed_work_sync(&ls->ls_fence_work);
	} else
		spin_unlock(&ls->ls_lock);

	spin_lock(&clp->cl_lock);
	list_del_init(&ls->ls_perclnt);
	spin_unlock(&clp->cl_lock);

	spin_lock(&fp->fi_lock);
	list_del_init(&ls->ls_perfile);
	spin_unlock(&fp->fi_lock);

	nfsd4_close_layout(ls);

	if (ls->ls_recalled)
		atomic_dec(&ls->ls_stid.sc_file->fi_lo_recalls);

	kmem_cache_free(nfs4_layout_stateid_cache, ls);
}

static int
nfsd4_layout_setlease(struct nfs4_layout_stateid *ls)
{
	struct file_lease *fl;
	int status;

	if (nfsd4_layout_ops[ls->ls_layout_type]->disable_recalls)
		return 0;

	fl = locks_alloc_lease();
	if (!fl)
		return -ENOMEM;
	locks_init_lease(fl);
	fl->fl_lmops = &nfsd4_layouts_lm_ops;
	fl->c.flc_flags = FL_LAYOUT;
	fl->c.flc_type = F_RDLCK;
	fl->c.flc_owner = ls;
	fl->c.flc_pid = current->tgid;
	fl->c.flc_file = ls->ls_file->nf_file;

	status = kernel_setlease(fl->c.flc_file, fl->c.flc_type, &fl, NULL);
	if (status) {
		locks_free_lease(fl);
		return status;
	}
	BUG_ON(fl != NULL);
	return 0;
}

static struct nfs4_layout_stateid *
nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
		struct nfs4_stid *parent, u32 layout_type)
{
	struct nfs4_client *clp = cstate->clp;
	struct nfs4_file *fp = parent->sc_file;
	struct nfs4_layout_stateid *ls;
	struct nfs4_stid *stp;

	stp = nfs4_alloc_stid(cstate->clp, nfs4_layout_stateid_cache,
					nfsd4_free_layout_stateid);
	if (!stp)
		return NULL;

	get_nfs4_file(fp);
	stp->sc_file = fp;
	if (parent->sc_export)
		stp->sc_export = exp_get(parent->sc_export);

	ls = layoutstateid(stp);
	INIT_LIST_HEAD(&ls->ls_perclnt);
	INIT_LIST_HEAD(&ls->ls_perfile);
	spin_lock_init(&ls->ls_lock);
	INIT_LIST_HEAD(&ls->ls_layouts);
	mutex_init(&ls->ls_mutex);
	ls->ls_layout_type = layout_type;
	nfsd4_init_cb(&ls->ls_recall, clp, &nfsd4_cb_layout_ops,
			NFSPROC4_CLNT_CB_LAYOUT);

	if (parent->sc_type == SC_TYPE_DELEG) {
		rcu_read_lock();
		ls->ls_file = nfsd_file_get(rcu_dereference(fp->fi_deleg_file));
		rcu_read_unlock();
	} else {
		ls->ls_file = find_any_file(fp);
	}

	if (!ls->ls_file) {
		nfs4_put_stid(stp);
		return NULL;
	}

	ls->ls_fenced = false;
	ls->ls_fence_inflight = false;
	ls->ls_fence_delay = 0;
	INIT_DELAYED_WORK(&ls->ls_fence_work, nfsd4_layout_fence_worker);

	if (nfsd4_layout_setlease(ls)) {
		nfs4_put_stid(stp);
		return NULL;
	}

	spin_lock(&clp->cl_lock);
	stp->sc_type = SC_TYPE_LAYOUT;
	list_add(&ls->ls_perclnt, &clp->cl_lo_states);
	spin_unlock(&clp->cl_lock);

	spin_lock(&fp->fi_lock);
	list_add(&ls->ls_perfile, &fp->fi_lo_states);
	spin_unlock(&fp->fi_lock);

	trace_nfsd_layoutstate_alloc(&ls->ls_stid.sc_stateid);
	return ls;
}

__be32
nfsd4_preprocess_layout_stateid(struct svc_rqst *rqstp,
		struct nfsd4_compound_state *cstate, stateid_t *stateid,
		bool create, u32 layout_type, struct nfs4_layout_stateid **lsp)
{
	struct nfs4_layout_stateid *ls;
	struct nfs4_stid *stid;
	unsigned short typemask = SC_TYPE_LAYOUT;
	__be32 status;

	if (create)
		typemask |= (SC_TYPE_OPEN | SC_TYPE_LOCK | SC_TYPE_DELEG);

	status = nfsd4_lookup_stateid(cstate, stateid, typemask, 0, &stid,
			net_generic(SVC_NET(rqstp), nfsd_net_id));
	if (status)
		goto out;

	if (!fh_match(&cstate->current_fh.fh_handle,
		      &stid->sc_file->fi_fhandle)) {
		status = nfserr_bad_stateid;
		goto out_put_stid;
	}

	if (stid->sc_type != SC_TYPE_LAYOUT) {
		ls = nfsd4_alloc_layout_stateid(cstate, stid, layout_type);
		nfs4_put_stid(stid);

		status = nfserr_jukebox;
		if (!ls)
			goto out;
		mutex_lock(&ls->ls_mutex);
	} else {
		ls = container_of(stid, struct nfs4_layout_stateid, ls_stid);

		status = nfserr_bad_stateid;
		mutex_lock(&ls->ls_mutex);
		if (nfsd4_stateid_generation_after(stateid, &stid->sc_stateid))
			goto out_unlock_stid;
		if (layout_type != ls->ls_layout_type)
			goto out_unlock_stid;
	}

	*lsp = ls;
	return 0;

out_unlock_stid:
	mutex_unlock(&ls->ls_mutex);
out_put_stid:
	nfs4_put_stid(stid);
out:
	return status;
}

static void
nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
{
	spin_lock(&ls->ls_lock);
	if (ls->ls_recalled)
		goto out_unlock;

	if (list_empty(&ls->ls_layouts))
		goto out_unlock;

	ls->ls_recalled = true;
	atomic_inc(&ls->ls_stid.sc_file->fi_lo_recalls);
	trace_nfsd_layout_recall(&ls->ls_stid.sc_stateid);

	if (!test_and_set_bit(NFSD4_CALLBACK_RUNNING, &ls->ls_recall.cb_flags)) {
		refcount_inc(&ls->ls_stid.sc_count);
		nfsd4_run_cb(&ls->ls_recall);
	}
out_unlock:
	spin_unlock(&ls->ls_lock);
}

static inline u64
layout_end(struct nfsd4_layout_seg *seg)
{
	u64 end = seg->offset + seg->length;
	return end >= seg->offset ? end : NFS4_MAX_UINT64;
}

static void
layout_update_len(struct nfsd4_layout_seg *lo, u64 end)
{
	if (end == NFS4_MAX_UINT64)
		lo->length = NFS4_MAX_UINT64;
	else
		lo->length = end - lo->offset;
}

static bool
layouts_overlapping(struct nfs4_layout *lo, struct nfsd4_layout_seg *s)
{
	if (s->iomode != IOMODE_ANY && s->iomode != lo->lo_seg.iomode)
		return false;
	if (layout_end(&lo->lo_seg) <= s->offset)
		return false;
	if (layout_end(s) <= lo->lo_seg.offset)
		return false;
	return true;
}

static bool
layouts_try_merge(struct nfsd4_layout_seg *lo, struct nfsd4_layout_seg *new)
{
	if (lo->iomode != new->iomode)
		return false;
	if (layout_end(new) < lo->offset)
		return false;
	if (layout_end(lo) < new->offset)
		return false;

	lo->offset = min(lo->offset, new->offset);
	layout_update_len(lo, max(layout_end(lo), layout_end(new)));
	return true;
}

static __be32
nfsd4_recall_conflict(struct nfs4_layout_stateid *ls)
{
	struct nfs4_file *fp = ls->ls_stid.sc_file;
	struct nfs4_layout_stateid *l, *n;
	__be32 nfserr = nfs_ok;

	assert_spin_locked(&fp->fi_lock);

	list_for_each_entry_safe(l, n, &fp->fi_lo_states, ls_perfile) {
		if (l != ls) {
			nfsd4_recall_file_layout(l);
			nfserr = nfserr_recallconflict;
		}
	}

	return nfserr;
}

__be32
nfsd4_insert_layout(struct nfsd4_layoutget *lgp, struct nfs4_layout_stateid *ls)
{
	struct nfsd4_layout_seg *seg = &lgp->lg_seg;
	struct nfs4_file *fp = ls->ls_stid.sc_file;
	struct nfs4_layout *lp, *new = NULL;
	__be32 nfserr;

	spin_lock(&fp->fi_lock);
	nfserr = nfsd4_recall_conflict(ls);
	if (nfserr)
		goto out;
	spin_lock(&ls->ls_lock);
	list_for_each_entry(lp, &ls->ls_layouts, lo_perstate) {
		if (layouts_try_merge(&lp->lo_seg, seg))
			goto done;
	}
	spin_unlock(&ls->ls_lock);
	spin_unlock(&fp->fi_lock);

	new = kmem_cache_alloc(nfs4_layout_cache, GFP_KERNEL);
	if (!new)
		return nfserr_jukebox;
	memcpy(&new->lo_seg, seg, sizeof(new->lo_seg));
	new->lo_state = ls;

	spin_lock(&fp->fi_lock);
	nfserr = nfsd4_recall_conflict(ls);
	if (nfserr)
		goto out;
	spin_lock(&ls->ls_lock);
	list_for_each_entry(lp, &ls->ls_layouts, lo_perstate) {
		if (layouts_try_merge(&lp->lo_seg, seg))
			goto done;
	}

	refcount_inc(&ls->ls_stid.sc_count);
	list_add_tail(&new->lo_perstate, &ls->ls_layouts);
	new = NULL;
done:
	nfs4_inc_and_copy_stateid(&lgp->lg_sid, &ls->ls_stid);
	spin_unlock(&ls->ls_lock);
out:
	spin_unlock(&fp->fi_lock);
	if (new)
		kmem_cache_free(nfs4_layout_cache, new);
	return nfserr;
}

static void
nfsd4_free_layouts(struct list_head *reaplist)
{
	while (!list_empty(reaplist)) {
		struct nfs4_layout *lp = list_first_entry(reaplist,
				struct nfs4_layout, lo_perstate);

		list_del(&lp->lo_perstate);
		nfs4_put_stid(&lp->lo_state->ls_stid);
		kmem_cache_free(nfs4_layout_cache, lp);
	}
}

static void
nfsd4_return_file_layout(struct nfs4_layout *lp, struct nfsd4_layout_seg *seg,
		struct list_head *reaplist)
{
	struct nfsd4_layout_seg *lo = &lp->lo_seg;
	u64 end = layout_end(lo);

	if (seg->offset <= lo->offset) {
		if (layout_end(seg) >= end) {
			list_move_tail(&lp->lo_perstate, reaplist);
			return;
		}
		lo->offset = layout_end(seg);
	} else {
		/* retain the whole layout segment on a split. */
		if (layout_end(seg) < end) {
			dprintk("%s: split not supported\n", __func__);
			return;
		}
		end = seg->offset;
	}

	layout_update_len(lo, end);
}

__be32
nfsd4_return_file_layouts(struct svc_rqst *rqstp,
		struct nfsd4_compound_state *cstate,
		struct nfsd4_layoutreturn *lrp)
{
	struct nfs4_layout_stateid *ls;
	struct nfs4_layout *lp, *n;
	LIST_HEAD(reaplist);
	__be32 nfserr;
	int found = 0;

	nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lrp->lr_sid,
						false, lrp->lr_layout_type,
						&ls);
	if (nfserr) {
		trace_nfsd_layout_return_lookup_fail(&lrp->lr_sid);
		return nfserr;
	}

	spin_lock(&ls->ls_lock);
	list_for_each_entry_safe(lp, n, &ls->ls_layouts, lo_perstate) {
		if (layouts_overlapping(lp, &lrp->lr_seg)) {
			nfsd4_return_file_layout(lp, &lrp->lr_seg, &reaplist);
			found++;
		}
	}
	if (!list_empty(&ls->ls_layouts)) {
		if (found)
			nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
		lrp->lrs_present = true;
	} else {
		trace_nfsd_layoutstate_unhash(&ls->ls_stid.sc_stateid);
		ls->ls_stid.sc_status |= SC_STATUS_CLOSED;
		lrp->lrs_present = false;
	}
	spin_unlock(&ls->ls_lock);

	mutex_unlock(&ls->ls_mutex);
	nfs4_put_stid(&ls->ls_stid);
	nfsd4_free_layouts(&reaplist);
	return nfs_ok;
}

__be32
nfsd4_return_client_layouts(struct svc_rqst *rqstp,
		struct nfsd4_compound_state *cstate,
		struct nfsd4_layoutreturn *lrp)
{
	struct nfs4_layout_stateid *ls, *n;
	struct nfs4_client *clp = cstate->clp;
	struct nfs4_layout *lp, *t;
	LIST_HEAD(reaplist);

	lrp->lrs_present = false;

	spin_lock(&clp->cl_lock);
	list_for_each_entry_safe(ls, n, &clp->cl_lo_states, ls_perclnt) {
		if (ls->ls_layout_type != lrp->lr_layout_type)
			continue;

		if (lrp->lr_return_type == RETURN_FSID &&
		    !fh_fsid_match(&ls->ls_stid.sc_file->fi_fhandle,
				   &cstate->current_fh.fh_handle))
			continue;

		spin_lock(&ls->ls_lock);
		list_for_each_entry_safe(lp, t, &ls->ls_layouts, lo_perstate) {
			if (lrp->lr_seg.iomode == IOMODE_ANY ||
			    lrp->lr_seg.iomode == lp->lo_seg.iomode)
				list_move_tail(&lp->lo_perstate, &reaplist);
		}
		spin_unlock(&ls->ls_lock);
	}
	spin_unlock(&clp->cl_lock);

	nfsd4_free_layouts(&reaplist);
	return 0;
}

static void
nfsd4_return_all_layouts(struct nfs4_layout_stateid *ls,
		struct list_head *reaplist)
{
	spin_lock(&ls->ls_lock);
	list_splice_init(&ls->ls_layouts, reaplist);
	spin_unlock(&ls->ls_lock);
}

void
nfsd4_return_all_client_layouts(struct nfs4_client *clp)
{
	struct nfs4_layout_stateid *ls, *n;
	LIST_HEAD(reaplist);

	spin_lock(&clp->cl_lock);
	list_for_each_entry_safe(ls, n, &clp->cl_lo_states, ls_perclnt)
		nfsd4_return_all_layouts(ls, &reaplist);
	spin_unlock(&clp->cl_lock);

	nfsd4_free_layouts(&reaplist);
}

void
nfsd4_return_all_file_layouts(struct nfs4_client *clp, struct nfs4_file *fp)
{
	struct nfs4_layout_stateid *ls, *n;
	LIST_HEAD(reaplist);

	spin_lock(&fp->fi_lock);
	list_for_each_entry_safe(ls, n, &fp->fi_lo_states, ls_perfile) {
		if (ls->ls_stid.sc_client == clp)
			nfsd4_return_all_layouts(ls, &reaplist);
	}
	spin_unlock(&fp->fi_lock);

	nfsd4_free_layouts(&reaplist);
}

static void
nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls, struct nfsd_file *file)
{
	struct nfs4_client *clp = ls->ls_stid.sc_client;
	char addr_str[INET6_ADDRSTRLEN];
	static char const nfsd_recall_failed[] = "/sbin/nfsd-recall-failed";
	static char *envp[] = {
		"HOME=/",
		"TERM=linux",
		"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
		NULL
	};
	char *argv[8];
	int error;

	rpc_ntop((struct sockaddr *)&clp->cl_addr, addr_str, sizeof(addr_str));

	printk(KERN_WARNING
		"nfsd: client %s failed to respond to layout recall. "
		"  Fencing..\n", addr_str);

	argv[0] = (char *)nfsd_recall_failed;
	argv[1] = addr_str;
	argv[2] = file->nf_file->f_path.mnt->mnt_sb->s_id;
	argv[3] = NULL;

	error = call_usermodehelper(nfsd_recall_failed, argv, envp,
				    UMH_WAIT_PROC);
	if (error) {
		printk(KERN_ERR "nfsd: fence failed for client %s: %d!\n",
			addr_str, error);
	}
}

static bool
nfsd4_cb_layout_prepare(struct nfsd4_callback *cb)
{
	struct nfs4_layout_stateid *ls =
		container_of(cb, struct nfs4_layout_stateid, ls_recall);

	mutex_lock(&ls->ls_mutex);
	nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid);
	mutex_unlock(&ls->ls_mutex);
	return true;
}

static int
nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
{
	struct nfs4_layout_stateid *ls =
		container_of(cb, struct nfs4_layout_stateid, ls_recall);
	struct nfsd_net *nn;
	ktime_t now, cutoff;
	const struct nfsd4_layout_ops *ops;
	struct nfsd_file *fl;

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

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

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

		if (ktime_before(now, cutoff)) {
			rpc_delay(task, HZ/100); /* 10 mili-seconds */
			return 0;
		}
		fallthrough;
	default:
		/*
		 * Unknown error or non-responding client, we'll need to fence.
		 */
		trace_nfsd_layout_recall_fail(&ls->ls_stid.sc_stateid);
		rcu_read_lock();
		fl = nfsd_file_get(ls->ls_file);
		rcu_read_unlock();
		if (fl) {
			ops = nfsd4_layout_ops[ls->ls_layout_type];
			if (ops->fence_client)
				ops->fence_client(ls, fl);
			else
				nfsd4_cb_layout_fail(ls, fl);
			nfsd_file_put(fl);
		}
		return 1;
	case -NFS4ERR_NOMATCHING_LAYOUT:
		trace_nfsd_layout_recall_done(&ls->ls_stid.sc_stateid);
		task->tk_status = 0;
		return 1;
	}
}

static void
nfsd4_cb_layout_release(struct nfsd4_callback *cb)
{
	struct nfs4_layout_stateid *ls =
		container_of(cb, struct nfs4_layout_stateid, ls_recall);
	LIST_HEAD(reaplist);

	trace_nfsd_layout_recall_release(&ls->ls_stid.sc_stateid);

	nfsd4_return_all_layouts(ls, &reaplist);
	nfsd4_free_layouts(&reaplist);
	nfs4_put_stid(&ls->ls_stid);
}

static const struct nfsd4_callback_ops nfsd4_cb_layout_ops = {
	.prepare	= nfsd4_cb_layout_prepare,
	.done		= nfsd4_cb_layout_done,
	.release	= nfsd4_cb_layout_release,
	.opcode		= OP_CB_LAYOUTRECALL,
};

static bool
nfsd4_layout_lm_break(struct file_lease *fl)
{
	/*
	 * Enforce break lease timeout to prevent NFSD
	 * thread from hanging in __break_lease.
	 */
	nfsd4_recall_file_layout(fl->c.flc_owner);
	return false;
}

static int
nfsd4_layout_lm_change(struct file_lease *onlist, int arg,
		struct list_head *dispose)
{
	BUG_ON(!(arg & F_UNLCK));
	return lease_modify(onlist, arg, dispose);
}

/**
 *  nfsd4_layout_lm_open_conflict - see if the given file points to an inode that has
 *				    an existing open that would conflict with the
 *				    desired lease.
 * @filp:	file to check
 * @arg:	type of lease that we're trying to acquire
 *
 * The kernel will call into this operation to determine whether there
 * are conflicting opens that may prevent the layout from being granted.
 * For nfsd, that check is done at a higher level, so this trivially
 * returns 0.
 */
static int
nfsd4_layout_lm_open_conflict(struct file *filp, int arg)
{
	return 0;
}

static void
nfsd4_layout_fence_worker(struct work_struct *work)
{
	struct delayed_work *dwork = to_delayed_work(work);
	struct nfs4_layout_stateid *ls = container_of(dwork,
			struct nfs4_layout_stateid, ls_fence_work);
	struct nfsd_file *nf;
	struct block_device *bdev;
	struct nfs4_client *clp;
	struct nfsd_net *nn;

	spin_lock(&ls->ls_lock);
	if (list_empty(&ls->ls_layouts)) {
		spin_unlock(&ls->ls_lock);
dispose:
		cancel_delayed_work(&ls->ls_fence_work);
		/* unlock the lease so that tasks waiting on it can proceed */
		nfsd4_close_layout(ls);

		ls->ls_fenced = true;
		spin_lock(&ls->ls_lock);
		ls->ls_fence_inflight = false;
		spin_unlock(&ls->ls_lock);
		nfs4_put_stid(&ls->ls_stid);
		return;
	}
	spin_unlock(&ls->ls_lock);

	rcu_read_lock();
	nf = nfsd_file_get(ls->ls_file);
	rcu_read_unlock();
	if (!nf)
		goto dispose;

	clp = ls->ls_stid.sc_client;
	nn = net_generic(clp->net, nfsd_net_id);
	bdev = nf->nf_file->f_path.mnt->mnt_sb->s_bdev;
	if (nfsd4_layout_ops[ls->ls_layout_type]->fence_client(ls, nf)) {
		/* fenced ok */
		nfsd_file_put(nf);
		pr_warn("%s: FENCED client[%pISpc] clid[%d] to device[%s]\n",
			__func__, (struct sockaddr *)&clp->cl_addr,
			clp->cl_clientid.cl_id - nn->clientid_base,
			bdev->bd_disk->disk_name);
		goto dispose;
	}
	/* fence failed */
	nfsd_file_put(nf);

	if (!clp->cl_fence_retry_warn) {
		pr_warn("%s: FENCE failed client[%pISpc] clid[%d] device[%s]\n",
			__func__, (struct sockaddr *)&clp->cl_addr,
			clp->cl_clientid.cl_id - nn->clientid_base,
			bdev->bd_disk->disk_name);
		clp->cl_fence_retry_warn = true;
	}
	/*
	 * The fence worker retries the fencing operation indefinitely to
	 * prevent data corruption. The admin needs to take the following
	 * actions to restore access to the file for other clients:
	 *
	 *  . shutdown or power off the client being fenced.
	 *  . manually expire the client to release all its state on the server;
	 *    echo 'expire' > /proc/fs/nfsd/clients/clid/ctl'.
	 *
	 *    Where:
	 *
	 *    clid: is the unique client identifier displayed in
	 *          the warning message above.
	 */
	if (!ls->ls_fence_delay)
		ls->ls_fence_delay = HZ;
	else
		ls->ls_fence_delay = min(ls->ls_fence_delay << 1,
					 MAX_FENCE_DELAY);
	mod_delayed_work(system_dfl_wq, &ls->ls_fence_work, ls->ls_fence_delay);
}

/**
 * nfsd4_layout_lm_breaker_timedout - The layout recall has timed out.
 * @fl: file to check
 *
 * If the layout type supports a fence operation, schedule a worker to
 * fence the client from accessing the block device.
 *
 * This function runs under the protection of the spin_lock flc_lock.
 * At this time, the file_lease associated with the layout stateid is
 * on the flc_list. A reference count is incremented on the layout
 * stateid to prevent it from being freed while the fence worker is
 * executing. Once the fence worker finishes its operation, it releases
 * this reference.
 *
 * The fence worker continues to run until either the client has been
 * fenced or the layout becomes invalid. The layout can become invalid
 * as a result of a LAYOUTRETURN or when the CB_LAYOUT recall callback
 * has completed.
 *
 * Return true if the file_lease should be disposed of by the caller;
 * otherwise, return false.
 */
static bool
nfsd4_layout_lm_breaker_timedout(struct file_lease *fl)
{
	struct nfs4_layout_stateid *ls = fl->c.flc_owner;

	if ((!nfsd4_layout_ops[ls->ls_layout_type]->fence_client) ||
			ls->ls_fenced)
		return true;
	/*
	 * Make sure layout has not been returned yet before
	 * taking a reference count on the layout stateid. The
	 * ls_fence_inflight flag is set together with the sc_count
	 * increment under ls_lock so that a fence worker invocation
	 * already in progress (which has cleared WORK_STRUCT_PENDING
	 * but not yet reached dispose:) cannot be coalesced with a
	 * fresh schedule that takes an extra unmatched reference.
	 */
	spin_lock(&ls->ls_lock);
	if (ls->ls_fence_inflight) {
		spin_unlock(&ls->ls_lock);
		return false;
	}
	if (list_empty(&ls->ls_layouts) ||
			!refcount_inc_not_zero(&ls->ls_stid.sc_count)) {
		spin_unlock(&ls->ls_lock);
		return true;
	}
	ls->ls_fence_inflight = true;
	spin_unlock(&ls->ls_lock);

	mod_delayed_work(system_dfl_wq, &ls->ls_fence_work, 0);
	return false;
}

static const struct lease_manager_operations nfsd4_layouts_lm_ops = {
	.lm_break		= nfsd4_layout_lm_break,
	.lm_change		= nfsd4_layout_lm_change,
	.lm_open_conflict	= nfsd4_layout_lm_open_conflict,
	.lm_breaker_timedout	= nfsd4_layout_lm_breaker_timedout,
};

int
nfsd4_init_pnfs(void)
{
	int i;

	for (i = 0; i < DEVID_HASH_SIZE; i++)
		INIT_LIST_HEAD(&nfsd_devid_hash[i]);

	nfs4_layout_cache = KMEM_CACHE(nfs4_layout, 0);
	if (!nfs4_layout_cache)
		return -ENOMEM;

	nfs4_layout_stateid_cache = KMEM_CACHE(nfs4_layout_stateid, 0);
	if (!nfs4_layout_stateid_cache) {
		kmem_cache_destroy(nfs4_layout_cache);
		return -ENOMEM;
	}
	return 0;
}

void
nfsd4_exit_pnfs(void)
{
	int i;

	kmem_cache_destroy(nfs4_layout_cache);
	kmem_cache_destroy(nfs4_layout_stateid_cache);

	for (i = 0; i < DEVID_HASH_SIZE; i++) {
		struct nfsd4_deviceid_map *map, *n;

		list_for_each_entry_safe(map, n, &nfsd_devid_hash[i], hash)
			kfree(map);
	}
}
