]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Use OFD locks where available 216/head
authorGreg Hudson <ghudson@mit.edu>
Tue, 7 Oct 2014 16:12:11 +0000 (12:12 -0400)
committerGreg Hudson <ghudson@mit.edu>
Mon, 15 Dec 2014 20:22:39 +0000 (15:22 -0500)
Linux 3.15 has added OFD locks, which contend with POSIX file locks
but are owned by the open file description instead of the process.
Use these in krb5_lock_file where available, for safer concurrency
behavior.

ticket: 8023 (new)

src/lib/krb5/os/lock_file.c

index 224e58fbf5b106cbad2dc5f3b7e013801b54d6cf..a2f247cd994d62c1430fb3fb491de5918becbb5c 100644 (file)
 #endif
 #endif
 
+#ifdef POSIX_FILE_LOCKS
+/*
+ * Try to use OFD locks where available (e.g. Linux 3.15 and later).  OFD locks
+ * contend with regular POSIX file locks, but are owned by the open file
+ * description instead of the process, which is much better for thread safety.
+ * Fall back to regular POSIX locks on EINVAL in case we are running with an
+ * older kernel than we were built with.
+ */
+static int
+ofdlock(int fd, int cmd, struct flock *lock_arg)
+{
+#ifdef F_OFD_SETLKW
+    int st, ofdcmd;
+
+    assert(cmd == F_SETLKW || cmd == F_SETLK);
+    ofdcmd = (cmd == F_SETLKW) ? F_OFD_SETLKW : F_OFD_SETLK;
+    st = fcntl(fd, ofdcmd, lock_arg);
+    if (st == 0 || errno != EINVAL)
+        return st;
+#endif
+    return fcntl(fd, cmd, lock_arg);
+}
+#endif /* POSIX_FILE_LOCKS */
+
 /*ARGSUSED*/
 krb5_error_code
 krb5_lock_file(krb5_context context, int fd, int mode)
@@ -105,7 +129,7 @@ krb5_lock_file(krb5_context context, int fd, int mode)
     lock_arg.l_whence = 0;
     lock_arg.l_start = 0;
     lock_arg.l_len = 0;
-    if (fcntl(fd, lock_cmd, &lock_arg) == -1) {
+    if (ofdlock(fd, lock_cmd, &lock_arg) == -1) {
         if (errno == EACCES || errno == EAGAIN) /* see POSIX/IEEE 1003.1-1988,
                                                    6.5.2.4 */
             return(EAGAIN);