Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d10c2c1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-3.17' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields:
 "This includes a major rewrite of the NFSv4 state code, which has
  always depended on a single mutex.  As an example, open creates are no
  longer serialized, fixing a performance regression on NFSv3->NFSv4
  upgrades.  Thanks to Jeff, Trond, and Benny, and to Christoph for
  review.

  Also some RDMA fixes from Chuck Lever and Steve Wise, and
  miscellaneous fixes from Kinglong Mee and others"

* 'for-3.17' of git://linux-nfs.org/~bfields/linux: (167 commits)
  svcrdma: remove rdma_create_qp() failure recovery logic
  nfsd: add some comments to the nfsd4 object definitions
  nfsd: remove the client_mutex and the nfs4_lock/unlock_state wrappers
  nfsd: remove nfs4_lock_state: nfs4_state_shutdown_net
  nfsd: remove nfs4_lock_state: nfs4_laundromat
  nfsd: Remove nfs4_lock_state(): reclaim_complete()
  nfsd: Remove nfs4_lock_state(): setclientid, setclientid_confirm, renew
  nfsd: Remove nfs4_lock_state(): exchange_id, create/destroy_session()
  nfsd: Remove nfs4_lock_state(): nfsd4_open and nfsd4_open_confirm
  nfsd: Remove nfs4_lock_state(): nfsd4_delegreturn()
  nfsd: Remove nfs4_lock_state(): nfsd4_open_downgrade + nfsd4_close
  nfsd: Remove nfs4_lock_state(): nfsd4_lock/locku/lockt()
  nfsd: Remove nfs4_lock_state(): nfsd4_release_lockowner
  nfsd: Remove nfs4_lock_state(): nfsd4_test_stateid/nfsd4_free_stateid
  nfsd: Remove nfs4_lock_state(): nfs4_preprocess_stateid_op()
  nfsd: remove old fault injection infrastructure
  nfsd: add more granular locking to *_delegations fault injectors
  nfsd: add more granular locking to forget_openowners fault injector
  nfsd: add more granular locking to forget_locks fault injector
  nfsd: add a list_head arg to nfsd_foreach_client_lock
  ...
parents 023f78b0 d1e458fe
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ struct svc_rqst;
#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \
			/ sizeof(struct nfs4_ace))

struct nfs4_acl *nfs4_acl_new(int);
int nfs4_acl_bytes(int entries);
int nfs4_acl_get_whotype(char *, u32);
__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who);

+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
	validate_process_creds();

	/* discard any old override before preparing the new set */
	revert_creds(get_cred(current->real_cred));
	revert_creds(get_cred(current_real_cred()));
	new = prepare_creds();
	if (!new)
		return -ENOMEM;
+3 −3
Original line number Diff line number Diff line
@@ -698,8 +698,8 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)

	kref_get(&item->ex_client->ref);
	new->ex_client = item->ex_client;
	new->ex_path.dentry = dget(item->ex_path.dentry);
	new->ex_path.mnt = mntget(item->ex_path.mnt);
	new->ex_path = item->ex_path;
	path_get(&item->ex_path);
	new->ex_fslocs.locations = NULL;
	new->ex_fslocs.locations_count = 0;
	new->ex_fslocs.migrated = 0;
@@ -1253,7 +1253,7 @@ static int e_show(struct seq_file *m, void *p)
		return 0;
	}

	cache_get(&exp->h);
	exp_get(exp);
	if (cache_check(cd, &exp->h, NULL))
		return 0;
	exp_put(exp);
+2 −1
Original line number Diff line number Diff line
@@ -101,9 +101,10 @@ static inline void exp_put(struct svc_export *exp)
	cache_put(&exp->h, exp->cd);
}

static inline void exp_get(struct svc_export *exp)
static inline struct svc_export *exp_get(struct svc_export *exp)
{
	cache_get(&exp->h);
	return exp;
}
struct svc_export * rqst_exp_find(struct svc_rqst *, int, u32 *);

+62 −76
Original line number Diff line number Diff line
@@ -17,81 +17,13 @@

struct nfsd_fault_inject_op {
	char *file;
	u64 (*forget)(struct nfs4_client *, u64);
	u64 (*print)(struct nfs4_client *, u64);
	u64 (*get)(void);
	u64 (*set_val)(u64);
	u64 (*set_clnt)(struct sockaddr_storage *, size_t);
};

static struct nfsd_fault_inject_op inject_ops[] = {
	{
		.file   = "forget_clients",
		.forget = nfsd_forget_client,
		.print  = nfsd_print_client,
	},
	{
		.file   = "forget_locks",
		.forget = nfsd_forget_client_locks,
		.print  = nfsd_print_client_locks,
	},
	{
		.file   = "forget_openowners",
		.forget = nfsd_forget_client_openowners,
		.print  = nfsd_print_client_openowners,
	},
	{
		.file   = "forget_delegations",
		.forget = nfsd_forget_client_delegations,
		.print  = nfsd_print_client_delegations,
	},
	{
		.file   = "recall_delegations",
		.forget = nfsd_recall_client_delegations,
		.print  = nfsd_print_client_delegations,
	},
};

static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op);
static struct dentry *debug_dir;

static void nfsd_inject_set(struct nfsd_fault_inject_op *op, u64 val)
{
	u64 count = 0;

	if (val == 0)
		printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file);
	else
		printk(KERN_INFO "NFSD Fault Injection: %s (n = %llu)", op->file, val);

	nfs4_lock_state();
	count = nfsd_for_n_state(val, op->forget);
	nfs4_unlock_state();
	printk(KERN_INFO "NFSD: %s: found %llu", op->file, count);
}

static void nfsd_inject_set_client(struct nfsd_fault_inject_op *op,
				   struct sockaddr_storage *addr,
				   size_t addr_size)
{
	char buf[INET6_ADDRSTRLEN];
	struct nfs4_client *clp;
	u64 count;

	nfs4_lock_state();
	clp = nfsd_find_client(addr, addr_size);
	if (clp) {
		count = op->forget(clp, 0);
		rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
		printk(KERN_INFO "NFSD [%s]: Client %s had %llu state object(s)\n", op->file, buf, count);
	}
	nfs4_unlock_state();
}

static void nfsd_inject_get(struct nfsd_fault_inject_op *op, u64 *val)
{
	nfs4_lock_state();
	*val = nfsd_for_n_state(0, op->print);
	nfs4_unlock_state();
}

static ssize_t fault_inject_read(struct file *file, char __user *buf,
				 size_t len, loff_t *ppos)
{
@@ -99,9 +31,10 @@ static ssize_t fault_inject_read(struct file *file, char __user *buf,
	char read_buf[25];
	size_t size;
	loff_t pos = *ppos;
	struct nfsd_fault_inject_op *op = file_inode(file)->i_private;

	if (!pos)
		nfsd_inject_get(file_inode(file)->i_private, &val);
		val = op->get();
	size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val);

	return simple_read_from_buffer(buf, len, ppos, read_buf, size);
@@ -114,18 +47,36 @@ static ssize_t fault_inject_write(struct file *file, const char __user *buf,
	size_t size = min(sizeof(write_buf) - 1, len);
	struct net *net = current->nsproxy->net_ns;
	struct sockaddr_storage sa;
	struct nfsd_fault_inject_op *op = file_inode(file)->i_private;
	u64 val;
	char *nl;

	if (copy_from_user(write_buf, buf, size))
		return -EFAULT;
	write_buf[size] = '\0';

	/* Deal with any embedded newlines in the string */
	nl = strchr(write_buf, '\n');
	if (nl) {
		size = nl - write_buf;
		*nl = '\0';
	}

	size = rpc_pton(net, write_buf, size, (struct sockaddr *)&sa, sizeof(sa));
	if (size > 0)
		nfsd_inject_set_client(file_inode(file)->i_private, &sa, size);
	else {
	if (size > 0) {
		val = op->set_clnt(&sa, size);
		if (val)
			pr_info("NFSD [%s]: Client %s had %llu state object(s)\n",
				op->file, write_buf, val);
	} else {
		val = simple_strtoll(write_buf, NULL, 0);
		nfsd_inject_set(file_inode(file)->i_private, val);
		if (val == 0)
			pr_info("NFSD Fault Injection: %s (all)", op->file);
		else
			pr_info("NFSD Fault Injection: %s (n = %llu)",
				op->file, val);
		val = op->set_val(val);
		pr_info("NFSD: %s: found %llu", op->file, val);
	}
	return len; /* on success, claim we got the whole input */
}
@@ -141,6 +92,41 @@ void nfsd_fault_inject_cleanup(void)
	debugfs_remove_recursive(debug_dir);
}

static struct nfsd_fault_inject_op inject_ops[] = {
	{
		.file     = "forget_clients",
		.get	  = nfsd_inject_print_clients,
		.set_val  = nfsd_inject_forget_clients,
		.set_clnt = nfsd_inject_forget_client,
	},
	{
		.file     = "forget_locks",
		.get	  = nfsd_inject_print_locks,
		.set_val  = nfsd_inject_forget_locks,
		.set_clnt = nfsd_inject_forget_client_locks,
	},
	{
		.file     = "forget_openowners",
		.get	  = nfsd_inject_print_openowners,
		.set_val  = nfsd_inject_forget_openowners,
		.set_clnt = nfsd_inject_forget_client_openowners,
	},
	{
		.file     = "forget_delegations",
		.get	  = nfsd_inject_print_delegations,
		.set_val  = nfsd_inject_forget_delegations,
		.set_clnt = nfsd_inject_forget_client_delegations,
	},
	{
		.file     = "recall_delegations",
		.get	  = nfsd_inject_print_delegations,
		.set_val  = nfsd_inject_recall_delegations,
		.set_clnt = nfsd_inject_recall_client_delegations,
	},
};

#define NUM_INJECT_OPS (sizeof(inject_ops)/sizeof(struct nfsd_fault_inject_op))

int nfsd_fault_inject_init(void)
{
	unsigned int i;
Loading