DEVEL15-linux-byte-range-locks-sensibility-20090526

LICENSE IPL10
FIXES 124766

make our locks work correctly with the linux connectathon lock testing


(cherry picked from commit 49b7bbdd3b45df694fadbef48f9ed99d9bfe07b9)
This commit is contained in:
Simon Wilkinson 2009-05-27 01:47:51 +00:00 committed by Derrick Brashear
parent 1934ba67b7
commit 4ffdd7d045
4 changed files with 77 additions and 6 deletions

View File

@ -915,6 +915,8 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
LINUX_KERNEL_LINUX_SYSCALL_H
LINUX_KERNEL_LINUX_SEQ_FILE_H
LINUX_KERNEL_POSIX_LOCK_FILE_WAIT_ARG
LINUX_POSIX_TEST_LOCK_RETURNS_CONFLICT
LINUX_POSIX_TEST_LOCK_CONFLICT_ARG
LINUX_KERNEL_SELINUX
LINUX_KERNEL_SOCK_CREATE
LINUX_KERNEL_PAGE_FOLLOW_LINK

View File

@ -504,13 +504,19 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
struct vcache *vcp = VTOAFS(FILE_INODE(fp));
cred_t *credp = crref();
struct AFS_FLOCK flock;
#if defined(POSIX_TEST_LOCK_CONFLICT_ARG)
struct file_lock conflict;
#elif defined(POSIX_TEST_LOCK_RETURNS_CONFLICT)
struct file_lock *conflict;
#endif
/* Convert to a lock format afs_lockctl understands. */
memset((char *)&flock, 0, sizeof(flock));
flock.l_type = flp->fl_type;
flock.l_pid = flp->fl_pid;
flock.l_whence = 0;
flock.l_start = flp->fl_start;
flock.l_len = flp->fl_end - flp->fl_start;
flock.l_len = flp->fl_end - flp->fl_start + 1;
/* Safe because there are no large files, yet */
#if defined(F_GETLK64) && (F_GETLK != F_GETLK64)
@ -529,12 +535,12 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
#ifdef AFS_LINUX24_ENV
if ((code == 0 || flp->fl_type == F_UNLCK) &&
(cmd == F_SETLK || cmd == F_SETLKW)) {
#ifdef POSIX_LOCK_FILE_WAIT_ARG
# ifdef POSIX_LOCK_FILE_WAIT_ARG
code = posix_lock_file(fp, flp, 0);
#else
# else
flp->fl_flags &=~ FL_SLEEP;
code = posix_lock_file(fp, flp);
#endif
# endif
if (code && flp->fl_type != F_UNLCK) {
struct AFS_FLOCK flock2;
flock2 = flock;
@ -544,12 +550,40 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
AFS_GUNLOCK();
}
}
/* If lockctl says there are no conflicting locks, then also check with the
* kernel, as lockctl knows nothing about byte range locks
*/
if (code == 0 && cmd == F_GETLK && flock.l_type == F_UNLCK) {
# if defined(POSIX_TEST_LOCK_CONFLICT_ARG)
if (posix_test_lock(fp, flp, &conflict)) {
locks_copy_lock(flp, &conflict);
flp->fl_type = F_UNLCK;
crfree(credp);
return 0;
}
# elif defined(POSIX_TEST_LOCK_RETURNS_CONFLICT)
if ((conflict = posix_test_lock(fp, flp))) {
locks_copy_lock(flp, conflict);
flp->fl_type = F_UNLCK;
crfee(credp);
return 0;
}
# else
posix_test_lock(fp, flp);
/* If we found a lock in the kernel's structure, return it */
if (flp->fl_type != F_UNLCK) {
crfree(credp);
return 0;
}
}
# endif
#endif
/* Convert flock back to Linux's file_lock */
flp->fl_type = flock.l_type;
flp->fl_pid = flock.l_pid;
flp->fl_start = flock.l_start;
flp->fl_end = flock.l_start + flock.l_len;
flp->fl_end = flock.l_start + flock.l_len - 1;
crfree(credp);
return -code;

View File

@ -485,8 +485,13 @@ DoLockWarning(void)
/* otherwise, it is time to nag the user */
lastWarnTime = now;
#ifdef AFS_LINUX26_ENV
afs_warn
("afs: byte-range locks only enforced for processes on this machine.\n");
#else
afs_warn
("afs: byte-range lock/unlock ignored; make sure no one else is running this program.\n");
#endif
}

View File

@ -486,7 +486,6 @@ AC_DEFUN([LINUX_KERNEL_POSIX_LOCK_FILE_WAIT_ARG], [
ac_cv_linux_kernel_posix_lock_file_wait_arg=no)])
AC_MSG_RESULT($ac_cv_linux_kernel_posix_lock_file_wait_arg)])
AC_DEFUN([LINUX_KERNEL_SOCK_CREATE], [
AC_MSG_CHECKING([for 5th argument in sock_create found in some SELinux kernels])
AC_CACHE_VAL([ac_cv_linux_kernel_sock_create_v], [
@ -1215,3 +1214,34 @@ _p.owner= "";],
if test "x$ac_cv_linux_struct_proc_dir_entry_has_owner" = "xyes"; then
AC_DEFINE([STRUCT_PROC_DIR_ENTRY_HAS_OWNER], 1, [define if struct proc_dir_entry has an owner member])
fi])
AC_DEFUN([LINUX_POSIX_TEST_LOCK_RETURNS_CONFLICT], [
AC_MSG_CHECKING([if posix_test_lock returns a struct file_lock])
AC_CACHE_VAL([ac_cv_linux_posix_test_lock_returns_conflict], [
AC_TRY_KBUILD(
[#include <linux/fs.h>],
[struct file_lock *lock;
struct file * file;
lock = posix_test_lock(file, lock);],
ac_cv_linux_posix_test_lock_returns_conflict=yes,
ac_cv_linux_posix_test_lock_returns_conflict=no)])
AC_MSG_RESULT($ac_cv_linux_posix_test_lock_returns_conflict)
if test "x$ac_cv_linux_posix_test_lock_returns_conflict" = "xyes"; then
AC_DEFINE([POSIX_TEST_LOCK_RETURNS_CONFLICT], 1, [define if posix_test_lock returns the conflicting lock])
fi])
AC_DEFUN([LINUX_POSIX_TEST_LOCK_CONFLICT_ARG], [
AC_MSG_CHECKING([if posix_test_lock takes a conflict argument])
AC_CACHE_VAL([ac_cv_linux_posix_test_lock_conflict_arg], [
AC_TRY_KBUILD(
[#include <linux/fs.h>],
[ struct file_lock *lock;
struct file *file;
posix_test_lock(file, lock, lock);],
ac_cv_linux_posix_test_lock_conflict_arg=yes,
ac_cv_lonuc_posix_test_lock_conflict_arg=no)])
AC_MSG_RESULT($ac_cv_linux_posix_test_lock_conflict_arg)
if test "x$ac_cv_linux_posix_test_lock_conflict_arg" = "xyes"; then
AC_DEFINE([POSIX_TEST_LOCK_CONFLICT_ARG], 1, [define if posix_test_lock takes a conflict argument])
fi])