diff --git a/kmod/src/lock.c b/kmod/src/lock.c index 290439dd..aa3d6b04 100644 --- a/kmod/src/lock.c +++ b/kmod/src/lock.c @@ -1288,6 +1288,25 @@ void scoutfs_lock_del_coverage(struct super_block *sb, spin_unlock(&cov->cov_lock); } +/* + * Returns true if the given lock protects the given access of the given + * key. The lock must have a current granted mode that is compatible + * with the access mode and the access key must be in the lock's key + * range. + * + * This is called by lock holders who's use of the lock must be preventing + * the mode and keys from changing. + */ +bool scoutfs_lock_protected(struct scoutfs_lock *lock, struct scoutfs_key *key, + int mode) +{ + signed char lock_mode = ACCESS_ONCE(lock->mode); + + return lock_modes_match(lock_mode, mode) && + scoutfs_key_compare_ranges(key, key, + &lock->start, &lock->end) == 0; +} + /* * The shrink callback got the lock, marked it request_pending, and * handed it off to us. We kick off a null request and the lock will diff --git a/kmod/src/lock.h b/kmod/src/lock.h index febd5ff5..8a665c10 100644 --- a/kmod/src/lock.h +++ b/kmod/src/lock.h @@ -83,6 +83,8 @@ bool scoutfs_lock_is_covered(struct super_block *sb, struct scoutfs_lock_coverage *cov); void scoutfs_lock_del_coverage(struct super_block *sb, struct scoutfs_lock_coverage *cov); +bool scoutfs_lock_protected(struct scoutfs_lock *lock, struct scoutfs_key *key, + int mode); void scoutfs_free_unused_locks(struct super_block *sb, unsigned long nr);