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

Commit d2c3ac7e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull nfsd updates from Bruce Fields:
 "A relatively quiet cycle, with a mix of cleanup and smaller bugfixes"

* 'for-4.2' of git://linux-nfs.org/~bfields/linux: (24 commits)
  sunrpc: use sg_init_one() in krb5_rc4_setup_enc/seq_key()
  nfsd: wrap too long lines in nfsd4_encode_read
  nfsd: fput rd_file from XDR encode context
  nfsd: take struct file setup fully into nfs4_preprocess_stateid_op
  nfsd: refactor nfs4_preprocess_stateid_op
  nfsd: clean up raparams handling
  nfsd: use swap() in sort_pacl_range()
  rpcrdma: Merge svcrdma and xprtrdma modules into one
  svcrdma: Add a separate "max data segs macro for svcrdma
  svcrdma: Replace GFP_KERNEL in a loop with GFP_NOFAIL
  svcrdma: Keep rpcrdma_msg fields in network byte-order
  svcrdma: Fix byte-swapping in svc_rdma_sendto.c
  nfsd: Update callback sequnce id only CB_SEQUENCE success
  nfsd: Reset cb_status in nfsd4_cb_prepare() at retrying
  svcrdma: Remove svc_rdma_xdr_decode_deferred_req()
  SUNRPC: Move EXPORT_SYMBOL for svc_process
  uapi/nfs: Add NFSv4.1 ACL definitions
  nfsd: Remove dead declarations
  nfsd: work around a gcc-5.1 warning
  nfsd: Checking for acl support does not require fetching any acls
  ...
parents 546fac60 901f1379
Loading
Loading
Loading
Loading
+4 −40
Original line number Diff line number Diff line
@@ -68,16 +68,10 @@ sockets-enqueued
	rate of change for this counter is zero; significantly non-zero
	values may indicate a performance limitation.

	This can happen either because there are too few nfsd threads in the
	thread pool for the NFS workload (the workload is thread-limited),
	or because the NFS workload needs more CPU time than is available in
	the thread pool (the workload is CPU-limited).  In the former case,
	configuring more nfsd threads will probably improve the performance
	of the NFS workload.  In the latter case, the sunrpc server layer is
	already choosing not to wake idle nfsd threads because there are too
	many nfsd threads which want to run but cannot, so configuring more
	nfsd threads will make no difference whatsoever.  The overloads-avoided
	statistic (see below) can be used to distinguish these cases.
	This can happen because there are too few nfsd threads in the thread
	pool for the NFS workload (the workload is thread-limited), in which
	case configuring more nfsd threads will probably improve the
	performance of the NFS workload.

threads-woken
	Counts how many times an idle nfsd thread is woken to try to
@@ -88,36 +82,6 @@ threads-woken
	thing.  The ideal rate of change for this counter will be close
	to but less than the rate of change of the packets-arrived counter.

overloads-avoided
	Counts how many times the sunrpc server layer chose not to wake an
	nfsd thread, despite the presence of idle nfsd threads, because
	too many nfsd threads had been recently woken but could not get
	enough CPU time to actually run.

	This statistic counts a circumstance where the sunrpc layer
	heuristically avoids overloading the CPU scheduler with too many
	runnable nfsd threads.  The ideal rate of change for this counter
	is zero.  Significant non-zero values indicate that the workload
	is CPU limited.  Usually this is associated with heavy CPU usage
	on all the CPUs in the nfsd thread pool.

	If a sustained large overloads-avoided rate is detected on a pool,
	the top(1) utility should be used to check for the following
	pattern of CPU usage on all the CPUs associated with the given
	nfsd thread pool.

	 - %us ~= 0 (as you're *NOT* running applications on your NFS server)

	 - %wa ~= 0

	 - %id ~= 0

	 - %sy + %hi + %si ~= 100

	If this pattern is seen, configuring more nfsd threads will *not*
	improve the performance of the workload.  If this patten is not
	seen, then something more subtle is wrong.

threads-timedout
	Counts how many times an nfsd thread triggered an idle timeout,
	i.e. was not woken to handle any incoming network packets for
+7 −5
Original line number Diff line number Diff line
@@ -805,7 +805,7 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,

static __be32
compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
		const char *name, int namlen)
		 const char *name, int namlen, u64 ino)
{
	struct svc_export	*exp;
	struct dentry		*dparent, *dchild;
@@ -830,19 +830,21 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
		goto out;
	if (d_really_is_negative(dchild))
		goto out;
	if (dchild->d_inode->i_ino != ino)
		goto out;
	rv = fh_compose(fhp, exp, dchild, &cd->fh);
out:
	dput(dchild);
	return rv;
}

static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen)
static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen, u64 ino)
{
	struct svc_fh	*fh = &cd->scratch;
	__be32 err;

	fh_init(fh, NFS3_FHSIZE);
	err = compose_entry_fh(cd, fh, name, namlen);
	err = compose_entry_fh(cd, fh, name, namlen, ino);
	if (err) {
		*p++ = 0;
		*p++ = 0;
@@ -927,7 +929,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
		p = encode_entry_baggage(cd, p, name, namlen, ino);

		if (plus)
			p = encode_entryplus_baggage(cd, p, name, namlen);
			p = encode_entryplus_baggage(cd, p, name, namlen, ino);
		num_entry_words = p - cd->buffer;
	} else if (*(page+1) != NULL) {
		/* temporarily encode entry into next page, then move back to
@@ -941,7 +943,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
		p1 = encode_entry_baggage(cd, p1, name, namlen, ino);

		if (plus)
			p1 = encode_entryplus_baggage(cd, p1, name, namlen);
			p1 = encode_entryplus_baggage(cd, p1, name, namlen, ino);

		/* determine entry word length and lengths to go in pages */
		num_entry_words = p1 - tmp;
+2 −16
Original line number Diff line number Diff line
@@ -52,10 +52,6 @@
#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE)
#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)

/* We don't support these bits; insist they be neither allowed nor denied */
#define NFS4_MASK_UNSUPP (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
		| NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)

/* flags used to simulate posix default ACLs */
#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
		| NFS4_ACE_DIRECTORY_INHERIT_ACE)
@@ -64,9 +60,6 @@
		| NFS4_ACE_INHERIT_ONLY_ACE \
		| NFS4_ACE_IDENTIFIER_GROUP)

#define MASK_EQUAL(mask1, mask2) \
	( ((mask1) & NFS4_ACE_MASK_ALL) == ((mask2) & NFS4_ACE_MASK_ALL) )

static u32
mask_from_posix(unsigned short perm, unsigned int flags)
{
@@ -126,11 +119,6 @@ low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
		*mode |= ACL_EXECUTE;
}

struct ace_container {
	struct nfs4_ace  *ace;
	struct list_head  ace_l;
};

static short ace2type(struct nfs4_ace *);
static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *,
				unsigned int);
@@ -384,7 +372,6 @@ pace_gt(struct posix_acl_entry *pace1, struct posix_acl_entry *pace2)
static void
sort_pacl_range(struct posix_acl *pacl, int start, int end) {
	int sorted = 0, i;
	struct posix_acl_entry tmp;

	/* We just do a bubble sort; easy to do in place, and we're not
	 * expecting acl's to be long enough to justify anything more. */
@@ -394,9 +381,8 @@ sort_pacl_range(struct posix_acl *pacl, int start, int end) {
			if (pace_gt(&pacl->a_entries[i],
				    &pacl->a_entries[i+1])) {
				sorted = 0;
				tmp = pacl->a_entries[i];
				pacl->a_entries[i] = pacl->a_entries[i+1];
				pacl->a_entries[i+1] = tmp;
				swap(pacl->a_entries[i],
				     pacl->a_entries[i + 1]);
			}
		}
	}
+13 −2
Original line number Diff line number Diff line
@@ -455,6 +455,7 @@ static int decode_cb_sequence4res(struct xdr_stream *xdr,
	if (unlikely(status || cb->cb_status))
		return status;

	cb->cb_update_seq_nr = true;
	return decode_cb_sequence4resok(xdr, cb);
}

@@ -875,6 +876,8 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
	u32 minorversion = clp->cl_minorversion;

	cb->cb_minorversion = minorversion;
	cb->cb_update_seq_nr = false;
	cb->cb_status = 0;
	if (minorversion) {
		if (!nfsd41_cb_get_slot(clp, task))
			return;
@@ -891,9 +894,16 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
		clp->cl_minorversion);

	if (clp->cl_minorversion) {
		/* No need for lock, access serialized in nfsd4_cb_prepare */
		if (!task->tk_status)
		/*
		 * No need for lock, access serialized in nfsd4_cb_prepare
		 *
		 * RFC5661 20.9.3
		 * If CB_SEQUENCE returns an error, then the state of the slot
		 * (sequence ID, cached reply) MUST NOT change.
		 */
		if (cb->cb_update_seq_nr)
			++clp->cl_cb_session->se_cb_seq_nr;

		clear_bit(0, &clp->cl_cb_slot_busy);
		rpc_wake_up_next(&clp->cl_cb_waitq);
		dprintk("%s: freed slot, new seqid=%d\n", __func__,
@@ -1090,6 +1100,7 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
	cb->cb_ops = ops;
	INIT_WORK(&cb->cb_work, nfsd4_run_cb_work);
	cb->cb_status = 0;
	cb->cb_update_seq_nr = false;
	cb->cb_need_restart = false;
}

+15 −28
Original line number Diff line number Diff line
@@ -760,8 +760,6 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
{
	__be32 status;

	/* no need to check permission - this will be done in nfsd_read() */

	read->rd_filp = NULL;
	if (read->rd_offset >= OFFSET_MAX)
		return nfserr_inval;
@@ -778,9 +776,9 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);

	/* check stateid */
	if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
						 cstate, &read->rd_stateid,
						 RD_STATE, &read->rd_filp))) {
	status = nfs4_preprocess_stateid_op(rqstp, cstate, &read->rd_stateid,
			RD_STATE, &read->rd_filp, &read->rd_tmp_file);
	if (status) {
		dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
		goto out;
	}
@@ -924,8 +922,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	int err;

	if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
		status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
			&setattr->sa_stateid, WR_STATE, NULL);
		status = nfs4_preprocess_stateid_op(rqstp, cstate,
			&setattr->sa_stateid, WR_STATE, NULL, NULL);
		if (status) {
			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
			return status;
@@ -986,13 +984,11 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	unsigned long cnt;
	int nvecs;

	/* no need to check permission - this will be done in nfsd_write() */

	if (write->wr_offset >= OFFSET_MAX)
		return nfserr_inval;

	status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
					cstate, stateid, WR_STATE, &filp);
	status = nfs4_preprocess_stateid_op(rqstp, cstate, stateid, WR_STATE,
			&filp, NULL);
	if (status) {
		dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
		return status;
@@ -1005,10 +1001,9 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	nvecs = fill_in_write_vector(rqstp->rq_vec, write);
	WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));

	status =  nfsd_write(rqstp, &cstate->current_fh, filp,
			     write->wr_offset, rqstp->rq_vec, nvecs,
			     &cnt, &write->wr_how_written);
	if (filp)
	status = nfsd_vfs_write(rqstp, &cstate->current_fh, filp,
				write->wr_offset, rqstp->rq_vec, nvecs, &cnt,
				&write->wr_how_written);
	fput(filp);

	write->wr_bytes_written = cnt;
@@ -1023,15 +1018,13 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	__be32 status = nfserr_notsupp;
	struct file *file;

	status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
	status = nfs4_preprocess_stateid_op(rqstp, cstate,
					    &fallocate->falloc_stateid,
					    WR_STATE, &file);
					    WR_STATE, &file, NULL);
	if (status != nfs_ok) {
		dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
		return status;
	}
	if (!file)
		return nfserr_bad_stateid;

	status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
				     fallocate->falloc_offset,
@@ -1064,15 +1057,13 @@ nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	__be32 status;
	struct file *file;

	status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
	status = nfs4_preprocess_stateid_op(rqstp, cstate,
					    &seek->seek_stateid,
					    RD_STATE, &file);
					    RD_STATE, &file, NULL);
	if (status) {
		dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
		return status;
	}
	if (!file)
		return nfserr_bad_stateid;

	switch (seek->seek_whence) {
	case NFS4_CONTENT_DATA:
@@ -1732,10 +1723,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
			be32_to_cpu(status));

		nfsd4_cstate_clear_replay(cstate);
		/* XXX Ugh, we need to get rid of this kind of special case: */
		if (op->opnum == OP_READ && op->u.read.rd_filp)
			fput(op->u.read.rd_filp);

		nfsd4_increment_op_stats(op->opnum);
	}

Loading