DEVEL15-linux-byte-range-locks-sensibility-20090526
authorSimon Wilkinson <sxw@inf.ed.ac.uk>
Wed, 27 May 2009 01:47:51 +0000 (01:47 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 27 May 2009 01:47:51 +0000 (01:47 +0000)
LICENSE IPL10
FIXES 124766

make our locks work correctly with the linux connectathon lock testing

(cherry picked from commit 49b7bbdd3b45df694fadbef48f9ed99d9bfe07b9)

acinclude.m4
src/afs/LINUX/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_flock.c
src/cf/linux-test4.m4

index ae20bde..1998621 100644 (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
index 557129b..3bee726 100644 (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;
index 30e83a7..bc405f2 100644 (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
 }
 
 
index 2976499..0b28ce1 100644 (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])
+