mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
lockd: introduce safe async lock op
This patch reverts mostly commit40595cdc93
("nfs: block notification on fs with its own ->lock") and introduces an EXPORT_OP_ASYNC_LOCK export flag to signal that the "own ->lock" implementation supports async lock requests. The only main user is DLM that is used by GFS2 and OCFS2 filesystem. Those implement their own lock() implementation and return FILE_LOCK_DEFERRED as return value. Since commit40595cdc93
("nfs: block notification on fs with its own ->lock") the DLM implementation were never updated. This patch should prepare for DLM to set the EXPORT_OP_ASYNC_LOCK export flag and update the DLM plock implementation regarding to it. Acked-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
1b2021bdee
commit
2dd10de8e6
@ -241,3 +241,10 @@ following flags are defined:
|
|||||||
all of an inode's dirty data on last close. Exports that behave this
|
all of an inode's dirty data on last close. Exports that behave this
|
||||||
way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip
|
way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip
|
||||||
waiting for writeback when closing such files.
|
waiting for writeback when closing such files.
|
||||||
|
|
||||||
|
EXPORT_OP_ASYNC_LOCK - Indicates a capable filesystem to do async lock
|
||||||
|
requests from lockd. Only set EXPORT_OP_ASYNC_LOCK if the filesystem has
|
||||||
|
it's own ->lock() functionality as core posix_lock_file() implementation
|
||||||
|
has no async lock request handling yet. For more information about how to
|
||||||
|
indicate an async lock request from a ->lock() file_operations struct, see
|
||||||
|
fs/locks.c and comment for the function vfs_lock_file().
|
||||||
|
@ -481,9 +481,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
|
|||||||
struct nlm_host *host, struct nlm_lock *lock, int wait,
|
struct nlm_host *host, struct nlm_lock *lock, int wait,
|
||||||
struct nlm_cookie *cookie, int reclaim)
|
struct nlm_cookie *cookie, int reclaim)
|
||||||
{
|
{
|
||||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
|
||||||
struct inode *inode = nlmsvc_file_inode(file);
|
struct inode *inode = nlmsvc_file_inode(file);
|
||||||
#endif
|
|
||||||
struct nlm_block *block = NULL;
|
struct nlm_block *block = NULL;
|
||||||
int error;
|
int error;
|
||||||
int mode;
|
int mode;
|
||||||
@ -497,7 +495,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
|
|||||||
(long long)lock->fl.fl_end,
|
(long long)lock->fl.fl_end,
|
||||||
wait);
|
wait);
|
||||||
|
|
||||||
if (nlmsvc_file_file(file)->f_op->lock) {
|
if (!exportfs_lock_op_is_async(inode->i_sb->s_export_op)) {
|
||||||
async_block = wait;
|
async_block = wait;
|
||||||
wait = 0;
|
wait = 0;
|
||||||
}
|
}
|
||||||
|
@ -7487,6 +7487,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
struct nfsd4_blocked_lock *nbl = NULL;
|
struct nfsd4_blocked_lock *nbl = NULL;
|
||||||
struct file_lock *file_lock = NULL;
|
struct file_lock *file_lock = NULL;
|
||||||
struct file_lock *conflock = NULL;
|
struct file_lock *conflock = NULL;
|
||||||
|
struct super_block *sb;
|
||||||
__be32 status = 0;
|
__be32 status = 0;
|
||||||
int lkflg;
|
int lkflg;
|
||||||
int err;
|
int err;
|
||||||
@ -7508,6 +7509,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
dprintk("NFSD: nfsd4_lock: permission denied!\n");
|
dprintk("NFSD: nfsd4_lock: permission denied!\n");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
sb = cstate->current_fh.fh_dentry->d_sb;
|
||||||
|
|
||||||
if (lock->lk_is_new) {
|
if (lock->lk_is_new) {
|
||||||
if (nfsd4_has_session(cstate))
|
if (nfsd4_has_session(cstate))
|
||||||
@ -7559,7 +7561,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
fp = lock_stp->st_stid.sc_file;
|
fp = lock_stp->st_stid.sc_file;
|
||||||
switch (lock->lk_type) {
|
switch (lock->lk_type) {
|
||||||
case NFS4_READW_LT:
|
case NFS4_READW_LT:
|
||||||
if (nfsd4_has_session(cstate))
|
if (nfsd4_has_session(cstate) ||
|
||||||
|
exportfs_lock_op_is_async(sb->s_export_op))
|
||||||
fl_flags |= FL_SLEEP;
|
fl_flags |= FL_SLEEP;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case NFS4_READ_LT:
|
case NFS4_READ_LT:
|
||||||
@ -7571,7 +7574,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
fl_type = F_RDLCK;
|
fl_type = F_RDLCK;
|
||||||
break;
|
break;
|
||||||
case NFS4_WRITEW_LT:
|
case NFS4_WRITEW_LT:
|
||||||
if (nfsd4_has_session(cstate))
|
if (nfsd4_has_session(cstate) ||
|
||||||
|
exportfs_lock_op_is_async(sb->s_export_op))
|
||||||
fl_flags |= FL_SLEEP;
|
fl_flags |= FL_SLEEP;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case NFS4_WRITE_LT:
|
case NFS4_WRITE_LT:
|
||||||
@ -7599,7 +7603,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
* for file locks), so don't attempt blocking lock notifications
|
* for file locks), so don't attempt blocking lock notifications
|
||||||
* on those filesystems:
|
* on those filesystems:
|
||||||
*/
|
*/
|
||||||
if (nf->nf_file->f_op->lock)
|
if (!exportfs_lock_op_is_async(sb->s_export_op))
|
||||||
fl_flags &= ~FL_SLEEP;
|
fl_flags &= ~FL_SLEEP;
|
||||||
|
|
||||||
nbl = find_or_allocate_block(lock_sop, &fp->fi_fhandle, nn);
|
nbl = find_or_allocate_block(lock_sop, &fp->fi_fhandle, nn);
|
||||||
|
@ -224,9 +224,23 @@ struct export_operations {
|
|||||||
atomic attribute updates
|
atomic attribute updates
|
||||||
*/
|
*/
|
||||||
#define EXPORT_OP_FLUSH_ON_CLOSE (0x20) /* fs flushes file data on close */
|
#define EXPORT_OP_FLUSH_ON_CLOSE (0x20) /* fs flushes file data on close */
|
||||||
|
#define EXPORT_OP_ASYNC_LOCK (0x40) /* fs can do async lock request */
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* exportfs_lock_op_is_async() - export op supports async lock operation
|
||||||
|
* @export_ops: the nfs export operations to check
|
||||||
|
*
|
||||||
|
* Returns true if the nfs export_operations structure has
|
||||||
|
* EXPORT_OP_ASYNC_LOCK in their flags set
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
exportfs_lock_op_is_async(const struct export_operations *export_ops)
|
||||||
|
{
|
||||||
|
return export_ops->flags & EXPORT_OP_ASYNC_LOCK;
|
||||||
|
}
|
||||||
|
|
||||||
extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
|
extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
|
||||||
int *max_len, struct inode *parent,
|
int *max_len, struct inode *parent,
|
||||||
int flags);
|
int flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user