Re: different kernels mean NFS4/GSSAPI works or doesn't

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11-03-30 08:09 AM, Brian J. Murrell wrote:
> 
> OK.  So I have linux-2.6.32.11.tar.bz2 and patch-2.6.32.12.bz2 from
> kernel.org.
> 
> patch-2.6.32.12.bz2 doesn't apply cleanly to the linux-2.6.32.11 tree
> that's in linux-2.6.32.11.tar.bz2 though:
> 
> # bzcat ../patch-2.6.32.12.bz2 | patch -p1 --dry-run
> patching file Documentation/Changes
> Reversed (or previously applied) patch detected!  Assume -R? [n]

OK.  I figured this out.  .12 patch is to 2.6.32 not 2.6.32.11.

Any ideas on which of the below I should try backing out in my .12 build
to see which might be causing the problem?

> diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
> index fc6a43c..2370ab4 100644
> --- a/net/sunrpc/auth_gss/auth_gss.c
> +++ b/net/sunrpc/auth_gss/auth_gss.c
> @@ -485,7 +485,7 @@ gss_refresh_upcall(struct rpc_task *task)
>  	dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
>  								cred->cr_uid);
>  	gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
> -	if (IS_ERR(gss_msg) == -EAGAIN) {
> +	if (PTR_ERR(gss_msg) == -EAGAIN) {
>  		/* XXX: warning on the first, under the assumption we
>  		 * shouldn't normally hit this case on a refresh. */
>  		warn_gssd();
> @@ -644,7 +644,22 @@ gss_pipe_downcall(struct file *filp, const char
> __user *src, size_t mlen)
>  	p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
>  	if (IS_ERR(p)) {
>  		err = PTR_ERR(p);
> -		gss_msg->msg.errno = (err == -EAGAIN) ? -EAGAIN : -EACCES;
> +		switch (err) {
> +		case -EACCES:
> +			gss_msg->msg.errno = err;
> +			err = mlen;
> +			break;
> +		case -EFAULT:
> +		case -ENOMEM:
> +		case -EINVAL:
> +		case -ENOSYS:
> +			gss_msg->msg.errno = -EAGAIN;
> +			break;
> +		default:
> +			printk(KERN_CRIT "%s: bad return from "
> +				"gss_fill_context: %ld\n", __func__, err);
> +			BUG();
> +		}
>  		goto err_release_msg;
>  	}
>  	gss_msg->ctx = gss_get_ctx(ctx);
> @@ -1258,9 +1273,8 @@ alloc_enc_pages(struct rpc_rqst *rqstp)
>  	rqstp->rq_release_snd_buf = priv_release_snd_buf;
>  	return 0;
>  out_free:
> -	for (i--; i >= 0; i--) {
> -		__free_page(rqstp->rq_enc_pages[i]);
> -	}
> +	rqstp->rq_enc_pages_num = i;
> +	priv_release_snd_buf(rqstp);
>  out:
>  	return -EAGAIN;
>  }
> diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c
> b/net/sunrpc/auth_gss/gss_krb5_mech.c
> index ef45eba..2deb0ed 100644
> --- a/net/sunrpc/auth_gss/gss_krb5_mech.c
> +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
> @@ -131,8 +131,10 @@ gss_import_sec_context_kerberos(const void *p,
>  	struct	krb5_ctx *ctx;
>  	int tmp;
> 
> -	if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS)))
> +	if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) {
> +		p = ERR_PTR(-ENOMEM);
>  		goto out_err;
> +	}
> 
>  	p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
>  	if (IS_ERR(p))
> diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c
> b/net/sunrpc/auth_gss/gss_mech_switch.c
> index 6efbb0c..76e4c6f 100644
> --- a/net/sunrpc/auth_gss/gss_mech_switch.c
> +++ b/net/sunrpc/auth_gss/gss_mech_switch.c
> @@ -252,7 +252,7 @@ gss_import_sec_context(const void *input_token,
> size_t bufsize,
>  		       struct gss_ctx		**ctx_id)
>  {
>  	if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL)))
> -		return GSS_S_FAILURE;
> +		return -ENOMEM;
>  	(*ctx_id)->mech_type = gss_mech_get(mech);
> 
>  	return mech->gm_ops
> diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
> index 49278f8..27a2378 100644
> --- a/net/sunrpc/rpc_pipe.c
> +++ b/net/sunrpc/rpc_pipe.c
> @@ -587,6 +587,8 @@ static struct dentry
> *__rpc_lookup_create_exclusive(struct dentry *parent,
>  	struct dentry *dentry;
> 
>  	dentry = __rpc_lookup_create(parent, name);
> +	if (IS_ERR(dentry))
> +		return dentry;
>  	if (dentry->d_inode == NULL)
>  		return dentry;
>  	dput(dentry);
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index df124f7..3fbd6ba 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -711,7 +711,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
>  	spin_unlock_bh(&pool->sp_lock);
> 
>  	len = 0;
> -	if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
> +	if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
> +		dprintk("svc_recv: found XPT_CLOSE\n");
> +		svc_delete_xprt(xprt);
> +	} else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
>  		struct svc_xprt *newxpt;
>  		newxpt = xprt->xpt_ops->xpo_accept(xprt);
>  		if (newxpt) {
> @@ -737,7 +740,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
>  			svc_xprt_received(newxpt);
>  		}
>  		svc_xprt_received(xprt);
> -	} else if (!test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
> +	} else {
>  		dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
>  			rqstp, pool->sp_id, xprt,
>  			atomic_read(&xprt->xpt_ref.refcount));
> @@ -750,11 +753,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
>  		dprintk("svc: got len=%d\n", len);
>  	}
> 
> -	if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
> -		dprintk("svc_recv: found XPT_CLOSE\n");
> -		svc_delete_xprt(xprt);
> -	}
> -
>  	/* No data, incomplete (TCP) read, or accept() */
>  	if (len == 0 || len == -EAGAIN) {
>  		rqstp->rq_res.len = 0;
> @@ -900,11 +898,8 @@ void svc_delete_xprt(struct svc_xprt *xprt)
>  	if (test_bit(XPT_TEMP, &xprt->xpt_flags))
>  		serv->sv_tmpcnt--;
> 
> -	for (dr = svc_deferred_dequeue(xprt); dr;
> -	     dr = svc_deferred_dequeue(xprt)) {
> -		svc_xprt_put(xprt);
> +	while ((dr = svc_deferred_dequeue(xprt)) != NULL)
>  		kfree(dr);
> -	}
> 
>  	svc_xprt_put(xprt);
>  	spin_unlock_bh(&serv->sv_lock);
> diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
> index 117f68a..97cc3de 100644
> --- a/net/sunrpc/svcauth_unix.c
> +++ b/net/sunrpc/svcauth_unix.c
> @@ -655,23 +655,25 @@ static struct unix_gid *unix_gid_lookup(uid_t uid)
>  		return NULL;
>  }
> 
> -static int unix_gid_find(uid_t uid, struct group_info **gip,
> -			 struct svc_rqst *rqstp)
> +static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
>  {
> -	struct unix_gid *ug = unix_gid_lookup(uid);
> +	struct unix_gid *ug;
> +	struct group_info *gi;
> +	int ret;
> +
> +	ug = unix_gid_lookup(uid);
>  	if (!ug)
> -		return -EAGAIN;
> -	switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) {
> +		return ERR_PTR(-EAGAIN);
> +	ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle);
> +	switch (ret) {
>  	case -ENOENT:
> -		*gip = NULL;
> -		return 0;
> +		return ERR_PTR(-ENOENT);
>  	case 0:
> -		*gip = ug->gi;
> -		get_group_info(*gip);
> +		gi = get_group_info(ug->gi);
>  		cache_put(&ug->h, &unix_gid_cache);
> -		return 0;
> +		return gi;
>  	default:
> -		return -EAGAIN;
> +		return ERR_PTR(-EAGAIN);
>  	}
>  }
> 
> @@ -681,6 +683,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
>  	struct sockaddr_in *sin;
>  	struct sockaddr_in6 *sin6, sin6_storage;
>  	struct ip_map *ipm;
> +	struct group_info *gi;
> +	struct svc_cred *cred = &rqstp->rq_cred;
> 
>  	switch (rqstp->rq_addr.ss_family) {
>  	case AF_INET:
> @@ -722,6 +726,17 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
>  			ip_map_cached_put(rqstp, ipm);
>  			break;
>  	}
> +
> +	gi = unix_gid_find(cred->cr_uid, rqstp);
> +	switch (PTR_ERR(gi)) {
> +	case -EAGAIN:
> +		return SVC_DROP;
> +	case -ENOENT:
> +		break;
> +	default:
> +		put_group_info(cred->cr_group_info);
> +		cred->cr_group_info = gi;
> +	}
>  	return SVC_OK;
>  }
> 
> @@ -818,19 +833,11 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32
> *authp)
>  	slen = svc_getnl(argv);			/* gids length */
>  	if (slen > 16 || (len -= (slen + 2)*4) < 0)
>  		goto badcred;
> -	if (unix_gid_find(cred->cr_uid, &cred->cr_group_info, rqstp)
> -	    == -EAGAIN)
> +	cred->cr_group_info = groups_alloc(slen);
> +	if (cred->cr_group_info == NULL)
>  		return SVC_DROP;
> -	if (cred->cr_group_info == NULL) {
> -		cred->cr_group_info = groups_alloc(slen);
> -		if (cred->cr_group_info == NULL)
> -			return SVC_DROP;
> -		for (i = 0; i < slen; i++)
> -			GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
> -	} else {
> -		for (i = 0; i < slen ; i++)
> -			svc_getnl(argv);
> -	}
> +	for (i = 0; i < slen; i++)
> +		GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
>  	if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
>  		*authp = rpc_autherr_badverf;
>  		return SVC_DENIED;
> diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
> index 1c246a4..70b0a22 100644
> --- a/net/sunrpc/svcsock.c
> +++ b/net/sunrpc/svcsock.c
> @@ -968,6 +968,7 @@ static int svc_tcp_recv_record(struct svc_sock
> *svsk, struct svc_rqst *rqstp)
>  	return len;
>   err_delete:
>  	set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
> +	svc_xprt_received(&svsk->sk_xprt);
>   err_again:
>  	return -EAGAIN;
>  }
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 37c5475..5cdbf7c 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -1926,6 +1926,11 @@ static void xs_tcp_setup_socket(struct rpc_xprt
> *xprt,
>  	case -EALREADY:
>  		xprt_clear_connecting(xprt);
>  		return;
> +	case -EINVAL:
> +		/* Happens, for instance, if the user specified a link
> +		 * local IPv6 address without a scope-id.
> +		 */
> +		goto out;
>  	}
>  out_eagain:
>  	status = -EAGAIN;
> 
> Anything jump out at you?
> 
> b.
> 


Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux