457c899653991 (Thomas Gleixner 2019-05-19 13:08:55 +0100 1) // SPDX-License-Identifier: GPL-2.0-only
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) * linux/fs/locks.c
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) * Provide support for fcntl()'s F_GETLK, F_SETLK, and F_SETLKW calls.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) * Doug Evans (dje@spiff.uucp), August 07, 1992
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8) * Deadlock detection added.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9) * FIXME: one thing isn't handled yet:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 10) * - mandatory locks (requires lots of changes elsewhere)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 11) * Kelly Carmichael (kelly@[142.24.8.65]), September 17, 1994.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 12) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13) * Miscellaneous edits, and a total rewrite of posix_lock_file() code.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14) * Kai Petzke (wpp@marie.physik.tu-berlin.de), 1994
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 15) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) * Converted file_lock_table to a linked list from an array, which eliminates
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 17) * the limits on how many active file locks are open.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) * Chad Page (pageone@netcom.com), November 27, 1994
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 19) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 20) * Removed dependency on file descriptors. dup()'ed file descriptors now
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21) * get the same locks as the original file descriptors, and a close() on
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) * any file descriptor removes ALL the locks on the file for the current
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) * process. Since locks still depend on the process id, locks are inherited
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24) * after an exec() but not after a fork(). This agrees with POSIX, and both
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25) * BSD and SVR4 practice.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26) * Andy Walker (andy@lysaker.kvaerner.no), February 14, 1995
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 27) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) * Scrapped free list which is redundant now that we allocate locks
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 29) * dynamically with kmalloc()/kfree().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 30) * Andy Walker (andy@lysaker.kvaerner.no), February 21, 1995
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 31) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 32) * Implemented two lock personalities - FL_FLOCK and FL_POSIX.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 33) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 34) * FL_POSIX locks are created with calls to fcntl() and lockf() through the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 35) * fcntl() system call. They have the semantics described above.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 36) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 37) * FL_FLOCK locks are created with calls to flock(), through the flock()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 38) * system call, which is new. Old C libraries implement flock() via fcntl()
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 39) * and will continue to use the old, broken implementation.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 40) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 41) * FL_FLOCK locks follow the 4.4 BSD flock() semantics. They are associated
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) * with a file pointer (filp). As a result they can be shared by a parent
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43) * process and its children after a fork(). They are removed when the last
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 44) * file descriptor referring to the file pointer is closed (unless explicitly
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 45) * unlocked).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 46) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 47) * FL_FLOCK locks never deadlock, an existing lock is always removed before
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 48) * upgrading from shared to exclusive (or vice versa). When this happens
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 49) * any processes blocked by the current lock are woken up and allowed to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 50) * run before the new lock is applied.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 51) * Andy Walker (andy@lysaker.kvaerner.no), June 09, 1995
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 52) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 53) * Removed some race conditions in flock_lock_file(), marked other possible
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 54) * races. Just grep for FIXME to see them.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 55) * Dmitry Gorodchanin (pgmdsg@ibi.com), February 09, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 56) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 57) * Addressed Dmitry's concerns. Deadlock checking no longer recursive.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 58) * Lock allocation changed to GFP_ATOMIC as we can't afford to sleep
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 59) * once we've checked for blocking and deadlocking.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 60) * Andy Walker (andy@lysaker.kvaerner.no), April 03, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 61) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 62) * Initial implementation of mandatory locks. SunOS turned out to be
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 63) * a rotten model, so I implemented the "obvious" semantics.
a02dcdf65bcfc (Mauro Carvalho Chehab 2020-04-27 23:17:08 +0200 64) * See 'Documentation/filesystems/mandatory-locking.rst' for details.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 65) * Andy Walker (andy@lysaker.kvaerner.no), April 06, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 66) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 67) * Don't allow mandatory locks on mmap()'ed files. Added simple functions to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 68) * check if a file has mandatory locks, used by mmap(), open() and creat() to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 69) * see if system call should be rejected. Ref. HP-UX/SunOS/Solaris Reference
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 70) * Manual, Section 2.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) * Andy Walker (andy@lysaker.kvaerner.no), April 09, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) * Tidied up block list handling. Added '/proc/locks' interface.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) * Andy Walker (andy@lysaker.kvaerner.no), April 24, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 76) * Fixed deadlock condition for pathological code that mixes calls to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 77) * flock() and fcntl().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 78) * Andy Walker (andy@lysaker.kvaerner.no), April 29, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 79) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 80) * Allow only one type of locking scheme (FL_POSIX or FL_FLOCK) to be in use
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 81) * for a given file at a time. Changed the CONFIG_LOCK_MANDATORY scheme to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 82) * guarantee sensible behaviour in the case where file system modules might
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 83) * be compiled with different options than the kernel itself.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 84) * Andy Walker (andy@lysaker.kvaerner.no), May 15, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 85) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 86) * Added a couple of missing wake_up() calls. Thanks to Thomas Meckel
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 87) * (Thomas.Meckel@mni.fh-giessen.de) for spotting this.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 88) * Andy Walker (andy@lysaker.kvaerner.no), May 15, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 89) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 90) * Changed FL_POSIX locks to use the block list in the same way as FL_FLOCK
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91) * locks. Changed process synchronisation to avoid dereferencing locks that
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 92) * have already been freed.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 93) * Andy Walker (andy@lysaker.kvaerner.no), Sep 21, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 94) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 95) * Made the block list a circular list to minimise searching in the list.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 96) * Andy Walker (andy@lysaker.kvaerner.no), Sep 25, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 97) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 98) * Made mandatory locking a mount option. Default is not to allow mandatory
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 99) * locking.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 100) * Andy Walker (andy@lysaker.kvaerner.no), Oct 04, 1996.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 101) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 102) * Some adaptations for NFS support.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 103) * Olaf Kirch (okir@monad.swb.de), Dec 1996,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 104) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 105) * Fixed /proc/locks interface so that we can't overrun the buffer we are handed.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 106) * Andy Walker (andy@lysaker.kvaerner.no), May 12, 1997.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 107) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 108) * Use slab allocator instead of kmalloc/kfree.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 109) * Use generic list implementation from <linux/list.h>.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 110) * Sped up posix_locks_deadlock by only considering blocked locks.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 111) * Matthew Wilcox <willy@debian.org>, March, 2000.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 112) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 113) * Leases and LOCK_MAND
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 114) * Matthew Wilcox <willy@debian.org>, June, 2000.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 115) * Stephen Rothwell <sfr@canb.auug.org.au>, June, 2000.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 116) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 117) * Locking conflicts and dependencies:
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 118) * If multiple threads attempt to lock the same byte (or flock the same file)
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 119) * only one can be granted the lock, and other must wait their turn.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 120) * The first lock has been "applied" or "granted", the others are "waiting"
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 121) * and are "blocked" by the "applied" lock..
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 122) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 123) * Waiting and applied locks are all kept in trees whose properties are:
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 124) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 125) * - the root of a tree may be an applied or waiting lock.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 126) * - every other node in the tree is a waiting lock that
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 127) * conflicts with every ancestor of that node.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 128) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 129) * Every such tree begins life as a waiting singleton which obviously
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 130) * satisfies the above properties.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 131) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 132) * The only ways we modify trees preserve these properties:
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 133) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 134) * 1. We may add a new leaf node, but only after first verifying that it
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 135) * conflicts with all of its ancestors.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 136) * 2. We may remove the root of a tree, creating a new singleton
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 137) * tree from the root and N new trees rooted in the immediate
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 138) * children.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 139) * 3. If the root of a tree is not currently an applied lock, we may
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 140) * apply it (if possible).
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 141) * 4. We may upgrade the root of the tree (either extend its range,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 142) * or upgrade its entire range from read to write).
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 143) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 144) * When an applied lock is modified in a way that reduces or downgrades any
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 145) * part of its range, we remove all its children (2 above). This particularly
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 146) * happens when a lock is unlocked.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 147) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 148) * For each of those child trees we "wake up" the thread which is
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 149) * waiting for the lock so it can continue handling as follows: if the
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 150) * root of the tree applies, we do so (3). If it doesn't, it must
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 151) * conflict with some applied lock. We remove (wake up) all of its children
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 152) * (2), and add it is a new leaf to the tree rooted in the applied
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 153) * lock (1). We then repeat the process recursively with those
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 154) * children.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 155) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 156) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 157)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 158) #include <linux/capability.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 159) #include <linux/file.h>
9f3acc3140444 (Al Viro 2008-04-24 07:44:08 -0400 160) #include <linux/fdtable.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 161) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 162) #include <linux/init.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 163) #include <linux/security.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 164) #include <linux/slab.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 165) #include <linux/syscalls.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 166) #include <linux/time.h>
4fb3a53860cee (Dipankar Sarma 2005-09-16 19:28:13 -0700 167) #include <linux/rcupdate.h>
ab1f16116527e (Vitaliy Gusev 2008-01-17 00:07:08 +0000 168) #include <linux/pid_namespace.h>
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 169) #include <linux/hashtable.h>
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 170) #include <linux/percpu.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 171)
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 172) #define CREATE_TRACE_POINTS
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 173) #include <trace/events/filelock.h>
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 174)
7c0f6ba682b9c (Linus Torvalds 2016-12-24 11:46:01 -0800 175) #include <linux/uaccess.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 176)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 177) #define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 178) #define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
11afe9f76e121 (Christoph Hellwig 2015-01-21 19:17:03 +0100 179) #define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 180) #define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 181) #define IS_REMOTELCK(fl) (fl->fl_pid <= 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 182)
ab83fa4b49a54 (J. Bruce Fields 2011-07-26 20:10:51 -0400 183) static bool lease_breaking(struct file_lock *fl)
ab83fa4b49a54 (J. Bruce Fields 2011-07-26 20:10:51 -0400 184) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 185) return fl->fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING);
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 186) }
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 187)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 188) static int target_leasetype(struct file_lock *fl)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 189) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 190) if (fl->fl_flags & FL_UNLOCK_PENDING)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 191) return F_UNLCK;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 192) if (fl->fl_flags & FL_DOWNGRADE_PENDING)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 193) return F_RDLCK;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 194) return fl->fl_type;
ab83fa4b49a54 (J. Bruce Fields 2011-07-26 20:10:51 -0400 195) }
ab83fa4b49a54 (J. Bruce Fields 2011-07-26 20:10:51 -0400 196)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 197) int leases_enable = 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 198) int lease_break_time = 45;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 199)
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 200) /*
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 201) * The global file_lock_list is only used for displaying /proc/locks, so we
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 202) * keep a list on each CPU, with each list protected by its own spinlock.
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 203) * Global serialization is done using file_rwsem.
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 204) *
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 205) * Note that alterations to the list also require that the relevant flc_lock is
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 206) * held.
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 207) */
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 208) struct file_lock_list_struct {
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 209) spinlock_t lock;
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 210) struct hlist_head hlist;
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 211) };
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 212) static DEFINE_PER_CPU(struct file_lock_list_struct, file_lock_list);
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 213) DEFINE_STATIC_PERCPU_RWSEM(file_rwsem);
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 214)
eb82dd3937441 (Jeff Layton 2019-08-18 14:18:53 -0400 215)
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 216) /*
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 217) * The blocked_hash is used to find POSIX lock loops for deadlock detection.
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 218) * It is protected by blocked_lock_lock.
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 219) *
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 220) * We hash locks by lockowner in order to optimize searching for the lock a
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 221) * particular lockowner is waiting on.
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 222) *
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 223) * FIXME: make this value scale via some heuristic? We generally will want more
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 224) * buckets when we have more lockowners holding locks, but that's a little
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 225) * difficult to determine without knowing what the workload will look like.
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 226) */
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 227) #define BLOCKED_HASH_BITS 7
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 228) static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS);
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 229)
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 230) /*
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 231) * This lock protects the blocked_hash. Generally, if you're accessing it, you
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 232) * want to be holding this lock.
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 233) *
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 234) * In addition, it also protects the fl->fl_blocked_requests list, and the
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 235) * fl->fl_blocker pointer for file_lock structures that are acting as lock
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 236) * requests (in contrast to those that are acting as records of acquired locks).
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 237) *
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 238) * Note that when we acquire this lock in order to change the above fields,
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 239) * we often hold the flc_lock as well. In certain cases, when reading the fields
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 240) * protected by this lock, we can skip acquiring it iff we already hold the
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 241) * flc_lock.
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 242) */
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 243) static DEFINE_SPINLOCK(blocked_lock_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 244)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 245) static struct kmem_cache *flctx_cache __read_mostly;
e18b890bb0881 (Christoph Lameter 2006-12-06 20:33:20 -0800 246) static struct kmem_cache *filelock_cache __read_mostly;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 247)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 248) static struct file_lock_context *
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 249) locks_get_lock_context(struct inode *inode, int type)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 250) {
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 251) struct file_lock_context *ctx;
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 252)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 253) /* paired with cmpxchg() below */
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 254) ctx = smp_load_acquire(&inode->i_flctx);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 255) if (likely(ctx) || type == F_UNLCK)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 256) goto out;
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 257)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 258) ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 259) if (!ctx)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 260) goto out;
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 261)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 262) spin_lock_init(&ctx->flc_lock);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 263) INIT_LIST_HEAD(&ctx->flc_flock);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 264) INIT_LIST_HEAD(&ctx->flc_posix);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 265) INIT_LIST_HEAD(&ctx->flc_lease);
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 266)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 267) /*
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 268) * Assign the pointer if it's not already assigned. If it is, then
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 269) * free the context we just allocated.
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 270) */
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 271) if (cmpxchg(&inode->i_flctx, NULL, ctx)) {
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 272) kmem_cache_free(flctx_cache, ctx);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 273) ctx = smp_load_acquire(&inode->i_flctx);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 274) }
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 275) out:
1890910fd06fe (Jeff Layton 2016-01-06 21:26:10 -0500 276) trace_locks_get_lock_context(inode, type, ctx);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 277) return ctx;
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 278) }
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 279)
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 280) static void
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 281) locks_dump_ctx_list(struct list_head *list, char *list_type)
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 282) {
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 283) struct file_lock *fl;
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 284)
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 285) list_for_each_entry(fl, list, fl_list) {
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 286) pr_warn("%s: fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n", list_type, fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid);
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 287) }
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 288) }
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 289)
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 290) static void
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 291) locks_check_ctx_lists(struct inode *inode)
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 292) {
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 293) struct file_lock_context *ctx = inode->i_flctx;
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 294)
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 295) if (unlikely(!list_empty(&ctx->flc_flock) ||
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 296) !list_empty(&ctx->flc_posix) ||
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 297) !list_empty(&ctx->flc_lease))) {
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 298) pr_warn("Leaked locks on dev=0x%x:0x%x ino=0x%lx:\n",
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 299) MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev),
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 300) inode->i_ino);
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 301) locks_dump_ctx_list(&ctx->flc_flock, "FLOCK");
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 302) locks_dump_ctx_list(&ctx->flc_posix, "POSIX");
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 303) locks_dump_ctx_list(&ctx->flc_lease, "LEASE");
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 304) }
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 305) }
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 306)
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 307) static void
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 308) locks_check_ctx_file_list(struct file *filp, struct list_head *list,
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 309) char *list_type)
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 310) {
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 311) struct file_lock *fl;
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 312) struct inode *inode = locks_inode(filp);
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 313)
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 314) list_for_each_entry(fl, list, fl_list)
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 315) if (fl->fl_file == filp)
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 316) pr_warn("Leaked %s lock on dev=0x%x:0x%x ino=0x%lx "
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 317) " fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n",
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 318) list_type, MAJOR(inode->i_sb->s_dev),
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 319) MINOR(inode->i_sb->s_dev), inode->i_ino,
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 320) fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid);
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 321) }
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 322)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 323) void
f27a0fe083bf4 (Jeff Layton 2016-01-07 15:08:51 -0500 324) locks_free_lock_context(struct inode *inode)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 325) {
f27a0fe083bf4 (Jeff Layton 2016-01-07 15:08:51 -0500 326) struct file_lock_context *ctx = inode->i_flctx;
f27a0fe083bf4 (Jeff Layton 2016-01-07 15:08:51 -0500 327)
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 328) if (unlikely(ctx)) {
e24dadab08a2a (Jeff Layton 2016-01-06 21:28:41 -0500 329) locks_check_ctx_lists(inode);
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 330) kmem_cache_free(flctx_cache, ctx);
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 331) }
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 332) }
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 333)
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 334) static void locks_init_lock_heads(struct file_lock *fl)
a51cb91d81f8e (Miklos Szeredi 2011-07-06 12:33:55 +0200 335) {
139ca04ee572f (Jeff Layton 2013-06-21 08:58:17 -0400 336) INIT_HLIST_NODE(&fl->fl_link);
6dee60f69d48f (Jeff Layton 2015-01-16 15:05:54 -0500 337) INIT_LIST_HEAD(&fl->fl_list);
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 338) INIT_LIST_HEAD(&fl->fl_blocked_requests);
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 339) INIT_LIST_HEAD(&fl->fl_blocked_member);
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 340) init_waitqueue_head(&fl->fl_wait);
a51cb91d81f8e (Miklos Szeredi 2011-07-06 12:33:55 +0200 341) }
a51cb91d81f8e (Miklos Szeredi 2011-07-06 12:33:55 +0200 342)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 343) /* Allocate an empty lock structure. */
c5b1f0d92c368 (Arnd Bergmann 2010-10-27 15:46:08 +0200 344) struct file_lock *locks_alloc_lock(void)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 345) {
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 346) struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a51cb91d81f8e (Miklos Szeredi 2011-07-06 12:33:55 +0200 347)
a51cb91d81f8e (Miklos Szeredi 2011-07-06 12:33:55 +0200 348) if (fl)
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 349) locks_init_lock_heads(fl);
a51cb91d81f8e (Miklos Szeredi 2011-07-06 12:33:55 +0200 350)
a51cb91d81f8e (Miklos Szeredi 2011-07-06 12:33:55 +0200 351) return fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 352) }
c5b1f0d92c368 (Arnd Bergmann 2010-10-27 15:46:08 +0200 353) EXPORT_SYMBOL_GPL(locks_alloc_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 354)
a9e61e25f9d2e (Felix Blyakher 2009-03-31 15:12:56 -0500 355) void locks_release_private(struct file_lock *fl)
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 356) {
5926459e7c897 (NeilBrown 2019-04-24 12:00:08 +1000 357) BUG_ON(waitqueue_active(&fl->fl_wait));
5926459e7c897 (NeilBrown 2019-04-24 12:00:08 +1000 358) BUG_ON(!list_empty(&fl->fl_list));
5926459e7c897 (NeilBrown 2019-04-24 12:00:08 +1000 359) BUG_ON(!list_empty(&fl->fl_blocked_requests));
5926459e7c897 (NeilBrown 2019-04-24 12:00:08 +1000 360) BUG_ON(!list_empty(&fl->fl_blocked_member));
5926459e7c897 (NeilBrown 2019-04-24 12:00:08 +1000 361) BUG_ON(!hlist_unhashed(&fl->fl_link));
5926459e7c897 (NeilBrown 2019-04-24 12:00:08 +1000 362)
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 363) if (fl->fl_ops) {
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 364) if (fl->fl_ops->fl_release_private)
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 365) fl->fl_ops->fl_release_private(fl);
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 366) fl->fl_ops = NULL;
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 367) }
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 368)
5c97d7b147998 (Kinglong Mee 2014-08-22 10:18:43 -0400 369) if (fl->fl_lmops) {
cae80b305e1c3 (Jeff Layton 2015-04-03 09:04:04 -0400 370) if (fl->fl_lmops->lm_put_owner) {
cae80b305e1c3 (Jeff Layton 2015-04-03 09:04:04 -0400 371) fl->fl_lmops->lm_put_owner(fl->fl_owner);
cae80b305e1c3 (Jeff Layton 2015-04-03 09:04:04 -0400 372) fl->fl_owner = NULL;
cae80b305e1c3 (Jeff Layton 2015-04-03 09:04:04 -0400 373) }
5c97d7b147998 (Kinglong Mee 2014-08-22 10:18:43 -0400 374) fl->fl_lmops = NULL;
5c97d7b147998 (Kinglong Mee 2014-08-22 10:18:43 -0400 375) }
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 376) }
a9e61e25f9d2e (Felix Blyakher 2009-03-31 15:12:56 -0500 377) EXPORT_SYMBOL_GPL(locks_release_private);
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 378)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 379) /* Free a lock which is not in use. */
05fa3135fdc7b (J. Bruce Fields 2010-10-30 17:31:15 -0400 380) void locks_free_lock(struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 381) {
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 382) locks_release_private(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 383) kmem_cache_free(filelock_cache, fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 384) }
05fa3135fdc7b (J. Bruce Fields 2010-10-30 17:31:15 -0400 385) EXPORT_SYMBOL(locks_free_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 386)
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 387) static void
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 388) locks_dispose_list(struct list_head *dispose)
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 389) {
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 390) struct file_lock *fl;
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 391)
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 392) while (!list_empty(dispose)) {
6dee60f69d48f (Jeff Layton 2015-01-16 15:05:54 -0500 393) fl = list_first_entry(dispose, struct file_lock, fl_list);
6dee60f69d48f (Jeff Layton 2015-01-16 15:05:54 -0500 394) list_del_init(&fl->fl_list);
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 395) locks_free_lock(fl);
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 396) }
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 397) }
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 398)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 399) void locks_init_lock(struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 400) {
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 401) memset(fl, 0, sizeof(struct file_lock));
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 402) locks_init_lock_heads(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 403) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 404) EXPORT_SYMBOL(locks_init_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 405)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 406) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 407) * Initialize a new lock from an existing file_lock structure.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 408) */
3fe0fff18fe87 (Kinglong Mee 2014-08-22 10:18:42 -0400 409) void locks_copy_conflock(struct file_lock *new, struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 410) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 411) new->fl_owner = fl->fl_owner;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 412) new->fl_pid = fl->fl_pid;
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 413) new->fl_file = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 414) new->fl_flags = fl->fl_flags;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 415) new->fl_type = fl->fl_type;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 416) new->fl_start = fl->fl_start;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 417) new->fl_end = fl->fl_end;
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 418) new->fl_lmops = fl->fl_lmops;
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 419) new->fl_ops = NULL;
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 420)
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 421) if (fl->fl_lmops) {
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 422) if (fl->fl_lmops->lm_get_owner)
cae80b305e1c3 (Jeff Layton 2015-04-03 09:04:04 -0400 423) fl->fl_lmops->lm_get_owner(fl->fl_owner);
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 424) }
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 425) }
3fe0fff18fe87 (Kinglong Mee 2014-08-22 10:18:42 -0400 426) EXPORT_SYMBOL(locks_copy_conflock);
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 427)
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 428) void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 429) {
566709bd627ca (Jeff Layton 2014-08-11 14:09:35 -0400 430) /* "new" must be a freshly-initialized lock */
566709bd627ca (Jeff Layton 2014-08-11 14:09:35 -0400 431) WARN_ON_ONCE(new->fl_ops);
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 432)
3fe0fff18fe87 (Kinglong Mee 2014-08-22 10:18:42 -0400 433) locks_copy_conflock(new, fl);
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 434)
0996905f9301c (Trond Myklebust 2006-03-20 13:44:38 -0500 435) new->fl_file = fl->fl_file;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 436) new->fl_ops = fl->fl_ops;
47831f35b83e4 (Trond Myklebust 2006-03-20 13:44:05 -0500 437)
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 438) if (fl->fl_ops) {
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 439) if (fl->fl_ops->fl_copy_lock)
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 440) fl->fl_ops->fl_copy_lock(new, fl);
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 441) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 442) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 443) EXPORT_SYMBOL(locks_copy_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 444)
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 445) static void locks_move_blocks(struct file_lock *new, struct file_lock *fl)
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 446) {
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 447) struct file_lock *f;
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 448)
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 449) /*
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 450) * As ctx->flc_lock is held, new requests cannot be added to
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 451) * ->fl_blocked_requests, so we don't need a lock to check if it
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 452) * is empty.
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 453) */
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 454) if (list_empty(&fl->fl_blocked_requests))
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 455) return;
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 456) spin_lock(&blocked_lock_lock);
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 457) list_splice_init(&fl->fl_blocked_requests, &new->fl_blocked_requests);
bf77ae4c98d72 (NeilBrown 2019-01-03 11:04:08 +1100 458) list_for_each_entry(f, &new->fl_blocked_requests, fl_blocked_member)
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 459) f->fl_blocker = new;
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 460) spin_unlock(&blocked_lock_lock);
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 461) }
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 462)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 463) static inline int flock_translate_cmd(int cmd) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 464) if (cmd & LOCK_MAND)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 465) return cmd & (LOCK_MAND | LOCK_RW);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 466) switch (cmd) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 467) case LOCK_SH:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 468) return F_RDLCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 469) case LOCK_EX:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 470) return F_WRLCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 471) case LOCK_UN:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 472) return F_UNLCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 473) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 474) return -EINVAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 475) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 476)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 477) /* Fill in a file_lock structure with an appropriate FLOCK lock. */
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 478) static struct file_lock *
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 479) flock_make_lock(struct file *filp, unsigned int cmd, struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 480) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 481) int type = flock_translate_cmd(cmd);
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 482)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 483) if (type < 0)
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 484) return ERR_PTR(type);
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 485)
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 486) if (fl == NULL) {
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 487) fl = locks_alloc_lock();
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 488) if (fl == NULL)
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 489) return ERR_PTR(-ENOMEM);
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 490) } else {
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 491) locks_init_lock(fl);
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 492) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 493)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 494) fl->fl_file = filp;
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 495) fl->fl_owner = filp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 496) fl->fl_pid = current->tgid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 497) fl->fl_flags = FL_FLOCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 498) fl->fl_type = type;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 499) fl->fl_end = OFFSET_MAX;
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 500)
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 501) return fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 502) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 503)
0ec4f431eb56d (J. Bruce Fields 2012-07-23 15:17:17 -0400 504) static int assign_type(struct file_lock *fl, long type)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 505) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 506) switch (type) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 507) case F_RDLCK:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 508) case F_WRLCK:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 509) case F_UNLCK:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 510) fl->fl_type = type;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 511) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 512) default:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 513) return -EINVAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 514) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 515) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 516) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 517)
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 518) static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 519) struct flock64 *l)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 520) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 521) switch (l->l_whence) {
f5579f8c7d7e2 (Josef 'Jeff' Sipek 2006-09-30 23:27:35 -0700 522) case SEEK_SET:
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 523) fl->fl_start = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 524) break;
f5579f8c7d7e2 (Josef 'Jeff' Sipek 2006-09-30 23:27:35 -0700 525) case SEEK_CUR:
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 526) fl->fl_start = filp->f_pos;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 527) break;
f5579f8c7d7e2 (Josef 'Jeff' Sipek 2006-09-30 23:27:35 -0700 528) case SEEK_END:
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 529) fl->fl_start = i_size_read(file_inode(filp));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 530) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 531) default:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 532) return -EINVAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 533) }
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 534) if (l->l_start > OFFSET_MAX - fl->fl_start)
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 535) return -EOVERFLOW;
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 536) fl->fl_start += l->l_start;
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 537) if (fl->fl_start < 0)
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 538) return -EINVAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 539)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 540) /* POSIX-1996 leaves the case l->l_len < 0 undefined;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 541) POSIX-2001 defines it. */
4c780a4688b42 (Trond Myklebust 2005-10-18 14:20:21 -0700 542) if (l->l_len > 0) {
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 543) if (l->l_len - 1 > OFFSET_MAX - fl->fl_start)
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 544) return -EOVERFLOW;
16238415eb988 (Luo Meng 2020-10-23 14:20:05 +0800 545) fl->fl_end = fl->fl_start + (l->l_len - 1);
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 546)
4c780a4688b42 (Trond Myklebust 2005-10-18 14:20:21 -0700 547) } else if (l->l_len < 0) {
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 548) if (fl->fl_start + l->l_len < 0)
4c780a4688b42 (Trond Myklebust 2005-10-18 14:20:21 -0700 549) return -EINVAL;
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 550) fl->fl_end = fl->fl_start - 1;
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 551) fl->fl_start += l->l_len;
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 552) } else
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 553) fl->fl_end = OFFSET_MAX;
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 554)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 555) fl->fl_owner = current->files;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 556) fl->fl_pid = current->tgid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 557) fl->fl_file = filp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 558) fl->fl_flags = FL_POSIX;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 559) fl->fl_ops = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 560) fl->fl_lmops = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 561)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 562) return assign_type(fl, l->l_type);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 563) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 564)
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 565) /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 566) * style lock.
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 567) */
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 568) static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 569) struct flock *l)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 570) {
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 571) struct flock64 ll = {
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 572) .l_type = l->l_type,
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 573) .l_whence = l->l_whence,
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 574) .l_start = l->l_start,
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 575) .l_len = l->l_len,
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 576) };
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 577)
ef12e72a01f30 (J. Bruce Fields 2014-02-03 12:13:08 -0500 578) return flock64_to_posix_lock(filp, fl, &ll);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 579) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 580)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 581) /* default lease lock manager operations */
4d01b7f5e7576 (Jeff Layton 2014-09-01 15:06:54 -0400 582) static bool
4d01b7f5e7576 (Jeff Layton 2014-09-01 15:06:54 -0400 583) lease_break_callback(struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 584) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 585) kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG);
4d01b7f5e7576 (Jeff Layton 2014-09-01 15:06:54 -0400 586) return false;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 587) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 588)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 589) static void
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 590) lease_setup(struct file_lock *fl, void **priv)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 591) {
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 592) struct file *filp = fl->fl_file;
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 593) struct fasync_struct *fa = *priv;
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 594)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 595) /*
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 596) * fasync_insert_entry() returns the old entry if any. If there was no
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 597) * old entry, then it used "priv" and inserted it into the fasync list.
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 598) * Clear the pointer to indicate that it shouldn't be freed.
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 599) */
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 600) if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa))
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 601) *priv = NULL;
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 602)
019191342fecc (Eric W. Biederman 2017-07-16 22:05:57 -0500 603) __f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 604) }
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 605)
7b021967c5e14 (Alexey Dobriyan 2009-09-21 17:01:12 -0700 606) static const struct lock_manager_operations lease_manager_ops = {
8fb47a4fbf858 (J. Bruce Fields 2011-07-20 20:21:59 -0400 607) .lm_break = lease_break_callback,
8fb47a4fbf858 (J. Bruce Fields 2011-07-20 20:21:59 -0400 608) .lm_change = lease_modify,
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 609) .lm_setup = lease_setup,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 610) };
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 611)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 612) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 613) * Initialize a lease, use the default lock manager operations
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 614) */
0ec4f431eb56d (J. Bruce Fields 2012-07-23 15:17:17 -0400 615) static int lease_init(struct file *filp, long type, struct file_lock *fl)
447a5647c9e7a (Joe Perches 2018-03-21 15:09:32 -0700 616) {
75dff55af9a98 (Trond Myklebust 2006-05-07 23:02:42 -0400 617) if (assign_type(fl, type) != 0)
75dff55af9a98 (Trond Myklebust 2006-05-07 23:02:42 -0400 618) return -EINVAL;
75dff55af9a98 (Trond Myklebust 2006-05-07 23:02:42 -0400 619)
7ca76311fe6c3 (Jeff Layton 2014-09-01 19:04:48 -0400 620) fl->fl_owner = filp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 621) fl->fl_pid = current->tgid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 622)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 623) fl->fl_file = filp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 624) fl->fl_flags = FL_LEASE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 625) fl->fl_start = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 626) fl->fl_end = OFFSET_MAX;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 627) fl->fl_ops = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 628) fl->fl_lmops = &lease_manager_ops;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 629) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 630) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 631)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 632) /* Allocate a file_lock initialised to this type of lease */
0ec4f431eb56d (J. Bruce Fields 2012-07-23 15:17:17 -0400 633) static struct file_lock *lease_alloc(struct file *filp, long type)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 634) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 635) struct file_lock *fl = locks_alloc_lock();
75dff55af9a98 (Trond Myklebust 2006-05-07 23:02:42 -0400 636) int error = -ENOMEM;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 637)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 638) if (fl == NULL)
e32b8ee27b486 (J. Bruce Fields 2007-03-01 14:34:35 -0500 639) return ERR_PTR(error);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 640)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 641) error = lease_init(filp, type, fl);
75dff55af9a98 (Trond Myklebust 2006-05-07 23:02:42 -0400 642) if (error) {
75dff55af9a98 (Trond Myklebust 2006-05-07 23:02:42 -0400 643) locks_free_lock(fl);
e32b8ee27b486 (J. Bruce Fields 2007-03-01 14:34:35 -0500 644) return ERR_PTR(error);
75dff55af9a98 (Trond Myklebust 2006-05-07 23:02:42 -0400 645) }
e32b8ee27b486 (J. Bruce Fields 2007-03-01 14:34:35 -0500 646) return fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 647) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 648)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 649) /* Check if two locks overlap each other.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 650) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 651) static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 652) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 653) return ((fl1->fl_end >= fl2->fl_start) &&
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 654) (fl2->fl_end >= fl1->fl_start));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 655) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 656)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 657) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 658) * Check whether two locks have the same owner.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 659) */
33443c42f4ffa (Matt Mackall 2006-01-08 01:05:22 -0800 660) static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 661) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 662) return fl1->fl_owner == fl2->fl_owner;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 663) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 664)
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 665) /* Must be called with the flc_lock held! */
6ca10ed8edfd8 (Jeff Layton 2014-02-03 12:13:07 -0500 666) static void locks_insert_global_locks(struct file_lock *fl)
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 667) {
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 668) struct file_lock_list_struct *fll = this_cpu_ptr(&file_lock_list);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 669)
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 670) percpu_rwsem_assert_held(&file_rwsem);
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 671)
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 672) spin_lock(&fll->lock);
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 673) fl->fl_link_cpu = smp_processor_id();
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 674) hlist_add_head(&fl->fl_link, &fll->hlist);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 675) spin_unlock(&fll->lock);
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 676) }
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 677)
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 678) /* Must be called with the flc_lock held! */
6ca10ed8edfd8 (Jeff Layton 2014-02-03 12:13:07 -0500 679) static void locks_delete_global_locks(struct file_lock *fl)
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 680) {
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 681) struct file_lock_list_struct *fll;
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 682)
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 683) percpu_rwsem_assert_held(&file_rwsem);
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 684)
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 685) /*
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 686) * Avoid taking lock if already unhashed. This is safe since this check
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 687) * is done while holding the flc_lock, and new insertions into the list
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 688) * also require that it be held.
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 689) */
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 690) if (hlist_unhashed(&fl->fl_link))
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 691) return;
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 692)
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 693) fll = per_cpu_ptr(&file_lock_list, fl->fl_link_cpu);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 694) spin_lock(&fll->lock);
139ca04ee572f (Jeff Layton 2013-06-21 08:58:17 -0400 695) hlist_del_init(&fl->fl_link);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 696) spin_unlock(&fll->lock);
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 697) }
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 698)
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 699) static unsigned long
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 700) posix_owner_key(struct file_lock *fl)
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 701) {
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 702) return (unsigned long)fl->fl_owner;
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 703) }
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 704)
6ca10ed8edfd8 (Jeff Layton 2014-02-03 12:13:07 -0500 705) static void locks_insert_global_blocked(struct file_lock *waiter)
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 706) {
663d5af750b8c (Daniel Wagner 2015-04-03 09:04:03 -0400 707) lockdep_assert_held(&blocked_lock_lock);
663d5af750b8c (Daniel Wagner 2015-04-03 09:04:03 -0400 708)
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 709) hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter));
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 710) }
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 711)
6ca10ed8edfd8 (Jeff Layton 2014-02-03 12:13:07 -0500 712) static void locks_delete_global_blocked(struct file_lock *waiter)
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 713) {
663d5af750b8c (Daniel Wagner 2015-04-03 09:04:03 -0400 714) lockdep_assert_held(&blocked_lock_lock);
663d5af750b8c (Daniel Wagner 2015-04-03 09:04:03 -0400 715)
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 716) hash_del(&waiter->fl_link);
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 717) }
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 718)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 719) /* Remove waiter from blocker's block list.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 720) * When blocker ends up pointing to itself then the list is empty.
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 721) *
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 722) * Must be called with blocked_lock_lock held.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 723) */
33443c42f4ffa (Matt Mackall 2006-01-08 01:05:22 -0800 724) static void __locks_delete_block(struct file_lock *waiter)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 725) {
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 726) locks_delete_global_blocked(waiter);
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 727) list_del_init(&waiter->fl_blocked_member);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 728) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 729)
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 730) static void __locks_wake_up_blocks(struct file_lock *blocker)
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 731) {
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 732) while (!list_empty(&blocker->fl_blocked_requests)) {
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 733) struct file_lock *waiter;
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 734)
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 735) waiter = list_first_entry(&blocker->fl_blocked_requests,
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 736) struct file_lock, fl_blocked_member);
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 737) __locks_delete_block(waiter);
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 738) if (waiter->fl_lmops && waiter->fl_lmops->lm_notify)
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 739) waiter->fl_lmops->lm_notify(waiter);
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 740) else
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 741) wake_up(&waiter->fl_wait);
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 742)
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 743) /*
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 744) * The setting of fl_blocker to NULL marks the "done"
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 745) * point in deleting a block. Paired with acquire at the top
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 746) * of locks_delete_block().
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 747) */
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 748) smp_store_release(&waiter->fl_blocker, NULL);
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 749) }
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 750) }
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 751)
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 752) /**
529adfe8f131c (Mauro Carvalho Chehab 2020-10-23 18:33:23 +0200 753) * locks_delete_block - stop waiting for a file lock
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 754) * @waiter: the lock which was waiting
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 755) *
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 756) * lockd/nfsd need to disconnect the lock while working on it.
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 757) */
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 758) int locks_delete_block(struct file_lock *waiter)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 759) {
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 760) int status = -ENOENT;
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 761)
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 762) /*
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 763) * If fl_blocker is NULL, it won't be set again as this thread "owns"
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 764) * the lock and is the only one that might try to claim the lock.
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 765) *
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 766) * We use acquire/release to manage fl_blocker so that we can
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 767) * optimize away taking the blocked_lock_lock in many cases.
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 768) *
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 769) * The smp_load_acquire guarantees two things:
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 770) *
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 771) * 1/ that fl_blocked_requests can be tested locklessly. If something
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 772) * was recently added to that list it must have been in a locked region
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 773) * *before* the locked region when fl_blocker was set to NULL.
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 774) *
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 775) * 2/ that no other thread is accessing 'waiter', so it is safe to free
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 776) * it. __locks_wake_up_blocks is careful not to touch waiter after
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 777) * fl_blocker is released.
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 778) *
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 779) * If a lockless check of fl_blocker shows it to be NULL, we know that
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 780) * no new locks can be inserted into its fl_blocked_requests list, and
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 781) * can avoid doing anything further if the list is empty.
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 782) */
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 783) if (!smp_load_acquire(&waiter->fl_blocker) &&
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 784) list_empty(&waiter->fl_blocked_requests))
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 785) return status;
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 786)
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 787) spin_lock(&blocked_lock_lock);
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 788) if (waiter->fl_blocker)
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 789) status = 0;
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 790) __locks_wake_up_blocks(waiter);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 791) __locks_delete_block(waiter);
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 792)
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 793) /*
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 794) * The setting of fl_blocker to NULL marks the "done" point in deleting
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 795) * a block. Paired with acquire at the top of this function.
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 796) */
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 797) smp_store_release(&waiter->fl_blocker, NULL);
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 798) spin_unlock(&blocked_lock_lock);
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 799) return status;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 800) }
cb03f94ffb070 (NeilBrown 2018-11-30 10:04:08 +1100 801) EXPORT_SYMBOL(locks_delete_block);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 802)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 803) /* Insert waiter into blocker's block list.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 804) * We use a circular list so that processes can be easily woken up in
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 805) * the order they blocked. The documentation doesn't require this but
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 806) * it seems like the reasonable thing to do.
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 807) *
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 808) * Must be called with both the flc_lock and blocked_lock_lock held. The
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 809) * fl_blocked_requests list itself is protected by the blocked_lock_lock,
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 810) * but by ensuring that the flc_lock is also held on insertions we can avoid
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 811) * taking the blocked_lock_lock in some cases when we see that the
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 812) * fl_blocked_requests list is empty.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 813) *
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 814) * Rather than just adding to the list, we check for conflicts with any existing
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 815) * waiters, and add beneath any waiter that blocks the new waiter.
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 816) * Thus wakeups don't happen until needed.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 817) */
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 818) static void __locks_insert_block(struct file_lock *blocker,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 819) struct file_lock *waiter,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 820) bool conflict(struct file_lock *,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 821) struct file_lock *))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 822) {
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 823) struct file_lock *fl;
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 824) BUG_ON(!list_empty(&waiter->fl_blocked_member));
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 825)
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 826) new_blocker:
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 827) list_for_each_entry(fl, &blocker->fl_blocked_requests, fl_blocked_member)
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 828) if (conflict(fl, waiter)) {
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 829) blocker = fl;
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 830) goto new_blocker;
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 831) }
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 832) waiter->fl_blocker = blocker;
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 833) list_add_tail(&waiter->fl_blocked_member, &blocker->fl_blocked_requests);
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 834) if (IS_POSIX(blocker) && !IS_OFDLCK(blocker))
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 835) locks_insert_global_blocked(waiter);
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 836)
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 837) /* The requests in waiter->fl_blocked are known to conflict with
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 838) * waiter, but might not conflict with blocker, or the requests
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 839) * and lock which block it. So they all need to be woken.
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 840) */
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 841) __locks_wake_up_blocks(waiter);
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 842) }
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 843)
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 844) /* Must be called with flc_lock held. */
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 845) static void locks_insert_block(struct file_lock *blocker,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 846) struct file_lock *waiter,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 847) bool conflict(struct file_lock *,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 848) struct file_lock *))
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 849) {
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 850) spin_lock(&blocked_lock_lock);
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 851) __locks_insert_block(blocker, waiter, conflict);
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 852) spin_unlock(&blocked_lock_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 853) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 854)
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 855) /*
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 856) * Wake up processes blocked waiting for blocker.
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 857) *
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 858) * Must be called with the inode->flc_lock held!
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 859) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 860) static void locks_wake_up_blocks(struct file_lock *blocker)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 861) {
4e8c765d384e5 (Jeff Layton 2013-06-21 08:58:16 -0400 862) /*
4e8c765d384e5 (Jeff Layton 2013-06-21 08:58:16 -0400 863) * Avoid taking global lock if list is empty. This is safe since new
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 864) * blocked requests are only added to the list under the flc_lock, and
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 865) * the flc_lock is always held here. Note that removal from the
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 866) * fl_blocked_requests list does not require the flc_lock, so we must
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 867) * recheck list_empty() after acquiring the blocked_lock_lock.
4e8c765d384e5 (Jeff Layton 2013-06-21 08:58:16 -0400 868) */
ada5c1da8660e (NeilBrown 2018-11-30 10:04:08 +1100 869) if (list_empty(&blocker->fl_blocked_requests))
4e8c765d384e5 (Jeff Layton 2013-06-21 08:58:16 -0400 870) return;
4e8c765d384e5 (Jeff Layton 2013-06-21 08:58:16 -0400 871)
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 872) spin_lock(&blocked_lock_lock);
ad6bbd8b18dad (NeilBrown 2018-11-30 10:04:08 +1100 873) __locks_wake_up_blocks(blocker);
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 874) spin_unlock(&blocked_lock_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 875) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 876)
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 877) static void
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 878) locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before)
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 879) {
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 880) list_add_tail(&fl->fl_list, before);
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 881) locks_insert_global_locks(fl);
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 882) }
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 883)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 884) static void
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 885) locks_unlink_lock_ctx(struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 886) {
889746917193a (Jeff Layton 2013-06-21 08:58:14 -0400 887) locks_delete_global_locks(fl);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 888) list_del_init(&fl->fl_list);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 889) locks_wake_up_blocks(fl);
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 890) }
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 891)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 892) static void
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 893) locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose)
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 894) {
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 895) locks_unlink_lock_ctx(fl);
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 896) if (dispose)
6dee60f69d48f (Jeff Layton 2015-01-16 15:05:54 -0500 897) list_add(&fl->fl_list, dispose);
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 898) else
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 899) locks_free_lock(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 900) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 901)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 902) /* Determine if lock sys_fl blocks lock caller_fl. Common functionality
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 903) * checks for shared/exclusive status of overlapping locks.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 904) */
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 905) static bool locks_conflict(struct file_lock *caller_fl,
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 906) struct file_lock *sys_fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 907) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 908) if (sys_fl->fl_type == F_WRLCK)
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 909) return true;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 910) if (caller_fl->fl_type == F_WRLCK)
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 911) return true;
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 912) return false;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 913) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 914)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 915) /* Determine if lock sys_fl blocks lock caller_fl. POSIX specific
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 916) * checking before calling the locks_conflict().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 917) */
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 918) static bool posix_locks_conflict(struct file_lock *caller_fl,
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 919) struct file_lock *sys_fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 920) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 921) /* POSIX locks owned by the same process do not conflict with
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 922) * each other.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 923) */
9b8c86956dea4 (Jeff Layton 2015-04-03 09:04:02 -0400 924) if (posix_same_owner(caller_fl, sys_fl))
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 925) return false;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 926)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 927) /* Check whether they overlap */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 928) if (!locks_overlap(caller_fl, sys_fl))
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 929) return false;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 930)
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 931) return locks_conflict(caller_fl, sys_fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 932) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 933)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 934) /* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 935) * checking before calling the locks_conflict().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 936) */
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 937) static bool flock_locks_conflict(struct file_lock *caller_fl,
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 938) struct file_lock *sys_fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 939) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 940) /* FLOCK locks referring to the same filp do not conflict with
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 941) * each other.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 942) */
9b8c86956dea4 (Jeff Layton 2015-04-03 09:04:02 -0400 943) if (caller_fl->fl_file == sys_fl->fl_file)
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 944) return false;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 945) if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND))
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 946) return false;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 947)
c0e15908979d2 (NeilBrown 2018-11-30 10:04:08 +1100 948) return locks_conflict(caller_fl, sys_fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 949) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 950)
6d34ac199a4af (J. Bruce Fields 2007-05-11 16:09:32 -0400 951) void
9d6a8c5c213e3 (Marc Eshel 2007-02-21 00:55:18 -0500 952) posix_test_lock(struct file *filp, struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 953) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 954) struct file_lock *cfl;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 955) struct file_lock_context *ctx;
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 956) struct inode *inode = locks_inode(filp);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 957)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 958) ctx = smp_load_acquire(&inode->i_flctx);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 959) if (!ctx || list_empty_careful(&ctx->flc_posix)) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 960) fl->fl_type = F_UNLCK;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 961) return;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 962) }
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 963)
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 964) spin_lock(&ctx->flc_lock);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 965) list_for_each_entry(cfl, &ctx->flc_posix, fl_list) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 966) if (posix_locks_conflict(fl, cfl)) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 967) locks_copy_conflock(fl, cfl);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 968) goto out;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 969) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 970) }
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 971) fl->fl_type = F_UNLCK;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 972) out:
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 973) spin_unlock(&ctx->flc_lock);
6d34ac199a4af (J. Bruce Fields 2007-05-11 16:09:32 -0400 974) return;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 975) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 976) EXPORT_SYMBOL(posix_test_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 977)
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 978) /*
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 979) * Deadlock detection:
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 980) *
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 981) * We attempt to detect deadlocks that are due purely to posix file
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 982) * locks.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 983) *
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 984) * We assume that a task can be waiting for at most one lock at a time.
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 985) * So for any acquired lock, the process holding that lock may be
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 986) * waiting on at most one other lock. That lock in turns may be held by
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 987) * someone waiting for at most one other lock. Given a requested lock
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 988) * caller_fl which is about to wait for a conflicting lock block_fl, we
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 989) * follow this chain of waiters to ensure we are not about to create a
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 990) * cycle.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 991) *
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 992) * Since we do this before we ever put a process to sleep on a lock, we
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 993) * are ensured that there is never a cycle; that is what guarantees that
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 994) * the while() loop in posix_locks_deadlock() eventually completes.
97855b49b6bac (J. Bruce Fields 2007-10-30 11:20:02 -0400 995) *
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 996) * Note: the above assumption may not be true when handling lock
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 997) * requests from a broken NFS client. It may also fail in the presence
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 998) * of tasks (such as posix threads) sharing the same open file table.
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 999) * To handle those cases, we just bail out after a few iterations.
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1000) *
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 1001) * For FL_OFDLCK locks, the owner is the filp, not the files_struct.
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1002) * Because the owner is not even nominally tied to a thread of
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1003) * execution, the deadlock detection below can't reasonably work well. Just
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1004) * skip it for those.
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1005) *
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 1006) * In principle, we could do a more limited deadlock detection on FL_OFDLCK
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1007) * locks that just checks for the case where two tasks are attempting to
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1008) * upgrade from read to write locks on the same inode.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1009) */
97855b49b6bac (J. Bruce Fields 2007-10-30 11:20:02 -0400 1010)
97855b49b6bac (J. Bruce Fields 2007-10-30 11:20:02 -0400 1011) #define MAX_DEADLK_ITERATIONS 10
97855b49b6bac (J. Bruce Fields 2007-10-30 11:20:02 -0400 1012)
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1013) /* Find a lock that the owner of the given block_fl is blocking on. */
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1014) static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl)
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1015) {
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1016) struct file_lock *fl;
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1017)
3999e49364193 (Jeff Layton 2013-06-21 08:58:19 -0400 1018) hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) {
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 1019) if (posix_same_owner(fl, block_fl)) {
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 1020) while (fl->fl_blocker)
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 1021) fl = fl->fl_blocker;
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 1022) return fl;
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 1023) }
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1024) }
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1025) return NULL;
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1026) }
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1027)
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 1028) /* Must be called with the blocked_lock_lock held! */
b0904e147f7cb (Adrian Bunk 2006-06-23 02:05:13 -0700 1029) static int posix_locks_deadlock(struct file_lock *caller_fl,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1030) struct file_lock *block_fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1031) {
97855b49b6bac (J. Bruce Fields 2007-10-30 11:20:02 -0400 1032) int i = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1033)
663d5af750b8c (Daniel Wagner 2015-04-03 09:04:03 -0400 1034) lockdep_assert_held(&blocked_lock_lock);
663d5af750b8c (Daniel Wagner 2015-04-03 09:04:03 -0400 1035)
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1036) /*
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1037) * This deadlock detector can't reasonably detect deadlocks with
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 1038) * FL_OFDLCK locks, since they aren't owned by a process, per-se.
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1039) */
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 1040) if (IS_OFDLCK(caller_fl))
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1041) return 0;
57b65325fe34e (Jeff Layton 2014-02-03 12:13:09 -0500 1042)
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1043) while ((block_fl = what_owner_is_waiting_for(block_fl))) {
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1044) if (i++ > MAX_DEADLK_ITERATIONS)
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1045) return 0;
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1046) if (posix_same_owner(caller_fl, block_fl))
b533184fc353d (J. Bruce Fields 2007-10-26 18:05:40 -0400 1047) return 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1048) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1049) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1050) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1051)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1052) /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
02888f41e9d7f (J. Bruce Fields 2007-09-12 15:45:07 -0400 1053) * after any leases, but before any posix locks.
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1054) *
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1055) * Note that if called with an FL_EXISTS argument, the caller may determine
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1056) * whether or not a lock was successfully freed by testing the return
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1057) * value for -ENOENT.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1058) */
bcd7f78d078ff (Jeff Layton 2015-07-11 06:43:02 -0400 1059) static int flock_lock_inode(struct inode *inode, struct file_lock *request)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1060) {
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1061) struct file_lock *new_fl = NULL;
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 1062) struct file_lock *fl;
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 1063) struct file_lock_context *ctx;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1064) int error = 0;
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 1065) bool found = false;
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 1066) LIST_HEAD(dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1067)
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1068) ctx = locks_get_lock_context(inode, request->fl_type);
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1069) if (!ctx) {
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1070) if (request->fl_type != F_UNLCK)
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1071) return -ENOMEM;
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1072) return (request->fl_flags & FL_EXISTS) ? -ENOENT : 0;
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1073) }
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 1074)
b89f432133851 (Arnd Bergmann 2010-09-18 15:09:31 +0200 1075) if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) {
84d535ade62b6 (Pavel Emelyanov 2007-09-11 16:38:13 +0400 1076) new_fl = locks_alloc_lock();
b89f432133851 (Arnd Bergmann 2010-09-18 15:09:31 +0200 1077) if (!new_fl)
b89f432133851 (Arnd Bergmann 2010-09-18 15:09:31 +0200 1078) return -ENOMEM;
84d535ade62b6 (Pavel Emelyanov 2007-09-11 16:38:13 +0400 1079) }
84d535ade62b6 (Pavel Emelyanov 2007-09-11 16:38:13 +0400 1080)
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1081) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1082) spin_lock(&ctx->flc_lock);
b89f432133851 (Arnd Bergmann 2010-09-18 15:09:31 +0200 1083) if (request->fl_flags & FL_ACCESS)
b89f432133851 (Arnd Bergmann 2010-09-18 15:09:31 +0200 1084) goto find_conflict;
b89f432133851 (Arnd Bergmann 2010-09-18 15:09:31 +0200 1085)
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 1086) list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
bcd7f78d078ff (Jeff Layton 2015-07-11 06:43:02 -0400 1087) if (request->fl_file != fl->fl_file)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1088) continue;
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1089) if (request->fl_type == fl->fl_type)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1090) goto out;
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 1091) found = true;
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1092) locks_delete_lock_ctx(fl, &dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1093) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1094) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1095)
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1096) if (request->fl_type == F_UNLCK) {
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1097) if ((request->fl_flags & FL_EXISTS) && !found)
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1098) error = -ENOENT;
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1099) goto out;
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1100) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1101)
f07f18dd6f29f (Trond Myklebust 2006-06-29 16:38:37 -0400 1102) find_conflict:
5263e31e452fb (Jeff Layton 2015-01-16 15:05:55 -0500 1103) list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1104) if (!flock_locks_conflict(request, fl))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1105) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1106) error = -EAGAIN;
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 1107) if (!(request->fl_flags & FL_SLEEP))
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 1108) goto out;
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 1109) error = FILE_LOCK_DEFERRED;
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 1110) locks_insert_block(fl, request, flock_locks_conflict);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1111) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1112) }
f07f18dd6f29f (Trond Myklebust 2006-06-29 16:38:37 -0400 1113) if (request->fl_flags & FL_ACCESS)
f07f18dd6f29f (Trond Myklebust 2006-06-29 16:38:37 -0400 1114) goto out;
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1115) locks_copy_lock(new_fl, request);
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 1116) locks_move_blocks(new_fl, request);
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1117) locks_insert_lock_ctx(new_fl, &ctx->flc_flock);
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1118) new_fl = NULL;
9cedc194a7735 (Kirill Korotaev 2006-06-14 17:59:35 +0400 1119) error = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1120)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1121) out:
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1122) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1123) percpu_up_read(&file_rwsem);
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1124) if (new_fl)
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 1125) locks_free_lock(new_fl);
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 1126) locks_dispose_list(&dispose);
c883da313ebf4 (Jeff Layton 2018-07-30 07:54:56 -0400 1127) trace_flock_lock_inode(inode, request, error);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1128) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1129) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1130)
b4d629a39e104 (Jeff Layton 2016-01-07 18:27:42 -0500 1131) static int posix_lock_inode(struct inode *inode, struct file_lock *request,
b4d629a39e104 (Jeff Layton 2016-01-07 18:27:42 -0500 1132) struct file_lock *conflock)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1133) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1134) struct file_lock *fl, *tmp;
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1135) struct file_lock *new_fl = NULL;
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1136) struct file_lock *new_fl2 = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1137) struct file_lock *left = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1138) struct file_lock *right = NULL;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1139) struct file_lock_context *ctx;
b9746ef80fa69 (Jeff Layton 2013-06-21 08:58:13 -0400 1140) int error;
b9746ef80fa69 (Jeff Layton 2013-06-21 08:58:13 -0400 1141) bool added = false;
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 1142) LIST_HEAD(dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1143)
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1144) ctx = locks_get_lock_context(inode, request->fl_type);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1145) if (!ctx)
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1146) return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1147)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1148) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1149) * We may need two file_lock structures for this operation,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1150) * so we get them in advance to avoid races.
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1151) *
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1152) * In some cases we can be sure, that no new locks will be needed
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1153) */
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1154) if (!(request->fl_flags & FL_ACCESS) &&
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1155) (request->fl_type != F_UNLCK ||
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1156) request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1157) new_fl = locks_alloc_lock();
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1158) new_fl2 = locks_alloc_lock();
39005d022ad22 (Miklos Szeredi 2006-06-23 02:05:10 -0700 1159) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1160)
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1161) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1162) spin_lock(&ctx->flc_lock);
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1163) /*
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1164) * New lock request. Walk all POSIX locks and look for conflicts. If
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1165) * there are any, either return error or put the request on the
48f74186546cd (Jeff Layton 2013-06-21 08:58:18 -0400 1166) * blocker's list of waiters and the global blocked_hash.
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1167) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1168) if (request->fl_type != F_UNLCK) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1169) list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1170) if (!posix_locks_conflict(request, fl))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1171) continue;
5842add2f3b51 (Andy Adamson 2006-03-26 01:37:26 -0800 1172) if (conflock)
3fe0fff18fe87 (Kinglong Mee 2014-08-22 10:18:42 -0400 1173) locks_copy_conflock(conflock, fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1174) error = -EAGAIN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1175) if (!(request->fl_flags & FL_SLEEP))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1176) goto out;
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1177) /*
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1178) * Deadlock detection and insertion into the blocked
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1179) * locks list must be done while holding the same lock!
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1180) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1181) error = -EDEADLK;
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 1182) spin_lock(&blocked_lock_lock);
945ab8f6de944 (Jeff Layton 2019-03-25 08:15:14 -0400 1183) /*
945ab8f6de944 (Jeff Layton 2019-03-25 08:15:14 -0400 1184) * Ensure that we don't find any locks blocked on this
945ab8f6de944 (Jeff Layton 2019-03-25 08:15:14 -0400 1185) * request during deadlock detection.
945ab8f6de944 (Jeff Layton 2019-03-25 08:15:14 -0400 1186) */
945ab8f6de944 (Jeff Layton 2019-03-25 08:15:14 -0400 1187) __locks_wake_up_blocks(request);
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1188) if (likely(!posix_locks_deadlock(request, fl))) {
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1189) error = FILE_LOCK_DEFERRED;
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 1190) __locks_insert_block(fl, request,
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 1191) posix_locks_conflict);
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1192) }
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 1193) spin_unlock(&blocked_lock_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1194) goto out;
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 1195) }
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 1196) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1197)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1198) /* If we're just looking for a conflict, we're done. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1199) error = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1200) if (request->fl_flags & FL_ACCESS)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1201) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1202)
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1203) /* Find the first old lock with the same owner as the new lock */
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1204) list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1205) if (posix_same_owner(request, fl))
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1206) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1207) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1208)
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1209) /* Process locks with this owner. */
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1210) list_for_each_entry_safe_from(fl, tmp, &ctx->flc_posix, fl_list) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1211) if (!posix_same_owner(request, fl))
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1212) break;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1213)
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1214) /* Detect adjacent or overlapping regions (if same lock type) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1215) if (request->fl_type == fl->fl_type) {
449231d6ddf50 (Olaf Kirch 2005-08-25 16:25:35 -0700 1216) /* In all comparisons of start vs end, use
449231d6ddf50 (Olaf Kirch 2005-08-25 16:25:35 -0700 1217) * "start - 1" rather than "end + 1". If end
449231d6ddf50 (Olaf Kirch 2005-08-25 16:25:35 -0700 1218) * is OFFSET_MAX, end + 1 will become negative.
449231d6ddf50 (Olaf Kirch 2005-08-25 16:25:35 -0700 1219) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1220) if (fl->fl_end < request->fl_start - 1)
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1221) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1222) /* If the next lock in the list has entirely bigger
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1223) * addresses than the new one, insert the lock here.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1224) */
449231d6ddf50 (Olaf Kirch 2005-08-25 16:25:35 -0700 1225) if (fl->fl_start - 1 > request->fl_end)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1226) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1227)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1228) /* If we come here, the new and old lock are of the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1229) * same type and adjacent or overlapping. Make one
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1230) * lock yielding from the lower start address of both
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1231) * locks to the higher end address.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1232) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1233) if (fl->fl_start > request->fl_start)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1234) fl->fl_start = request->fl_start;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1235) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1236) request->fl_start = fl->fl_start;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1237) if (fl->fl_end < request->fl_end)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1238) fl->fl_end = request->fl_end;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1239) else
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1240) request->fl_end = fl->fl_end;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1241) if (added) {
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1242) locks_delete_lock_ctx(fl, &dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1243) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1244) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1245) request = fl;
b9746ef80fa69 (Jeff Layton 2013-06-21 08:58:13 -0400 1246) added = true;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1247) } else {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1248) /* Processing for different lock types is a bit
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1249) * more complex.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1250) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1251) if (fl->fl_end < request->fl_start)
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1252) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1253) if (fl->fl_start > request->fl_end)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1254) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1255) if (request->fl_type == F_UNLCK)
b9746ef80fa69 (Jeff Layton 2013-06-21 08:58:13 -0400 1256) added = true;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1257) if (fl->fl_start < request->fl_start)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1258) left = fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1259) /* If the next lock in the list has a higher end
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1260) * address than the new one, insert the new one here.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1261) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1262) if (fl->fl_end > request->fl_end) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1263) right = fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1264) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1265) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1266) if (fl->fl_start >= request->fl_start) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1267) /* The new lock completely replaces an old
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1268) * one (This may happen several times).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1269) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1270) if (added) {
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1271) locks_delete_lock_ctx(fl, &dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1272) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1273) }
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1274) /*
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1275) * Replace the old lock with new_fl, and
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1276) * remove the old one. It's safe to do the
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1277) * insert here since we know that we won't be
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1278) * using new_fl later, and that the lock is
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1279) * just replacing an existing lock.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1280) */
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1281) error = -ENOLCK;
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1282) if (!new_fl)
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1283) goto out;
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1284) locks_copy_lock(new_fl, request);
5ef1596813096 (yangerkun 2020-06-01 17:16:16 +0800 1285) locks_move_blocks(new_fl, request);
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1286) request = new_fl;
b84d49f9440b2 (Jeff Layton 2014-08-12 08:03:49 -0400 1287) new_fl = NULL;
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1288) locks_insert_lock_ctx(request, &fl->fl_list);
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1289) locks_delete_lock_ctx(fl, &dispose);
b9746ef80fa69 (Jeff Layton 2013-06-21 08:58:13 -0400 1290) added = true;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1291) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1292) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1293) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1294)
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1295) /*
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1296) * The above code only modifies existing locks in case of merging or
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1297) * replacing. If new lock(s) need to be inserted all modifications are
1cb360125966c (Jeff Layton 2013-06-21 08:58:12 -0400 1298) * done below this, so it's safe yet to bail out.
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1299) */
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1300) error = -ENOLCK; /* "no luck" */
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1301) if (right && left == right && !new_fl2)
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1302) goto out;
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1303)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1304) error = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1305) if (!added) {
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1306) if (request->fl_type == F_UNLCK) {
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1307) if (request->fl_flags & FL_EXISTS)
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1308) error = -ENOENT;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1309) goto out;
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1310) }
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1311)
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1312) if (!new_fl) {
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1313) error = -ENOLCK;
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1314) goto out;
0d9a490abe1f6 (Miklos Szeredi 2006-06-23 02:05:09 -0700 1315) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1316) locks_copy_lock(new_fl, request);
5946c4319ebb3 (NeilBrown 2018-11-30 10:04:08 +1100 1317) locks_move_blocks(new_fl, request);
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1318) locks_insert_lock_ctx(new_fl, &fl->fl_list);
2e2f756f81edd (Jeff Layton 2015-02-17 17:08:23 -0500 1319) fl = new_fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1320) new_fl = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1321) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1322) if (right) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1323) if (left == right) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1324) /* The new lock breaks the old one in two pieces,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1325) * so we have to use the second new lock.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1326) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1327) left = new_fl2;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1328) new_fl2 = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1329) locks_copy_lock(left, right);
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1330) locks_insert_lock_ctx(left, &fl->fl_list);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1331) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1332) right->fl_start = request->fl_end + 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1333) locks_wake_up_blocks(right);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1334) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1335) if (left) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1336) left->fl_end = request->fl_start - 1;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1337) locks_wake_up_blocks(left);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1338) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1339) out:
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1340) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1341) percpu_up_read(&file_rwsem);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1342) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1343) * Free any unused locks.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1344) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1345) if (new_fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1346) locks_free_lock(new_fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1347) if (new_fl2)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1348) locks_free_lock(new_fl2);
ed9814d85810c (Jeff Layton 2014-08-11 14:20:31 -0400 1349) locks_dispose_list(&dispose);
1890910fd06fe (Jeff Layton 2016-01-06 21:26:10 -0500 1350) trace_posix_lock_inode(inode, request, error);
1890910fd06fe (Jeff Layton 2016-01-06 21:26:10 -0500 1351)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1352) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1353) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1354)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1355) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1356) * posix_lock_file - Apply a POSIX-style lock to a file
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1357) * @filp: The file to apply the lock to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1358) * @fl: The lock to be applied
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 1359) * @conflock: Place to return a copy of the conflicting lock, if found.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1360) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1361) * Add a POSIX style lock to a file.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1362) * We merge adjacent & overlapping locks whenever possible.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1363) * POSIX locks are sorted by owner task, then by starting address
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1364) *
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1365) * Note that if called with an FL_EXISTS argument, the caller may determine
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1366) * whether or not a lock was successfully freed by testing the return
f475ae957db66 (Trond Myklebust 2006-06-29 16:38:32 -0400 1367) * value for -ENOENT.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1368) */
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 1369) int posix_lock_file(struct file *filp, struct file_lock *fl,
5842add2f3b51 (Andy Adamson 2006-03-26 01:37:26 -0800 1370) struct file_lock *conflock)
5842add2f3b51 (Andy Adamson 2006-03-26 01:37:26 -0800 1371) {
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 1372) return posix_lock_inode(locks_inode(filp), fl, conflock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1373) }
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 1374) EXPORT_SYMBOL(posix_lock_file);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1375)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1376) /**
29d01b22eaa18 (Jeff Layton 2015-07-11 06:43:02 -0400 1377) * posix_lock_inode_wait - Apply a POSIX-style lock to a file
29d01b22eaa18 (Jeff Layton 2015-07-11 06:43:02 -0400 1378) * @inode: inode of file to which lock request should be applied
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1379) * @fl: The lock to be applied
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1380) *
616fb38fa7a95 (Benjamin Coddington 2015-10-22 13:38:15 -0400 1381) * Apply a POSIX style lock request to an inode.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1382) */
616fb38fa7a95 (Benjamin Coddington 2015-10-22 13:38:15 -0400 1383) static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1384) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1385) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1386) might_sleep ();
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1387) for (;;) {
b4d629a39e104 (Jeff Layton 2016-01-07 18:27:42 -0500 1388) error = posix_lock_inode(inode, fl, NULL);
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 1389) if (error != FILE_LOCK_DEFERRED)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1390) break;
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 1391) error = wait_event_interruptible(fl->fl_wait,
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 1392) list_empty(&fl->fl_blocked_member));
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 1393) if (error)
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 1394) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1395) }
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 1396) locks_delete_block(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1397) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1398) }
29d01b22eaa18 (Jeff Layton 2015-07-11 06:43:02 -0400 1399)
9e8925b67a809 (Jeff Layton 2015-11-16 09:49:34 -0500 1400) #ifdef CONFIG_MANDATORY_FILE_LOCKING
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1401) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1402) * locks_mandatory_locked - Check for an active lock
d7a06983a01a3 (Jeff Layton 2014-03-10 09:54:15 -0400 1403) * @file: the file to check
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1404) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1405) * Searches the inode's list of locks to find any POSIX locks which conflict.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1406) * This function is called from locks_verify_locked() only.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1407) */
d7a06983a01a3 (Jeff Layton 2014-03-10 09:54:15 -0400 1408) int locks_mandatory_locked(struct file *file)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1409) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1410) int ret;
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 1411) struct inode *inode = locks_inode(file);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1412) struct file_lock_context *ctx;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1413) struct file_lock *fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1414)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1415) ctx = smp_load_acquire(&inode->i_flctx);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1416) if (!ctx || list_empty_careful(&ctx->flc_posix))
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1417) return 0;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1418)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1419) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1420) * Search the lock list for this inode for any POSIX locks.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1421) */
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1422) spin_lock(&ctx->flc_lock);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1423) ret = 0;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1424) list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 1425) if (fl->fl_owner != current->files &&
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1426) fl->fl_owner != file) {
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1427) ret = -EAGAIN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1428) break;
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1429) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1430) }
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1431) spin_unlock(&ctx->flc_lock);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 1432) return ret;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1433) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1434)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1435) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1436) * locks_mandatory_area - Check for a conflicting lock
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1437) * @inode: the file to check
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1438) * @filp: how the file was opened (if it was)
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1439) * @start: first byte in the file to check
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1440) * @end: lastbyte in the file to check
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1441) * @type: %F_WRLCK for a write lock, else %F_RDLCK
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1442) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1443) * Searches the inode's list of locks to find any POSIX locks which conflict.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1444) */
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1445) int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start,
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1446) loff_t end, unsigned char type)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1447) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1448) struct file_lock fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1449) int error;
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1450) bool sleep = false;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1451)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1452) locks_init_lock(&fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1453) fl.fl_pid = current->tgid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1454) fl.fl_file = filp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1455) fl.fl_flags = FL_POSIX | FL_ACCESS;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1456) if (filp && !(filp->f_flags & O_NONBLOCK))
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1457) sleep = true;
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1458) fl.fl_type = type;
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1459) fl.fl_start = start;
acc15575e78e5 (Christoph Hellwig 2015-12-03 12:59:49 +0100 1460) fl.fl_end = end;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1461)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1462) for (;;) {
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1463) if (filp) {
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 1464) fl.fl_owner = filp;
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1465) fl.fl_flags &= ~FL_SLEEP;
b4d629a39e104 (Jeff Layton 2016-01-07 18:27:42 -0500 1466) error = posix_lock_inode(inode, &fl, NULL);
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1467) if (!error)
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1468) break;
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1469) }
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1470)
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1471) if (sleep)
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1472) fl.fl_flags |= FL_SLEEP;
29723adee1180 (Jeff Layton 2014-03-10 09:54:19 -0400 1473) fl.fl_owner = current->files;
b4d629a39e104 (Jeff Layton 2016-01-07 18:27:42 -0500 1474) error = posix_lock_inode(inode, &fl, NULL);
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 1475) if (error != FILE_LOCK_DEFERRED)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1476) break;
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 1477) error = wait_event_interruptible(fl.fl_wait,
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 1478) list_empty(&fl.fl_blocked_member));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1479) if (!error) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1480) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1481) * If we've been sleeping someone might have
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1482) * changed the permissions behind our back.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1483) */
a16877ca9cec2 (Pavel Emelyanov 2007-10-01 14:41:11 -0700 1484) if (__mandatory_lock(inode))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1485) continue;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1486) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1487)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1488) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1489) }
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 1490) locks_delete_block(&fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1491)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1492) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1493) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1494) EXPORT_SYMBOL(locks_mandatory_area);
9e8925b67a809 (Jeff Layton 2015-11-16 09:49:34 -0500 1495) #endif /* CONFIG_MANDATORY_FILE_LOCKING */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1496)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1497) static void lease_clear_pending(struct file_lock *fl, int arg)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1498) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1499) switch (arg) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1500) case F_UNLCK:
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1501) fl->fl_flags &= ~FL_UNLOCK_PENDING;
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 1502) fallthrough;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1503) case F_RDLCK:
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1504) fl->fl_flags &= ~FL_DOWNGRADE_PENDING;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1505) }
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1506) }
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1507)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1508) /* We already had a lease on this file; just change its type */
7448cc37b1a6b (Jeff Layton 2015-01-16 15:05:57 -0500 1509) int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1510) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1511) int error = assign_type(fl, arg);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1512)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1513) if (error)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1514) return error;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1515) lease_clear_pending(fl, arg);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1516) locks_wake_up_blocks(fl);
3b6e2723f32de (Filipe Brandenburger 2012-07-27 00:42:52 -0400 1517) if (arg == F_UNLCK) {
3b6e2723f32de (Filipe Brandenburger 2012-07-27 00:42:52 -0400 1518) struct file *filp = fl->fl_file;
3b6e2723f32de (Filipe Brandenburger 2012-07-27 00:42:52 -0400 1519)
3b6e2723f32de (Filipe Brandenburger 2012-07-27 00:42:52 -0400 1520) f_delown(filp);
3b6e2723f32de (Filipe Brandenburger 2012-07-27 00:42:52 -0400 1521) filp->f_owner.signum = 0;
96d6d59ceaeaa (J. Bruce Fields 2012-07-27 16:18:00 -0400 1522) fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync);
96d6d59ceaeaa (J. Bruce Fields 2012-07-27 16:18:00 -0400 1523) if (fl->fl_fasync != NULL) {
96d6d59ceaeaa (J. Bruce Fields 2012-07-27 16:18:00 -0400 1524) printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync);
96d6d59ceaeaa (J. Bruce Fields 2012-07-27 16:18:00 -0400 1525) fl->fl_fasync = NULL;
96d6d59ceaeaa (J. Bruce Fields 2012-07-27 16:18:00 -0400 1526) }
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1527) locks_delete_lock_ctx(fl, dispose);
3b6e2723f32de (Filipe Brandenburger 2012-07-27 00:42:52 -0400 1528) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1529) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1530) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1531) EXPORT_SYMBOL(lease_modify);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1532)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1533) static bool past_time(unsigned long then)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1534) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1535) if (!then)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1536) /* 0 is a special value meaning "this never expires": */
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1537) return false;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1538) return time_after(jiffies, then);
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1539) }
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1540)
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1541) static void time_out_leases(struct inode *inode, struct list_head *dispose)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1542) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1543) struct file_lock_context *ctx = inode->i_flctx;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1544) struct file_lock *fl, *tmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1545)
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1546) lockdep_assert_held(&ctx->flc_lock);
f82b4b6780afa (Jeff Layton 2014-08-22 18:50:48 -0400 1547)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1548) list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) {
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 1549) trace_time_out_leases(inode, fl);
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1550) if (past_time(fl->fl_downgrade_time))
7448cc37b1a6b (Jeff Layton 2015-01-16 15:05:57 -0500 1551) lease_modify(fl, F_RDLCK, dispose);
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1552) if (past_time(fl->fl_break_time))
7448cc37b1a6b (Jeff Layton 2015-01-16 15:05:57 -0500 1553) lease_modify(fl, F_UNLCK, dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1554) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1555) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1556)
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1557) static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker)
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1558) {
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1559) bool rc;
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1560)
28df3d1539de5 (J. Bruce Fields 2017-07-28 16:35:15 -0400 1561) if (lease->fl_lmops->lm_breaker_owns_lease
28df3d1539de5 (J. Bruce Fields 2017-07-28 16:35:15 -0400 1562) && lease->fl_lmops->lm_breaker_owns_lease(lease))
28df3d1539de5 (J. Bruce Fields 2017-07-28 16:35:15 -0400 1563) return false;
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1564) if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT)) {
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1565) rc = false;
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1566) goto trace;
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1567) }
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1568) if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE)) {
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1569) rc = false;
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1570) goto trace;
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1571) }
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1572)
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1573) rc = locks_conflict(breaker, lease);
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1574) trace:
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1575) trace_leases_conflict(rc, lease, breaker);
d51f527f44f96 (Ira Weiny 2019-06-05 18:45:34 -0700 1576) return rc;
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1577) }
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1578)
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1579) static bool
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1580) any_leases_conflict(struct inode *inode, struct file_lock *breaker)
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1581) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1582) struct file_lock_context *ctx = inode->i_flctx;
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1583) struct file_lock *fl;
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1584)
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1585) lockdep_assert_held(&ctx->flc_lock);
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1586)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1587) list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1588) if (leases_conflict(fl, breaker))
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1589) return true;
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1590) }
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1591) return false;
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1592) }
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1593)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1594) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1595) * __break_lease - revoke all outstanding leases on file
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1596) * @inode: the inode of the file to return
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1597) * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR:
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1598) * break all leases
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1599) * @type: FL_LEASE: break leases and delegations; FL_DELEG: break
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1600) * only delegations
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1601) *
87250dd26a34c (david m. richter 2007-05-09 16:10:27 -0400 1602) * break_lease (inlined for speed) has checked there already is at least
87250dd26a34c (david m. richter 2007-05-09 16:10:27 -0400 1603) * some kind of lock (maybe a lease) on this file. Leases are broken on
87250dd26a34c (david m. richter 2007-05-09 16:10:27 -0400 1604) * a call to open() or truncate(). This function can sleep unless you
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1605) * specified %O_NONBLOCK to your open().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1606) */
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1607) int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1608) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1609) int error = 0;
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1610) struct file_lock_context *ctx;
a901125c65544 (Yan, Zheng 2015-03-27 10:34:20 +0800 1611) struct file_lock *new_fl, *fl, *tmp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1612) unsigned long break_time;
8737c9305bd56 (Al Viro 2009-12-24 06:47:55 -0500 1613) int want_write = (mode & O_ACCMODE) != O_RDONLY;
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1614) LIST_HEAD(dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1615)
8737c9305bd56 (Al Viro 2009-12-24 06:47:55 -0500 1616) new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
6d4b9e38d3980 (Linus Torvalds 2011-12-26 10:25:26 -0800 1617) if (IS_ERR(new_fl))
6d4b9e38d3980 (Linus Torvalds 2011-12-26 10:25:26 -0800 1618) return PTR_ERR(new_fl);
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1619) new_fl->fl_flags = type;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1620)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1621) /* typically we will check that ctx is non-NULL before calling */
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1622) ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1623) if (!ctx) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1624) WARN_ON_ONCE(1);
cfddf9f4c9f03 (Wenwen Wang 2019-08-19 18:47:34 -0500 1625) goto free_lock;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1626) }
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1627)
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1628) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1629) spin_lock(&ctx->flc_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1630)
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1631) time_out_leases(inode, &dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1632)
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1633) if (!any_leases_conflict(inode, new_fl))
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1634) goto out;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1635)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1636) break_time = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1637) if (lease_break_time > 0) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1638) break_time = jiffies + lease_break_time * HZ;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1639) if (break_time == 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1640) break_time++; /* so that 0 means no break time */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1641) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1642)
a901125c65544 (Yan, Zheng 2015-03-27 10:34:20 +0800 1643) list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) {
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1644) if (!leases_conflict(fl, new_fl))
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1645) continue;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1646) if (want_write) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1647) if (fl->fl_flags & FL_UNLOCK_PENDING)
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1648) continue;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1649) fl->fl_flags |= FL_UNLOCK_PENDING;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1650) fl->fl_break_time = break_time;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1651) } else {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1652) if (lease_breaking(fl))
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1653) continue;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1654) fl->fl_flags |= FL_DOWNGRADE_PENDING;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1655) fl->fl_downgrade_time = break_time;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1656) }
4d01b7f5e7576 (Jeff Layton 2014-09-01 15:06:54 -0400 1657) if (fl->fl_lmops->lm_break(fl))
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1658) locks_delete_lock_ctx(fl, &dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1659) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1660)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1661) if (list_empty(&ctx->flc_lease))
4d01b7f5e7576 (Jeff Layton 2014-09-01 15:06:54 -0400 1662) goto out;
4d01b7f5e7576 (Jeff Layton 2014-09-01 15:06:54 -0400 1663)
843c6b2f4cef3 (Jeff Layton 2014-09-01 14:27:43 -0400 1664) if (mode & O_NONBLOCK) {
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 1665) trace_break_lease_noblock(inode, new_fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1666) error = -EWOULDBLOCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1667) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1668) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1669)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1670) restart:
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1671) fl = list_first_entry(&ctx->flc_lease, struct file_lock, fl_list);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1672) break_time = fl->fl_break_time;
f1c6bb2cb8b81 (Jeff Layton 2014-04-15 06:17:49 -0400 1673) if (break_time != 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1674) break_time -= jiffies;
f1c6bb2cb8b81 (Jeff Layton 2014-04-15 06:17:49 -0400 1675) if (break_time == 0)
f1c6bb2cb8b81 (Jeff Layton 2014-04-15 06:17:49 -0400 1676) break_time++;
fd7732e033e30 (NeilBrown 2018-11-30 10:04:08 +1100 1677) locks_insert_block(fl, new_fl, leases_conflict);
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 1678) trace_break_lease_block(inode, new_fl);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1679) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1680) percpu_up_read(&file_rwsem);
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 1681)
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1682) locks_dispose_list(&dispose);
4321e01e7dce8 (Matthew Wilcox 2008-01-14 21:28:30 -0700 1683) error = wait_event_interruptible_timeout(new_fl->fl_wait,
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 1684) list_empty(&new_fl->fl_blocked_member),
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 1685) break_time);
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 1686)
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1687) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1688) spin_lock(&ctx->flc_lock);
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 1689) trace_break_lease_unblock(inode, new_fl);
1c8c601a8c0dc (Jeff Layton 2013-06-21 08:58:15 -0400 1690) locks_delete_block(new_fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1691) if (error >= 0) {
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1692) /*
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1693) * Wait for the next conflicting lease that has not been
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1694) * broken yet
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1695) */
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1696) if (error == 0)
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1697) time_out_leases(inode, &dispose);
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1698) if (any_leases_conflict(inode, new_fl))
03d12ddf845a4 (Jeff Layton 2014-09-01 14:53:41 -0400 1699) goto restart;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1700) error = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1701) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1702) out:
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1703) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1704) percpu_up_read(&file_rwsem);
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1705) locks_dispose_list(&dispose);
cfddf9f4c9f03 (Wenwen Wang 2019-08-19 18:47:34 -0500 1706) free_lock:
6d4b9e38d3980 (Linus Torvalds 2011-12-26 10:25:26 -0800 1707) locks_free_lock(new_fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1708) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1709) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1710) EXPORT_SYMBOL(__break_lease);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1711)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1712) /**
76c479480b9af (Amir Goldstein 2018-01-03 17:14:34 +0200 1713) * lease_get_mtime - update modified time of an inode with exclusive lease
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1714) * @inode: the inode
76c479480b9af (Amir Goldstein 2018-01-03 17:14:34 +0200 1715) * @time: pointer to a timespec which contains the last modified time
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1716) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1717) * This is to force NFS clients to flush their caches for files with
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1718) * exclusive leases. The justification is that if someone has an
a6b91919e0881 (Randy Dunlap 2008-03-19 17:01:00 -0700 1719) * exclusive lease, then they could be modifying it.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1720) */
95582b0083883 (Deepa Dinamani 2018-05-08 19:36:02 -0700 1721) void lease_get_mtime(struct inode *inode, struct timespec64 *time)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1722) {
bfe8602436c80 (Jeff Layton 2014-08-22 10:18:44 -0400 1723) bool has_lease = false;
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1724) struct file_lock_context *ctx;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1725) struct file_lock *fl;
bfe8602436c80 (Jeff Layton 2014-08-22 10:18:44 -0400 1726)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1727) ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1728) if (ctx && !list_empty_careful(&ctx->flc_lease)) {
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1729) spin_lock(&ctx->flc_lock);
8ace5dfb983e8 (Geliang Tang 2015-11-18 21:40:33 +0800 1730) fl = list_first_entry_or_null(&ctx->flc_lease,
8ace5dfb983e8 (Geliang Tang 2015-11-18 21:40:33 +0800 1731) struct file_lock, fl_list);
8ace5dfb983e8 (Geliang Tang 2015-11-18 21:40:33 +0800 1732) if (fl && (fl->fl_type == F_WRLCK))
8ace5dfb983e8 (Geliang Tang 2015-11-18 21:40:33 +0800 1733) has_lease = true;
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1734) spin_unlock(&ctx->flc_lock);
bfe8602436c80 (Jeff Layton 2014-08-22 10:18:44 -0400 1735) }
bfe8602436c80 (Jeff Layton 2014-08-22 10:18:44 -0400 1736)
bfe8602436c80 (Jeff Layton 2014-08-22 10:18:44 -0400 1737) if (has_lease)
c2050a454c7f1 (Deepa Dinamani 2016-09-14 07:48:06 -0700 1738) *time = current_time(inode);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1739) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1740) EXPORT_SYMBOL(lease_get_mtime);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1741)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1742) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1743) * fcntl_getlease - Enquire what lease is currently active
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1744) * @filp: the file
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1745) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1746) * The value returned by this function will be one of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1747) * (if no lease break is pending):
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1748) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1749) * %F_RDLCK to indicate a shared lease is held.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1750) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1751) * %F_WRLCK to indicate an exclusive lease is held.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1752) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1753) * %F_UNLCK to indicate no lease is held.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1754) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1755) * (if a lease break is pending):
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1756) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1757) * %F_RDLCK to indicate an exclusive lease needs to be
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1758) * changed to a shared lease (or removed).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1759) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1760) * %F_UNLCK to indicate the lease needs to be removed.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1761) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1762) * XXX: sfr & willy disagree over whether F_INPROGRESS
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1763) * should be returned to userspace.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1764) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1765) int fcntl_getlease(struct file *filp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1766) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1767) struct file_lock *fl;
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 1768) struct inode *inode = locks_inode(filp);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1769) struct file_lock_context *ctx;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1770) int type = F_UNLCK;
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1771) LIST_HEAD(dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1772)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1773) ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1774) if (ctx && !list_empty_careful(&ctx->flc_lease)) {
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1775) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1776) spin_lock(&ctx->flc_lock);
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 1777) time_out_leases(inode, &dispose);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1778) list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1779) if (fl->fl_file != filp)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1780) continue;
778fc546f749c (J. Bruce Fields 2011-07-26 18:25:49 -0400 1781) type = target_leasetype(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1782) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1783) }
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1784) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1785) percpu_up_read(&file_rwsem);
5f43086bb9224 (Peter Zijlstra 2016-10-08 10:12:28 +0200 1786)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1787) locks_dispose_list(&dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1788) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1789) return type;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1790) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1791)
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1792) /**
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1793) * check_conflicting_open - see if the given file points to an inode that has
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 1794) * an existing open that would conflict with the
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 1795) * desired lease.
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1796) * @filp: file to check
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1797) * @arg: type of lease that we're trying to acquire
7fadc59cc89f2 (Randy Dunlap 2015-08-09 18:43:17 -0700 1798) * @flags: current lock flags
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1799) *
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1800) * Check to see if there's an existing open fd on this file that would
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1801) * conflict with the lease we're trying to set.
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1802) */
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1803) static int
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1804) check_conflicting_open(struct file *filp, const long arg, int flags)
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1805) {
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1806) struct inode *inode = locks_inode(filp);
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1807) int self_wcount = 0, self_rcount = 0;
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1808)
11afe9f76e121 (Christoph Hellwig 2015-01-21 19:17:03 +0100 1809) if (flags & FL_LAYOUT)
11afe9f76e121 (Christoph Hellwig 2015-01-21 19:17:03 +0100 1810) return 0;
aba2072f45234 (J. Bruce Fields 2021-04-16 14:00:18 -0400 1811) if (flags & FL_DELEG)
aba2072f45234 (J. Bruce Fields 2021-04-16 14:00:18 -0400 1812) /* We leave these checks to the caller */
aba2072f45234 (J. Bruce Fields 2021-04-16 14:00:18 -0400 1813) return 0;
11afe9f76e121 (Christoph Hellwig 2015-01-21 19:17:03 +0100 1814)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1815) if (arg == F_RDLCK)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1816) return inode_is_open_for_write(inode) ? -EAGAIN : 0;
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1817) else if (arg != F_WRLCK)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1818) return 0;
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1819)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1820) /*
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1821) * Make sure that only read/write count is from lease requestor.
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1822) * Note that this will result in denying write leases when i_writecount
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1823) * is negative, which is what we want. (We shouldn't grant write leases
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1824) * on files open for execution.)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1825) */
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1826) if (filp->f_mode & FMODE_WRITE)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1827) self_wcount = 1;
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1828) else if (filp->f_mode & FMODE_READ)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1829) self_rcount = 1;
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1830)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1831) if (atomic_read(&inode->i_writecount) != self_wcount ||
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1832) atomic_read(&inode->i_readcount) != self_rcount)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1833) return -EAGAIN;
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1834)
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1835) return 0;
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1836) }
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1837)
e6f5c78930e40 (Jeff Layton 2014-08-22 10:40:25 -0400 1838) static int
e6f5c78930e40 (Jeff Layton 2014-08-22 10:40:25 -0400 1839) generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **priv)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1840) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1841) struct file_lock *fl, *my_fl = NULL, *lease;
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1842) struct inode *inode = locks_inode(filp);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1843) struct file_lock_context *ctx;
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1844) bool is_deleg = (*flp)->fl_flags & FL_DELEG;
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1845) int error;
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1846) LIST_HEAD(dispose);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1847)
096657b65e1ac (J. Bruce Fields 2010-10-30 17:31:14 -0400 1848) lease = *flp;
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 1849) trace_generic_add_lease(inode, lease);
62af4f1f7df44 (Jeff Layton 2014-05-09 14:13:05 -0400 1850)
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1851) /* Note that arg is never F_UNLCK here */
5c1c669a1b243 (Jeff Layton 2015-04-03 09:04:03 -0400 1852) ctx = locks_get_lock_context(inode, arg);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1853) if (!ctx)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1854) return -ENOMEM;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1855)
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1856) /*
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1857) * In the delegation case we need mutual exclusion with
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1858) * a number of operations that take the i_mutex. We trylock
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1859) * because delegations are an optional optimization, and if
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1860) * there's some chance of a conflict--we'd rather not
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1861) * bother, maybe that's a sign this just isn't a good file to
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1862) * hand out a delegation on.
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1863) */
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 1864) if (is_deleg && !inode_trylock(inode))
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1865) return -EAGAIN;
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1866)
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1867) if (is_deleg && arg == F_WRLCK) {
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1868) /* Write delegations are not currently supported: */
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 1869) inode_unlock(inode);
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1870) WARN_ON_ONCE(1);
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1871) return -EINVAL;
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1872) }
096657b65e1ac (J. Bruce Fields 2010-10-30 17:31:14 -0400 1873)
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1874) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1875) spin_lock(&ctx->flc_lock);
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1876) time_out_leases(inode, &dispose);
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1877) error = check_conflicting_open(filp, arg, lease->fl_flags);
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1878) if (error)
096657b65e1ac (J. Bruce Fields 2010-10-30 17:31:14 -0400 1879) goto out;
6d5e8b05caf07 (J. Bruce Fields 2007-05-31 17:03:46 -0400 1880)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1881) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1882) * At this point, we know that if there is an exclusive
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1883) * lease on this file, then we hold it on this filp
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1884) * (otherwise our open of this file would have blocked).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1885) * And if we are trying to acquire an exclusive lease,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1886) * then the file is not open by anyone (including us)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1887) * except for this filp.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1888) */
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1889) error = -EAGAIN;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1890) list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
2ab99ee12440e (Christoph Hellwig 2015-01-21 19:14:02 +0100 1891) if (fl->fl_file == filp &&
2ab99ee12440e (Christoph Hellwig 2015-01-21 19:14:02 +0100 1892) fl->fl_owner == lease->fl_owner) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1893) my_fl = fl;
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1894) continue;
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1895) }
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1896)
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1897) /*
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1898) * No exclusive leases if someone else has a lease on
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1899) * this file:
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1900) */
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1901) if (arg == F_WRLCK)
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1902) goto out;
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1903) /*
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1904) * Modifying our existing lease is OK, but no getting a
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1905) * new lease if someone else is opening for write:
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1906) */
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1907) if (fl->fl_flags & FL_UNLOCK_PENDING)
c1f24ef4ed46f (J. Bruce Fields 2011-08-19 10:59:49 -0400 1908) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1909) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1910)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1911) if (my_fl != NULL) {
0164bf0239777 (Jeff Layton 2015-03-04 17:34:32 -0500 1912) lease = my_fl;
0164bf0239777 (Jeff Layton 2015-03-04 17:34:32 -0500 1913) error = lease->fl_lmops->lm_change(lease, arg, &dispose);
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1914) if (error)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1915) goto out;
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1916) goto out_setup;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1917) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1918)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1919) error = -EINVAL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1920) if (!leases_enable)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1921) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1922)
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1923) locks_insert_lock_ctx(lease, &ctx->flc_lease);
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1924) /*
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1925) * The check in break_lease() is lockless. It's possible for another
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1926) * open to race in after we did the earlier check for a conflicting
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1927) * open but before the lease was inserted. Check again for a
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1928) * conflicting open and cancel the lease if there is one.
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1929) *
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1930) * We also add a barrier here to ensure that the insertion of the lock
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1931) * precedes these checks.
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1932) */
24cbe7845ea50 (Jeff Layton 2014-02-03 12:13:06 -0500 1933) smp_mb();
387e3746d01c3 (Amir Goldstein 2019-06-07 17:24:38 +0300 1934) error = check_conflicting_open(filp, arg, lease->fl_flags);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1935) if (error) {
e084c1bd40926 (Jeff Layton 2015-02-16 14:32:03 -0500 1936) locks_unlink_lock_ctx(lease);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1937) goto out;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1938) }
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1939)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1940) out_setup:
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1941) if (lease->fl_lmops->lm_setup)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1942) lease->fl_lmops->lm_setup(lease, priv);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1943) out:
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1944) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1945) percpu_up_read(&file_rwsem);
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1946) locks_dispose_list(&dispose);
df4e8d2c1d2bb (J. Bruce Fields 2012-03-05 13:18:59 -0500 1947) if (is_deleg)
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 1948) inode_unlock(inode);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1949) if (!error && !my_fl)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1950) *flp = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1951) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1952) }
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1953)
2ab99ee12440e (Christoph Hellwig 2015-01-21 19:14:02 +0100 1954) static int generic_delete_lease(struct file *filp, void *owner)
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1955) {
0efaa7e82f02f (Jeff Layton 2014-08-22 10:18:45 -0400 1956) int error = -EAGAIN;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1957) struct file_lock *fl, *victim = NULL;
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 1958) struct inode *inode = locks_inode(filp);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1959) struct file_lock_context *ctx;
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1960) LIST_HEAD(dispose);
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1961)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 1962) ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1963) if (!ctx) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1964) trace_generic_delete_lease(inode, NULL);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1965) return error;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1966) }
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1967)
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1968) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1969) spin_lock(&ctx->flc_lock);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1970) list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
2ab99ee12440e (Christoph Hellwig 2015-01-21 19:14:02 +0100 1971) if (fl->fl_file == filp &&
2ab99ee12440e (Christoph Hellwig 2015-01-21 19:14:02 +0100 1972) fl->fl_owner == owner) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1973) victim = fl;
0efaa7e82f02f (Jeff Layton 2014-08-22 10:18:45 -0400 1974) break;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1975) }
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1976) }
a9b1b455c519e (Jeff Layton 2015-03-14 09:45:35 -0400 1977) trace_generic_delete_lease(inode, victim);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 1978) if (victim)
7448cc37b1a6b (Jeff Layton 2015-01-16 15:05:57 -0500 1979) error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 1980) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 1981) percpu_up_read(&file_rwsem);
c45198eda2794 (Jeff Layton 2014-09-01 07:12:07 -0400 1982) locks_dispose_list(&dispose);
0efaa7e82f02f (Jeff Layton 2014-08-22 10:18:45 -0400 1983) return error;
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1984) }
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1985)
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1986) /**
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1987) * generic_setlease - sets a lease on an open file
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1988) * @filp: file pointer
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1989) * @arg: type of lease to obtain
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1990) * @flp: input - file_lock to use, output - file_lock inserted
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1991) * @priv: private data for lm_setup (may be NULL if lm_setup
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 1992) * doesn't require it)
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1993) *
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1994) * The (input) flp->fl_lmops->lm_break function is required
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1995) * by break_lease().
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1996) */
e6f5c78930e40 (Jeff Layton 2014-08-22 10:40:25 -0400 1997) int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
e6f5c78930e40 (Jeff Layton 2014-08-22 10:40:25 -0400 1998) void **priv)
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 1999) {
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2000) struct inode *inode = locks_inode(filp);
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2001) int error;
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2002)
8e96e3b7b8407 (Eric W. Biederman 2012-03-03 21:17:15 -0800 2003) if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE))
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2004) return -EACCES;
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2005) if (!S_ISREG(inode->i_mode))
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2006) return -EINVAL;
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2007) error = security_file_lock(filp, arg);
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2008) if (error)
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2009) return error;
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2010)
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2011) switch (arg) {
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2012) case F_UNLCK:
2ab99ee12440e (Christoph Hellwig 2015-01-21 19:14:02 +0100 2013) return generic_delete_lease(filp, *priv);
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2014) case F_RDLCK:
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2015) case F_WRLCK:
0efaa7e82f02f (Jeff Layton 2014-08-22 10:18:45 -0400 2016) if (!(*flp)->fl_lmops->lm_break) {
0efaa7e82f02f (Jeff Layton 2014-08-22 10:18:45 -0400 2017) WARN_ON_ONCE(1);
0efaa7e82f02f (Jeff Layton 2014-08-22 10:18:45 -0400 2018) return -ENOLCK;
0efaa7e82f02f (Jeff Layton 2014-08-22 10:18:45 -0400 2019) }
11afe9f76e121 (Christoph Hellwig 2015-01-21 19:17:03 +0100 2020)
e6f5c78930e40 (Jeff Layton 2014-08-22 10:40:25 -0400 2021) return generic_add_lease(filp, arg, flp, priv);
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2022) default:
8d657eb3b4386 (Dave Jones 2012-07-13 13:35:36 -0400 2023) return -EINVAL;
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2024) }
8335ebd94b3f5 (J. Bruce Fields 2011-09-21 08:34:32 -0400 2025) }
0af1a45046995 (Christoph Hellwig 2007-07-31 00:39:22 -0700 2026) EXPORT_SYMBOL(generic_setlease);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2027)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2028) #if IS_ENABLED(CONFIG_SRCU)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2029) /*
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2030) * Kernel subsystems can register to be notified on any attempt to set
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2031) * a new lease with the lease_notifier_chain. This is used by (e.g.) nfsd
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2032) * to close files that it may have cached when there is an attempt to set a
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2033) * conflicting lease.
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2034) */
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2035) static struct srcu_notifier_head lease_notifier_chain;
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2036)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2037) static inline void
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2038) lease_notifier_chain_init(void)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2039) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2040) srcu_init_notifier_head(&lease_notifier_chain);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2041) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2042)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2043) static inline void
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2044) setlease_notifier(long arg, struct file_lock *lease)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2045) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2046) if (arg != F_UNLCK)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2047) srcu_notifier_call_chain(&lease_notifier_chain, arg, lease);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2048) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2049)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2050) int lease_register_notifier(struct notifier_block *nb)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2051) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2052) return srcu_notifier_chain_register(&lease_notifier_chain, nb);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2053) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2054) EXPORT_SYMBOL_GPL(lease_register_notifier);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2055)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2056) void lease_unregister_notifier(struct notifier_block *nb)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2057) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2058) srcu_notifier_chain_unregister(&lease_notifier_chain, nb);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2059) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2060) EXPORT_SYMBOL_GPL(lease_unregister_notifier);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2061)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2062) #else /* !IS_ENABLED(CONFIG_SRCU) */
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2063) static inline void
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2064) lease_notifier_chain_init(void)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2065) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2066) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2067)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2068) static inline void
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2069) setlease_notifier(long arg, struct file_lock *lease)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2070) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2071) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2072)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2073) int lease_register_notifier(struct notifier_block *nb)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2074) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2075) return 0;
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2076) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2077) EXPORT_SYMBOL_GPL(lease_register_notifier);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2078)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2079) void lease_unregister_notifier(struct notifier_block *nb)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2080) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2081) }
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2082) EXPORT_SYMBOL_GPL(lease_unregister_notifier);
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2083)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2084) #endif /* IS_ENABLED(CONFIG_SRCU) */
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2085)
b89f432133851 (Arnd Bergmann 2010-09-18 15:09:31 +0200 2086) /**
e51673aa5d9a8 (Jeff Layton 2014-08-22 18:13:28 -0400 2087) * vfs_setlease - sets a lease on an open file
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2088) * @filp: file pointer
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2089) * @arg: type of lease to obtain
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2090) * @lease: file_lock to use when adding a lease
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2091) * @priv: private info for lm_setup when adding a lease (may be
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 2092) * NULL if lm_setup doesn't require it)
e51673aa5d9a8 (Jeff Layton 2014-08-22 18:13:28 -0400 2093) *
e51673aa5d9a8 (Jeff Layton 2014-08-22 18:13:28 -0400 2094) * Call this to establish a lease on the file. The "lease" argument is not
e51673aa5d9a8 (Jeff Layton 2014-08-22 18:13:28 -0400 2095) * used for F_UNLCK requests and may be NULL. For commands that set or alter
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2096) * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2097) * set; if not, this function will return -ENOLCK (and generate a scary-looking
e51673aa5d9a8 (Jeff Layton 2014-08-22 18:13:28 -0400 2098) * stack trace).
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2099) *
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2100) * The "priv" pointer is passed directly to the lm_setup function as-is. It
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2101) * may be NULL if the lm_setup operation doesn't require it.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2102) */
e6f5c78930e40 (Jeff Layton 2014-08-22 10:40:25 -0400 2103) int
e6f5c78930e40 (Jeff Layton 2014-08-22 10:40:25 -0400 2104) vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2105) {
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2106) if (lease)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 2107) setlease_notifier(arg, *lease);
de2a4a501e716 (Miklos Szeredi 2018-07-18 15:44:43 +0200 2108) if (filp->f_op->setlease)
f82b4b6780afa (Jeff Layton 2014-08-22 18:50:48 -0400 2109) return filp->f_op->setlease(filp, arg, lease, priv);
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2110) else
f82b4b6780afa (Jeff Layton 2014-08-22 18:50:48 -0400 2111) return generic_setlease(filp, arg, lease, priv);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2112) }
a9933cea7a1d8 (J. Bruce Fields 2007-06-07 17:09:49 -0400 2113) EXPORT_SYMBOL_GPL(vfs_setlease);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2114)
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2115) static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2116) {
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2117) struct file_lock *fl;
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2118) struct fasync_struct *new;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2119) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2120)
c5b1f0d92c368 (Arnd Bergmann 2010-10-27 15:46:08 +0200 2121) fl = lease_alloc(filp, arg);
c5b1f0d92c368 (Arnd Bergmann 2010-10-27 15:46:08 +0200 2122) if (IS_ERR(fl))
c5b1f0d92c368 (Arnd Bergmann 2010-10-27 15:46:08 +0200 2123) return PTR_ERR(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2124)
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2125) new = fasync_alloc();
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2126) if (!new) {
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2127) locks_free_lock(fl);
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2128) return -ENOMEM;
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2129) }
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2130) new->fa_fd = fd;
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2131)
1c7dd2ff430fa (Jeff Layton 2014-08-22 10:55:47 -0400 2132) error = vfs_setlease(filp, arg, &fl, (void **)&new);
2dfb928f7e597 (Jeff Layton 2014-08-11 18:14:12 -0400 2133) if (fl)
2dfb928f7e597 (Jeff Layton 2014-08-11 18:14:12 -0400 2134) locks_free_lock(fl);
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2135) if (new)
f7347ce4ee7c6 (Linus Torvalds 2010-10-27 12:38:12 -0400 2136) fasync_free(new);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2137) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2138) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2139)
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2140) /**
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2141) * fcntl_setlease - sets a lease on an open file
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2142) * @fd: open file descriptor
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2143) * @filp: file pointer
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2144) * @arg: type of lease to obtain
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2145) *
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2146) * Call this fcntl to establish a lease on the file.
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2147) * Note that you also need to call %F_SETSIG to
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2148) * receive a signal when the lease is broken.
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2149) */
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2150) int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2151) {
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2152) if (arg == F_UNLCK)
2ab99ee12440e (Christoph Hellwig 2015-01-21 19:14:02 +0100 2153) return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp);
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2154) return do_fcntl_add_lease(fd, filp, arg);
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2155) }
0ceaf6c700f82 (J. Bruce Fields 2010-10-30 17:31:13 -0400 2156)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2157) /**
29d01b22eaa18 (Jeff Layton 2015-07-11 06:43:02 -0400 2158) * flock_lock_inode_wait - Apply a FLOCK-style lock to a file
29d01b22eaa18 (Jeff Layton 2015-07-11 06:43:02 -0400 2159) * @inode: inode of the file to apply to
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2160) * @fl: The lock to be applied
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2161) *
29d01b22eaa18 (Jeff Layton 2015-07-11 06:43:02 -0400 2162) * Apply a FLOCK style lock request to an inode.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2163) */
616fb38fa7a95 (Benjamin Coddington 2015-10-22 13:38:15 -0400 2164) static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2165) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2166) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2167) might_sleep();
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2168) for (;;) {
29d01b22eaa18 (Jeff Layton 2015-07-11 06:43:02 -0400 2169) error = flock_lock_inode(inode, fl);
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2170) if (error != FILE_LOCK_DEFERRED)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2171) break;
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 2172) error = wait_event_interruptible(fl->fl_wait,
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 2173) list_empty(&fl->fl_blocked_member));
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 2174) if (error)
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 2175) break;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2176) }
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 2177) locks_delete_block(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2178) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2179) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2180)
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2181) /**
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2182) * locks_lock_inode_wait - Apply a lock to an inode
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2183) * @inode: inode of the file to apply to
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2184) * @fl: The lock to be applied
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2185) *
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2186) * Apply a POSIX or FLOCK style lock request to an inode.
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2187) */
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2188) int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2189) {
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2190) int res = 0;
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2191) switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2192) case FL_POSIX:
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2193) res = posix_lock_inode_wait(inode, fl);
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2194) break;
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2195) case FL_FLOCK:
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2196) res = flock_lock_inode_wait(inode, fl);
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2197) break;
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2198) default:
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2199) BUG();
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2200) }
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2201) return res;
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2202) }
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2203) EXPORT_SYMBOL(locks_lock_inode_wait);
e55c34a66f87e (Benjamin Coddington 2015-10-22 13:38:13 -0400 2204)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2205) /**
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2206) * sys_flock: - flock() system call.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2207) * @fd: the file descriptor to lock.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2208) * @cmd: the type of lock to apply.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2209) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2210) * Apply a %FL_FLOCK style lock to an open file descriptor.
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2211) * The @cmd can be one of:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2212) *
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2213) * - %LOCK_SH -- a shared lock.
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2214) * - %LOCK_EX -- an exclusive lock.
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2215) * - %LOCK_UN -- remove an existing lock.
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2216) * - %LOCK_MAND -- a 'mandatory' flock.
80b79dd0e2f29 (Mauro Carvalho Chehab 2017-05-27 06:07:18 -0400 2217) * This exists to emulate Windows Share Modes.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2218) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2219) * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2220) * processes read and write access respectively.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2221) */
002c8976ee537 (Heiko Carstens 2009-01-14 14:14:18 +0100 2222) SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2223) {
2903ff019b346 (Al Viro 2012-08-28 12:52:22 -0400 2224) struct fd f = fdget(fd);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2225) struct file_lock *lock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2226) int can_sleep, unlock;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2227) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2228)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2229) error = -EBADF;
2903ff019b346 (Al Viro 2012-08-28 12:52:22 -0400 2230) if (!f.file)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2231) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2232)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2233) can_sleep = !(cmd & LOCK_NB);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2234) cmd &= ~LOCK_NB;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2235) unlock = (cmd == LOCK_UN);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2236)
aeb5d727062a0 (Al Viro 2008-09-02 15:28:45 -0400 2237) if (!unlock && !(cmd & LOCK_MAND) &&
2903ff019b346 (Al Viro 2012-08-28 12:52:22 -0400 2238) !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2239) goto out_putf;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2240)
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 2241) lock = flock_make_lock(f.file, cmd, NULL);
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 2242) if (IS_ERR(lock)) {
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 2243) error = PTR_ERR(lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2244) goto out_putf;
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 2245) }
6e129d00689c4 (Jeff Layton 2014-09-04 10:25:06 -0400 2246)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2247) if (can_sleep)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2248) lock->fl_flags |= FL_SLEEP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2249)
2903ff019b346 (Al Viro 2012-08-28 12:52:22 -0400 2250) error = security_file_lock(f.file, lock->fl_type);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2251) if (error)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2252) goto out_free;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2253)
de2a4a501e716 (Miklos Szeredi 2018-07-18 15:44:43 +0200 2254) if (f.file->f_op->flock)
2903ff019b346 (Al Viro 2012-08-28 12:52:22 -0400 2255) error = f.file->f_op->flock(f.file,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2256) (can_sleep) ? F_SETLKW : F_SETLK,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2257) lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2258) else
4f6563677ae83 (Benjamin Coddington 2015-10-22 13:38:14 -0400 2259) error = locks_lock_file_wait(f.file, lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2260)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2261) out_free:
993dfa8776308 (Trond Myklebust 2006-03-31 02:30:55 -0800 2262) locks_free_lock(lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2263)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2264) out_putf:
2903ff019b346 (Al Viro 2012-08-28 12:52:22 -0400 2265) fdput(f);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2266) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2267) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2268) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2269)
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2270) /**
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2271) * vfs_test_lock - test file byte range lock
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2272) * @filp: The file to test lock for
6924c55492c90 (J. Bruce Fields 2007-05-11 16:22:50 -0400 2273) * @fl: The lock to test; also used to hold result
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2274) *
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2275) * Returns -ERRNO on failure. Indicates presence of conflicting lock by
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2276) * setting conf->fl_type to something other than F_UNLCK.
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2277) */
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2278) int vfs_test_lock(struct file *filp, struct file_lock *fl)
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2279) {
de2a4a501e716 (Miklos Szeredi 2018-07-18 15:44:43 +0200 2280) if (filp->f_op->lock)
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2281) return filp->f_op->lock(filp, F_GETLK, fl);
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2282) posix_test_lock(filp, fl);
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2283) return 0;
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2284) }
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2285) EXPORT_SYMBOL_GPL(vfs_test_lock);
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2286)
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2287) /**
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2288) * locks_translate_pid - translate a file_lock's fl_pid number into a namespace
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2289) * @fl: The file_lock who's fl_pid should be translated
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2290) * @ns: The namespace into which the pid should be translated
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2291) *
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2292) * Used to tranlate a fl_pid into a namespace virtual pid number
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2293) */
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2294) static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns)
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2295) {
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2296) pid_t vnr;
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2297) struct pid *pid;
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2298)
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2299) if (IS_OFDLCK(fl))
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2300) return -1;
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2301) if (IS_REMOTELCK(fl))
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2302) return fl->fl_pid;
826d7bc9f013d (Konstantin Khorenko 2018-06-08 17:27:11 +0300 2303) /*
826d7bc9f013d (Konstantin Khorenko 2018-06-08 17:27:11 +0300 2304) * If the flock owner process is dead and its pid has been already
826d7bc9f013d (Konstantin Khorenko 2018-06-08 17:27:11 +0300 2305) * freed, the translation below won't work, but we still want to show
826d7bc9f013d (Konstantin Khorenko 2018-06-08 17:27:11 +0300 2306) * flock owner pid number in init pidns.
826d7bc9f013d (Konstantin Khorenko 2018-06-08 17:27:11 +0300 2307) */
826d7bc9f013d (Konstantin Khorenko 2018-06-08 17:27:11 +0300 2308) if (ns == &init_pid_ns)
826d7bc9f013d (Konstantin Khorenko 2018-06-08 17:27:11 +0300 2309) return (pid_t)fl->fl_pid;
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2310)
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2311) rcu_read_lock();
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2312) pid = find_pid_ns(fl->fl_pid, &init_pid_ns);
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2313) vnr = pid_nr_ns(pid, ns);
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2314) rcu_read_unlock();
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2315) return vnr;
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2316) }
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2317)
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2318) static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2319) {
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2320) flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2321) #if BITS_PER_LONG == 32
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2322) /*
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2323) * Make sure we can represent the posix lock via
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2324) * legacy 32bit flock.
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2325) */
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2326) if (fl->fl_start > OFFT_OFFSET_MAX)
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2327) return -EOVERFLOW;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2328) if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX)
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2329) return -EOVERFLOW;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2330) #endif
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2331) flock->l_start = fl->fl_start;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2332) flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2333) fl->fl_end - fl->fl_start + 1;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2334) flock->l_whence = 0;
129a84de23470 (J. Bruce Fields 2007-05-10 18:38:43 -0400 2335) flock->l_type = fl->fl_type;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2336) return 0;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2337) }
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2338)
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2339) #if BITS_PER_LONG == 32
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2340) static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2341) {
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2342) flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2343) flock->l_start = fl->fl_start;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2344) flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2345) fl->fl_end - fl->fl_start + 1;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2346) flock->l_whence = 0;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2347) flock->l_type = fl->fl_type;
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2348) }
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2349) #endif
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2350)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2351) /* Report the first existing lock that would conflict with l.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2352) * This implements the F_GETLK command of fcntl().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2353) */
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2354) int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2355) {
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2356) struct file_lock *fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2357) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2358)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2359) fl = locks_alloc_lock();
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2360) if (fl == NULL)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2361) return -ENOMEM;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2362) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2363) if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2364) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2365)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2366) error = flock_to_posix_lock(filp, fl, flock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2367) if (error)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2368) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2369)
0d3f7a2dd2f5c (Jeff Layton 2014-04-22 08:23:58 -0400 2370) if (cmd == F_OFD_GETLK) {
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2371) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2372) if (flock->l_pid != 0)
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2373) goto out;
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2374)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2375) fl->fl_flags |= FL_OFDLCK;
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2376) fl->fl_owner = filp;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2377) }
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2378)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2379) error = vfs_test_lock(filp, fl);
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2380) if (error)
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2381) goto out;
7bbd1fc0e9f12 (NeilBrown 2018-11-30 10:04:08 +1100 2382)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2383) flock->l_type = fl->fl_type;
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2384) if (fl->fl_type != F_UNLCK) {
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2385) error = posix_lock_to_flock(flock, fl);
c2fa1b8a6c059 (J. Bruce Fields 2007-02-20 16:10:11 -0500 2386) if (error)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2387) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2388) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2389) out:
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2390) locks_free_lock(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2391) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2392) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2393)
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2394) /**
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2395) * vfs_lock_file - file byte range lock
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2396) * @filp: The file to apply the lock to
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2397) * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2398) * @fl: The lock to be applied
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2399) * @conf: Place to return a copy of the conflicting lock, if found.
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2400) *
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2401) * A caller that doesn't care about the conflicting lock may pass NULL
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2402) * as the final argument.
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2403) *
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2404) * If the filesystem defines a private ->lock() method, then @conf will
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2405) * be left unchanged; so a caller that cares should initialize it to
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2406) * some acceptable default.
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2407) *
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2408) * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2409) * locks, the ->lock() interface may return asynchronously, before the lock has
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2410) * been granted or denied by the underlying filesystem, if (and only if)
8fb47a4fbf858 (J. Bruce Fields 2011-07-20 20:21:59 -0400 2411) * lm_grant is set. Callers expecting ->lock() to return asynchronously
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2412) * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if)
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2413) * the request is for a blocking lock. When ->lock() does return asynchronously,
8fb47a4fbf858 (J. Bruce Fields 2011-07-20 20:21:59 -0400 2414) * it must return FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2415) * request completes.
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2416) * If the request is for non-blocking lock the file system should return
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2417) * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine
bde74e4bc6441 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2418) * with the result. If the request timed out the callback routine will return a
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2419) * nonzero return code and the file system should release the lock. The file
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2420) * system is also responsible to keep a corresponding posix lock when it
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2421) * grants a lock so the VFS can find out which locks are locally held and do
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2422) * the correct lock cleanup when required.
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2423) * The underlying filesystem must not drop the kernel lock or call
8fb47a4fbf858 (J. Bruce Fields 2011-07-20 20:21:59 -0400 2424) * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED
2beb6614f5e36 (Marc Eshel 2006-12-05 23:31:28 -0500 2425) * return code.
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2426) */
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2427) int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2428) {
de2a4a501e716 (Miklos Szeredi 2018-07-18 15:44:43 +0200 2429) if (filp->f_op->lock)
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2430) return filp->f_op->lock(filp, cmd, fl);
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2431) else
150b393456e5a (Marc Eshel 2007-01-18 16:15:35 -0500 2432) return posix_lock_file(filp, fl, conf);
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2433) }
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2434) EXPORT_SYMBOL_GPL(vfs_lock_file);
7723ec9777d98 (Marc Eshel 2007-01-18 15:08:55 -0500 2435)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2436) static int do_lock_file_wait(struct file *filp, unsigned int cmd,
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2437) struct file_lock *fl)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2438) {
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2439) int error;
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2440)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2441) error = security_file_lock(filp, fl->fl_type);
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2442) if (error)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2443) return error;
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2444)
764c76b371722 (Miklos Szeredi 2008-07-25 01:48:58 -0700 2445) for (;;) {
764c76b371722 (Miklos Szeredi 2008-07-25 01:48:58 -0700 2446) error = vfs_lock_file(filp, cmd, fl, NULL);
764c76b371722 (Miklos Szeredi 2008-07-25 01:48:58 -0700 2447) if (error != FILE_LOCK_DEFERRED)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2448) break;
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 2449) error = wait_event_interruptible(fl->fl_wait,
dcf23ac3e846c (Linus Torvalds 2020-03-18 07:52:21 -0400 2450) list_empty(&fl->fl_blocked_member));
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 2451) if (error)
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 2452) break;
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2453) }
16306a61d3b7c (NeilBrown 2018-11-30 10:04:08 +1100 2454) locks_delete_block(fl);
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2455)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2456) return error;
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2457) }
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2458)
6ca7d910121af (Benjamin Coddington 2015-10-15 09:07:07 -0400 2459) /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2460) static int
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2461) check_fmode_for_setlk(struct file_lock *fl)
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2462) {
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2463) switch (fl->fl_type) {
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2464) case F_RDLCK:
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2465) if (!(fl->fl_file->f_mode & FMODE_READ))
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2466) return -EBADF;
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2467) break;
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2468) case F_WRLCK:
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2469) if (!(fl->fl_file->f_mode & FMODE_WRITE))
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2470) return -EBADF;
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2471) }
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2472) return 0;
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2473) }
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2474)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2475) /* Apply the lock described by l to an open file descriptor.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2476) * This implements both the F_SETLK and F_SETLKW commands of fcntl().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2477) */
c293621bbf678 (Peter Staubach 2005-07-27 11:45:09 -0700 2478) int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2479) struct flock *flock)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2480) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2481) struct file_lock *file_lock = locks_alloc_lock();
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2482) struct inode *inode = locks_inode(filp);
0b2bac2f1ea0d (Al Viro 2008-05-06 13:58:34 -0400 2483) struct file *f;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2484) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2485)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2486) if (file_lock == NULL)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2487) return -ENOLCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2488)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2489) /* Don't allow mandatory locks on files that may be memory mapped
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2490) * and shared.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2491) */
a16877ca9cec2 (Pavel Emelyanov 2007-10-01 14:41:11 -0700 2492) if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2493) error = -EAGAIN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2494) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2495) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2496)
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2497) error = flock_to_posix_lock(filp, file_lock, flock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2498) if (error)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2499) goto out;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2500)
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2501) error = check_fmode_for_setlk(file_lock);
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2502) if (error)
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2503) goto out;
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2504)
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2505) /*
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2506) * If the cmd is requesting file-private locks, then set the
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 2507) * FL_OFDLCK flag and override the owner.
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2508) */
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2509) switch (cmd) {
0d3f7a2dd2f5c (Jeff Layton 2014-04-22 08:23:58 -0400 2510) case F_OFD_SETLK:
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2511) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2512) if (flock->l_pid != 0)
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2513) goto out;
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2514)
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2515) cmd = F_SETLK;
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 2516) file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 2517) file_lock->fl_owner = filp;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2518) break;
0d3f7a2dd2f5c (Jeff Layton 2014-04-22 08:23:58 -0400 2519) case F_OFD_SETLKW:
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2520) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2521) if (flock->l_pid != 0)
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2522) goto out;
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2523)
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2524) cmd = F_SETLKW;
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 2525) file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 2526) file_lock->fl_owner = filp;
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 2527) fallthrough;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2528) case F_SETLKW:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2529) file_lock->fl_flags |= FL_SLEEP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2530) }
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2531)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2532) error = do_lock_file_wait(filp, cmd, file_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2533)
c293621bbf678 (Peter Staubach 2005-07-27 11:45:09 -0700 2534) /*
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2535) * Attempt to detect a close/fcntl race and recover by releasing the
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2536) * lock that was just acquired. There is no need to do that when we're
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2537) * unlocking though, or for OFD locks.
c293621bbf678 (Peter Staubach 2005-07-27 11:45:09 -0700 2538) */
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2539) if (!error && file_lock->fl_type != F_UNLCK &&
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2540) !(file_lock->fl_flags & FL_OFDLCK)) {
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2541) struct files_struct *files = current->files;
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2542) /*
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2543) * We need that spin_lock here - it prevents reordering between
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2544) * update of i_flctx->flc_posix and check for it done in
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2545) * close(). rcu_read_lock() wouldn't do.
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2546) */
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2547) spin_lock(&files->file_lock);
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2548) f = files_lookup_fd_locked(files, fd);
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2549) spin_unlock(&files->file_lock);
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2550) if (f != filp) {
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2551) file_lock->fl_type = F_UNLCK;
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2552) error = do_lock_file_wait(filp, cmd, file_lock);
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2553) WARN_ON_ONCE(error);
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2554) error = -EBADF;
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2555) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2556) }
c293621bbf678 (Peter Staubach 2005-07-27 11:45:09 -0700 2557) out:
1890910fd06fe (Jeff Layton 2016-01-06 21:26:10 -0500 2558) trace_fcntl_setlk(inode, file_lock, error);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2559) locks_free_lock(file_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2560) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2561) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2562)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2563) #if BITS_PER_LONG == 32
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2564) /* Report the first existing lock that would conflict with l.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2565) * This implements the F_GETLK command of fcntl().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2566) */
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2567) int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2568) {
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2569) struct file_lock *fl;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2570) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2571)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2572) fl = locks_alloc_lock();
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2573) if (fl == NULL)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2574) return -ENOMEM;
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2575)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2576) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2577) if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2578) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2579)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2580) error = flock64_to_posix_lock(filp, fl, flock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2581) if (error)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2582) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2583)
0d3f7a2dd2f5c (Jeff Layton 2014-04-22 08:23:58 -0400 2584) if (cmd == F_OFD_GETLK) {
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2585) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2586) if (flock->l_pid != 0)
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2587) goto out;
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2588)
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2589) cmd = F_GETLK64;
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2590) fl->fl_flags |= FL_OFDLCK;
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2591) fl->fl_owner = filp;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2592) }
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2593)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2594) error = vfs_test_lock(filp, fl);
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2595) if (error)
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2596) goto out;
3ee17abd14c72 (J. Bruce Fields 2007-02-21 00:58:50 -0500 2597)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2598) flock->l_type = fl->fl_type;
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2599) if (fl->fl_type != F_UNLCK)
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2600) posix_lock_to_flock64(flock, fl);
f328296e27414 (Kinglong Mee 2014-08-22 10:18:43 -0400 2601)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2602) out:
52306e882f77d (Benjamin Coddington 2017-07-16 10:28:21 -0400 2603) locks_free_lock(fl);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2604) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2605) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2606)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2607) /* Apply the lock described by l to an open file descriptor.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2608) * This implements both the F_SETLK and F_SETLKW commands of fcntl().
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2609) */
c293621bbf678 (Peter Staubach 2005-07-27 11:45:09 -0700 2610) int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2611) struct flock64 *flock)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2612) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2613) struct file_lock *file_lock = locks_alloc_lock();
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2614) struct inode *inode = locks_inode(filp);
0b2bac2f1ea0d (Al Viro 2008-05-06 13:58:34 -0400 2615) struct file *f;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2616) int error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2617)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2618) if (file_lock == NULL)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2619) return -ENOLCK;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2620)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2621) /* Don't allow mandatory locks on files that may be memory mapped
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2622) * and shared.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2623) */
a16877ca9cec2 (Pavel Emelyanov 2007-10-01 14:41:11 -0700 2624) if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2625) error = -EAGAIN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2626) goto out;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2627) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2628)
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2629) error = flock64_to_posix_lock(filp, file_lock, flock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2630) if (error)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2631) goto out;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2632)
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2633) error = check_fmode_for_setlk(file_lock);
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2634) if (error)
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2635) goto out;
cf01f4eef9fe3 (Jeff Layton 2014-05-09 11:41:54 -0400 2636)
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2637) /*
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2638) * If the cmd is requesting file-private locks, then set the
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 2639) * FL_OFDLCK flag and override the owner.
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2640) */
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2641) switch (cmd) {
0d3f7a2dd2f5c (Jeff Layton 2014-04-22 08:23:58 -0400 2642) case F_OFD_SETLK:
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2643) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2644) if (flock->l_pid != 0)
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2645) goto out;
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2646)
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2647) cmd = F_SETLK64;
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 2648) file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 2649) file_lock->fl_owner = filp;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2650) break;
0d3f7a2dd2f5c (Jeff Layton 2014-04-22 08:23:58 -0400 2651) case F_OFD_SETLKW:
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2652) error = -EINVAL;
a75d30c772078 (Christoph Hellwig 2017-05-27 06:07:19 -0400 2653) if (flock->l_pid != 0)
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2654) goto out;
90478939dce09 (Jeff Layton 2014-03-04 10:30:23 -0500 2655)
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2656) cmd = F_SETLKW64;
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 2657) file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 2658) file_lock->fl_owner = filp;
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 2659) fallthrough;
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2660) case F_SETLKW64:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2661) file_lock->fl_flags |= FL_SLEEP;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2662) }
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2663)
b648a6de00770 (Miklos Szeredi 2008-07-25 01:48:57 -0700 2664) error = do_lock_file_wait(filp, cmd, file_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2665)
c293621bbf678 (Peter Staubach 2005-07-27 11:45:09 -0700 2666) /*
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2667) * Attempt to detect a close/fcntl race and recover by releasing the
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2668) * lock that was just acquired. There is no need to do that when we're
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2669) * unlocking though, or for OFD locks.
c293621bbf678 (Peter Staubach 2005-07-27 11:45:09 -0700 2670) */
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2671) if (!error && file_lock->fl_type != F_UNLCK &&
0752ba807b04c (Jeff Layton 2016-01-08 07:30:43 -0500 2672) !(file_lock->fl_flags & FL_OFDLCK)) {
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2673) struct files_struct *files = current->files;
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2674) /*
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2675) * We need that spin_lock here - it prevents reordering between
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2676) * update of i_flctx->flc_posix and check for it done in
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2677) * close(). rcu_read_lock() wouldn't do.
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2678) */
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2679) spin_lock(&files->file_lock);
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2680) f = files_lookup_fd_locked(files, fd);
120ce2b0cd52a (Eric W. Biederman 2020-11-20 17:14:25 -0600 2681) spin_unlock(&files->file_lock);
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2682) if (f != filp) {
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2683) file_lock->fl_type = F_UNLCK;
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2684) error = do_lock_file_wait(filp, cmd, file_lock);
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2685) WARN_ON_ONCE(error);
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2686) error = -EBADF;
7f3697e24dc38 (Jeff Layton 2016-01-07 16:38:10 -0500 2687) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2688) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2689) out:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2690) locks_free_lock(file_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2691) return error;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2692) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2693) #endif /* BITS_PER_LONG == 32 */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2694)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2695) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2696) * This function is called when the file is being removed
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2697) * from the task's fd array. POSIX locks belonging to this task
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2698) * are deleted at this time.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2699) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2700) void locks_remove_posix(struct file *filp, fl_owner_t owner)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2701) {
1890910fd06fe (Jeff Layton 2016-01-06 21:26:10 -0500 2702) int error;
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2703) struct inode *inode = locks_inode(filp);
ff7b86b82083f (Miklos Szeredi 2006-06-23 02:05:11 -0700 2704) struct file_lock lock;
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2705) struct file_lock_context *ctx;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2706)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2707) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2708) * If there are no locks held on this file, we don't need to call
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2709) * posix_lock_file(). Another process could be setting a lock on this
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2710) * file at the same time, but we wouldn't remove that lock anyway.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2711) */
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2712) ctx = smp_load_acquire(&inode->i_flctx);
bd61e0a9c852d (Jeff Layton 2015-01-16 15:05:55 -0500 2713) if (!ctx || list_empty(&ctx->flc_posix))
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2714) return;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2715)
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 2716) locks_init_lock(&lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2717) lock.fl_type = F_UNLCK;
75e1fcc0b18df (Miklos Szeredi 2006-06-23 02:05:12 -0700 2718) lock.fl_flags = FL_POSIX | FL_CLOSE;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2719) lock.fl_start = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2720) lock.fl_end = OFFSET_MAX;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2721) lock.fl_owner = owner;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2722) lock.fl_pid = current->tgid;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2723) lock.fl_file = filp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2724) lock.fl_ops = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2725) lock.fl_lmops = NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2726)
1890910fd06fe (Jeff Layton 2016-01-06 21:26:10 -0500 2727) error = vfs_lock_file(filp, F_SETLK, &lock, NULL);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2728)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2729) if (lock.fl_ops && lock.fl_ops->fl_release_private)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2730) lock.fl_ops->fl_release_private(&lock);
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2731) trace_locks_remove_posix(inode, &lock, error);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2732) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2733) EXPORT_SYMBOL(locks_remove_posix);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2734)
3d8e560de4a07 (Jeff Layton 2015-01-16 15:05:58 -0500 2735) /* The i_flctx must be valid when calling into here */
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2736) static void
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2737) locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2738) {
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 2739) struct file_lock fl;
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2740) struct inode *inode = locks_inode(filp);
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2741)
3d8e560de4a07 (Jeff Layton 2015-01-16 15:05:58 -0500 2742) if (list_empty(&flctx->flc_flock))
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2743) return;
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2744)
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 2745) flock_make_lock(filp, LOCK_UN, &fl);
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 2746) fl.fl_flags |= FL_CLOSE;
d6367d6241371 (NeilBrown 2018-11-30 10:04:08 +1100 2747)
de2a4a501e716 (Miklos Szeredi 2018-07-18 15:44:43 +0200 2748) if (filp->f_op->flock)
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2749) filp->f_op->flock(filp, F_SETLKW, &fl);
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2750) else
bcd7f78d078ff (Jeff Layton 2015-07-11 06:43:02 -0400 2751) flock_lock_inode(inode, &fl);
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2752)
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2753) if (fl.fl_ops && fl.fl_ops->fl_release_private)
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2754) fl.fl_ops->fl_release_private(&fl);
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2755) }
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2756)
3d8e560de4a07 (Jeff Layton 2015-01-16 15:05:58 -0500 2757) /* The i_flctx must be valid when calling into here */
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2758) static void
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2759) locks_remove_lease(struct file *filp, struct file_lock_context *ctx)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2760) {
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2761) struct file_lock *fl, *tmp;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2762) LIST_HEAD(dispose);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2763)
3d8e560de4a07 (Jeff Layton 2015-01-16 15:05:58 -0500 2764) if (list_empty(&ctx->flc_lease))
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2765) return;
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2766)
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 2767) percpu_down_read(&file_rwsem);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 2768) spin_lock(&ctx->flc_lock);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2769) list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list)
c4e136cda11cb (Jeff Layton 2015-02-16 19:37:42 -0500 2770) if (filp == fl->fl_file)
c4e136cda11cb (Jeff Layton 2015-02-16 19:37:42 -0500 2771) lease_modify(fl, F_UNLCK, &dispose);
6109c85037e53 (Jeff Layton 2015-01-16 15:05:57 -0500 2772) spin_unlock(&ctx->flc_lock);
02e525b2aff1d (Peter Zijlstra 2019-02-21 15:38:40 +0100 2773) percpu_up_read(&file_rwsem);
5f43086bb9224 (Peter Zijlstra 2016-10-08 10:12:28 +0200 2774)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2775) locks_dispose_list(&dispose);
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2776) }
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2777)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2778) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2779) * This function is called on the last close of an open file.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2780) */
78ed8a13382b1 (Jeff Layton 2014-02-03 12:13:08 -0500 2781) void locks_remove_file(struct file *filp)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2782) {
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2783) struct file_lock_context *ctx;
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2784)
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2785) ctx = smp_load_acquire(&locks_inode(filp)->i_flctx);
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2786) if (!ctx)
3d8e560de4a07 (Jeff Layton 2015-01-16 15:05:58 -0500 2787) return;
3d8e560de4a07 (Jeff Layton 2015-01-16 15:05:58 -0500 2788)
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2789) /* remove any OFD locks */
73a8f5f7e6350 (Christoph Hellwig 2014-07-13 17:00:38 +0200 2790) locks_remove_posix(filp, filp);
5d50ffd7c31da (Jeff Layton 2014-02-03 12:13:10 -0500 2791)
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2792) /* remove flock locks */
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2793) locks_remove_flock(filp, ctx);
dd459bb1974c5 (Jeff Layton 2015-01-16 15:05:54 -0500 2794)
8634b51f6ca29 (Jeff Layton 2015-01-16 15:05:55 -0500 2795) /* remove any leases */
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 2796) locks_remove_lease(filp, ctx);
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 2797)
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 2798) spin_lock(&ctx->flc_lock);
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 2799) locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX");
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 2800) locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK");
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 2801) locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE");
3953704fde7ec (Benjamin Coddington 2017-07-21 13:36:25 -0400 2802) spin_unlock(&ctx->flc_lock);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2803) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2804)
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2805) /**
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2806) * vfs_cancel_lock - file byte range unblock lock
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2807) * @filp: The file to apply the unblock to
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2808) * @fl: The lock to be unblocked
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2809) *
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2810) * Used by lock managers to cancel blocked requests
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2811) */
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2812) int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2813) {
de2a4a501e716 (Miklos Szeredi 2018-07-18 15:44:43 +0200 2814) if (filp->f_op->lock)
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2815) return filp->f_op->lock(filp, F_CANCELLK, fl);
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2816) return 0;
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2817) }
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2818) EXPORT_SYMBOL_GPL(vfs_cancel_lock);
9b9d2ab4154a4 (Marc Eshel 2007-01-18 17:52:58 -0500 2819)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2820) #ifdef CONFIG_PROC_FS
d8ba7a363393f (Alexey Dobriyan 2008-10-04 22:34:18 +0400 2821) #include <linux/proc_fs.h>
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2822) #include <linux/seq_file.h>
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2823)
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 2824) struct locks_iterator {
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 2825) int li_cpu;
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 2826) loff_t li_pos;
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 2827) };
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 2828)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2829) static void lock_get_status(struct seq_file *f, struct file_lock *fl,
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2830) loff_t id, char *pfx, int repeat)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2831) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2832) struct inode *inode = NULL;
ab1f16116527e (Vitaliy Gusev 2008-01-17 00:07:08 +0000 2833) unsigned int fl_pid;
9d78edeaec759 (Alexey Gladkov 2020-05-18 20:07:38 +0200 2834) struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb);
ab1f16116527e (Vitaliy Gusev 2008-01-17 00:07:08 +0000 2835)
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2836) fl_pid = locks_translate_pid(fl, proc_pidns);
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2837) /*
1cf8e5de4055f (Konstantin Khorenko 2018-06-08 17:27:12 +0300 2838) * If lock owner is dead (and pid is freed) or not visible in current
1cf8e5de4055f (Konstantin Khorenko 2018-06-08 17:27:12 +0300 2839) * pidns, zero is shown as a pid value. Check lock info from
1cf8e5de4055f (Konstantin Khorenko 2018-06-08 17:27:12 +0300 2840) * init_pid_ns to get saved lock pid value.
9d5b86ac13c57 (Benjamin Coddington 2017-07-16 10:28:22 -0400 2841) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2842)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2843) if (fl->fl_file != NULL)
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2844) inode = locks_inode(fl->fl_file);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2845)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2846) seq_printf(f, "%lld: ", id);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2847)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2848) if (repeat)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2849) seq_printf(f, "%*s", repeat - 1 + (int)strlen(pfx), pfx);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2850)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2851) if (IS_POSIX(fl)) {
c918d42a27a9b (Jeff Layton 2014-02-03 12:13:09 -0500 2852) if (fl->fl_flags & FL_ACCESS)
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2853) seq_puts(f, "ACCESS");
cff2fce58b2b0 (Jeff Layton 2014-04-22 08:24:32 -0400 2854) else if (IS_OFDLCK(fl))
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2855) seq_puts(f, "OFDLCK");
c918d42a27a9b (Jeff Layton 2014-02-03 12:13:09 -0500 2856) else
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2857) seq_puts(f, "POSIX ");
c918d42a27a9b (Jeff Layton 2014-02-03 12:13:09 -0500 2858)
c918d42a27a9b (Jeff Layton 2014-02-03 12:13:09 -0500 2859) seq_printf(f, " %s ",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2860) (inode == NULL) ? "*NOINODE*" :
a16877ca9cec2 (Pavel Emelyanov 2007-10-01 14:41:11 -0700 2861) mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2862) } else if (IS_FLOCK(fl)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2863) if (fl->fl_type & LOCK_MAND) {
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2864) seq_puts(f, "FLOCK MSNFS ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2865) } else {
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2866) seq_puts(f, "FLOCK ADVISORY ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2867) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2868) } else if (IS_LEASE(fl)) {
8144f1f69943f (Jeff Layton 2014-08-11 13:36:54 -0400 2869) if (fl->fl_flags & FL_DELEG)
8144f1f69943f (Jeff Layton 2014-08-11 13:36:54 -0400 2870) seq_puts(f, "DELEG ");
8144f1f69943f (Jeff Layton 2014-08-11 13:36:54 -0400 2871) else
8144f1f69943f (Jeff Layton 2014-08-11 13:36:54 -0400 2872) seq_puts(f, "LEASE ");
8144f1f69943f (Jeff Layton 2014-08-11 13:36:54 -0400 2873)
ab83fa4b49a54 (J. Bruce Fields 2011-07-26 20:10:51 -0400 2874) if (lease_breaking(fl))
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2875) seq_puts(f, "BREAKING ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2876) else if (fl->fl_file)
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2877) seq_puts(f, "ACTIVE ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2878) else
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2879) seq_puts(f, "BREAKER ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2880) } else {
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2881) seq_puts(f, "UNKNOWN UNKNOWN ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2882) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2883) if (fl->fl_type & LOCK_MAND) {
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2884) seq_printf(f, "%s ",
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2885) (fl->fl_type & LOCK_READ)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2886) ? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ "
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2887) : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2888) } else {
43e4cb942e88e (Pavel Begunkov 2019-07-24 20:16:31 +0300 2889) int type = IS_LEASE(fl) ? target_leasetype(fl) : fl->fl_type;
43e4cb942e88e (Pavel Begunkov 2019-07-24 20:16:31 +0300 2890)
43e4cb942e88e (Pavel Begunkov 2019-07-24 20:16:31 +0300 2891) seq_printf(f, "%s ", (type == F_WRLCK) ? "WRITE" :
43e4cb942e88e (Pavel Begunkov 2019-07-24 20:16:31 +0300 2892) (type == F_RDLCK) ? "READ" : "UNLCK");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2893) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2894) if (inode) {
3648888e90bb7 (Jeff Layton 2015-04-03 09:04:04 -0400 2895) /* userspace relies on this representation of dev_t */
98ca480a8f22f (Amir Goldstein 2019-12-22 20:45:28 +0200 2896) seq_printf(f, "%d %02x:%02x:%lu ", fl_pid,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2897) MAJOR(inode->i_sb->s_dev),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2898) MINOR(inode->i_sb->s_dev), inode->i_ino);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2899) } else {
ab1f16116527e (Vitaliy Gusev 2008-01-17 00:07:08 +0000 2900) seq_printf(f, "%d <none>:0 ", fl_pid);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2901) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2902) if (IS_POSIX(fl)) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2903) if (fl->fl_end == OFFSET_MAX)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2904) seq_printf(f, "%Ld EOF\n", fl->fl_start);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2905) else
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2906) seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2907) } else {
5315c26a6c557 (Fabian Frederick 2014-05-09 14:13:05 -0400 2908) seq_puts(f, "0 EOF\n");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2909) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2910) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2911)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2912) static struct file_lock *get_next_blocked_member(struct file_lock *node)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2913) {
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2914) struct file_lock *tmp;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2915)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2916) /* NULL node or root node */
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2917) if (node == NULL || node->fl_blocker == NULL)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2918) return NULL;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2919)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2920) /* Next member in the linked list could be itself */
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2921) tmp = list_next_entry(node, fl_blocked_member);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2922) if (list_entry_is_head(tmp, &node->fl_blocker->fl_blocked_requests, fl_blocked_member)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2923) || tmp == node) {
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2924) return NULL;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2925) }
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2926)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2927) return tmp;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2928) }
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2929)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2930) static int locks_show(struct seq_file *f, void *v)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2931) {
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 2932) struct locks_iterator *iter = f->private;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2933) struct file_lock *cur, *tmp;
9d78edeaec759 (Alexey Gladkov 2020-05-18 20:07:38 +0200 2934) struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2935) int level = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2936)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2937) cur = hlist_entry(v, struct file_lock, fl_link);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2938)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2939) if (locks_translate_pid(cur, proc_pidns) == 0)
d67fd44f697df (Nikolay Borisov 2016-08-17 16:18:46 -0400 2940) return 0;
d67fd44f697df (Nikolay Borisov 2016-08-17 16:18:46 -0400 2941)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2942) /* View this crossed linked list as a binary tree, the first member of fl_blocked_requests
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2943) * is the left child of current node, the next silibing in fl_blocked_member is the
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2944) * right child, we can alse get the parent of current node from fl_blocker, so this
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2945) * question becomes traversal of a binary tree
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2946) */
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2947) while (cur != NULL) {
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2948) if (level)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2949) lock_get_status(f, cur, iter->li_pos, "-> ", level);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2950) else
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2951) lock_get_status(f, cur, iter->li_pos, "", level);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2952)
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2953) if (!list_empty(&cur->fl_blocked_requests)) {
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2954) /* Turn left */
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2955) cur = list_first_entry_or_null(&cur->fl_blocked_requests,
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2956) struct file_lock, fl_blocked_member);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2957) level++;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2958) } else {
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2959) /* Turn right */
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2960) tmp = get_next_blocked_member(cur);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2961) /* Fall back to parent node */
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2962) while (tmp == NULL && cur->fl_blocker != NULL) {
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2963) cur = cur->fl_blocker;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2964) level--;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2965) tmp = get_next_blocked_member(cur);
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2966) }
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2967) cur = tmp;
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2968) }
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2969) }
094f2825218fe (Matthias Kaehlcke 2007-10-02 11:21:34 -0700 2970)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2971) return 0;
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 2972) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2973)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2974) static void __show_fd_locks(struct seq_file *f,
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2975) struct list_head *head, int *id,
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2976) struct file *filp, struct files_struct *files)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2977) {
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2978) struct file_lock *fl;
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2979)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2980) list_for_each_entry(fl, head, fl_list) {
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2981)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2982) if (filp != fl->fl_file)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2983) continue;
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2984) if (fl->fl_owner != files &&
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2985) fl->fl_owner != filp)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2986) continue;
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2987)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2988) (*id)++;
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2989) seq_puts(f, "lock:\t");
b8da9b10e26ce (Luo Longjun 2021-02-25 22:58:29 -0500 2990) lock_get_status(f, fl, *id, "", 0);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2991) }
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2992) }
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2993)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2994) void show_fd_locks(struct seq_file *f,
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2995) struct file *filp, struct files_struct *files)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2996) {
c568d68341be7 (Miklos Szeredi 2016-09-16 12:44:20 +0200 2997) struct inode *inode = locks_inode(filp);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2998) struct file_lock_context *ctx;
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 2999) int id = 0;
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3000)
128a37852234c (Dmitry Vyukov 2015-09-21 09:43:06 +0200 3001) ctx = smp_load_acquire(&inode->i_flctx);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3002) if (!ctx)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3003) return;
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3004)
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3005) spin_lock(&ctx->flc_lock);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3006) __show_fd_locks(f, &ctx->flc_flock, &id, filp, files);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3007) __show_fd_locks(f, &ctx->flc_posix, &id, filp, files);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3008) __show_fd_locks(f, &ctx->flc_lease, &id, filp, files);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3009) spin_unlock(&ctx->flc_lock);
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3010) }
6c8c90319c0bb (Andrey Vagin 2015-04-16 12:49:38 -0700 3011)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3012) static void *locks_start(struct seq_file *f, loff_t *pos)
b03dfdec03818 (Jeff Layton 2014-02-03 12:13:07 -0500 3013) __acquires(&blocked_lock_lock)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3014) {
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3015) struct locks_iterator *iter = f->private;
99dc829256bb8 (Jerome Marchand 2010-10-26 14:22:33 -0700 3016)
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3017) iter->li_pos = *pos + 1;
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 3018) percpu_down_write(&file_rwsem);
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 3019) spin_lock(&blocked_lock_lock);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3020) return seq_hlist_start_percpu(&file_lock_list.hlist, &iter->li_cpu, *pos);
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3021) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3022)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3023) static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3024) {
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3025) struct locks_iterator *iter = f->private;
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3026)
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3027) ++iter->li_pos;
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3028) return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos);
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3029) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3030)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3031) static void locks_stop(struct seq_file *f, void *v)
b03dfdec03818 (Jeff Layton 2014-02-03 12:13:07 -0500 3032) __releases(&blocked_lock_lock)
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3033) {
7b2296afb392b (Jeff Layton 2013-06-21 08:58:20 -0400 3034) spin_unlock(&blocked_lock_lock);
aba3766073832 (Peter Zijlstra 2015-06-22 14:16:33 +0200 3035) percpu_up_write(&file_rwsem);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3036) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3037)
d8ba7a363393f (Alexey Dobriyan 2008-10-04 22:34:18 +0400 3038) static const struct seq_operations locks_seq_operations = {
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3039) .start = locks_start,
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3040) .next = locks_next,
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3041) .stop = locks_stop,
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3042) .show = locks_show,
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3043) };
d8ba7a363393f (Alexey Dobriyan 2008-10-04 22:34:18 +0400 3044)
d8ba7a363393f (Alexey Dobriyan 2008-10-04 22:34:18 +0400 3045) static int __init proc_locks_init(void)
d8ba7a363393f (Alexey Dobriyan 2008-10-04 22:34:18 +0400 3046) {
44414d82cfe0f (Christoph Hellwig 2018-04-24 17:05:17 +0200 3047) proc_create_seq_private("locks", 0, NULL, &locks_seq_operations,
44414d82cfe0f (Christoph Hellwig 2018-04-24 17:05:17 +0200 3048) sizeof(struct locks_iterator), NULL);
d8ba7a363393f (Alexey Dobriyan 2008-10-04 22:34:18 +0400 3049) return 0;
d8ba7a363393f (Alexey Dobriyan 2008-10-04 22:34:18 +0400 3050) }
9189922675ecc (Paul Gortmaker 2015-12-17 14:11:03 -0500 3051) fs_initcall(proc_locks_init);
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3052) #endif
7f8ada98d9edd (Pavel Emelyanov 2007-10-01 14:41:15 -0700 3053)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3054) static int __init filelock_init(void)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3055) {
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3056) int i;
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3057)
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 3058) flctx_cache = kmem_cache_create("file_lock_ctx",
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 3059) sizeof(struct file_lock_context), 0, SLAB_PANIC, NULL);
4a075e39c8649 (Jeff Layton 2015-01-16 15:05:54 -0500 3060)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3061) filelock_cache = kmem_cache_create("file_lock_cache",
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 3062) sizeof(struct file_lock), 0, SLAB_PANIC, NULL);
ee19cc406d4c0 (Miklos Szeredi 2011-07-07 13:06:09 +0200 3063)
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3064) for_each_possible_cpu(i) {
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3065) struct file_lock_list_struct *fll = per_cpu_ptr(&file_lock_list, i);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3066)
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3067) spin_lock_init(&fll->lock);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3068) INIT_HLIST_HEAD(&fll->hlist);
7c3f654d8e189 (Peter Zijlstra 2015-06-22 14:16:34 +0200 3069) }
7012b02a2b2c4 (Jeff Layton 2013-06-21 08:58:22 -0400 3070)
18f6622ebbdea (Jeff Layton 2019-08-18 14:18:45 -0400 3071) lease_notifier_chain_init();
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3072) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3073) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3074) core_initcall(filelock_init);