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

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

Merge branch 'nfsd-next' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields:
 "This was a very quiet cycle! Just a few bugfixes and some cleanup"

* 'nfsd-next' of git://linux-nfs.org/~bfields/linux:
  rpc: let xdr layer allocate gssproxy receieve pages
  rpc: fix huge kmalloc's in gss-proxy
  rpc: comment on linux_cred encoding, treat all as unsigned
  rpc: clean up decoding of gssproxy linux creds
  svcrpc: remove unused rq_resused
  nfsd4: nfsd4_create_clid_dir prints uninitialized data
  nfsd4: fix leak of inode reference on delegation failure
  Revert "nfsd: nfs4_file_get_access: need to be more careful with O_RDWR"
  sunrpc: prepare NFS for 2038
  nfsd4: fix setlease error return
  nfsd: nfs4_file_get_access: need to be more careful with O_RDWR
parents 516f7b3f d4a51656
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -173,8 +173,6 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
	int status;
	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);

	dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);

	if (test_and_set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
		return;
	if (!nn->rec_file)
+21 −12
Original line number Diff line number Diff line
@@ -368,11 +368,8 @@ static struct nfs4_delegation *
alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh)
{
	struct nfs4_delegation *dp;
	struct nfs4_file *fp = stp->st_file;

	dprintk("NFSD alloc_init_deleg\n");
	if (fp->fi_had_conflict)
		return NULL;
	if (num_delegations > max_delegations)
		return NULL;
	dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
@@ -389,8 +386,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
	INIT_LIST_HEAD(&dp->dl_perfile);
	INIT_LIST_HEAD(&dp->dl_perclnt);
	INIT_LIST_HEAD(&dp->dl_recall_lru);
	get_nfs4_file(fp);
	dp->dl_file = fp;
	dp->dl_file = NULL;
	dp->dl_type = NFS4_OPEN_DELEGATE_READ;
	fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
	dp->dl_time = 0;
@@ -3035,7 +3031,7 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
	if (status) {
		list_del_init(&dp->dl_perclnt);
		locks_free_lock(fl);
		return -ENOMEM;
		return status;
	}
	fp->fi_lease = fl;
	fp->fi_deleg_file = get_file(fl->fl_file);
@@ -3044,22 +3040,35 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
	return 0;
}

static int nfs4_set_delegation(struct nfs4_delegation *dp)
static int nfs4_set_delegation(struct nfs4_delegation *dp, struct nfs4_file *fp)
{
	struct nfs4_file *fp = dp->dl_file;
	int status;

	if (!fp->fi_lease)
		return nfs4_setlease(dp);
	if (fp->fi_had_conflict)
		return -EAGAIN;
	get_nfs4_file(fp);
	dp->dl_file = fp;
	if (!fp->fi_lease) {
		status = nfs4_setlease(dp);
		if (status)
			goto out_free;
		return 0;
	}
	spin_lock(&recall_lock);
	if (fp->fi_had_conflict) {
		spin_unlock(&recall_lock);
		return -EAGAIN;
		status = -EAGAIN;
		goto out_free;
	}
	atomic_inc(&fp->fi_delegees);
	list_add(&dp->dl_perfile, &fp->fi_delegations);
	spin_unlock(&recall_lock);
	list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
	return 0;
out_free:
	put_nfs4_file(fp);
	dp->dl_file = fp;
	return status;
}

static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
@@ -3134,7 +3143,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
	dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh);
	if (dp == NULL)
		goto out_no_deleg;
	status = nfs4_set_delegation(dp);
	status = nfs4_set_delegation(dp, stp->st_file);
	if (status)
		goto out_free;

+20 −2
Original line number Diff line number Diff line
@@ -264,12 +264,30 @@ static inline int get_uint(char **bpp, unsigned int *anint)
	return 0;
}

static inline int get_time(char **bpp, time_t *time)
{
	char buf[50];
	long long ll;
	int len = qword_get(bpp, buf, sizeof(buf));

	if (len < 0)
		return -EINVAL;
	if (len == 0)
		return -ENOENT;

	if (kstrtoll(buf, 0, &ll))
		return -EINVAL;

	*time = (time_t)ll;
	return 0;
}

static inline time_t get_expiry(char **bpp)
{
	int rv;
	time_t rv;
	struct timespec boot;

	if (get_int(bpp, &rv))
	if (get_time(bpp, &rv))
		return 0;
	if (rv < 0)
		return 0;
+0 −1
Original line number Diff line number Diff line
@@ -243,7 +243,6 @@ struct svc_rqst {
	struct xdr_buf		rq_res;
	struct page *		rq_pages[RPCSVC_MAXPAGES];
	struct page *		*rq_respages;	/* points into rq_pages */
	int			rq_resused;	/* number of pages used for result */
	struct page *		*rq_next_page; /* next reply page to use */

	struct kvec		rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
+26 −0
Original line number Diff line number Diff line
@@ -213,6 +213,26 @@ static int gssp_call(struct net *net, struct rpc_message *msg)
	return status;
}

static void gssp_free_receive_pages(struct gssx_arg_accept_sec_context *arg)
{
	int i;

	for (i = 0; i < arg->npages && arg->pages[i]; i++)
		__free_page(arg->pages[i]);
}

static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg)
{
	arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE);
	arg->pages = kzalloc(arg->npages * sizeof(struct page *), GFP_KERNEL);
	/*
	 * XXX: actual pages are allocated by xdr layer in
	 * xdr_partial_copy_from_skb.
	 */
	if (!arg->pages)
		return -ENOMEM;
	return 0;
}

/*
 * Public functions
@@ -261,10 +281,16 @@ int gssp_accept_sec_context_upcall(struct net *net,
		arg.context_handle = &ctxh;
	res.output_token->len = GSSX_max_output_token_sz;

	ret = gssp_alloc_receive_pages(&arg);
	if (ret)
		return ret;

	/* use nfs/ for targ_name ? */

	ret = gssp_call(net, &msg);

	gssp_free_receive_pages(&arg);

	/* we need to fetch all data even in case of error so
	 * that we can free special strctures is they have been allocated */
	data->major_status = res.status.major_status;
Loading