VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   35 Branches   59 Tags
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);