MFC: r205941
This patch should fix handling of byte range locks locally on the server for the experimental nfs server. When enabled by setting vfs.newnfs.locallocks_enable to non-zero, the experimental nfs server will now acquire byte range locks on the file on behalf of NFSv4 clients, such that lock conflicts between the NFSv4 clients and processes running locally on the server, will be recognized and handled correctly.
This commit is contained in:
parent
f49339f5cd
commit
066adacfb1
@ -82,7 +82,8 @@ SYSCTL_STRING(_vfs_newnfs, OID_AUTO, callback_addr, CTLFLAG_RW,
|
||||
*/
|
||||
MALLOC_DEFINE(M_NEWNFSRVCACHE, "NFSD srvcache", "NFSD Server Request Cache");
|
||||
MALLOC_DEFINE(M_NEWNFSDCLIENT, "NFSD V4client", "NFSD V4 Client Id");
|
||||
MALLOC_DEFINE(M_NEWNFSDSTATE, "NFSD V4state", "NFSD V4 State (Openowner, Open, Lockowner, Delegation");
|
||||
MALLOC_DEFINE(M_NEWNFSDSTATE, "NFSD V4state",
|
||||
"NFSD V4 State (Openowner, Open, Lockowner, Delegation");
|
||||
MALLOC_DEFINE(M_NEWNFSDLOCK, "NFSD V4lock", "NFSD V4 byte range lock");
|
||||
MALLOC_DEFINE(M_NEWNFSDLOCKFILE, "NFSD lckfile", "NFSD Open/Lock file");
|
||||
MALLOC_DEFINE(M_NEWNFSSTRING, "NFSD string", "NFSD V4 long string");
|
||||
@ -97,7 +98,10 @@ MALLOC_DEFINE(M_NEWNFSCLLOCKOWNER, "NFSCL lckown", "NFSCL Lock Owner");
|
||||
MALLOC_DEFINE(M_NEWNFSCLLOCK, "NFSCL lck", "NFSCL Lock");
|
||||
MALLOC_DEFINE(M_NEWNFSV4NODE, "NEWNFSnode", "New nfs vnode");
|
||||
MALLOC_DEFINE(M_NEWNFSDIRECTIO, "NEWdirectio", "New nfs Direct IO buffer");
|
||||
MALLOC_DEFINE(M_NEWNFSDIROFF, "Newnfscl_diroff", "New NFS directory offset data");
|
||||
MALLOC_DEFINE(M_NEWNFSDIROFF, "NFSCL diroffdiroff",
|
||||
"New NFS directory offset data");
|
||||
MALLOC_DEFINE(M_NEWNFSDROLLBACK, "NFSD rollback",
|
||||
"New NFS local lock rollback");
|
||||
|
||||
/*
|
||||
* Definition of mutex locks.
|
||||
|
@ -1834,6 +1834,19 @@ nfsv4_getref(struct nfsv4lock *lp, int *isleptp, void *mutex)
|
||||
lp->nfslock_usecnt++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for a lock. Return 1 if locked, 0 otherwise.
|
||||
*/
|
||||
APPLESTATIC int
|
||||
nfsv4_testlock(struct nfsv4lock *lp)
|
||||
{
|
||||
|
||||
if ((lp->nfslock_lock & NFSV4LOCK_LOCK) == 0 &&
|
||||
lp->nfslock_usecnt == 0)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up anyone sleeping, waiting for this lock.
|
||||
*/
|
||||
|
@ -251,6 +251,7 @@ int nfsv4_lock(struct nfsv4lock *, int, int *, void *);
|
||||
void nfsv4_unlock(struct nfsv4lock *, int);
|
||||
void nfsv4_relref(struct nfsv4lock *);
|
||||
void nfsv4_getref(struct nfsv4lock *, int *, void *);
|
||||
int nfsv4_testlock(struct nfsv4lock *);
|
||||
int nfsrv_mtostr(struct nfsrv_descript *, char *, int);
|
||||
int nfsrv_checkutf8(u_int8_t *, int);
|
||||
int newnfs_sndlock(int *);
|
||||
|
@ -543,6 +543,7 @@ void nfsrvd_rcv(struct socket *, void *, int);
|
||||
#define NFSSTATESPINLOCK extern struct mtx nfs_state_mutex
|
||||
#define NFSLOCKSTATE() mtx_lock(&nfs_state_mutex)
|
||||
#define NFSUNLOCKSTATE() mtx_unlock(&nfs_state_mutex)
|
||||
#define NFSSTATEMUTEXPTR (&nfs_state_mutex)
|
||||
#define NFSREQSPINLOCK extern struct mtx nfs_req_mutex
|
||||
#define NFSLOCKREQ() mtx_lock(&nfs_req_mutex)
|
||||
#define NFSUNLOCKREQ() mtx_unlock(&nfs_req_mutex)
|
||||
@ -678,6 +679,7 @@ MALLOC_DECLARE(M_NEWNFSDIROFF);
|
||||
MALLOC_DECLARE(M_NEWNFSV4NODE);
|
||||
MALLOC_DECLARE(M_NEWNFSDIRECTIO);
|
||||
MALLOC_DECLARE(M_NEWNFSMNT);
|
||||
MALLOC_DECLARE(M_NEWNFSDROLLBACK);
|
||||
#define M_NFSRVCACHE M_NEWNFSRVCACHE
|
||||
#define M_NFSDCLIENT M_NEWNFSDCLIENT
|
||||
#define M_NFSDSTATE M_NEWNFSDSTATE
|
||||
@ -696,6 +698,7 @@ MALLOC_DECLARE(M_NEWNFSMNT);
|
||||
#define M_NFSDIROFF M_NEWNFSDIROFF
|
||||
#define M_NFSV4NODE M_NEWNFSV4NODE
|
||||
#define M_NFSDIRECTIO M_NEWNFSDIRECTIO
|
||||
#define M_NFSDROLLBACK M_NEWNFSDROLLBACK
|
||||
|
||||
#define NFSINT_SIGMASK(set) \
|
||||
(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \
|
||||
|
@ -184,6 +184,17 @@ struct nfslockconflict {
|
||||
u_char cl_owner[NFSV4_OPAQUELIMIT];
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure is used to keep track of local locks that might need
|
||||
* to be rolled back.
|
||||
*/
|
||||
struct nfsrollback {
|
||||
LIST_ENTRY(nfsrollback) rlck_list;
|
||||
uint64_t rlck_first;
|
||||
uint64_t rlck_end;
|
||||
int rlck_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure refers to a file for which lock(s) and/or open(s) exist.
|
||||
* Searched via hash table on file handle or found via the back pointer from an
|
||||
@ -193,8 +204,12 @@ struct nfslockfile {
|
||||
LIST_HEAD(, nfsstate) lf_open; /* Open list */
|
||||
LIST_HEAD(, nfsstate) lf_deleg; /* Delegation list */
|
||||
LIST_HEAD(, nfslock) lf_lock; /* Lock list */
|
||||
LIST_HEAD(, nfslock) lf_locallock; /* Local lock list */
|
||||
LIST_HEAD(, nfsrollback) lf_rollback; /* Local lock rollback list */
|
||||
LIST_ENTRY(nfslockfile) lf_hash; /* Hash list entry */
|
||||
fhandle_t lf_fh; /* The file handle */
|
||||
struct nfsv4lock lf_locallock_lck; /* serialize local locking */
|
||||
int lf_usecount; /* Ref count for locking */
|
||||
};
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user