mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
lockd: Have nlm_fopen() return errno values
The nlm_fopen() function is part of the API between nfsd and lockd. Currently its return value is an on-the-wire NLM status code. But that forces NFSD to include NLM wire protocol definitions despite having no other dependency on the NLM wire protocol. In addition, a CONFIG_LOCKD_V4 Kconfig symbol appears in the middle of NFSD source code. Refactor: Let's not use on-the-wire values as part of a high-level API between two Linux kernel modules. That's what we have errno for, right? And, instead of simply moving the CONFIG_LOCKD_V4 check, we can get rid of it entirely and let the decision of what actual NLM status code goes on the wire to be left up to NLM version-specific code. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
9e0d0c6194
commit
7db001e03d
|
|
@ -73,9 +73,21 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
|
|||
|
||||
no_locks:
|
||||
nlmsvc_release_host(host);
|
||||
if (error)
|
||||
return error;
|
||||
return nlm_lck_denied_nolocks;
|
||||
switch (error) {
|
||||
case nlm_granted:
|
||||
return nlm_lck_denied_nolocks;
|
||||
case nlm__int__stale_fh:
|
||||
return nlm4_stale_fh;
|
||||
case nlm__int__failed:
|
||||
return nlm4_failed;
|
||||
default:
|
||||
if (be32_to_cpu(error) >= 30000) {
|
||||
pr_warn_once("lockd: unhandled internal status %u\n",
|
||||
be32_to_cpu(error));
|
||||
return nlm4_failed;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -39,8 +39,20 @@ static inline __be32 cast_status(__be32 status)
|
|||
#else
|
||||
static inline __be32 cast_status(__be32 status)
|
||||
{
|
||||
if (status == nlm__int__deadlock)
|
||||
switch (status) {
|
||||
case nlm__int__deadlock:
|
||||
status = nlm_lck_denied;
|
||||
break;
|
||||
case nlm__int__stale_fh:
|
||||
case nlm__int__failed:
|
||||
status = nlm_lck_denied_nolocks;
|
||||
break;
|
||||
default:
|
||||
if (be32_to_cpu(status) >= 30000)
|
||||
pr_warn_once("lockd: unhandled internal status %u\n",
|
||||
be32_to_cpu(status));
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -87,14 +87,29 @@ static __be32 nlm_do_fopen(struct svc_rqst *rqstp,
|
|||
struct nlm_file *file, int mode)
|
||||
{
|
||||
struct file **fp = &file->f_file[mode];
|
||||
__be32 nfserr;
|
||||
__be32 nlmerr = nlm_granted;
|
||||
int error;
|
||||
|
||||
if (*fp)
|
||||
return 0;
|
||||
nfserr = nlmsvc_ops->fopen(rqstp, &file->f_handle, fp, mode);
|
||||
if (nfserr)
|
||||
dprintk("lockd: open failed (error %d)\n", nfserr);
|
||||
return nfserr;
|
||||
return nlmerr;
|
||||
|
||||
error = nlmsvc_ops->fopen(rqstp, &file->f_handle, fp, mode);
|
||||
if (error) {
|
||||
dprintk("lockd: open failed (errno %d)\n", error);
|
||||
switch (error) {
|
||||
case -EWOULDBLOCK:
|
||||
nlmerr = nlm__int__drop_reply;
|
||||
break;
|
||||
case -ESTALE:
|
||||
nlmerr = nlm__int__stale_fh;
|
||||
break;
|
||||
default:
|
||||
nlmerr = nlm__int__failed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nlmerr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,19 +14,20 @@
|
|||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_LOCKD
|
||||
|
||||
#ifdef CONFIG_LOCKD_V4
|
||||
#define nlm_stale_fh nlm4_stale_fh
|
||||
#define nlm_failed nlm4_failed
|
||||
#else
|
||||
#define nlm_stale_fh nlm_lck_denied_nolocks
|
||||
#define nlm_failed nlm_lck_denied_nolocks
|
||||
#endif
|
||||
/*
|
||||
* Note: we hold the dentry use count while the file is open.
|
||||
/**
|
||||
* nlm_fopen - Open an NFSD file
|
||||
* @rqstp: NLM RPC procedure execution context
|
||||
* @f: NFS file handle to be opened
|
||||
* @filp: OUT: an opened struct file
|
||||
* @flags: the POSIX open flags to use
|
||||
*
|
||||
* nlm_fopen() holds the dentry reference until nlm_fclose() releases it.
|
||||
*
|
||||
* Returns zero on success or a negative errno value if the file
|
||||
* cannot be opened.
|
||||
*/
|
||||
static __be32
|
||||
nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp,
|
||||
int mode)
|
||||
static int nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f,
|
||||
struct file **filp, int flags)
|
||||
{
|
||||
__be32 nfserr;
|
||||
int access;
|
||||
|
|
@ -47,18 +48,17 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp,
|
|||
* if NFSEXP_NOAUTHNLM is set. Some older clients use AUTH_NULL
|
||||
* for NLM requests.
|
||||
*/
|
||||
access = (mode == O_WRONLY) ? NFSD_MAY_WRITE : NFSD_MAY_READ;
|
||||
access = (flags == O_WRONLY) ? NFSD_MAY_WRITE : NFSD_MAY_READ;
|
||||
access |= NFSD_MAY_NLM | NFSD_MAY_OWNER_OVERRIDE | NFSD_MAY_BYPASS_GSS;
|
||||
nfserr = nfsd_open(rqstp, &fh, S_IFREG, access, filp);
|
||||
fh_put(&fh);
|
||||
/* We return nlm error codes as nlm doesn't know
|
||||
* about nfsd, but nfsd does know about nlm..
|
||||
*/
|
||||
|
||||
switch (nfserr) {
|
||||
case nfs_ok:
|
||||
return 0;
|
||||
break;
|
||||
case nfserr_jukebox:
|
||||
/* this error can indicate a presence of a conflicting
|
||||
/*
|
||||
* This error can indicate a presence of a conflicting
|
||||
* delegation to an NLM lock request. Options are:
|
||||
* (1) For now, drop this request and make the client
|
||||
* retry. When delegation is returned, client's lock retry
|
||||
|
|
@ -66,19 +66,25 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp,
|
|||
* (2) NLM4_DENIED as per "spec" signals to the client
|
||||
* that the lock is unavailable now but client can retry.
|
||||
* Linux client implementation does not. It treats
|
||||
* NLM4_DENIED same as NLM4_FAILED and errors the request.
|
||||
* NLM4_DENIED same as NLM4_FAILED and fails the request.
|
||||
* (3) For the future, treat this as blocked lock and try
|
||||
* to callback when the delegation is returned but might
|
||||
* not have a proper lock request to block on.
|
||||
*/
|
||||
return nlm__int__drop_reply;
|
||||
return -EWOULDBLOCK;
|
||||
case nfserr_stale:
|
||||
return nlm_stale_fh;
|
||||
return -ESTALE;
|
||||
default:
|
||||
return nlm_failed;
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nlm_fclose - Close an NFSD file
|
||||
* @filp: a struct file that was opened by nlm_fopen()
|
||||
*/
|
||||
static void
|
||||
nlm_fclose(struct file *filp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,11 +26,9 @@ struct rpc_clnt;
|
|||
* This is the set of functions for lockd->nfsd communication
|
||||
*/
|
||||
struct nlmsvc_binding {
|
||||
__be32 (*fopen)(struct svc_rqst *,
|
||||
struct nfs_fh *,
|
||||
struct file **,
|
||||
int mode);
|
||||
void (*fclose)(struct file *);
|
||||
int (*fopen)(struct svc_rqst *rqstp, struct nfs_fh *f,
|
||||
struct file **filp, int flags);
|
||||
void (*fclose)(struct file *filp);
|
||||
};
|
||||
|
||||
extern const struct nlmsvc_binding *nlmsvc_ops;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
*/
|
||||
#define nlm__int__drop_reply cpu_to_be32(30000)
|
||||
#define nlm__int__deadlock cpu_to_be32(30001)
|
||||
#define nlm__int__stale_fh cpu_to_be32(30002)
|
||||
#define nlm__int__failed cpu_to_be32(30003)
|
||||
|
||||
/*
|
||||
* Lockd host handle (used both by the client and server personality).
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user