11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/fs/locks.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Provide support for fcntl()'s F_GETLK, F_SETLK, and F_SETLKW calls. 51da177e4SLinus Torvalds * Doug Evans (dje@spiff.uucp), August 07, 1992 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * Deadlock detection added. 81da177e4SLinus Torvalds * FIXME: one thing isn't handled yet: 91da177e4SLinus Torvalds * - mandatory locks (requires lots of changes elsewhere) 101da177e4SLinus Torvalds * Kelly Carmichael (kelly@[142.24.8.65]), September 17, 1994. 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds * Miscellaneous edits, and a total rewrite of posix_lock_file() code. 131da177e4SLinus Torvalds * Kai Petzke (wpp@marie.physik.tu-berlin.de), 1994 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * Converted file_lock_table to a linked list from an array, which eliminates 161da177e4SLinus Torvalds * the limits on how many active file locks are open. 171da177e4SLinus Torvalds * Chad Page (pageone@netcom.com), November 27, 1994 181da177e4SLinus Torvalds * 191da177e4SLinus Torvalds * Removed dependency on file descriptors. dup()'ed file descriptors now 201da177e4SLinus Torvalds * get the same locks as the original file descriptors, and a close() on 211da177e4SLinus Torvalds * any file descriptor removes ALL the locks on the file for the current 221da177e4SLinus Torvalds * process. Since locks still depend on the process id, locks are inherited 231da177e4SLinus Torvalds * after an exec() but not after a fork(). This agrees with POSIX, and both 241da177e4SLinus Torvalds * BSD and SVR4 practice. 251da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), February 14, 1995 261da177e4SLinus Torvalds * 271da177e4SLinus Torvalds * Scrapped free list which is redundant now that we allocate locks 281da177e4SLinus Torvalds * dynamically with kmalloc()/kfree(). 291da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), February 21, 1995 301da177e4SLinus Torvalds * 311da177e4SLinus Torvalds * Implemented two lock personalities - FL_FLOCK and FL_POSIX. 321da177e4SLinus Torvalds * 331da177e4SLinus Torvalds * FL_POSIX locks are created with calls to fcntl() and lockf() through the 341da177e4SLinus Torvalds * fcntl() system call. They have the semantics described above. 351da177e4SLinus Torvalds * 361da177e4SLinus Torvalds * FL_FLOCK locks are created with calls to flock(), through the flock() 371da177e4SLinus Torvalds * system call, which is new. Old C libraries implement flock() via fcntl() 381da177e4SLinus Torvalds * and will continue to use the old, broken implementation. 391da177e4SLinus Torvalds * 401da177e4SLinus Torvalds * FL_FLOCK locks follow the 4.4 BSD flock() semantics. They are associated 411da177e4SLinus Torvalds * with a file pointer (filp). As a result they can be shared by a parent 421da177e4SLinus Torvalds * process and its children after a fork(). They are removed when the last 431da177e4SLinus Torvalds * file descriptor referring to the file pointer is closed (unless explicitly 441da177e4SLinus Torvalds * unlocked). 451da177e4SLinus Torvalds * 461da177e4SLinus Torvalds * FL_FLOCK locks never deadlock, an existing lock is always removed before 471da177e4SLinus Torvalds * upgrading from shared to exclusive (or vice versa). When this happens 481da177e4SLinus Torvalds * any processes blocked by the current lock are woken up and allowed to 491da177e4SLinus Torvalds * run before the new lock is applied. 501da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), June 09, 1995 511da177e4SLinus Torvalds * 521da177e4SLinus Torvalds * Removed some race conditions in flock_lock_file(), marked other possible 531da177e4SLinus Torvalds * races. Just grep for FIXME to see them. 541da177e4SLinus Torvalds * Dmitry Gorodchanin (pgmdsg@ibi.com), February 09, 1996. 551da177e4SLinus Torvalds * 561da177e4SLinus Torvalds * Addressed Dmitry's concerns. Deadlock checking no longer recursive. 571da177e4SLinus Torvalds * Lock allocation changed to GFP_ATOMIC as we can't afford to sleep 581da177e4SLinus Torvalds * once we've checked for blocking and deadlocking. 591da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), April 03, 1996. 601da177e4SLinus Torvalds * 611da177e4SLinus Torvalds * Initial implementation of mandatory locks. SunOS turned out to be 621da177e4SLinus Torvalds * a rotten model, so I implemented the "obvious" semantics. 63395cf969SPaul Bolle * See 'Documentation/filesystems/mandatory-locking.txt' for details. 641da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), April 06, 1996. 651da177e4SLinus Torvalds * 661da177e4SLinus Torvalds * Don't allow mandatory locks on mmap()'ed files. Added simple functions to 671da177e4SLinus Torvalds * check if a file has mandatory locks, used by mmap(), open() and creat() to 681da177e4SLinus Torvalds * see if system call should be rejected. Ref. HP-UX/SunOS/Solaris Reference 691da177e4SLinus Torvalds * Manual, Section 2. 701da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), April 09, 1996. 711da177e4SLinus Torvalds * 721da177e4SLinus Torvalds * Tidied up block list handling. Added '/proc/locks' interface. 731da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), April 24, 1996. 741da177e4SLinus Torvalds * 751da177e4SLinus Torvalds * Fixed deadlock condition for pathological code that mixes calls to 761da177e4SLinus Torvalds * flock() and fcntl(). 771da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), April 29, 1996. 781da177e4SLinus Torvalds * 791da177e4SLinus Torvalds * Allow only one type of locking scheme (FL_POSIX or FL_FLOCK) to be in use 801da177e4SLinus Torvalds * for a given file at a time. Changed the CONFIG_LOCK_MANDATORY scheme to 811da177e4SLinus Torvalds * guarantee sensible behaviour in the case where file system modules might 821da177e4SLinus Torvalds * be compiled with different options than the kernel itself. 831da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), May 15, 1996. 841da177e4SLinus Torvalds * 851da177e4SLinus Torvalds * Added a couple of missing wake_up() calls. Thanks to Thomas Meckel 861da177e4SLinus Torvalds * (Thomas.Meckel@mni.fh-giessen.de) for spotting this. 871da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), May 15, 1996. 881da177e4SLinus Torvalds * 891da177e4SLinus Torvalds * Changed FL_POSIX locks to use the block list in the same way as FL_FLOCK 901da177e4SLinus Torvalds * locks. Changed process synchronisation to avoid dereferencing locks that 911da177e4SLinus Torvalds * have already been freed. 921da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), Sep 21, 1996. 931da177e4SLinus Torvalds * 941da177e4SLinus Torvalds * Made the block list a circular list to minimise searching in the list. 951da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), Sep 25, 1996. 961da177e4SLinus Torvalds * 971da177e4SLinus Torvalds * Made mandatory locking a mount option. Default is not to allow mandatory 981da177e4SLinus Torvalds * locking. 991da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), Oct 04, 1996. 1001da177e4SLinus Torvalds * 1011da177e4SLinus Torvalds * Some adaptations for NFS support. 1021da177e4SLinus Torvalds * Olaf Kirch (okir@monad.swb.de), Dec 1996, 1031da177e4SLinus Torvalds * 1041da177e4SLinus Torvalds * Fixed /proc/locks interface so that we can't overrun the buffer we are handed. 1051da177e4SLinus Torvalds * Andy Walker (andy@lysaker.kvaerner.no), May 12, 1997. 1061da177e4SLinus Torvalds * 1071da177e4SLinus Torvalds * Use slab allocator instead of kmalloc/kfree. 1081da177e4SLinus Torvalds * Use generic list implementation from <linux/list.h>. 1091da177e4SLinus Torvalds * Sped up posix_locks_deadlock by only considering blocked locks. 1101da177e4SLinus Torvalds * Matthew Wilcox <willy@debian.org>, March, 2000. 1111da177e4SLinus Torvalds * 1121da177e4SLinus Torvalds * Leases and LOCK_MAND 1131da177e4SLinus Torvalds * Matthew Wilcox <willy@debian.org>, June, 2000. 1141da177e4SLinus Torvalds * Stephen Rothwell <sfr@canb.auug.org.au>, June, 2000. 1151da177e4SLinus Torvalds */ 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds #include <linux/capability.h> 1181da177e4SLinus Torvalds #include <linux/file.h> 1199f3acc31SAl Viro #include <linux/fdtable.h> 1201da177e4SLinus Torvalds #include <linux/fs.h> 1211da177e4SLinus Torvalds #include <linux/init.h> 1221da177e4SLinus Torvalds #include <linux/security.h> 1231da177e4SLinus Torvalds #include <linux/slab.h> 1241da177e4SLinus Torvalds #include <linux/syscalls.h> 1251da177e4SLinus Torvalds #include <linux/time.h> 1264fb3a538SDipankar Sarma #include <linux/rcupdate.h> 127ab1f1611SVitaliy Gusev #include <linux/pid_namespace.h> 12848f74186SJeff Layton #include <linux/hashtable.h> 1297012b02aSJeff Layton #include <linux/percpu.h> 1301da177e4SLinus Torvalds 13162af4f1fSJeff Layton #define CREATE_TRACE_POINTS 13262af4f1fSJeff Layton #include <trace/events/filelock.h> 13362af4f1fSJeff Layton 1347c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds #define IS_POSIX(fl) (fl->fl_flags & FL_POSIX) 1371da177e4SLinus Torvalds #define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK) 13811afe9f7SChristoph Hellwig #define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) 139cff2fce5SJeff Layton #define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK) 140*9d5b86acSBenjamin Coddington #define IS_REMOTELCK(fl) (fl->fl_pid <= 0) 1411da177e4SLinus Torvalds 142c568d683SMiklos Szeredi static inline bool is_remote_lock(struct file *filp) 143c568d683SMiklos Szeredi { 144c568d683SMiklos Szeredi return likely(!(filp->f_path.dentry->d_sb->s_flags & MS_NOREMOTELOCK)); 145c568d683SMiklos Szeredi } 146c568d683SMiklos Szeredi 147ab83fa4bSJ. Bruce Fields static bool lease_breaking(struct file_lock *fl) 148ab83fa4bSJ. Bruce Fields { 149778fc546SJ. Bruce Fields return fl->fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING); 150778fc546SJ. Bruce Fields } 151778fc546SJ. Bruce Fields 152778fc546SJ. Bruce Fields static int target_leasetype(struct file_lock *fl) 153778fc546SJ. Bruce Fields { 154778fc546SJ. Bruce Fields if (fl->fl_flags & FL_UNLOCK_PENDING) 155778fc546SJ. Bruce Fields return F_UNLCK; 156778fc546SJ. Bruce Fields if (fl->fl_flags & FL_DOWNGRADE_PENDING) 157778fc546SJ. Bruce Fields return F_RDLCK; 158778fc546SJ. Bruce Fields return fl->fl_type; 159ab83fa4bSJ. Bruce Fields } 160ab83fa4bSJ. Bruce Fields 1611da177e4SLinus Torvalds int leases_enable = 1; 1621da177e4SLinus Torvalds int lease_break_time = 45; 1631da177e4SLinus Torvalds 1641c8c601aSJeff Layton /* 1657012b02aSJeff Layton * The global file_lock_list is only used for displaying /proc/locks, so we 1667c3f654dSPeter Zijlstra * keep a list on each CPU, with each list protected by its own spinlock. 1677c3f654dSPeter Zijlstra * Global serialization is done using file_rwsem. 1687c3f654dSPeter Zijlstra * 1697c3f654dSPeter Zijlstra * Note that alterations to the list also require that the relevant flc_lock is 1707c3f654dSPeter Zijlstra * held. 1711c8c601aSJeff Layton */ 1727c3f654dSPeter Zijlstra struct file_lock_list_struct { 1737c3f654dSPeter Zijlstra spinlock_t lock; 1747c3f654dSPeter Zijlstra struct hlist_head hlist; 1757c3f654dSPeter Zijlstra }; 1767c3f654dSPeter Zijlstra static DEFINE_PER_CPU(struct file_lock_list_struct, file_lock_list); 177aba37660SPeter Zijlstra DEFINE_STATIC_PERCPU_RWSEM(file_rwsem); 17888974691SJeff Layton 1791c8c601aSJeff Layton /* 18048f74186SJeff Layton * The blocked_hash is used to find POSIX lock loops for deadlock detection. 1817b2296afSJeff Layton * It is protected by blocked_lock_lock. 18248f74186SJeff Layton * 18348f74186SJeff Layton * We hash locks by lockowner in order to optimize searching for the lock a 18448f74186SJeff Layton * particular lockowner is waiting on. 18548f74186SJeff Layton * 18648f74186SJeff Layton * FIXME: make this value scale via some heuristic? We generally will want more 18748f74186SJeff Layton * buckets when we have more lockowners holding locks, but that's a little 18848f74186SJeff Layton * difficult to determine without knowing what the workload will look like. 1891c8c601aSJeff Layton */ 19048f74186SJeff Layton #define BLOCKED_HASH_BITS 7 19148f74186SJeff Layton static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS); 19288974691SJeff Layton 1931c8c601aSJeff Layton /* 1947b2296afSJeff Layton * This lock protects the blocked_hash. Generally, if you're accessing it, you 1957b2296afSJeff Layton * want to be holding this lock. 1961c8c601aSJeff Layton * 1971c8c601aSJeff Layton * In addition, it also protects the fl->fl_block list, and the fl->fl_next 1981c8c601aSJeff Layton * pointer for file_lock structures that are acting as lock requests (in 1991c8c601aSJeff Layton * contrast to those that are acting as records of acquired locks). 2001c8c601aSJeff Layton * 2011c8c601aSJeff Layton * Note that when we acquire this lock in order to change the above fields, 2026109c850SJeff Layton * we often hold the flc_lock as well. In certain cases, when reading the fields 2031c8c601aSJeff Layton * protected by this lock, we can skip acquiring it iff we already hold the 2046109c850SJeff Layton * flc_lock. 2051c8c601aSJeff Layton * 2061c8c601aSJeff Layton * In particular, adding an entry to the fl_block list requires that you hold 2076109c850SJeff Layton * both the flc_lock and the blocked_lock_lock (acquired in that order). 2086109c850SJeff Layton * Deleting an entry from the list however only requires the file_lock_lock. 2091c8c601aSJeff Layton */ 2107b2296afSJeff Layton static DEFINE_SPINLOCK(blocked_lock_lock); 2111da177e4SLinus Torvalds 2124a075e39SJeff Layton static struct kmem_cache *flctx_cache __read_mostly; 213e18b890bSChristoph Lameter static struct kmem_cache *filelock_cache __read_mostly; 2141da177e4SLinus Torvalds 2154a075e39SJeff Layton static struct file_lock_context * 2165c1c669aSJeff Layton locks_get_lock_context(struct inode *inode, int type) 2174a075e39SJeff Layton { 218128a3785SDmitry Vyukov struct file_lock_context *ctx; 2194a075e39SJeff Layton 220128a3785SDmitry Vyukov /* paired with cmpxchg() below */ 221128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 222128a3785SDmitry Vyukov if (likely(ctx) || type == F_UNLCK) 2234a075e39SJeff Layton goto out; 2244a075e39SJeff Layton 225128a3785SDmitry Vyukov ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL); 226128a3785SDmitry Vyukov if (!ctx) 2274a075e39SJeff Layton goto out; 2284a075e39SJeff Layton 229128a3785SDmitry Vyukov spin_lock_init(&ctx->flc_lock); 230128a3785SDmitry Vyukov INIT_LIST_HEAD(&ctx->flc_flock); 231128a3785SDmitry Vyukov INIT_LIST_HEAD(&ctx->flc_posix); 232128a3785SDmitry Vyukov INIT_LIST_HEAD(&ctx->flc_lease); 2334a075e39SJeff Layton 2344a075e39SJeff Layton /* 2354a075e39SJeff Layton * Assign the pointer if it's not already assigned. If it is, then 2364a075e39SJeff Layton * free the context we just allocated. 2374a075e39SJeff Layton */ 238128a3785SDmitry Vyukov if (cmpxchg(&inode->i_flctx, NULL, ctx)) { 239128a3785SDmitry Vyukov kmem_cache_free(flctx_cache, ctx); 240128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 241128a3785SDmitry Vyukov } 2424a075e39SJeff Layton out: 2431890910fSJeff Layton trace_locks_get_lock_context(inode, type, ctx); 244128a3785SDmitry Vyukov return ctx; 2454a075e39SJeff Layton } 2464a075e39SJeff Layton 247e24dadabSJeff Layton static void 248e24dadabSJeff Layton locks_dump_ctx_list(struct list_head *list, char *list_type) 249e24dadabSJeff Layton { 250e24dadabSJeff Layton struct file_lock *fl; 251e24dadabSJeff Layton 252e24dadabSJeff Layton list_for_each_entry(fl, list, fl_list) { 253e24dadabSJeff Layton 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); 254e24dadabSJeff Layton } 255e24dadabSJeff Layton } 256e24dadabSJeff Layton 257e24dadabSJeff Layton static void 258e24dadabSJeff Layton locks_check_ctx_lists(struct inode *inode) 259e24dadabSJeff Layton { 260e24dadabSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 261e24dadabSJeff Layton 262e24dadabSJeff Layton if (unlikely(!list_empty(&ctx->flc_flock) || 263e24dadabSJeff Layton !list_empty(&ctx->flc_posix) || 264e24dadabSJeff Layton !list_empty(&ctx->flc_lease))) { 265e24dadabSJeff Layton pr_warn("Leaked locks on dev=0x%x:0x%x ino=0x%lx:\n", 266e24dadabSJeff Layton MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev), 267e24dadabSJeff Layton inode->i_ino); 268e24dadabSJeff Layton locks_dump_ctx_list(&ctx->flc_flock, "FLOCK"); 269e24dadabSJeff Layton locks_dump_ctx_list(&ctx->flc_posix, "POSIX"); 270e24dadabSJeff Layton locks_dump_ctx_list(&ctx->flc_lease, "LEASE"); 271e24dadabSJeff Layton } 272e24dadabSJeff Layton } 273e24dadabSJeff Layton 2744a075e39SJeff Layton void 275f27a0fe0SJeff Layton locks_free_lock_context(struct inode *inode) 2764a075e39SJeff Layton { 277f27a0fe0SJeff Layton struct file_lock_context *ctx = inode->i_flctx; 278f27a0fe0SJeff Layton 279e24dadabSJeff Layton if (unlikely(ctx)) { 280e24dadabSJeff Layton locks_check_ctx_lists(inode); 2814a075e39SJeff Layton kmem_cache_free(flctx_cache, ctx); 2824a075e39SJeff Layton } 2834a075e39SJeff Layton } 2844a075e39SJeff Layton 285ee19cc40SMiklos Szeredi static void locks_init_lock_heads(struct file_lock *fl) 286a51cb91dSMiklos Szeredi { 287139ca04eSJeff Layton INIT_HLIST_NODE(&fl->fl_link); 2886dee60f6SJeff Layton INIT_LIST_HEAD(&fl->fl_list); 289ee19cc40SMiklos Szeredi INIT_LIST_HEAD(&fl->fl_block); 290ee19cc40SMiklos Szeredi init_waitqueue_head(&fl->fl_wait); 291a51cb91dSMiklos Szeredi } 292a51cb91dSMiklos Szeredi 2931da177e4SLinus Torvalds /* Allocate an empty lock structure. */ 294c5b1f0d9SArnd Bergmann struct file_lock *locks_alloc_lock(void) 2951da177e4SLinus Torvalds { 296ee19cc40SMiklos Szeredi struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL); 297a51cb91dSMiklos Szeredi 298a51cb91dSMiklos Szeredi if (fl) 299ee19cc40SMiklos Szeredi locks_init_lock_heads(fl); 300a51cb91dSMiklos Szeredi 301a51cb91dSMiklos Szeredi return fl; 3021da177e4SLinus Torvalds } 303c5b1f0d9SArnd Bergmann EXPORT_SYMBOL_GPL(locks_alloc_lock); 3041da177e4SLinus Torvalds 305a9e61e25SFelix Blyakher void locks_release_private(struct file_lock *fl) 30647831f35STrond Myklebust { 30747831f35STrond Myklebust if (fl->fl_ops) { 30847831f35STrond Myklebust if (fl->fl_ops->fl_release_private) 30947831f35STrond Myklebust fl->fl_ops->fl_release_private(fl); 31047831f35STrond Myklebust fl->fl_ops = NULL; 31147831f35STrond Myklebust } 31247831f35STrond Myklebust 3135c97d7b1SKinglong Mee if (fl->fl_lmops) { 314cae80b30SJeff Layton if (fl->fl_lmops->lm_put_owner) { 315cae80b30SJeff Layton fl->fl_lmops->lm_put_owner(fl->fl_owner); 316cae80b30SJeff Layton fl->fl_owner = NULL; 317cae80b30SJeff Layton } 3185c97d7b1SKinglong Mee fl->fl_lmops = NULL; 3195c97d7b1SKinglong Mee } 32047831f35STrond Myklebust } 321a9e61e25SFelix Blyakher EXPORT_SYMBOL_GPL(locks_release_private); 32247831f35STrond Myklebust 3231da177e4SLinus Torvalds /* Free a lock which is not in use. */ 32405fa3135SJ. Bruce Fields void locks_free_lock(struct file_lock *fl) 3251da177e4SLinus Torvalds { 3265ce29646SMiklos Szeredi BUG_ON(waitqueue_active(&fl->fl_wait)); 3276dee60f6SJeff Layton BUG_ON(!list_empty(&fl->fl_list)); 3285ce29646SMiklos Szeredi BUG_ON(!list_empty(&fl->fl_block)); 329139ca04eSJeff Layton BUG_ON(!hlist_unhashed(&fl->fl_link)); 3301da177e4SLinus Torvalds 33147831f35STrond Myklebust locks_release_private(fl); 3321da177e4SLinus Torvalds kmem_cache_free(filelock_cache, fl); 3331da177e4SLinus Torvalds } 33405fa3135SJ. Bruce Fields EXPORT_SYMBOL(locks_free_lock); 3351da177e4SLinus Torvalds 336ed9814d8SJeff Layton static void 337ed9814d8SJeff Layton locks_dispose_list(struct list_head *dispose) 338ed9814d8SJeff Layton { 339ed9814d8SJeff Layton struct file_lock *fl; 340ed9814d8SJeff Layton 341ed9814d8SJeff Layton while (!list_empty(dispose)) { 3426dee60f6SJeff Layton fl = list_first_entry(dispose, struct file_lock, fl_list); 3436dee60f6SJeff Layton list_del_init(&fl->fl_list); 344ed9814d8SJeff Layton locks_free_lock(fl); 345ed9814d8SJeff Layton } 346ed9814d8SJeff Layton } 347ed9814d8SJeff Layton 3481da177e4SLinus Torvalds void locks_init_lock(struct file_lock *fl) 3491da177e4SLinus Torvalds { 350ee19cc40SMiklos Szeredi memset(fl, 0, sizeof(struct file_lock)); 351ee19cc40SMiklos Szeredi locks_init_lock_heads(fl); 3521da177e4SLinus Torvalds } 3531da177e4SLinus Torvalds 3541da177e4SLinus Torvalds EXPORT_SYMBOL(locks_init_lock); 3551da177e4SLinus Torvalds 3561da177e4SLinus Torvalds /* 3571da177e4SLinus Torvalds * Initialize a new lock from an existing file_lock structure. 3581da177e4SLinus Torvalds */ 3593fe0fff1SKinglong Mee void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) 3601da177e4SLinus Torvalds { 3611da177e4SLinus Torvalds new->fl_owner = fl->fl_owner; 3621da177e4SLinus Torvalds new->fl_pid = fl->fl_pid; 3630996905fSTrond Myklebust new->fl_file = NULL; 3641da177e4SLinus Torvalds new->fl_flags = fl->fl_flags; 3651da177e4SLinus Torvalds new->fl_type = fl->fl_type; 3661da177e4SLinus Torvalds new->fl_start = fl->fl_start; 3671da177e4SLinus Torvalds new->fl_end = fl->fl_end; 368f328296eSKinglong Mee new->fl_lmops = fl->fl_lmops; 3690996905fSTrond Myklebust new->fl_ops = NULL; 370f328296eSKinglong Mee 371f328296eSKinglong Mee if (fl->fl_lmops) { 372f328296eSKinglong Mee if (fl->fl_lmops->lm_get_owner) 373cae80b30SJeff Layton fl->fl_lmops->lm_get_owner(fl->fl_owner); 374f328296eSKinglong Mee } 3750996905fSTrond Myklebust } 3763fe0fff1SKinglong Mee EXPORT_SYMBOL(locks_copy_conflock); 3770996905fSTrond Myklebust 3780996905fSTrond Myklebust void locks_copy_lock(struct file_lock *new, struct file_lock *fl) 3790996905fSTrond Myklebust { 380566709bdSJeff Layton /* "new" must be a freshly-initialized lock */ 381566709bdSJeff Layton WARN_ON_ONCE(new->fl_ops); 3820996905fSTrond Myklebust 3833fe0fff1SKinglong Mee locks_copy_conflock(new, fl); 384f328296eSKinglong Mee 3850996905fSTrond Myklebust new->fl_file = fl->fl_file; 3861da177e4SLinus Torvalds new->fl_ops = fl->fl_ops; 38747831f35STrond Myklebust 388f328296eSKinglong Mee if (fl->fl_ops) { 389f328296eSKinglong Mee if (fl->fl_ops->fl_copy_lock) 390f328296eSKinglong Mee fl->fl_ops->fl_copy_lock(new, fl); 391f328296eSKinglong Mee } 3921da177e4SLinus Torvalds } 3931da177e4SLinus Torvalds 3941da177e4SLinus Torvalds EXPORT_SYMBOL(locks_copy_lock); 3951da177e4SLinus Torvalds 3961da177e4SLinus Torvalds static inline int flock_translate_cmd(int cmd) { 3971da177e4SLinus Torvalds if (cmd & LOCK_MAND) 3981da177e4SLinus Torvalds return cmd & (LOCK_MAND | LOCK_RW); 3991da177e4SLinus Torvalds switch (cmd) { 4001da177e4SLinus Torvalds case LOCK_SH: 4011da177e4SLinus Torvalds return F_RDLCK; 4021da177e4SLinus Torvalds case LOCK_EX: 4031da177e4SLinus Torvalds return F_WRLCK; 4041da177e4SLinus Torvalds case LOCK_UN: 4051da177e4SLinus Torvalds return F_UNLCK; 4061da177e4SLinus Torvalds } 4071da177e4SLinus Torvalds return -EINVAL; 4081da177e4SLinus Torvalds } 4091da177e4SLinus Torvalds 4101da177e4SLinus Torvalds /* Fill in a file_lock structure with an appropriate FLOCK lock. */ 4116e129d00SJeff Layton static struct file_lock * 4126e129d00SJeff Layton flock_make_lock(struct file *filp, unsigned int cmd) 4131da177e4SLinus Torvalds { 4141da177e4SLinus Torvalds struct file_lock *fl; 4151da177e4SLinus Torvalds int type = flock_translate_cmd(cmd); 4166e129d00SJeff Layton 4171da177e4SLinus Torvalds if (type < 0) 4186e129d00SJeff Layton return ERR_PTR(type); 4191da177e4SLinus Torvalds 4201da177e4SLinus Torvalds fl = locks_alloc_lock(); 4211da177e4SLinus Torvalds if (fl == NULL) 4226e129d00SJeff Layton return ERR_PTR(-ENOMEM); 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds fl->fl_file = filp; 42573a8f5f7SChristoph Hellwig fl->fl_owner = filp; 4261da177e4SLinus Torvalds fl->fl_pid = current->tgid; 4271da177e4SLinus Torvalds fl->fl_flags = FL_FLOCK; 4281da177e4SLinus Torvalds fl->fl_type = type; 4291da177e4SLinus Torvalds fl->fl_end = OFFSET_MAX; 4301da177e4SLinus Torvalds 4316e129d00SJeff Layton return fl; 4321da177e4SLinus Torvalds } 4331da177e4SLinus Torvalds 4340ec4f431SJ. Bruce Fields static int assign_type(struct file_lock *fl, long type) 4351da177e4SLinus Torvalds { 4361da177e4SLinus Torvalds switch (type) { 4371da177e4SLinus Torvalds case F_RDLCK: 4381da177e4SLinus Torvalds case F_WRLCK: 4391da177e4SLinus Torvalds case F_UNLCK: 4401da177e4SLinus Torvalds fl->fl_type = type; 4411da177e4SLinus Torvalds break; 4421da177e4SLinus Torvalds default: 4431da177e4SLinus Torvalds return -EINVAL; 4441da177e4SLinus Torvalds } 4451da177e4SLinus Torvalds return 0; 4461da177e4SLinus Torvalds } 4471da177e4SLinus Torvalds 448ef12e72aSJ. Bruce Fields static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, 449ef12e72aSJ. Bruce Fields struct flock64 *l) 450ef12e72aSJ. Bruce Fields { 451ef12e72aSJ. Bruce Fields switch (l->l_whence) { 452ef12e72aSJ. Bruce Fields case SEEK_SET: 453ef12e72aSJ. Bruce Fields fl->fl_start = 0; 454ef12e72aSJ. Bruce Fields break; 455ef12e72aSJ. Bruce Fields case SEEK_CUR: 456ef12e72aSJ. Bruce Fields fl->fl_start = filp->f_pos; 457ef12e72aSJ. Bruce Fields break; 458ef12e72aSJ. Bruce Fields case SEEK_END: 459ef12e72aSJ. Bruce Fields fl->fl_start = i_size_read(file_inode(filp)); 460ef12e72aSJ. Bruce Fields break; 461ef12e72aSJ. Bruce Fields default: 462ef12e72aSJ. Bruce Fields return -EINVAL; 463ef12e72aSJ. Bruce Fields } 464ef12e72aSJ. Bruce Fields if (l->l_start > OFFSET_MAX - fl->fl_start) 465ef12e72aSJ. Bruce Fields return -EOVERFLOW; 466ef12e72aSJ. Bruce Fields fl->fl_start += l->l_start; 467ef12e72aSJ. Bruce Fields if (fl->fl_start < 0) 468ef12e72aSJ. Bruce Fields return -EINVAL; 469ef12e72aSJ. Bruce Fields 470ef12e72aSJ. Bruce Fields /* POSIX-1996 leaves the case l->l_len < 0 undefined; 471ef12e72aSJ. Bruce Fields POSIX-2001 defines it. */ 472ef12e72aSJ. Bruce Fields if (l->l_len > 0) { 473ef12e72aSJ. Bruce Fields if (l->l_len - 1 > OFFSET_MAX - fl->fl_start) 474ef12e72aSJ. Bruce Fields return -EOVERFLOW; 475ef12e72aSJ. Bruce Fields fl->fl_end = fl->fl_start + l->l_len - 1; 476ef12e72aSJ. Bruce Fields 477ef12e72aSJ. Bruce Fields } else if (l->l_len < 0) { 478ef12e72aSJ. Bruce Fields if (fl->fl_start + l->l_len < 0) 479ef12e72aSJ. Bruce Fields return -EINVAL; 480ef12e72aSJ. Bruce Fields fl->fl_end = fl->fl_start - 1; 481ef12e72aSJ. Bruce Fields fl->fl_start += l->l_len; 482ef12e72aSJ. Bruce Fields } else 483ef12e72aSJ. Bruce Fields fl->fl_end = OFFSET_MAX; 484ef12e72aSJ. Bruce Fields 485ef12e72aSJ. Bruce Fields fl->fl_owner = current->files; 486ef12e72aSJ. Bruce Fields fl->fl_pid = current->tgid; 487ef12e72aSJ. Bruce Fields fl->fl_file = filp; 488ef12e72aSJ. Bruce Fields fl->fl_flags = FL_POSIX; 489ef12e72aSJ. Bruce Fields fl->fl_ops = NULL; 490ef12e72aSJ. Bruce Fields fl->fl_lmops = NULL; 491ef12e72aSJ. Bruce Fields 492ef12e72aSJ. Bruce Fields return assign_type(fl, l->l_type); 493ef12e72aSJ. Bruce Fields } 494ef12e72aSJ. Bruce Fields 4951da177e4SLinus Torvalds /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX 4961da177e4SLinus Torvalds * style lock. 4971da177e4SLinus Torvalds */ 4981da177e4SLinus Torvalds static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, 4991da177e4SLinus Torvalds struct flock *l) 5001da177e4SLinus Torvalds { 501ef12e72aSJ. Bruce Fields struct flock64 ll = { 502ef12e72aSJ. Bruce Fields .l_type = l->l_type, 503ef12e72aSJ. Bruce Fields .l_whence = l->l_whence, 504ef12e72aSJ. Bruce Fields .l_start = l->l_start, 505ef12e72aSJ. Bruce Fields .l_len = l->l_len, 506ef12e72aSJ. Bruce Fields }; 5071da177e4SLinus Torvalds 508ef12e72aSJ. Bruce Fields return flock64_to_posix_lock(filp, fl, &ll); 5091da177e4SLinus Torvalds } 5101da177e4SLinus Torvalds 5111da177e4SLinus Torvalds /* default lease lock manager operations */ 5124d01b7f5SJeff Layton static bool 5134d01b7f5SJeff Layton lease_break_callback(struct file_lock *fl) 5141da177e4SLinus Torvalds { 5151da177e4SLinus Torvalds kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG); 5164d01b7f5SJeff Layton return false; 5171da177e4SLinus Torvalds } 5181da177e4SLinus Torvalds 5191c7dd2ffSJeff Layton static void 5201c7dd2ffSJeff Layton lease_setup(struct file_lock *fl, void **priv) 5211c7dd2ffSJeff Layton { 5221c7dd2ffSJeff Layton struct file *filp = fl->fl_file; 5231c7dd2ffSJeff Layton struct fasync_struct *fa = *priv; 5241c7dd2ffSJeff Layton 5251c7dd2ffSJeff Layton /* 5261c7dd2ffSJeff Layton * fasync_insert_entry() returns the old entry if any. If there was no 5271c7dd2ffSJeff Layton * old entry, then it used "priv" and inserted it into the fasync list. 5281c7dd2ffSJeff Layton * Clear the pointer to indicate that it shouldn't be freed. 5291c7dd2ffSJeff Layton */ 5301c7dd2ffSJeff Layton if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa)) 5311c7dd2ffSJeff Layton *priv = NULL; 5321c7dd2ffSJeff Layton 5331c7dd2ffSJeff Layton __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); 5341c7dd2ffSJeff Layton } 5351c7dd2ffSJeff Layton 5367b021967SAlexey Dobriyan static const struct lock_manager_operations lease_manager_ops = { 5378fb47a4fSJ. Bruce Fields .lm_break = lease_break_callback, 5388fb47a4fSJ. Bruce Fields .lm_change = lease_modify, 5391c7dd2ffSJeff Layton .lm_setup = lease_setup, 5401da177e4SLinus Torvalds }; 5411da177e4SLinus Torvalds 5421da177e4SLinus Torvalds /* 5431da177e4SLinus Torvalds * Initialize a lease, use the default lock manager operations 5441da177e4SLinus Torvalds */ 5450ec4f431SJ. Bruce Fields static int lease_init(struct file *filp, long type, struct file_lock *fl) 5461da177e4SLinus Torvalds { 54775dff55aSTrond Myklebust if (assign_type(fl, type) != 0) 54875dff55aSTrond Myklebust return -EINVAL; 54975dff55aSTrond Myklebust 5507ca76311SJeff Layton fl->fl_owner = filp; 5511da177e4SLinus Torvalds fl->fl_pid = current->tgid; 5521da177e4SLinus Torvalds 5531da177e4SLinus Torvalds fl->fl_file = filp; 5541da177e4SLinus Torvalds fl->fl_flags = FL_LEASE; 5551da177e4SLinus Torvalds fl->fl_start = 0; 5561da177e4SLinus Torvalds fl->fl_end = OFFSET_MAX; 5571da177e4SLinus Torvalds fl->fl_ops = NULL; 5581da177e4SLinus Torvalds fl->fl_lmops = &lease_manager_ops; 5591da177e4SLinus Torvalds return 0; 5601da177e4SLinus Torvalds } 5611da177e4SLinus Torvalds 5621da177e4SLinus Torvalds /* Allocate a file_lock initialised to this type of lease */ 5630ec4f431SJ. Bruce Fields static struct file_lock *lease_alloc(struct file *filp, long type) 5641da177e4SLinus Torvalds { 5651da177e4SLinus Torvalds struct file_lock *fl = locks_alloc_lock(); 56675dff55aSTrond Myklebust int error = -ENOMEM; 5671da177e4SLinus Torvalds 5681da177e4SLinus Torvalds if (fl == NULL) 569e32b8ee2SJ. Bruce Fields return ERR_PTR(error); 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds error = lease_init(filp, type, fl); 57275dff55aSTrond Myklebust if (error) { 57375dff55aSTrond Myklebust locks_free_lock(fl); 574e32b8ee2SJ. Bruce Fields return ERR_PTR(error); 57575dff55aSTrond Myklebust } 576e32b8ee2SJ. Bruce Fields return fl; 5771da177e4SLinus Torvalds } 5781da177e4SLinus Torvalds 5791da177e4SLinus Torvalds /* Check if two locks overlap each other. 5801da177e4SLinus Torvalds */ 5811da177e4SLinus Torvalds static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2) 5821da177e4SLinus Torvalds { 5831da177e4SLinus Torvalds return ((fl1->fl_end >= fl2->fl_start) && 5841da177e4SLinus Torvalds (fl2->fl_end >= fl1->fl_start)); 5851da177e4SLinus Torvalds } 5861da177e4SLinus Torvalds 5871da177e4SLinus Torvalds /* 5881da177e4SLinus Torvalds * Check whether two locks have the same owner. 5891da177e4SLinus Torvalds */ 59033443c42SMatt Mackall static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2) 5911da177e4SLinus Torvalds { 5928fb47a4fSJ. Bruce Fields if (fl1->fl_lmops && fl1->fl_lmops->lm_compare_owner) 5931da177e4SLinus Torvalds return fl2->fl_lmops == fl1->fl_lmops && 5948fb47a4fSJ. Bruce Fields fl1->fl_lmops->lm_compare_owner(fl1, fl2); 5951da177e4SLinus Torvalds return fl1->fl_owner == fl2->fl_owner; 5961da177e4SLinus Torvalds } 5971da177e4SLinus Torvalds 5986109c850SJeff Layton /* Must be called with the flc_lock held! */ 5996ca10ed8SJeff Layton static void locks_insert_global_locks(struct file_lock *fl) 60088974691SJeff Layton { 6017c3f654dSPeter Zijlstra struct file_lock_list_struct *fll = this_cpu_ptr(&file_lock_list); 6027c3f654dSPeter Zijlstra 603aba37660SPeter Zijlstra percpu_rwsem_assert_held(&file_rwsem); 604aba37660SPeter Zijlstra 6057c3f654dSPeter Zijlstra spin_lock(&fll->lock); 6067012b02aSJeff Layton fl->fl_link_cpu = smp_processor_id(); 6077c3f654dSPeter Zijlstra hlist_add_head(&fl->fl_link, &fll->hlist); 6087c3f654dSPeter Zijlstra spin_unlock(&fll->lock); 60988974691SJeff Layton } 61088974691SJeff Layton 6116109c850SJeff Layton /* Must be called with the flc_lock held! */ 6126ca10ed8SJeff Layton static void locks_delete_global_locks(struct file_lock *fl) 61388974691SJeff Layton { 6147c3f654dSPeter Zijlstra struct file_lock_list_struct *fll; 6157c3f654dSPeter Zijlstra 616aba37660SPeter Zijlstra percpu_rwsem_assert_held(&file_rwsem); 617aba37660SPeter Zijlstra 6187012b02aSJeff Layton /* 6197012b02aSJeff Layton * Avoid taking lock if already unhashed. This is safe since this check 6206109c850SJeff Layton * is done while holding the flc_lock, and new insertions into the list 6217012b02aSJeff Layton * also require that it be held. 6227012b02aSJeff Layton */ 6237012b02aSJeff Layton if (hlist_unhashed(&fl->fl_link)) 6247012b02aSJeff Layton return; 6257c3f654dSPeter Zijlstra 6267c3f654dSPeter Zijlstra fll = per_cpu_ptr(&file_lock_list, fl->fl_link_cpu); 6277c3f654dSPeter Zijlstra spin_lock(&fll->lock); 628139ca04eSJeff Layton hlist_del_init(&fl->fl_link); 6297c3f654dSPeter Zijlstra spin_unlock(&fll->lock); 63088974691SJeff Layton } 63188974691SJeff Layton 6323999e493SJeff Layton static unsigned long 6333999e493SJeff Layton posix_owner_key(struct file_lock *fl) 6343999e493SJeff Layton { 6353999e493SJeff Layton if (fl->fl_lmops && fl->fl_lmops->lm_owner_key) 6363999e493SJeff Layton return fl->fl_lmops->lm_owner_key(fl); 6373999e493SJeff Layton return (unsigned long)fl->fl_owner; 6383999e493SJeff Layton } 6393999e493SJeff Layton 6406ca10ed8SJeff Layton static void locks_insert_global_blocked(struct file_lock *waiter) 64188974691SJeff Layton { 642663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 643663d5af7SDaniel Wagner 6443999e493SJeff Layton hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter)); 64588974691SJeff Layton } 64688974691SJeff Layton 6476ca10ed8SJeff Layton static void locks_delete_global_blocked(struct file_lock *waiter) 64888974691SJeff Layton { 649663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 650663d5af7SDaniel Wagner 65148f74186SJeff Layton hash_del(&waiter->fl_link); 65288974691SJeff Layton } 65388974691SJeff Layton 6541da177e4SLinus Torvalds /* Remove waiter from blocker's block list. 6551da177e4SLinus Torvalds * When blocker ends up pointing to itself then the list is empty. 6561c8c601aSJeff Layton * 6577b2296afSJeff Layton * Must be called with blocked_lock_lock held. 6581da177e4SLinus Torvalds */ 65933443c42SMatt Mackall static void __locks_delete_block(struct file_lock *waiter) 6601da177e4SLinus Torvalds { 66188974691SJeff Layton locks_delete_global_blocked(waiter); 6621da177e4SLinus Torvalds list_del_init(&waiter->fl_block); 6631da177e4SLinus Torvalds waiter->fl_next = NULL; 6641da177e4SLinus Torvalds } 6651da177e4SLinus Torvalds 6661a9e64a7SJeff Layton static void locks_delete_block(struct file_lock *waiter) 6671da177e4SLinus Torvalds { 6687b2296afSJeff Layton spin_lock(&blocked_lock_lock); 6691da177e4SLinus Torvalds __locks_delete_block(waiter); 6707b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 6711da177e4SLinus Torvalds } 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds /* Insert waiter into blocker's block list. 6741da177e4SLinus Torvalds * We use a circular list so that processes can be easily woken up in 6751da177e4SLinus Torvalds * the order they blocked. The documentation doesn't require this but 6761da177e4SLinus Torvalds * it seems like the reasonable thing to do. 6771c8c601aSJeff Layton * 6786109c850SJeff Layton * Must be called with both the flc_lock and blocked_lock_lock held. The 6796109c850SJeff Layton * fl_block list itself is protected by the blocked_lock_lock, but by ensuring 6806109c850SJeff Layton * that the flc_lock is also held on insertions we can avoid taking the 6816109c850SJeff Layton * blocked_lock_lock in some cases when we see that the fl_block list is empty. 6821da177e4SLinus Torvalds */ 6831c8c601aSJeff Layton static void __locks_insert_block(struct file_lock *blocker, 6841da177e4SLinus Torvalds struct file_lock *waiter) 6851da177e4SLinus Torvalds { 6866dc0fe8fSJ. Bruce Fields BUG_ON(!list_empty(&waiter->fl_block)); 6871da177e4SLinus Torvalds waiter->fl_next = blocker; 68888974691SJeff Layton list_add_tail(&waiter->fl_block, &blocker->fl_block); 689cff2fce5SJeff Layton if (IS_POSIX(blocker) && !IS_OFDLCK(blocker)) 6901c8c601aSJeff Layton locks_insert_global_blocked(waiter); 6911c8c601aSJeff Layton } 6921c8c601aSJeff Layton 6936109c850SJeff Layton /* Must be called with flc_lock held. */ 6941c8c601aSJeff Layton static void locks_insert_block(struct file_lock *blocker, 6951c8c601aSJeff Layton struct file_lock *waiter) 6961c8c601aSJeff Layton { 6977b2296afSJeff Layton spin_lock(&blocked_lock_lock); 6981c8c601aSJeff Layton __locks_insert_block(blocker, waiter); 6997b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 7001da177e4SLinus Torvalds } 7011da177e4SLinus Torvalds 7021cb36012SJeff Layton /* 7031cb36012SJeff Layton * Wake up processes blocked waiting for blocker. 7041cb36012SJeff Layton * 7056109c850SJeff Layton * Must be called with the inode->flc_lock held! 7061da177e4SLinus Torvalds */ 7071da177e4SLinus Torvalds static void locks_wake_up_blocks(struct file_lock *blocker) 7081da177e4SLinus Torvalds { 7094e8c765dSJeff Layton /* 7104e8c765dSJeff Layton * Avoid taking global lock if list is empty. This is safe since new 7116109c850SJeff Layton * blocked requests are only added to the list under the flc_lock, and 7126109c850SJeff Layton * the flc_lock is always held here. Note that removal from the fl_block 7136109c850SJeff Layton * list does not require the flc_lock, so we must recheck list_empty() 7147b2296afSJeff Layton * after acquiring the blocked_lock_lock. 7154e8c765dSJeff Layton */ 7164e8c765dSJeff Layton if (list_empty(&blocker->fl_block)) 7174e8c765dSJeff Layton return; 7184e8c765dSJeff Layton 7197b2296afSJeff Layton spin_lock(&blocked_lock_lock); 7201da177e4SLinus Torvalds while (!list_empty(&blocker->fl_block)) { 721f0c1cd0eSPavel Emelyanov struct file_lock *waiter; 722f0c1cd0eSPavel Emelyanov 723f0c1cd0eSPavel Emelyanov waiter = list_first_entry(&blocker->fl_block, 7241da177e4SLinus Torvalds struct file_lock, fl_block); 7251da177e4SLinus Torvalds __locks_delete_block(waiter); 7268fb47a4fSJ. Bruce Fields if (waiter->fl_lmops && waiter->fl_lmops->lm_notify) 7278fb47a4fSJ. Bruce Fields waiter->fl_lmops->lm_notify(waiter); 7281da177e4SLinus Torvalds else 7291da177e4SLinus Torvalds wake_up(&waiter->fl_wait); 7301da177e4SLinus Torvalds } 7317b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 7321da177e4SLinus Torvalds } 7331da177e4SLinus Torvalds 7345263e31eSJeff Layton static void 735e084c1bdSJeff Layton locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) 7365263e31eSJeff Layton { 7375263e31eSJeff Layton list_add_tail(&fl->fl_list, before); 7385263e31eSJeff Layton locks_insert_global_locks(fl); 7395263e31eSJeff Layton } 7405263e31eSJeff Layton 7418634b51fSJeff Layton static void 742e084c1bdSJeff Layton locks_unlink_lock_ctx(struct file_lock *fl) 7431da177e4SLinus Torvalds { 74488974691SJeff Layton locks_delete_global_locks(fl); 7458634b51fSJeff Layton list_del_init(&fl->fl_list); 7461da177e4SLinus Torvalds locks_wake_up_blocks(fl); 74724cbe784SJeff Layton } 74824cbe784SJeff Layton 7495263e31eSJeff Layton static void 750e084c1bdSJeff Layton locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) 7515263e31eSJeff Layton { 752e084c1bdSJeff Layton locks_unlink_lock_ctx(fl); 7538634b51fSJeff Layton if (dispose) 7548634b51fSJeff Layton list_add(&fl->fl_list, dispose); 7558634b51fSJeff Layton else 7568634b51fSJeff Layton locks_free_lock(fl); 7575263e31eSJeff Layton } 7585263e31eSJeff Layton 7591da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. Common functionality 7601da177e4SLinus Torvalds * checks for shared/exclusive status of overlapping locks. 7611da177e4SLinus Torvalds */ 7621da177e4SLinus Torvalds static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) 7631da177e4SLinus Torvalds { 7641da177e4SLinus Torvalds if (sys_fl->fl_type == F_WRLCK) 7651da177e4SLinus Torvalds return 1; 7661da177e4SLinus Torvalds if (caller_fl->fl_type == F_WRLCK) 7671da177e4SLinus Torvalds return 1; 7681da177e4SLinus Torvalds return 0; 7691da177e4SLinus Torvalds } 7701da177e4SLinus Torvalds 7711da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. POSIX specific 7721da177e4SLinus Torvalds * checking before calling the locks_conflict(). 7731da177e4SLinus Torvalds */ 7741da177e4SLinus Torvalds static int posix_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) 7751da177e4SLinus Torvalds { 7761da177e4SLinus Torvalds /* POSIX locks owned by the same process do not conflict with 7771da177e4SLinus Torvalds * each other. 7781da177e4SLinus Torvalds */ 7799b8c8695SJeff Layton if (posix_same_owner(caller_fl, sys_fl)) 7801da177e4SLinus Torvalds return (0); 7811da177e4SLinus Torvalds 7821da177e4SLinus Torvalds /* Check whether they overlap */ 7831da177e4SLinus Torvalds if (!locks_overlap(caller_fl, sys_fl)) 7841da177e4SLinus Torvalds return 0; 7851da177e4SLinus Torvalds 7861da177e4SLinus Torvalds return (locks_conflict(caller_fl, sys_fl)); 7871da177e4SLinus Torvalds } 7881da177e4SLinus Torvalds 7891da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific 7901da177e4SLinus Torvalds * checking before calling the locks_conflict(). 7911da177e4SLinus Torvalds */ 7921da177e4SLinus Torvalds static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) 7931da177e4SLinus Torvalds { 7941da177e4SLinus Torvalds /* FLOCK locks referring to the same filp do not conflict with 7951da177e4SLinus Torvalds * each other. 7961da177e4SLinus Torvalds */ 7979b8c8695SJeff Layton if (caller_fl->fl_file == sys_fl->fl_file) 7981da177e4SLinus Torvalds return (0); 7991da177e4SLinus Torvalds if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND)) 8001da177e4SLinus Torvalds return 0; 8011da177e4SLinus Torvalds 8021da177e4SLinus Torvalds return (locks_conflict(caller_fl, sys_fl)); 8031da177e4SLinus Torvalds } 8041da177e4SLinus Torvalds 8056d34ac19SJ. Bruce Fields void 8069d6a8c5cSMarc Eshel posix_test_lock(struct file *filp, struct file_lock *fl) 8071da177e4SLinus Torvalds { 8081da177e4SLinus Torvalds struct file_lock *cfl; 809bd61e0a9SJeff Layton struct file_lock_context *ctx; 810c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 8111da177e4SLinus Torvalds 812128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 813bd61e0a9SJeff Layton if (!ctx || list_empty_careful(&ctx->flc_posix)) { 814bd61e0a9SJeff Layton fl->fl_type = F_UNLCK; 815bd61e0a9SJeff Layton return; 8161da177e4SLinus Torvalds } 817bd61e0a9SJeff Layton 8186109c850SJeff Layton spin_lock(&ctx->flc_lock); 819bd61e0a9SJeff Layton list_for_each_entry(cfl, &ctx->flc_posix, fl_list) { 820bd61e0a9SJeff Layton if (posix_locks_conflict(fl, cfl)) { 8213fe0fff1SKinglong Mee locks_copy_conflock(fl, cfl); 822bd61e0a9SJeff Layton goto out; 823bd61e0a9SJeff Layton } 824bd61e0a9SJeff Layton } 825129a84deSJ. Bruce Fields fl->fl_type = F_UNLCK; 826bd61e0a9SJeff Layton out: 8276109c850SJeff Layton spin_unlock(&ctx->flc_lock); 8286d34ac19SJ. Bruce Fields return; 8291da177e4SLinus Torvalds } 8301da177e4SLinus Torvalds EXPORT_SYMBOL(posix_test_lock); 8311da177e4SLinus Torvalds 832b533184fSJ. Bruce Fields /* 833b533184fSJ. Bruce Fields * Deadlock detection: 8341da177e4SLinus Torvalds * 835b533184fSJ. Bruce Fields * We attempt to detect deadlocks that are due purely to posix file 836b533184fSJ. Bruce Fields * locks. 8371da177e4SLinus Torvalds * 838b533184fSJ. Bruce Fields * We assume that a task can be waiting for at most one lock at a time. 839b533184fSJ. Bruce Fields * So for any acquired lock, the process holding that lock may be 840b533184fSJ. Bruce Fields * waiting on at most one other lock. That lock in turns may be held by 841b533184fSJ. Bruce Fields * someone waiting for at most one other lock. Given a requested lock 842b533184fSJ. Bruce Fields * caller_fl which is about to wait for a conflicting lock block_fl, we 843b533184fSJ. Bruce Fields * follow this chain of waiters to ensure we are not about to create a 844b533184fSJ. Bruce Fields * cycle. 84597855b49SJ. Bruce Fields * 846b533184fSJ. Bruce Fields * Since we do this before we ever put a process to sleep on a lock, we 847b533184fSJ. Bruce Fields * are ensured that there is never a cycle; that is what guarantees that 848b533184fSJ. Bruce Fields * the while() loop in posix_locks_deadlock() eventually completes. 849b533184fSJ. Bruce Fields * 850b533184fSJ. Bruce Fields * Note: the above assumption may not be true when handling lock 851b533184fSJ. Bruce Fields * requests from a broken NFS client. It may also fail in the presence 852b533184fSJ. Bruce Fields * of tasks (such as posix threads) sharing the same open file table. 853b533184fSJ. Bruce Fields * To handle those cases, we just bail out after a few iterations. 85457b65325SJeff Layton * 855cff2fce5SJeff Layton * For FL_OFDLCK locks, the owner is the filp, not the files_struct. 85657b65325SJeff Layton * Because the owner is not even nominally tied to a thread of 85757b65325SJeff Layton * execution, the deadlock detection below can't reasonably work well. Just 85857b65325SJeff Layton * skip it for those. 85957b65325SJeff Layton * 860cff2fce5SJeff Layton * In principle, we could do a more limited deadlock detection on FL_OFDLCK 86157b65325SJeff Layton * locks that just checks for the case where two tasks are attempting to 86257b65325SJeff Layton * upgrade from read to write locks on the same inode. 8631da177e4SLinus Torvalds */ 86497855b49SJ. Bruce Fields 86597855b49SJ. Bruce Fields #define MAX_DEADLK_ITERATIONS 10 86697855b49SJ. Bruce Fields 867b533184fSJ. Bruce Fields /* Find a lock that the owner of the given block_fl is blocking on. */ 868b533184fSJ. Bruce Fields static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl) 869b533184fSJ. Bruce Fields { 870b533184fSJ. Bruce Fields struct file_lock *fl; 871b533184fSJ. Bruce Fields 8723999e493SJeff Layton hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) { 873b533184fSJ. Bruce Fields if (posix_same_owner(fl, block_fl)) 874b533184fSJ. Bruce Fields return fl->fl_next; 875b533184fSJ. Bruce Fields } 876b533184fSJ. Bruce Fields return NULL; 877b533184fSJ. Bruce Fields } 878b533184fSJ. Bruce Fields 8797b2296afSJeff Layton /* Must be called with the blocked_lock_lock held! */ 880b0904e14SAdrian Bunk static int posix_locks_deadlock(struct file_lock *caller_fl, 8811da177e4SLinus Torvalds struct file_lock *block_fl) 8821da177e4SLinus Torvalds { 88397855b49SJ. Bruce Fields int i = 0; 8841da177e4SLinus Torvalds 885663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 886663d5af7SDaniel Wagner 88757b65325SJeff Layton /* 88857b65325SJeff Layton * This deadlock detector can't reasonably detect deadlocks with 889cff2fce5SJeff Layton * FL_OFDLCK locks, since they aren't owned by a process, per-se. 89057b65325SJeff Layton */ 891cff2fce5SJeff Layton if (IS_OFDLCK(caller_fl)) 89257b65325SJeff Layton return 0; 89357b65325SJeff Layton 894b533184fSJ. Bruce Fields while ((block_fl = what_owner_is_waiting_for(block_fl))) { 89597855b49SJ. Bruce Fields if (i++ > MAX_DEADLK_ITERATIONS) 89697855b49SJ. Bruce Fields return 0; 897b533184fSJ. Bruce Fields if (posix_same_owner(caller_fl, block_fl)) 898b533184fSJ. Bruce Fields return 1; 8991da177e4SLinus Torvalds } 9001da177e4SLinus Torvalds return 0; 9011da177e4SLinus Torvalds } 9021da177e4SLinus Torvalds 9031da177e4SLinus Torvalds /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 90402888f41SJ. Bruce Fields * after any leases, but before any posix locks. 905f475ae95STrond Myklebust * 906f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 907f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 908f475ae95STrond Myklebust * value for -ENOENT. 9091da177e4SLinus Torvalds */ 910bcd7f78dSJeff Layton static int flock_lock_inode(struct inode *inode, struct file_lock *request) 9111da177e4SLinus Torvalds { 912993dfa87STrond Myklebust struct file_lock *new_fl = NULL; 9135263e31eSJeff Layton struct file_lock *fl; 9145263e31eSJeff Layton struct file_lock_context *ctx; 9151da177e4SLinus Torvalds int error = 0; 9165263e31eSJeff Layton bool found = false; 917ed9814d8SJeff Layton LIST_HEAD(dispose); 9181da177e4SLinus Torvalds 9195c1c669aSJeff Layton ctx = locks_get_lock_context(inode, request->fl_type); 9205c1c669aSJeff Layton if (!ctx) { 9215c1c669aSJeff Layton if (request->fl_type != F_UNLCK) 9225263e31eSJeff Layton return -ENOMEM; 9235c1c669aSJeff Layton return (request->fl_flags & FL_EXISTS) ? -ENOENT : 0; 9245c1c669aSJeff Layton } 9255263e31eSJeff Layton 926b89f4321SArnd Bergmann if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) { 927b89f4321SArnd Bergmann new_fl = locks_alloc_lock(); 928b89f4321SArnd Bergmann if (!new_fl) 929b89f4321SArnd Bergmann return -ENOMEM; 930b89f4321SArnd Bergmann } 931b89f4321SArnd Bergmann 93287709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 9336109c850SJeff Layton spin_lock(&ctx->flc_lock); 934f07f18ddSTrond Myklebust if (request->fl_flags & FL_ACCESS) 935f07f18ddSTrond Myklebust goto find_conflict; 93684d535adSPavel Emelyanov 9375263e31eSJeff Layton list_for_each_entry(fl, &ctx->flc_flock, fl_list) { 938bcd7f78dSJeff Layton if (request->fl_file != fl->fl_file) 9391da177e4SLinus Torvalds continue; 940993dfa87STrond Myklebust if (request->fl_type == fl->fl_type) 9411da177e4SLinus Torvalds goto out; 9425263e31eSJeff Layton found = true; 943e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 9441da177e4SLinus Torvalds break; 9451da177e4SLinus Torvalds } 9461da177e4SLinus Torvalds 947f475ae95STrond Myklebust if (request->fl_type == F_UNLCK) { 948f475ae95STrond Myklebust if ((request->fl_flags & FL_EXISTS) && !found) 949f475ae95STrond Myklebust error = -ENOENT; 950993dfa87STrond Myklebust goto out; 951f475ae95STrond Myklebust } 9521da177e4SLinus Torvalds 953f07f18ddSTrond Myklebust find_conflict: 9545263e31eSJeff Layton list_for_each_entry(fl, &ctx->flc_flock, fl_list) { 955993dfa87STrond Myklebust if (!flock_locks_conflict(request, fl)) 9561da177e4SLinus Torvalds continue; 9571da177e4SLinus Torvalds error = -EAGAIN; 958bde74e4bSMiklos Szeredi if (!(request->fl_flags & FL_SLEEP)) 959bde74e4bSMiklos Szeredi goto out; 960bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 961993dfa87STrond Myklebust locks_insert_block(fl, request); 9621da177e4SLinus Torvalds goto out; 9631da177e4SLinus Torvalds } 964f07f18ddSTrond Myklebust if (request->fl_flags & FL_ACCESS) 965f07f18ddSTrond Myklebust goto out; 966993dfa87STrond Myklebust locks_copy_lock(new_fl, request); 967e084c1bdSJeff Layton locks_insert_lock_ctx(new_fl, &ctx->flc_flock); 968993dfa87STrond Myklebust new_fl = NULL; 9699cedc194SKirill Korotaev error = 0; 9701da177e4SLinus Torvalds 9711da177e4SLinus Torvalds out: 9726109c850SJeff Layton spin_unlock(&ctx->flc_lock); 97387709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 974993dfa87STrond Myklebust if (new_fl) 975993dfa87STrond Myklebust locks_free_lock(new_fl); 976ed9814d8SJeff Layton locks_dispose_list(&dispose); 9771da177e4SLinus Torvalds return error; 9781da177e4SLinus Torvalds } 9791da177e4SLinus Torvalds 980b4d629a3SJeff Layton static int posix_lock_inode(struct inode *inode, struct file_lock *request, 981b4d629a3SJeff Layton struct file_lock *conflock) 9821da177e4SLinus Torvalds { 983bd61e0a9SJeff Layton struct file_lock *fl, *tmp; 98439005d02SMiklos Szeredi struct file_lock *new_fl = NULL; 98539005d02SMiklos Szeredi struct file_lock *new_fl2 = NULL; 9861da177e4SLinus Torvalds struct file_lock *left = NULL; 9871da177e4SLinus Torvalds struct file_lock *right = NULL; 988bd61e0a9SJeff Layton struct file_lock_context *ctx; 989b9746ef8SJeff Layton int error; 990b9746ef8SJeff Layton bool added = false; 991ed9814d8SJeff Layton LIST_HEAD(dispose); 9921da177e4SLinus Torvalds 9935c1c669aSJeff Layton ctx = locks_get_lock_context(inode, request->fl_type); 994bd61e0a9SJeff Layton if (!ctx) 9955c1c669aSJeff Layton return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM; 996bd61e0a9SJeff Layton 9971da177e4SLinus Torvalds /* 9981da177e4SLinus Torvalds * We may need two file_lock structures for this operation, 9991da177e4SLinus Torvalds * so we get them in advance to avoid races. 100039005d02SMiklos Szeredi * 100139005d02SMiklos Szeredi * In some cases we can be sure, that no new locks will be needed 10021da177e4SLinus Torvalds */ 100339005d02SMiklos Szeredi if (!(request->fl_flags & FL_ACCESS) && 100439005d02SMiklos Szeredi (request->fl_type != F_UNLCK || 100539005d02SMiklos Szeredi request->fl_start != 0 || request->fl_end != OFFSET_MAX)) { 10061da177e4SLinus Torvalds new_fl = locks_alloc_lock(); 10071da177e4SLinus Torvalds new_fl2 = locks_alloc_lock(); 100839005d02SMiklos Szeredi } 10091da177e4SLinus Torvalds 101087709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 10116109c850SJeff Layton spin_lock(&ctx->flc_lock); 10121cb36012SJeff Layton /* 10131cb36012SJeff Layton * New lock request. Walk all POSIX locks and look for conflicts. If 10141cb36012SJeff Layton * there are any, either return error or put the request on the 101548f74186SJeff Layton * blocker's list of waiters and the global blocked_hash. 10161cb36012SJeff Layton */ 10171da177e4SLinus Torvalds if (request->fl_type != F_UNLCK) { 1018bd61e0a9SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, fl_list) { 10191da177e4SLinus Torvalds if (!posix_locks_conflict(request, fl)) 10201da177e4SLinus Torvalds continue; 10215842add2SAndy Adamson if (conflock) 10223fe0fff1SKinglong Mee locks_copy_conflock(conflock, fl); 10231da177e4SLinus Torvalds error = -EAGAIN; 10241da177e4SLinus Torvalds if (!(request->fl_flags & FL_SLEEP)) 10251da177e4SLinus Torvalds goto out; 10261c8c601aSJeff Layton /* 10271c8c601aSJeff Layton * Deadlock detection and insertion into the blocked 10281c8c601aSJeff Layton * locks list must be done while holding the same lock! 10291c8c601aSJeff Layton */ 10301da177e4SLinus Torvalds error = -EDEADLK; 10317b2296afSJeff Layton spin_lock(&blocked_lock_lock); 10321c8c601aSJeff Layton if (likely(!posix_locks_deadlock(request, fl))) { 1033bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 10341c8c601aSJeff Layton __locks_insert_block(fl, request); 10351c8c601aSJeff Layton } 10367b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 10371da177e4SLinus Torvalds goto out; 10381da177e4SLinus Torvalds } 10391da177e4SLinus Torvalds } 10401da177e4SLinus Torvalds 10411da177e4SLinus Torvalds /* If we're just looking for a conflict, we're done. */ 10421da177e4SLinus Torvalds error = 0; 10431da177e4SLinus Torvalds if (request->fl_flags & FL_ACCESS) 10441da177e4SLinus Torvalds goto out; 10451da177e4SLinus Torvalds 1046bd61e0a9SJeff Layton /* Find the first old lock with the same owner as the new lock */ 1047bd61e0a9SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, fl_list) { 1048bd61e0a9SJeff Layton if (posix_same_owner(request, fl)) 1049bd61e0a9SJeff Layton break; 10501da177e4SLinus Torvalds } 10511da177e4SLinus Torvalds 10521da177e4SLinus Torvalds /* Process locks with this owner. */ 1053bd61e0a9SJeff Layton list_for_each_entry_safe_from(fl, tmp, &ctx->flc_posix, fl_list) { 1054bd61e0a9SJeff Layton if (!posix_same_owner(request, fl)) 1055bd61e0a9SJeff Layton break; 1056bd61e0a9SJeff Layton 1057bd61e0a9SJeff Layton /* Detect adjacent or overlapping regions (if same lock type) */ 10581da177e4SLinus Torvalds if (request->fl_type == fl->fl_type) { 1059449231d6SOlaf Kirch /* In all comparisons of start vs end, use 1060449231d6SOlaf Kirch * "start - 1" rather than "end + 1". If end 1061449231d6SOlaf Kirch * is OFFSET_MAX, end + 1 will become negative. 1062449231d6SOlaf Kirch */ 10631da177e4SLinus Torvalds if (fl->fl_end < request->fl_start - 1) 1064bd61e0a9SJeff Layton continue; 10651da177e4SLinus Torvalds /* If the next lock in the list has entirely bigger 10661da177e4SLinus Torvalds * addresses than the new one, insert the lock here. 10671da177e4SLinus Torvalds */ 1068449231d6SOlaf Kirch if (fl->fl_start - 1 > request->fl_end) 10691da177e4SLinus Torvalds break; 10701da177e4SLinus Torvalds 10711da177e4SLinus Torvalds /* If we come here, the new and old lock are of the 10721da177e4SLinus Torvalds * same type and adjacent or overlapping. Make one 10731da177e4SLinus Torvalds * lock yielding from the lower start address of both 10741da177e4SLinus Torvalds * locks to the higher end address. 10751da177e4SLinus Torvalds */ 10761da177e4SLinus Torvalds if (fl->fl_start > request->fl_start) 10771da177e4SLinus Torvalds fl->fl_start = request->fl_start; 10781da177e4SLinus Torvalds else 10791da177e4SLinus Torvalds request->fl_start = fl->fl_start; 10801da177e4SLinus Torvalds if (fl->fl_end < request->fl_end) 10811da177e4SLinus Torvalds fl->fl_end = request->fl_end; 10821da177e4SLinus Torvalds else 10831da177e4SLinus Torvalds request->fl_end = fl->fl_end; 10841da177e4SLinus Torvalds if (added) { 1085e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 10861da177e4SLinus Torvalds continue; 10871da177e4SLinus Torvalds } 10881da177e4SLinus Torvalds request = fl; 1089b9746ef8SJeff Layton added = true; 1090bd61e0a9SJeff Layton } else { 10911da177e4SLinus Torvalds /* Processing for different lock types is a bit 10921da177e4SLinus Torvalds * more complex. 10931da177e4SLinus Torvalds */ 10941da177e4SLinus Torvalds if (fl->fl_end < request->fl_start) 1095bd61e0a9SJeff Layton continue; 10961da177e4SLinus Torvalds if (fl->fl_start > request->fl_end) 10971da177e4SLinus Torvalds break; 10981da177e4SLinus Torvalds if (request->fl_type == F_UNLCK) 1099b9746ef8SJeff Layton added = true; 11001da177e4SLinus Torvalds if (fl->fl_start < request->fl_start) 11011da177e4SLinus Torvalds left = fl; 11021da177e4SLinus Torvalds /* If the next lock in the list has a higher end 11031da177e4SLinus Torvalds * address than the new one, insert the new one here. 11041da177e4SLinus Torvalds */ 11051da177e4SLinus Torvalds if (fl->fl_end > request->fl_end) { 11061da177e4SLinus Torvalds right = fl; 11071da177e4SLinus Torvalds break; 11081da177e4SLinus Torvalds } 11091da177e4SLinus Torvalds if (fl->fl_start >= request->fl_start) { 11101da177e4SLinus Torvalds /* The new lock completely replaces an old 11111da177e4SLinus Torvalds * one (This may happen several times). 11121da177e4SLinus Torvalds */ 11131da177e4SLinus Torvalds if (added) { 1114e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 11151da177e4SLinus Torvalds continue; 11161da177e4SLinus Torvalds } 1117b84d49f9SJeff Layton /* 1118b84d49f9SJeff Layton * Replace the old lock with new_fl, and 1119b84d49f9SJeff Layton * remove the old one. It's safe to do the 1120b84d49f9SJeff Layton * insert here since we know that we won't be 1121b84d49f9SJeff Layton * using new_fl later, and that the lock is 1122b84d49f9SJeff Layton * just replacing an existing lock. 11231da177e4SLinus Torvalds */ 1124b84d49f9SJeff Layton error = -ENOLCK; 1125b84d49f9SJeff Layton if (!new_fl) 1126b84d49f9SJeff Layton goto out; 1127b84d49f9SJeff Layton locks_copy_lock(new_fl, request); 1128b84d49f9SJeff Layton request = new_fl; 1129b84d49f9SJeff Layton new_fl = NULL; 1130e084c1bdSJeff Layton locks_insert_lock_ctx(request, &fl->fl_list); 1131e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 1132b9746ef8SJeff Layton added = true; 11331da177e4SLinus Torvalds } 11341da177e4SLinus Torvalds } 11351da177e4SLinus Torvalds } 11361da177e4SLinus Torvalds 11370d9a490aSMiklos Szeredi /* 11381cb36012SJeff Layton * The above code only modifies existing locks in case of merging or 11391cb36012SJeff Layton * replacing. If new lock(s) need to be inserted all modifications are 11401cb36012SJeff Layton * done below this, so it's safe yet to bail out. 11410d9a490aSMiklos Szeredi */ 11420d9a490aSMiklos Szeredi error = -ENOLCK; /* "no luck" */ 11430d9a490aSMiklos Szeredi if (right && left == right && !new_fl2) 11440d9a490aSMiklos Szeredi goto out; 11450d9a490aSMiklos Szeredi 11461da177e4SLinus Torvalds error = 0; 11471da177e4SLinus Torvalds if (!added) { 1148f475ae95STrond Myklebust if (request->fl_type == F_UNLCK) { 1149f475ae95STrond Myklebust if (request->fl_flags & FL_EXISTS) 1150f475ae95STrond Myklebust error = -ENOENT; 11511da177e4SLinus Torvalds goto out; 1152f475ae95STrond Myklebust } 11530d9a490aSMiklos Szeredi 11540d9a490aSMiklos Szeredi if (!new_fl) { 11550d9a490aSMiklos Szeredi error = -ENOLCK; 11560d9a490aSMiklos Szeredi goto out; 11570d9a490aSMiklos Szeredi } 11581da177e4SLinus Torvalds locks_copy_lock(new_fl, request); 1159e084c1bdSJeff Layton locks_insert_lock_ctx(new_fl, &fl->fl_list); 11602e2f756fSJeff Layton fl = new_fl; 11611da177e4SLinus Torvalds new_fl = NULL; 11621da177e4SLinus Torvalds } 11631da177e4SLinus Torvalds if (right) { 11641da177e4SLinus Torvalds if (left == right) { 11651da177e4SLinus Torvalds /* The new lock breaks the old one in two pieces, 11661da177e4SLinus Torvalds * so we have to use the second new lock. 11671da177e4SLinus Torvalds */ 11681da177e4SLinus Torvalds left = new_fl2; 11691da177e4SLinus Torvalds new_fl2 = NULL; 11701da177e4SLinus Torvalds locks_copy_lock(left, right); 1171e084c1bdSJeff Layton locks_insert_lock_ctx(left, &fl->fl_list); 11721da177e4SLinus Torvalds } 11731da177e4SLinus Torvalds right->fl_start = request->fl_end + 1; 11741da177e4SLinus Torvalds locks_wake_up_blocks(right); 11751da177e4SLinus Torvalds } 11761da177e4SLinus Torvalds if (left) { 11771da177e4SLinus Torvalds left->fl_end = request->fl_start - 1; 11781da177e4SLinus Torvalds locks_wake_up_blocks(left); 11791da177e4SLinus Torvalds } 11801da177e4SLinus Torvalds out: 11816109c850SJeff Layton spin_unlock(&ctx->flc_lock); 118287709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 11831da177e4SLinus Torvalds /* 11841da177e4SLinus Torvalds * Free any unused locks. 11851da177e4SLinus Torvalds */ 11861da177e4SLinus Torvalds if (new_fl) 11871da177e4SLinus Torvalds locks_free_lock(new_fl); 11881da177e4SLinus Torvalds if (new_fl2) 11891da177e4SLinus Torvalds locks_free_lock(new_fl2); 1190ed9814d8SJeff Layton locks_dispose_list(&dispose); 11911890910fSJeff Layton trace_posix_lock_inode(inode, request, error); 11921890910fSJeff Layton 11931da177e4SLinus Torvalds return error; 11941da177e4SLinus Torvalds } 11951da177e4SLinus Torvalds 11961da177e4SLinus Torvalds /** 11971da177e4SLinus Torvalds * posix_lock_file - Apply a POSIX-style lock to a file 11981da177e4SLinus Torvalds * @filp: The file to apply the lock to 11991da177e4SLinus Torvalds * @fl: The lock to be applied 1200150b3934SMarc Eshel * @conflock: Place to return a copy of the conflicting lock, if found. 12011da177e4SLinus Torvalds * 12021da177e4SLinus Torvalds * Add a POSIX style lock to a file. 12031da177e4SLinus Torvalds * We merge adjacent & overlapping locks whenever possible. 12041da177e4SLinus Torvalds * POSIX locks are sorted by owner task, then by starting address 1205f475ae95STrond Myklebust * 1206f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 1207f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 1208f475ae95STrond Myklebust * value for -ENOENT. 12091da177e4SLinus Torvalds */ 1210150b3934SMarc Eshel int posix_lock_file(struct file *filp, struct file_lock *fl, 12115842add2SAndy Adamson struct file_lock *conflock) 12125842add2SAndy Adamson { 1213c568d683SMiklos Szeredi return posix_lock_inode(locks_inode(filp), fl, conflock); 12145842add2SAndy Adamson } 1215150b3934SMarc Eshel EXPORT_SYMBOL(posix_lock_file); 12161da177e4SLinus Torvalds 12171da177e4SLinus Torvalds /** 121829d01b22SJeff Layton * posix_lock_inode_wait - Apply a POSIX-style lock to a file 121929d01b22SJeff Layton * @inode: inode of file to which lock request should be applied 12201da177e4SLinus Torvalds * @fl: The lock to be applied 12211da177e4SLinus Torvalds * 1222616fb38fSBenjamin Coddington * Apply a POSIX style lock request to an inode. 12231da177e4SLinus Torvalds */ 1224616fb38fSBenjamin Coddington static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) 12251da177e4SLinus Torvalds { 12261da177e4SLinus Torvalds int error; 12271da177e4SLinus Torvalds might_sleep (); 12281da177e4SLinus Torvalds for (;;) { 1229b4d629a3SJeff Layton error = posix_lock_inode(inode, fl, NULL); 1230bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 12311da177e4SLinus Torvalds break; 12321da177e4SLinus Torvalds error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); 12331da177e4SLinus Torvalds if (!error) 12341da177e4SLinus Torvalds continue; 12351da177e4SLinus Torvalds 12361da177e4SLinus Torvalds locks_delete_block(fl); 12371da177e4SLinus Torvalds break; 12381da177e4SLinus Torvalds } 12391da177e4SLinus Torvalds return error; 12401da177e4SLinus Torvalds } 124129d01b22SJeff Layton 12429e8925b6SJeff Layton #ifdef CONFIG_MANDATORY_FILE_LOCKING 124329d01b22SJeff Layton /** 12441da177e4SLinus Torvalds * locks_mandatory_locked - Check for an active lock 1245d7a06983SJeff Layton * @file: the file to check 12461da177e4SLinus Torvalds * 12471da177e4SLinus Torvalds * Searches the inode's list of locks to find any POSIX locks which conflict. 12481da177e4SLinus Torvalds * This function is called from locks_verify_locked() only. 12491da177e4SLinus Torvalds */ 1250d7a06983SJeff Layton int locks_mandatory_locked(struct file *file) 12511da177e4SLinus Torvalds { 1252bd61e0a9SJeff Layton int ret; 1253c568d683SMiklos Szeredi struct inode *inode = locks_inode(file); 1254bd61e0a9SJeff Layton struct file_lock_context *ctx; 12551da177e4SLinus Torvalds struct file_lock *fl; 12561da177e4SLinus Torvalds 1257128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 1258bd61e0a9SJeff Layton if (!ctx || list_empty_careful(&ctx->flc_posix)) 1259bd61e0a9SJeff Layton return 0; 1260bd61e0a9SJeff Layton 12611da177e4SLinus Torvalds /* 12621da177e4SLinus Torvalds * Search the lock list for this inode for any POSIX locks. 12631da177e4SLinus Torvalds */ 12646109c850SJeff Layton spin_lock(&ctx->flc_lock); 1265bd61e0a9SJeff Layton ret = 0; 1266bd61e0a9SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, fl_list) { 126773a8f5f7SChristoph Hellwig if (fl->fl_owner != current->files && 1268bd61e0a9SJeff Layton fl->fl_owner != file) { 1269bd61e0a9SJeff Layton ret = -EAGAIN; 12701da177e4SLinus Torvalds break; 12711da177e4SLinus Torvalds } 1272bd61e0a9SJeff Layton } 12736109c850SJeff Layton spin_unlock(&ctx->flc_lock); 1274bd61e0a9SJeff Layton return ret; 12751da177e4SLinus Torvalds } 12761da177e4SLinus Torvalds 12771da177e4SLinus Torvalds /** 12781da177e4SLinus Torvalds * locks_mandatory_area - Check for a conflicting lock 12791da177e4SLinus Torvalds * @inode: the file to check 12801da177e4SLinus Torvalds * @filp: how the file was opened (if it was) 1281acc15575SChristoph Hellwig * @start: first byte in the file to check 1282acc15575SChristoph Hellwig * @end: lastbyte in the file to check 1283acc15575SChristoph Hellwig * @type: %F_WRLCK for a write lock, else %F_RDLCK 12841da177e4SLinus Torvalds * 12851da177e4SLinus Torvalds * Searches the inode's list of locks to find any POSIX locks which conflict. 12861da177e4SLinus Torvalds */ 1287acc15575SChristoph Hellwig int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start, 1288acc15575SChristoph Hellwig loff_t end, unsigned char type) 12891da177e4SLinus Torvalds { 12901da177e4SLinus Torvalds struct file_lock fl; 12911da177e4SLinus Torvalds int error; 129229723adeSJeff Layton bool sleep = false; 12931da177e4SLinus Torvalds 12941da177e4SLinus Torvalds locks_init_lock(&fl); 12951da177e4SLinus Torvalds fl.fl_pid = current->tgid; 12961da177e4SLinus Torvalds fl.fl_file = filp; 12971da177e4SLinus Torvalds fl.fl_flags = FL_POSIX | FL_ACCESS; 12981da177e4SLinus Torvalds if (filp && !(filp->f_flags & O_NONBLOCK)) 129929723adeSJeff Layton sleep = true; 1300acc15575SChristoph Hellwig fl.fl_type = type; 1301acc15575SChristoph Hellwig fl.fl_start = start; 1302acc15575SChristoph Hellwig fl.fl_end = end; 13031da177e4SLinus Torvalds 13041da177e4SLinus Torvalds for (;;) { 130529723adeSJeff Layton if (filp) { 130673a8f5f7SChristoph Hellwig fl.fl_owner = filp; 130729723adeSJeff Layton fl.fl_flags &= ~FL_SLEEP; 1308b4d629a3SJeff Layton error = posix_lock_inode(inode, &fl, NULL); 130929723adeSJeff Layton if (!error) 131029723adeSJeff Layton break; 131129723adeSJeff Layton } 131229723adeSJeff Layton 131329723adeSJeff Layton if (sleep) 131429723adeSJeff Layton fl.fl_flags |= FL_SLEEP; 131529723adeSJeff Layton fl.fl_owner = current->files; 1316b4d629a3SJeff Layton error = posix_lock_inode(inode, &fl, NULL); 1317bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 13181da177e4SLinus Torvalds break; 13191da177e4SLinus Torvalds error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); 13201da177e4SLinus Torvalds if (!error) { 13211da177e4SLinus Torvalds /* 13221da177e4SLinus Torvalds * If we've been sleeping someone might have 13231da177e4SLinus Torvalds * changed the permissions behind our back. 13241da177e4SLinus Torvalds */ 1325a16877caSPavel Emelyanov if (__mandatory_lock(inode)) 13261da177e4SLinus Torvalds continue; 13271da177e4SLinus Torvalds } 13281da177e4SLinus Torvalds 13291da177e4SLinus Torvalds locks_delete_block(&fl); 13301da177e4SLinus Torvalds break; 13311da177e4SLinus Torvalds } 13321da177e4SLinus Torvalds 13331da177e4SLinus Torvalds return error; 13341da177e4SLinus Torvalds } 13351da177e4SLinus Torvalds 13361da177e4SLinus Torvalds EXPORT_SYMBOL(locks_mandatory_area); 13379e8925b6SJeff Layton #endif /* CONFIG_MANDATORY_FILE_LOCKING */ 13381da177e4SLinus Torvalds 1339778fc546SJ. Bruce Fields static void lease_clear_pending(struct file_lock *fl, int arg) 1340778fc546SJ. Bruce Fields { 1341778fc546SJ. Bruce Fields switch (arg) { 1342778fc546SJ. Bruce Fields case F_UNLCK: 1343778fc546SJ. Bruce Fields fl->fl_flags &= ~FL_UNLOCK_PENDING; 1344778fc546SJ. Bruce Fields /* fall through: */ 1345778fc546SJ. Bruce Fields case F_RDLCK: 1346778fc546SJ. Bruce Fields fl->fl_flags &= ~FL_DOWNGRADE_PENDING; 1347778fc546SJ. Bruce Fields } 1348778fc546SJ. Bruce Fields } 1349778fc546SJ. Bruce Fields 13501da177e4SLinus Torvalds /* We already had a lease on this file; just change its type */ 13517448cc37SJeff Layton int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) 13521da177e4SLinus Torvalds { 13531da177e4SLinus Torvalds int error = assign_type(fl, arg); 13541da177e4SLinus Torvalds 13551da177e4SLinus Torvalds if (error) 13561da177e4SLinus Torvalds return error; 1357778fc546SJ. Bruce Fields lease_clear_pending(fl, arg); 13581da177e4SLinus Torvalds locks_wake_up_blocks(fl); 13593b6e2723SFilipe Brandenburger if (arg == F_UNLCK) { 13603b6e2723SFilipe Brandenburger struct file *filp = fl->fl_file; 13613b6e2723SFilipe Brandenburger 13623b6e2723SFilipe Brandenburger f_delown(filp); 13633b6e2723SFilipe Brandenburger filp->f_owner.signum = 0; 136496d6d59cSJ. Bruce Fields fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync); 136596d6d59cSJ. Bruce Fields if (fl->fl_fasync != NULL) { 136696d6d59cSJ. Bruce Fields printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); 136796d6d59cSJ. Bruce Fields fl->fl_fasync = NULL; 136896d6d59cSJ. Bruce Fields } 1369e084c1bdSJeff Layton locks_delete_lock_ctx(fl, dispose); 13703b6e2723SFilipe Brandenburger } 13711da177e4SLinus Torvalds return 0; 13721da177e4SLinus Torvalds } 13731da177e4SLinus Torvalds EXPORT_SYMBOL(lease_modify); 13741da177e4SLinus Torvalds 1375778fc546SJ. Bruce Fields static bool past_time(unsigned long then) 1376778fc546SJ. Bruce Fields { 1377778fc546SJ. Bruce Fields if (!then) 1378778fc546SJ. Bruce Fields /* 0 is a special value meaning "this never expires": */ 1379778fc546SJ. Bruce Fields return false; 1380778fc546SJ. Bruce Fields return time_after(jiffies, then); 1381778fc546SJ. Bruce Fields } 1382778fc546SJ. Bruce Fields 1383c45198edSJeff Layton static void time_out_leases(struct inode *inode, struct list_head *dispose) 13841da177e4SLinus Torvalds { 13858634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 13868634b51fSJeff Layton struct file_lock *fl, *tmp; 13871da177e4SLinus Torvalds 13886109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 1389f82b4b67SJeff Layton 13908634b51fSJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) { 139162af4f1fSJeff Layton trace_time_out_leases(inode, fl); 1392778fc546SJ. Bruce Fields if (past_time(fl->fl_downgrade_time)) 13937448cc37SJeff Layton lease_modify(fl, F_RDLCK, dispose); 1394778fc546SJ. Bruce Fields if (past_time(fl->fl_break_time)) 13957448cc37SJeff Layton lease_modify(fl, F_UNLCK, dispose); 13961da177e4SLinus Torvalds } 13971da177e4SLinus Torvalds } 13981da177e4SLinus Torvalds 1399df4e8d2cSJ. Bruce Fields static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker) 1400df4e8d2cSJ. Bruce Fields { 140111afe9f7SChristoph Hellwig if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT)) 140211afe9f7SChristoph Hellwig return false; 1403df4e8d2cSJ. Bruce Fields if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE)) 1404df4e8d2cSJ. Bruce Fields return false; 1405df4e8d2cSJ. Bruce Fields return locks_conflict(breaker, lease); 1406df4e8d2cSJ. Bruce Fields } 1407df4e8d2cSJ. Bruce Fields 140803d12ddfSJeff Layton static bool 140903d12ddfSJeff Layton any_leases_conflict(struct inode *inode, struct file_lock *breaker) 141003d12ddfSJeff Layton { 14118634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 141203d12ddfSJeff Layton struct file_lock *fl; 141303d12ddfSJeff Layton 14146109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 141503d12ddfSJeff Layton 14168634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 141703d12ddfSJeff Layton if (leases_conflict(fl, breaker)) 141803d12ddfSJeff Layton return true; 141903d12ddfSJeff Layton } 142003d12ddfSJeff Layton return false; 142103d12ddfSJeff Layton } 142203d12ddfSJeff Layton 14231da177e4SLinus Torvalds /** 14241da177e4SLinus Torvalds * __break_lease - revoke all outstanding leases on file 14251da177e4SLinus Torvalds * @inode: the inode of the file to return 1426df4e8d2cSJ. Bruce Fields * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR: 1427df4e8d2cSJ. Bruce Fields * break all leases 1428df4e8d2cSJ. Bruce Fields * @type: FL_LEASE: break leases and delegations; FL_DELEG: break 1429df4e8d2cSJ. Bruce Fields * only delegations 14301da177e4SLinus Torvalds * 143187250dd2Sdavid m. richter * break_lease (inlined for speed) has checked there already is at least 143287250dd2Sdavid m. richter * some kind of lock (maybe a lease) on this file. Leases are broken on 143387250dd2Sdavid m. richter * a call to open() or truncate(). This function can sleep unless you 14341da177e4SLinus Torvalds * specified %O_NONBLOCK to your open(). 14351da177e4SLinus Torvalds */ 1436df4e8d2cSJ. Bruce Fields int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) 14371da177e4SLinus Torvalds { 1438778fc546SJ. Bruce Fields int error = 0; 1439128a3785SDmitry Vyukov struct file_lock_context *ctx; 1440a901125cSYan, Zheng struct file_lock *new_fl, *fl, *tmp; 14411da177e4SLinus Torvalds unsigned long break_time; 14428737c930SAl Viro int want_write = (mode & O_ACCMODE) != O_RDONLY; 1443c45198edSJeff Layton LIST_HEAD(dispose); 14441da177e4SLinus Torvalds 14458737c930SAl Viro new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); 14466d4b9e38SLinus Torvalds if (IS_ERR(new_fl)) 14476d4b9e38SLinus Torvalds return PTR_ERR(new_fl); 1448df4e8d2cSJ. Bruce Fields new_fl->fl_flags = type; 14491da177e4SLinus Torvalds 14508634b51fSJeff Layton /* typically we will check that ctx is non-NULL before calling */ 1451128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 14528634b51fSJeff Layton if (!ctx) { 14538634b51fSJeff Layton WARN_ON_ONCE(1); 14548634b51fSJeff Layton return error; 14558634b51fSJeff Layton } 14568634b51fSJeff Layton 145787709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 14586109c850SJeff Layton spin_lock(&ctx->flc_lock); 14591da177e4SLinus Torvalds 1460c45198edSJeff Layton time_out_leases(inode, &dispose); 14611da177e4SLinus Torvalds 146203d12ddfSJeff Layton if (!any_leases_conflict(inode, new_fl)) 1463df4e8d2cSJ. Bruce Fields goto out; 14641da177e4SLinus Torvalds 14651da177e4SLinus Torvalds break_time = 0; 14661da177e4SLinus Torvalds if (lease_break_time > 0) { 14671da177e4SLinus Torvalds break_time = jiffies + lease_break_time * HZ; 14681da177e4SLinus Torvalds if (break_time == 0) 14691da177e4SLinus Torvalds break_time++; /* so that 0 means no break time */ 14701da177e4SLinus Torvalds } 14711da177e4SLinus Torvalds 1472a901125cSYan, Zheng list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) { 1473df4e8d2cSJ. Bruce Fields if (!leases_conflict(fl, new_fl)) 1474df4e8d2cSJ. Bruce Fields continue; 1475778fc546SJ. Bruce Fields if (want_write) { 1476778fc546SJ. Bruce Fields if (fl->fl_flags & FL_UNLOCK_PENDING) 1477778fc546SJ. Bruce Fields continue; 1478778fc546SJ. Bruce Fields fl->fl_flags |= FL_UNLOCK_PENDING; 14791da177e4SLinus Torvalds fl->fl_break_time = break_time; 1480778fc546SJ. Bruce Fields } else { 14818634b51fSJeff Layton if (lease_breaking(fl)) 1482778fc546SJ. Bruce Fields continue; 1483778fc546SJ. Bruce Fields fl->fl_flags |= FL_DOWNGRADE_PENDING; 1484778fc546SJ. Bruce Fields fl->fl_downgrade_time = break_time; 14851da177e4SLinus Torvalds } 14864d01b7f5SJeff Layton if (fl->fl_lmops->lm_break(fl)) 1487e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 14881da177e4SLinus Torvalds } 14891da177e4SLinus Torvalds 14908634b51fSJeff Layton if (list_empty(&ctx->flc_lease)) 14914d01b7f5SJeff Layton goto out; 14924d01b7f5SJeff Layton 1493843c6b2fSJeff Layton if (mode & O_NONBLOCK) { 149462af4f1fSJeff Layton trace_break_lease_noblock(inode, new_fl); 14951da177e4SLinus Torvalds error = -EWOULDBLOCK; 14961da177e4SLinus Torvalds goto out; 14971da177e4SLinus Torvalds } 14981da177e4SLinus Torvalds 14991da177e4SLinus Torvalds restart: 15008634b51fSJeff Layton fl = list_first_entry(&ctx->flc_lease, struct file_lock, fl_list); 15018634b51fSJeff Layton break_time = fl->fl_break_time; 1502f1c6bb2cSJeff Layton if (break_time != 0) 15031da177e4SLinus Torvalds break_time -= jiffies; 15041da177e4SLinus Torvalds if (break_time == 0) 15051da177e4SLinus Torvalds break_time++; 15068634b51fSJeff Layton locks_insert_block(fl, new_fl); 150762af4f1fSJeff Layton trace_break_lease_block(inode, new_fl); 15086109c850SJeff Layton spin_unlock(&ctx->flc_lock); 150987709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1510aba37660SPeter Zijlstra 1511c45198edSJeff Layton locks_dispose_list(&dispose); 15124321e01eSMatthew Wilcox error = wait_event_interruptible_timeout(new_fl->fl_wait, 15134321e01eSMatthew Wilcox !new_fl->fl_next, break_time); 1514aba37660SPeter Zijlstra 151587709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 15166109c850SJeff Layton spin_lock(&ctx->flc_lock); 151762af4f1fSJeff Layton trace_break_lease_unblock(inode, new_fl); 15181c8c601aSJeff Layton locks_delete_block(new_fl); 15191da177e4SLinus Torvalds if (error >= 0) { 1520778fc546SJ. Bruce Fields /* 1521778fc546SJ. Bruce Fields * Wait for the next conflicting lease that has not been 1522778fc546SJ. Bruce Fields * broken yet 1523778fc546SJ. Bruce Fields */ 152403d12ddfSJeff Layton if (error == 0) 152503d12ddfSJeff Layton time_out_leases(inode, &dispose); 152603d12ddfSJeff Layton if (any_leases_conflict(inode, new_fl)) 15271da177e4SLinus Torvalds goto restart; 15281da177e4SLinus Torvalds error = 0; 15291da177e4SLinus Torvalds } 15301da177e4SLinus Torvalds out: 15316109c850SJeff Layton spin_unlock(&ctx->flc_lock); 153287709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1533c45198edSJeff Layton locks_dispose_list(&dispose); 15341da177e4SLinus Torvalds locks_free_lock(new_fl); 15351da177e4SLinus Torvalds return error; 15361da177e4SLinus Torvalds } 15371da177e4SLinus Torvalds 15381da177e4SLinus Torvalds EXPORT_SYMBOL(__break_lease); 15391da177e4SLinus Torvalds 15401da177e4SLinus Torvalds /** 1541a6b91919SRandy Dunlap * lease_get_mtime - get the last modified time of an inode 15421da177e4SLinus Torvalds * @inode: the inode 15431da177e4SLinus Torvalds * @time: pointer to a timespec which will contain the last modified time 15441da177e4SLinus Torvalds * 15451da177e4SLinus Torvalds * This is to force NFS clients to flush their caches for files with 15461da177e4SLinus Torvalds * exclusive leases. The justification is that if someone has an 1547a6b91919SRandy Dunlap * exclusive lease, then they could be modifying it. 15481da177e4SLinus Torvalds */ 15491da177e4SLinus Torvalds void lease_get_mtime(struct inode *inode, struct timespec *time) 15501da177e4SLinus Torvalds { 1551bfe86024SJeff Layton bool has_lease = false; 1552128a3785SDmitry Vyukov struct file_lock_context *ctx; 15538634b51fSJeff Layton struct file_lock *fl; 1554bfe86024SJeff Layton 1555128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 15568634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 15576109c850SJeff Layton spin_lock(&ctx->flc_lock); 15588ace5dfbSGeliang Tang fl = list_first_entry_or_null(&ctx->flc_lease, 15598634b51fSJeff Layton struct file_lock, fl_list); 15608ace5dfbSGeliang Tang if (fl && (fl->fl_type == F_WRLCK)) 1561bfe86024SJeff Layton has_lease = true; 15626109c850SJeff Layton spin_unlock(&ctx->flc_lock); 1563bfe86024SJeff Layton } 1564bfe86024SJeff Layton 1565bfe86024SJeff Layton if (has_lease) 1566c2050a45SDeepa Dinamani *time = current_time(inode); 15671da177e4SLinus Torvalds else 15681da177e4SLinus Torvalds *time = inode->i_mtime; 15691da177e4SLinus Torvalds } 15701da177e4SLinus Torvalds 15711da177e4SLinus Torvalds EXPORT_SYMBOL(lease_get_mtime); 15721da177e4SLinus Torvalds 15731da177e4SLinus Torvalds /** 15741da177e4SLinus Torvalds * fcntl_getlease - Enquire what lease is currently active 15751da177e4SLinus Torvalds * @filp: the file 15761da177e4SLinus Torvalds * 15771da177e4SLinus Torvalds * The value returned by this function will be one of 15781da177e4SLinus Torvalds * (if no lease break is pending): 15791da177e4SLinus Torvalds * 15801da177e4SLinus Torvalds * %F_RDLCK to indicate a shared lease is held. 15811da177e4SLinus Torvalds * 15821da177e4SLinus Torvalds * %F_WRLCK to indicate an exclusive lease is held. 15831da177e4SLinus Torvalds * 15841da177e4SLinus Torvalds * %F_UNLCK to indicate no lease is held. 15851da177e4SLinus Torvalds * 15861da177e4SLinus Torvalds * (if a lease break is pending): 15871da177e4SLinus Torvalds * 15881da177e4SLinus Torvalds * %F_RDLCK to indicate an exclusive lease needs to be 15891da177e4SLinus Torvalds * changed to a shared lease (or removed). 15901da177e4SLinus Torvalds * 15911da177e4SLinus Torvalds * %F_UNLCK to indicate the lease needs to be removed. 15921da177e4SLinus Torvalds * 15931da177e4SLinus Torvalds * XXX: sfr & willy disagree over whether F_INPROGRESS 15941da177e4SLinus Torvalds * should be returned to userspace. 15951da177e4SLinus Torvalds */ 15961da177e4SLinus Torvalds int fcntl_getlease(struct file *filp) 15971da177e4SLinus Torvalds { 15981da177e4SLinus Torvalds struct file_lock *fl; 1599c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 1600128a3785SDmitry Vyukov struct file_lock_context *ctx; 16011da177e4SLinus Torvalds int type = F_UNLCK; 1602c45198edSJeff Layton LIST_HEAD(dispose); 16031da177e4SLinus Torvalds 1604128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 16058634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 16065f43086bSPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 16076109c850SJeff Layton spin_lock(&ctx->flc_lock); 1608c568d683SMiklos Szeredi time_out_leases(inode, &dispose); 16098634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 16108634b51fSJeff Layton if (fl->fl_file != filp) 16118634b51fSJeff Layton continue; 1612778fc546SJ. Bruce Fields type = target_leasetype(fl); 16131da177e4SLinus Torvalds break; 16141da177e4SLinus Torvalds } 16156109c850SJeff Layton spin_unlock(&ctx->flc_lock); 16165f43086bSPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 16175f43086bSPeter Zijlstra 1618c45198edSJeff Layton locks_dispose_list(&dispose); 16198634b51fSJeff Layton } 16201da177e4SLinus Torvalds return type; 16211da177e4SLinus Torvalds } 16221da177e4SLinus Torvalds 162324cbe784SJeff Layton /** 162424cbe784SJeff Layton * check_conflicting_open - see if the given dentry points to a file that has 162524cbe784SJeff Layton * an existing open that would conflict with the 162624cbe784SJeff Layton * desired lease. 162724cbe784SJeff Layton * @dentry: dentry to check 162824cbe784SJeff Layton * @arg: type of lease that we're trying to acquire 16297fadc59cSRandy Dunlap * @flags: current lock flags 163024cbe784SJeff Layton * 163124cbe784SJeff Layton * Check to see if there's an existing open fd on this file that would 163224cbe784SJeff Layton * conflict with the lease we're trying to set. 163324cbe784SJeff Layton */ 163424cbe784SJeff Layton static int 163511afe9f7SChristoph Hellwig check_conflicting_open(const struct dentry *dentry, const long arg, int flags) 163624cbe784SJeff Layton { 163724cbe784SJeff Layton int ret = 0; 163824cbe784SJeff Layton struct inode *inode = dentry->d_inode; 163924cbe784SJeff Layton 164011afe9f7SChristoph Hellwig if (flags & FL_LAYOUT) 164111afe9f7SChristoph Hellwig return 0; 164211afe9f7SChristoph Hellwig 16434d0c5ba2SMiklos Szeredi if ((arg == F_RDLCK) && 16444d0c5ba2SMiklos Szeredi (atomic_read(&d_real_inode(dentry)->i_writecount) > 0)) 164524cbe784SJeff Layton return -EAGAIN; 164624cbe784SJeff Layton 164724cbe784SJeff Layton if ((arg == F_WRLCK) && ((d_count(dentry) > 1) || 164824cbe784SJeff Layton (atomic_read(&inode->i_count) > 1))) 164924cbe784SJeff Layton ret = -EAGAIN; 165024cbe784SJeff Layton 165124cbe784SJeff Layton return ret; 165224cbe784SJeff Layton } 165324cbe784SJeff Layton 1654e6f5c789SJeff Layton static int 1655e6f5c789SJeff Layton generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **priv) 16561da177e4SLinus Torvalds { 16578634b51fSJeff Layton struct file_lock *fl, *my_fl = NULL, *lease; 16580f7fc9e4SJosef "Jeff" Sipek struct dentry *dentry = filp->f_path.dentry; 1659c568d683SMiklos Szeredi struct inode *inode = dentry->d_inode; 16608634b51fSJeff Layton struct file_lock_context *ctx; 1661df4e8d2cSJ. Bruce Fields bool is_deleg = (*flp)->fl_flags & FL_DELEG; 1662c1f24ef4SJ. Bruce Fields int error; 1663c45198edSJeff Layton LIST_HEAD(dispose); 16641da177e4SLinus Torvalds 1665096657b6SJ. Bruce Fields lease = *flp; 166662af4f1fSJeff Layton trace_generic_add_lease(inode, lease); 166762af4f1fSJeff Layton 16685c1c669aSJeff Layton /* Note that arg is never F_UNLCK here */ 16695c1c669aSJeff Layton ctx = locks_get_lock_context(inode, arg); 16708634b51fSJeff Layton if (!ctx) 16718634b51fSJeff Layton return -ENOMEM; 16728634b51fSJeff Layton 1673df4e8d2cSJ. Bruce Fields /* 1674df4e8d2cSJ. Bruce Fields * In the delegation case we need mutual exclusion with 1675df4e8d2cSJ. Bruce Fields * a number of operations that take the i_mutex. We trylock 1676df4e8d2cSJ. Bruce Fields * because delegations are an optional optimization, and if 1677df4e8d2cSJ. Bruce Fields * there's some chance of a conflict--we'd rather not 1678df4e8d2cSJ. Bruce Fields * bother, maybe that's a sign this just isn't a good file to 1679df4e8d2cSJ. Bruce Fields * hand out a delegation on. 1680df4e8d2cSJ. Bruce Fields */ 16815955102cSAl Viro if (is_deleg && !inode_trylock(inode)) 1682df4e8d2cSJ. Bruce Fields return -EAGAIN; 1683df4e8d2cSJ. Bruce Fields 1684df4e8d2cSJ. Bruce Fields if (is_deleg && arg == F_WRLCK) { 1685df4e8d2cSJ. Bruce Fields /* Write delegations are not currently supported: */ 16865955102cSAl Viro inode_unlock(inode); 1687df4e8d2cSJ. Bruce Fields WARN_ON_ONCE(1); 1688df4e8d2cSJ. Bruce Fields return -EINVAL; 1689df4e8d2cSJ. Bruce Fields } 1690096657b6SJ. Bruce Fields 169187709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 16926109c850SJeff Layton spin_lock(&ctx->flc_lock); 1693c45198edSJeff Layton time_out_leases(inode, &dispose); 169411afe9f7SChristoph Hellwig error = check_conflicting_open(dentry, arg, lease->fl_flags); 169524cbe784SJeff Layton if (error) 16961da177e4SLinus Torvalds goto out; 169785c59580SPavel Emelyanov 16981da177e4SLinus Torvalds /* 16991da177e4SLinus Torvalds * At this point, we know that if there is an exclusive 17001da177e4SLinus Torvalds * lease on this file, then we hold it on this filp 17011da177e4SLinus Torvalds * (otherwise our open of this file would have blocked). 17021da177e4SLinus Torvalds * And if we are trying to acquire an exclusive lease, 17031da177e4SLinus Torvalds * then the file is not open by anyone (including us) 17041da177e4SLinus Torvalds * except for this filp. 17051da177e4SLinus Torvalds */ 1706c1f24ef4SJ. Bruce Fields error = -EAGAIN; 17078634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 17082ab99ee1SChristoph Hellwig if (fl->fl_file == filp && 17092ab99ee1SChristoph Hellwig fl->fl_owner == lease->fl_owner) { 17108634b51fSJeff Layton my_fl = fl; 1711c1f24ef4SJ. Bruce Fields continue; 17121da177e4SLinus Torvalds } 17138634b51fSJeff Layton 1714c1f24ef4SJ. Bruce Fields /* 1715c1f24ef4SJ. Bruce Fields * No exclusive leases if someone else has a lease on 1716c1f24ef4SJ. Bruce Fields * this file: 1717c1f24ef4SJ. Bruce Fields */ 1718c1f24ef4SJ. Bruce Fields if (arg == F_WRLCK) 17191da177e4SLinus Torvalds goto out; 1720c1f24ef4SJ. Bruce Fields /* 1721c1f24ef4SJ. Bruce Fields * Modifying our existing lease is OK, but no getting a 1722c1f24ef4SJ. Bruce Fields * new lease if someone else is opening for write: 1723c1f24ef4SJ. Bruce Fields */ 1724c1f24ef4SJ. Bruce Fields if (fl->fl_flags & FL_UNLOCK_PENDING) 1725c1f24ef4SJ. Bruce Fields goto out; 1726c1f24ef4SJ. Bruce Fields } 17271da177e4SLinus Torvalds 17288634b51fSJeff Layton if (my_fl != NULL) { 17290164bf02SJeff Layton lease = my_fl; 17300164bf02SJeff Layton error = lease->fl_lmops->lm_change(lease, arg, &dispose); 17311c7dd2ffSJeff Layton if (error) 17321da177e4SLinus Torvalds goto out; 17331c7dd2ffSJeff Layton goto out_setup; 17341da177e4SLinus Torvalds } 17351da177e4SLinus Torvalds 17361da177e4SLinus Torvalds error = -EINVAL; 17371da177e4SLinus Torvalds if (!leases_enable) 17381da177e4SLinus Torvalds goto out; 17391da177e4SLinus Torvalds 1740e084c1bdSJeff Layton locks_insert_lock_ctx(lease, &ctx->flc_lease); 174124cbe784SJeff Layton /* 174224cbe784SJeff Layton * The check in break_lease() is lockless. It's possible for another 174324cbe784SJeff Layton * open to race in after we did the earlier check for a conflicting 174424cbe784SJeff Layton * open but before the lease was inserted. Check again for a 174524cbe784SJeff Layton * conflicting open and cancel the lease if there is one. 174624cbe784SJeff Layton * 174724cbe784SJeff Layton * We also add a barrier here to ensure that the insertion of the lock 174824cbe784SJeff Layton * precedes these checks. 174924cbe784SJeff Layton */ 175024cbe784SJeff Layton smp_mb(); 175111afe9f7SChristoph Hellwig error = check_conflicting_open(dentry, arg, lease->fl_flags); 17528634b51fSJeff Layton if (error) { 1753e084c1bdSJeff Layton locks_unlink_lock_ctx(lease); 17548634b51fSJeff Layton goto out; 17558634b51fSJeff Layton } 17561c7dd2ffSJeff Layton 17571c7dd2ffSJeff Layton out_setup: 17581c7dd2ffSJeff Layton if (lease->fl_lmops->lm_setup) 17591c7dd2ffSJeff Layton lease->fl_lmops->lm_setup(lease, priv); 17601da177e4SLinus Torvalds out: 17616109c850SJeff Layton spin_unlock(&ctx->flc_lock); 176287709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1763c45198edSJeff Layton locks_dispose_list(&dispose); 1764df4e8d2cSJ. Bruce Fields if (is_deleg) 17655955102cSAl Viro inode_unlock(inode); 17668634b51fSJeff Layton if (!error && !my_fl) 17671c7dd2ffSJeff Layton *flp = NULL; 17681da177e4SLinus Torvalds return error; 17691da177e4SLinus Torvalds } 17708335ebd9SJ. Bruce Fields 17712ab99ee1SChristoph Hellwig static int generic_delete_lease(struct file *filp, void *owner) 17728335ebd9SJ. Bruce Fields { 17730efaa7e8SJeff Layton int error = -EAGAIN; 17748634b51fSJeff Layton struct file_lock *fl, *victim = NULL; 1775c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 1776128a3785SDmitry Vyukov struct file_lock_context *ctx; 1777c45198edSJeff Layton LIST_HEAD(dispose); 17788335ebd9SJ. Bruce Fields 1779128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 17808634b51fSJeff Layton if (!ctx) { 17818634b51fSJeff Layton trace_generic_delete_lease(inode, NULL); 17828634b51fSJeff Layton return error; 17838634b51fSJeff Layton } 17848634b51fSJeff Layton 178587709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 17866109c850SJeff Layton spin_lock(&ctx->flc_lock); 17878634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 17882ab99ee1SChristoph Hellwig if (fl->fl_file == filp && 17892ab99ee1SChristoph Hellwig fl->fl_owner == owner) { 17908634b51fSJeff Layton victim = fl; 17910efaa7e8SJeff Layton break; 17928335ebd9SJ. Bruce Fields } 17938634b51fSJeff Layton } 1794a9b1b455SJeff Layton trace_generic_delete_lease(inode, victim); 17958634b51fSJeff Layton if (victim) 17967448cc37SJeff Layton error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose); 17976109c850SJeff Layton spin_unlock(&ctx->flc_lock); 179887709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1799c45198edSJeff Layton locks_dispose_list(&dispose); 18000efaa7e8SJeff Layton return error; 18018335ebd9SJ. Bruce Fields } 18028335ebd9SJ. Bruce Fields 18031da177e4SLinus Torvalds /** 18041da177e4SLinus Torvalds * generic_setlease - sets a lease on an open file 18051da177e4SLinus Torvalds * @filp: file pointer 18061da177e4SLinus Torvalds * @arg: type of lease to obtain 18071da177e4SLinus Torvalds * @flp: input - file_lock to use, output - file_lock inserted 18081c7dd2ffSJeff Layton * @priv: private data for lm_setup (may be NULL if lm_setup 18091c7dd2ffSJeff Layton * doesn't require it) 18101da177e4SLinus Torvalds * 18111da177e4SLinus Torvalds * The (input) flp->fl_lmops->lm_break function is required 18121da177e4SLinus Torvalds * by break_lease(). 18131da177e4SLinus Torvalds */ 1814e6f5c789SJeff Layton int generic_setlease(struct file *filp, long arg, struct file_lock **flp, 1815e6f5c789SJeff Layton void **priv) 18161da177e4SLinus Torvalds { 1817c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 18188335ebd9SJ. Bruce Fields int error; 18191da177e4SLinus Torvalds 18208e96e3b7SEric W. Biederman if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE)) 18218335ebd9SJ. Bruce Fields return -EACCES; 18221da177e4SLinus Torvalds if (!S_ISREG(inode->i_mode)) 18238335ebd9SJ. Bruce Fields return -EINVAL; 18241da177e4SLinus Torvalds error = security_file_lock(filp, arg); 18251da177e4SLinus Torvalds if (error) 18268335ebd9SJ. Bruce Fields return error; 18271da177e4SLinus Torvalds 18288335ebd9SJ. Bruce Fields switch (arg) { 18298335ebd9SJ. Bruce Fields case F_UNLCK: 18302ab99ee1SChristoph Hellwig return generic_delete_lease(filp, *priv); 18318335ebd9SJ. Bruce Fields case F_RDLCK: 18328335ebd9SJ. Bruce Fields case F_WRLCK: 18330efaa7e8SJeff Layton if (!(*flp)->fl_lmops->lm_break) { 18340efaa7e8SJeff Layton WARN_ON_ONCE(1); 18350efaa7e8SJeff Layton return -ENOLCK; 18360efaa7e8SJeff Layton } 183711afe9f7SChristoph Hellwig 1838e6f5c789SJeff Layton return generic_add_lease(filp, arg, flp, priv); 18398335ebd9SJ. Bruce Fields default: 18408d657eb3SDave Jones return -EINVAL; 18411da177e4SLinus Torvalds } 18421da177e4SLinus Torvalds } 18430af1a450SChristoph Hellwig EXPORT_SYMBOL(generic_setlease); 18441da177e4SLinus Torvalds 18451da177e4SLinus Torvalds /** 1846a9933ceaSJ. Bruce Fields * vfs_setlease - sets a lease on an open file 18471da177e4SLinus Torvalds * @filp: file pointer 18481da177e4SLinus Torvalds * @arg: type of lease to obtain 1849e51673aaSJeff Layton * @lease: file_lock to use when adding a lease 18501c7dd2ffSJeff Layton * @priv: private info for lm_setup when adding a lease (may be 18511c7dd2ffSJeff Layton * NULL if lm_setup doesn't require it) 18521da177e4SLinus Torvalds * 1853e51673aaSJeff Layton * Call this to establish a lease on the file. The "lease" argument is not 1854e51673aaSJeff Layton * used for F_UNLCK requests and may be NULL. For commands that set or alter 185580b79dd0SMauro Carvalho Chehab * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be 185680b79dd0SMauro Carvalho Chehab * set; if not, this function will return -ENOLCK (and generate a scary-looking 1857e51673aaSJeff Layton * stack trace). 18581c7dd2ffSJeff Layton * 18591c7dd2ffSJeff Layton * The "priv" pointer is passed directly to the lm_setup function as-is. It 18601c7dd2ffSJeff Layton * may be NULL if the lm_setup operation doesn't require it. 18611da177e4SLinus Torvalds */ 1862e6f5c789SJeff Layton int 1863e6f5c789SJeff Layton vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) 18641da177e4SLinus Torvalds { 1865c568d683SMiklos Szeredi if (filp->f_op->setlease && is_remote_lock(filp)) 1866f82b4b67SJeff Layton return filp->f_op->setlease(filp, arg, lease, priv); 18671c7dd2ffSJeff Layton else 1868f82b4b67SJeff Layton return generic_setlease(filp, arg, lease, priv); 18691da177e4SLinus Torvalds } 1870a9933ceaSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_setlease); 18711da177e4SLinus Torvalds 18720ceaf6c7SJ. Bruce Fields static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) 18731da177e4SLinus Torvalds { 18741c7dd2ffSJeff Layton struct file_lock *fl; 1875f7347ce4SLinus Torvalds struct fasync_struct *new; 18761da177e4SLinus Torvalds int error; 18771da177e4SLinus Torvalds 1878c5b1f0d9SArnd Bergmann fl = lease_alloc(filp, arg); 1879c5b1f0d9SArnd Bergmann if (IS_ERR(fl)) 1880c5b1f0d9SArnd Bergmann return PTR_ERR(fl); 18811da177e4SLinus Torvalds 1882f7347ce4SLinus Torvalds new = fasync_alloc(); 1883f7347ce4SLinus Torvalds if (!new) { 1884f7347ce4SLinus Torvalds locks_free_lock(fl); 1885f7347ce4SLinus Torvalds return -ENOMEM; 1886f7347ce4SLinus Torvalds } 18871c7dd2ffSJeff Layton new->fa_fd = fd; 18881da177e4SLinus Torvalds 18891c7dd2ffSJeff Layton error = vfs_setlease(filp, arg, &fl, (void **)&new); 18902dfb928fSJeff Layton if (fl) 18912dfb928fSJeff Layton locks_free_lock(fl); 1892f7347ce4SLinus Torvalds if (new) 1893f7347ce4SLinus Torvalds fasync_free(new); 18941da177e4SLinus Torvalds return error; 18951da177e4SLinus Torvalds } 18961da177e4SLinus Torvalds 18971da177e4SLinus Torvalds /** 18980ceaf6c7SJ. Bruce Fields * fcntl_setlease - sets a lease on an open file 18990ceaf6c7SJ. Bruce Fields * @fd: open file descriptor 19000ceaf6c7SJ. Bruce Fields * @filp: file pointer 19010ceaf6c7SJ. Bruce Fields * @arg: type of lease to obtain 19020ceaf6c7SJ. Bruce Fields * 19030ceaf6c7SJ. Bruce Fields * Call this fcntl to establish a lease on the file. 19040ceaf6c7SJ. Bruce Fields * Note that you also need to call %F_SETSIG to 19050ceaf6c7SJ. Bruce Fields * receive a signal when the lease is broken. 19060ceaf6c7SJ. Bruce Fields */ 19070ceaf6c7SJ. Bruce Fields int fcntl_setlease(unsigned int fd, struct file *filp, long arg) 19080ceaf6c7SJ. Bruce Fields { 19090ceaf6c7SJ. Bruce Fields if (arg == F_UNLCK) 19102ab99ee1SChristoph Hellwig return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); 19110ceaf6c7SJ. Bruce Fields return do_fcntl_add_lease(fd, filp, arg); 19120ceaf6c7SJ. Bruce Fields } 19130ceaf6c7SJ. Bruce Fields 19140ceaf6c7SJ. Bruce Fields /** 191529d01b22SJeff Layton * flock_lock_inode_wait - Apply a FLOCK-style lock to a file 191629d01b22SJeff Layton * @inode: inode of the file to apply to 19171da177e4SLinus Torvalds * @fl: The lock to be applied 19181da177e4SLinus Torvalds * 191929d01b22SJeff Layton * Apply a FLOCK style lock request to an inode. 19201da177e4SLinus Torvalds */ 1921616fb38fSBenjamin Coddington static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) 19221da177e4SLinus Torvalds { 19231da177e4SLinus Torvalds int error; 19241da177e4SLinus Torvalds might_sleep(); 19251da177e4SLinus Torvalds for (;;) { 192629d01b22SJeff Layton error = flock_lock_inode(inode, fl); 1927bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 19281da177e4SLinus Torvalds break; 19291da177e4SLinus Torvalds error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); 19301da177e4SLinus Torvalds if (!error) 19311da177e4SLinus Torvalds continue; 19321da177e4SLinus Torvalds 19331da177e4SLinus Torvalds locks_delete_block(fl); 19341da177e4SLinus Torvalds break; 19351da177e4SLinus Torvalds } 19361da177e4SLinus Torvalds return error; 19371da177e4SLinus Torvalds } 19381da177e4SLinus Torvalds 193929d01b22SJeff Layton /** 1940e55c34a6SBenjamin Coddington * locks_lock_inode_wait - Apply a lock to an inode 1941e55c34a6SBenjamin Coddington * @inode: inode of the file to apply to 1942e55c34a6SBenjamin Coddington * @fl: The lock to be applied 1943e55c34a6SBenjamin Coddington * 1944e55c34a6SBenjamin Coddington * Apply a POSIX or FLOCK style lock request to an inode. 1945e55c34a6SBenjamin Coddington */ 1946e55c34a6SBenjamin Coddington int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl) 1947e55c34a6SBenjamin Coddington { 1948e55c34a6SBenjamin Coddington int res = 0; 1949e55c34a6SBenjamin Coddington switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) { 1950e55c34a6SBenjamin Coddington case FL_POSIX: 1951e55c34a6SBenjamin Coddington res = posix_lock_inode_wait(inode, fl); 1952e55c34a6SBenjamin Coddington break; 1953e55c34a6SBenjamin Coddington case FL_FLOCK: 1954e55c34a6SBenjamin Coddington res = flock_lock_inode_wait(inode, fl); 1955e55c34a6SBenjamin Coddington break; 1956e55c34a6SBenjamin Coddington default: 1957e55c34a6SBenjamin Coddington BUG(); 1958e55c34a6SBenjamin Coddington } 1959e55c34a6SBenjamin Coddington return res; 1960e55c34a6SBenjamin Coddington } 1961e55c34a6SBenjamin Coddington EXPORT_SYMBOL(locks_lock_inode_wait); 1962e55c34a6SBenjamin Coddington 1963e55c34a6SBenjamin Coddington /** 19641da177e4SLinus Torvalds * sys_flock: - flock() system call. 19651da177e4SLinus Torvalds * @fd: the file descriptor to lock. 19661da177e4SLinus Torvalds * @cmd: the type of lock to apply. 19671da177e4SLinus Torvalds * 19681da177e4SLinus Torvalds * Apply a %FL_FLOCK style lock to an open file descriptor. 196980b79dd0SMauro Carvalho Chehab * The @cmd can be one of: 19701da177e4SLinus Torvalds * 197180b79dd0SMauro Carvalho Chehab * - %LOCK_SH -- a shared lock. 197280b79dd0SMauro Carvalho Chehab * - %LOCK_EX -- an exclusive lock. 197380b79dd0SMauro Carvalho Chehab * - %LOCK_UN -- remove an existing lock. 197480b79dd0SMauro Carvalho Chehab * - %LOCK_MAND -- a 'mandatory' flock. 197580b79dd0SMauro Carvalho Chehab * This exists to emulate Windows Share Modes. 19761da177e4SLinus Torvalds * 19771da177e4SLinus Torvalds * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other 19781da177e4SLinus Torvalds * processes read and write access respectively. 19791da177e4SLinus Torvalds */ 1980002c8976SHeiko Carstens SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) 19811da177e4SLinus Torvalds { 19822903ff01SAl Viro struct fd f = fdget(fd); 19831da177e4SLinus Torvalds struct file_lock *lock; 19841da177e4SLinus Torvalds int can_sleep, unlock; 19851da177e4SLinus Torvalds int error; 19861da177e4SLinus Torvalds 19871da177e4SLinus Torvalds error = -EBADF; 19882903ff01SAl Viro if (!f.file) 19891da177e4SLinus Torvalds goto out; 19901da177e4SLinus Torvalds 19911da177e4SLinus Torvalds can_sleep = !(cmd & LOCK_NB); 19921da177e4SLinus Torvalds cmd &= ~LOCK_NB; 19931da177e4SLinus Torvalds unlock = (cmd == LOCK_UN); 19941da177e4SLinus Torvalds 1995aeb5d727SAl Viro if (!unlock && !(cmd & LOCK_MAND) && 19962903ff01SAl Viro !(f.file->f_mode & (FMODE_READ|FMODE_WRITE))) 19971da177e4SLinus Torvalds goto out_putf; 19981da177e4SLinus Torvalds 19996e129d00SJeff Layton lock = flock_make_lock(f.file, cmd); 20006e129d00SJeff Layton if (IS_ERR(lock)) { 20016e129d00SJeff Layton error = PTR_ERR(lock); 20021da177e4SLinus Torvalds goto out_putf; 20036e129d00SJeff Layton } 20046e129d00SJeff Layton 20051da177e4SLinus Torvalds if (can_sleep) 20061da177e4SLinus Torvalds lock->fl_flags |= FL_SLEEP; 20071da177e4SLinus Torvalds 20082903ff01SAl Viro error = security_file_lock(f.file, lock->fl_type); 20091da177e4SLinus Torvalds if (error) 20101da177e4SLinus Torvalds goto out_free; 20111da177e4SLinus Torvalds 2012c568d683SMiklos Szeredi if (f.file->f_op->flock && is_remote_lock(f.file)) 20132903ff01SAl Viro error = f.file->f_op->flock(f.file, 20141da177e4SLinus Torvalds (can_sleep) ? F_SETLKW : F_SETLK, 20151da177e4SLinus Torvalds lock); 20161da177e4SLinus Torvalds else 20174f656367SBenjamin Coddington error = locks_lock_file_wait(f.file, lock); 20181da177e4SLinus Torvalds 20191da177e4SLinus Torvalds out_free: 20201da177e4SLinus Torvalds locks_free_lock(lock); 20211da177e4SLinus Torvalds 20221da177e4SLinus Torvalds out_putf: 20232903ff01SAl Viro fdput(f); 20241da177e4SLinus Torvalds out: 20251da177e4SLinus Torvalds return error; 20261da177e4SLinus Torvalds } 20271da177e4SLinus Torvalds 20283ee17abdSJ. Bruce Fields /** 20293ee17abdSJ. Bruce Fields * vfs_test_lock - test file byte range lock 20303ee17abdSJ. Bruce Fields * @filp: The file to test lock for 20316924c554SJ. Bruce Fields * @fl: The lock to test; also used to hold result 20323ee17abdSJ. Bruce Fields * 20333ee17abdSJ. Bruce Fields * Returns -ERRNO on failure. Indicates presence of conflicting lock by 20343ee17abdSJ. Bruce Fields * setting conf->fl_type to something other than F_UNLCK. 20353ee17abdSJ. Bruce Fields */ 20363ee17abdSJ. Bruce Fields int vfs_test_lock(struct file *filp, struct file_lock *fl) 20373ee17abdSJ. Bruce Fields { 2038c568d683SMiklos Szeredi if (filp->f_op->lock && is_remote_lock(filp)) 20393ee17abdSJ. Bruce Fields return filp->f_op->lock(filp, F_GETLK, fl); 20403ee17abdSJ. Bruce Fields posix_test_lock(filp, fl); 20413ee17abdSJ. Bruce Fields return 0; 20423ee17abdSJ. Bruce Fields } 20433ee17abdSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_test_lock); 20443ee17abdSJ. Bruce Fields 2045*9d5b86acSBenjamin Coddington /** 2046*9d5b86acSBenjamin Coddington * locks_translate_pid - translate a file_lock's fl_pid number into a namespace 2047*9d5b86acSBenjamin Coddington * @fl: The file_lock who's fl_pid should be translated 2048*9d5b86acSBenjamin Coddington * @ns: The namespace into which the pid should be translated 2049*9d5b86acSBenjamin Coddington * 2050*9d5b86acSBenjamin Coddington * Used to tranlate a fl_pid into a namespace virtual pid number 2051*9d5b86acSBenjamin Coddington */ 2052*9d5b86acSBenjamin Coddington static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns) 2053*9d5b86acSBenjamin Coddington { 2054*9d5b86acSBenjamin Coddington pid_t vnr; 2055*9d5b86acSBenjamin Coddington struct pid *pid; 2056*9d5b86acSBenjamin Coddington 2057*9d5b86acSBenjamin Coddington if (IS_OFDLCK(fl)) 2058*9d5b86acSBenjamin Coddington return -1; 2059*9d5b86acSBenjamin Coddington if (IS_REMOTELCK(fl)) 2060*9d5b86acSBenjamin Coddington return fl->fl_pid; 2061*9d5b86acSBenjamin Coddington 2062*9d5b86acSBenjamin Coddington rcu_read_lock(); 2063*9d5b86acSBenjamin Coddington pid = find_pid_ns(fl->fl_pid, &init_pid_ns); 2064*9d5b86acSBenjamin Coddington vnr = pid_nr_ns(pid, ns); 2065*9d5b86acSBenjamin Coddington rcu_read_unlock(); 2066*9d5b86acSBenjamin Coddington return vnr; 2067*9d5b86acSBenjamin Coddington } 2068*9d5b86acSBenjamin Coddington 2069c2fa1b8aSJ. Bruce Fields static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) 2070c2fa1b8aSJ. Bruce Fields { 2071*9d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 2072c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2073c2fa1b8aSJ. Bruce Fields /* 2074c2fa1b8aSJ. Bruce Fields * Make sure we can represent the posix lock via 2075c2fa1b8aSJ. Bruce Fields * legacy 32bit flock. 2076c2fa1b8aSJ. Bruce Fields */ 2077c2fa1b8aSJ. Bruce Fields if (fl->fl_start > OFFT_OFFSET_MAX) 2078c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2079c2fa1b8aSJ. Bruce Fields if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX) 2080c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2081c2fa1b8aSJ. Bruce Fields #endif 2082c2fa1b8aSJ. Bruce Fields flock->l_start = fl->fl_start; 2083c2fa1b8aSJ. Bruce Fields flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2084c2fa1b8aSJ. Bruce Fields fl->fl_end - fl->fl_start + 1; 2085c2fa1b8aSJ. Bruce Fields flock->l_whence = 0; 2086129a84deSJ. Bruce Fields flock->l_type = fl->fl_type; 2087c2fa1b8aSJ. Bruce Fields return 0; 2088c2fa1b8aSJ. Bruce Fields } 2089c2fa1b8aSJ. Bruce Fields 2090c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2091c2fa1b8aSJ. Bruce Fields static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) 2092c2fa1b8aSJ. Bruce Fields { 2093*9d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 2094c2fa1b8aSJ. Bruce Fields flock->l_start = fl->fl_start; 2095c2fa1b8aSJ. Bruce Fields flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2096c2fa1b8aSJ. Bruce Fields fl->fl_end - fl->fl_start + 1; 2097c2fa1b8aSJ. Bruce Fields flock->l_whence = 0; 2098c2fa1b8aSJ. Bruce Fields flock->l_type = fl->fl_type; 2099c2fa1b8aSJ. Bruce Fields } 2100c2fa1b8aSJ. Bruce Fields #endif 2101c2fa1b8aSJ. Bruce Fields 21021da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 21031da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 21041da177e4SLinus Torvalds */ 2105a75d30c7SChristoph Hellwig int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) 21061da177e4SLinus Torvalds { 210752306e88SBenjamin Coddington struct file_lock *fl; 21081da177e4SLinus Torvalds int error; 21091da177e4SLinus Torvalds 211052306e88SBenjamin Coddington fl = locks_alloc_lock(); 211152306e88SBenjamin Coddington if (fl == NULL) 211252306e88SBenjamin Coddington return -ENOMEM; 21131da177e4SLinus Torvalds error = -EINVAL; 2114a75d30c7SChristoph Hellwig if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) 21151da177e4SLinus Torvalds goto out; 21161da177e4SLinus Torvalds 211752306e88SBenjamin Coddington error = flock_to_posix_lock(filp, fl, flock); 21181da177e4SLinus Torvalds if (error) 21191da177e4SLinus Torvalds goto out; 21201da177e4SLinus Torvalds 21210d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 212290478939SJeff Layton error = -EINVAL; 2123a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 212490478939SJeff Layton goto out; 212590478939SJeff Layton 21265d50ffd7SJeff Layton cmd = F_GETLK; 212752306e88SBenjamin Coddington fl->fl_flags |= FL_OFDLCK; 212852306e88SBenjamin Coddington fl->fl_owner = filp; 21295d50ffd7SJeff Layton } 21305d50ffd7SJeff Layton 213152306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 21323ee17abdSJ. Bruce Fields if (error) 21331da177e4SLinus Torvalds goto out; 21341da177e4SLinus Torvalds 213552306e88SBenjamin Coddington flock->l_type = fl->fl_type; 213652306e88SBenjamin Coddington if (fl->fl_type != F_UNLCK) { 213752306e88SBenjamin Coddington error = posix_lock_to_flock(flock, fl); 2138c2fa1b8aSJ. Bruce Fields if (error) 213952306e88SBenjamin Coddington goto out; 21401da177e4SLinus Torvalds } 21411da177e4SLinus Torvalds out: 214252306e88SBenjamin Coddington locks_free_lock(fl); 21431da177e4SLinus Torvalds return error; 21441da177e4SLinus Torvalds } 21451da177e4SLinus Torvalds 21467723ec97SMarc Eshel /** 21477723ec97SMarc Eshel * vfs_lock_file - file byte range lock 21487723ec97SMarc Eshel * @filp: The file to apply the lock to 21497723ec97SMarc Eshel * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.) 21507723ec97SMarc Eshel * @fl: The lock to be applied 2151150b3934SMarc Eshel * @conf: Place to return a copy of the conflicting lock, if found. 2152150b3934SMarc Eshel * 2153150b3934SMarc Eshel * A caller that doesn't care about the conflicting lock may pass NULL 2154150b3934SMarc Eshel * as the final argument. 2155150b3934SMarc Eshel * 2156150b3934SMarc Eshel * If the filesystem defines a private ->lock() method, then @conf will 2157150b3934SMarc Eshel * be left unchanged; so a caller that cares should initialize it to 2158150b3934SMarc Eshel * some acceptable default. 21592beb6614SMarc Eshel * 21602beb6614SMarc Eshel * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX 21612beb6614SMarc Eshel * locks, the ->lock() interface may return asynchronously, before the lock has 21622beb6614SMarc Eshel * been granted or denied by the underlying filesystem, if (and only if) 21638fb47a4fSJ. Bruce Fields * lm_grant is set. Callers expecting ->lock() to return asynchronously 21642beb6614SMarc Eshel * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if) 21652beb6614SMarc Eshel * the request is for a blocking lock. When ->lock() does return asynchronously, 21668fb47a4fSJ. Bruce Fields * it must return FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock 21672beb6614SMarc Eshel * request completes. 21682beb6614SMarc Eshel * If the request is for non-blocking lock the file system should return 2169bde74e4bSMiklos Szeredi * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine 2170bde74e4bSMiklos Szeredi * with the result. If the request timed out the callback routine will return a 21712beb6614SMarc Eshel * nonzero return code and the file system should release the lock. The file 21722beb6614SMarc Eshel * system is also responsible to keep a corresponding posix lock when it 21732beb6614SMarc Eshel * grants a lock so the VFS can find out which locks are locally held and do 21742beb6614SMarc Eshel * the correct lock cleanup when required. 21752beb6614SMarc Eshel * The underlying filesystem must not drop the kernel lock or call 21768fb47a4fSJ. Bruce Fields * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED 21772beb6614SMarc Eshel * return code. 21787723ec97SMarc Eshel */ 2179150b3934SMarc Eshel int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) 21807723ec97SMarc Eshel { 2181c568d683SMiklos Szeredi if (filp->f_op->lock && is_remote_lock(filp)) 21827723ec97SMarc Eshel return filp->f_op->lock(filp, cmd, fl); 21837723ec97SMarc Eshel else 2184150b3934SMarc Eshel return posix_lock_file(filp, fl, conf); 21857723ec97SMarc Eshel } 21867723ec97SMarc Eshel EXPORT_SYMBOL_GPL(vfs_lock_file); 21877723ec97SMarc Eshel 2188b648a6deSMiklos Szeredi static int do_lock_file_wait(struct file *filp, unsigned int cmd, 2189b648a6deSMiklos Szeredi struct file_lock *fl) 2190b648a6deSMiklos Szeredi { 2191b648a6deSMiklos Szeredi int error; 2192b648a6deSMiklos Szeredi 2193b648a6deSMiklos Szeredi error = security_file_lock(filp, fl->fl_type); 2194b648a6deSMiklos Szeredi if (error) 2195b648a6deSMiklos Szeredi return error; 2196b648a6deSMiklos Szeredi 2197b648a6deSMiklos Szeredi for (;;) { 2198764c76b3SMiklos Szeredi error = vfs_lock_file(filp, cmd, fl, NULL); 2199b648a6deSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 2200b648a6deSMiklos Szeredi break; 2201764c76b3SMiklos Szeredi error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); 2202b648a6deSMiklos Szeredi if (!error) 2203b648a6deSMiklos Szeredi continue; 2204b648a6deSMiklos Szeredi 2205b648a6deSMiklos Szeredi locks_delete_block(fl); 2206b648a6deSMiklos Szeredi break; 2207b648a6deSMiklos Szeredi } 2208b648a6deSMiklos Szeredi 2209b648a6deSMiklos Szeredi return error; 2210b648a6deSMiklos Szeredi } 2211b648a6deSMiklos Szeredi 22126ca7d910SBenjamin Coddington /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */ 2213cf01f4eeSJeff Layton static int 2214cf01f4eeSJeff Layton check_fmode_for_setlk(struct file_lock *fl) 2215cf01f4eeSJeff Layton { 2216cf01f4eeSJeff Layton switch (fl->fl_type) { 2217cf01f4eeSJeff Layton case F_RDLCK: 2218cf01f4eeSJeff Layton if (!(fl->fl_file->f_mode & FMODE_READ)) 2219cf01f4eeSJeff Layton return -EBADF; 2220cf01f4eeSJeff Layton break; 2221cf01f4eeSJeff Layton case F_WRLCK: 2222cf01f4eeSJeff Layton if (!(fl->fl_file->f_mode & FMODE_WRITE)) 2223cf01f4eeSJeff Layton return -EBADF; 2224cf01f4eeSJeff Layton } 2225cf01f4eeSJeff Layton return 0; 2226cf01f4eeSJeff Layton } 2227cf01f4eeSJeff Layton 22281da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 22291da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 22301da177e4SLinus Torvalds */ 2231c293621bSPeter Staubach int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, 2232a75d30c7SChristoph Hellwig struct flock *flock) 22331da177e4SLinus Torvalds { 22341da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 2235a75d30c7SChristoph Hellwig struct inode *inode = locks_inode(filp); 22360b2bac2fSAl Viro struct file *f; 22371da177e4SLinus Torvalds int error; 22381da177e4SLinus Torvalds 22391da177e4SLinus Torvalds if (file_lock == NULL) 22401da177e4SLinus Torvalds return -ENOLCK; 22411da177e4SLinus Torvalds 22421da177e4SLinus Torvalds /* Don't allow mandatory locks on files that may be memory mapped 22431da177e4SLinus Torvalds * and shared. 22441da177e4SLinus Torvalds */ 2245a16877caSPavel Emelyanov if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) { 22461da177e4SLinus Torvalds error = -EAGAIN; 22471da177e4SLinus Torvalds goto out; 22481da177e4SLinus Torvalds } 22491da177e4SLinus Torvalds 2250a75d30c7SChristoph Hellwig error = flock_to_posix_lock(filp, file_lock, flock); 22511da177e4SLinus Torvalds if (error) 22521da177e4SLinus Torvalds goto out; 22535d50ffd7SJeff Layton 2254cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2255cf01f4eeSJeff Layton if (error) 2256cf01f4eeSJeff Layton goto out; 2257cf01f4eeSJeff Layton 22585d50ffd7SJeff Layton /* 22595d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2260cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 22615d50ffd7SJeff Layton */ 22625d50ffd7SJeff Layton switch (cmd) { 22630d3f7a2dSJeff Layton case F_OFD_SETLK: 226490478939SJeff Layton error = -EINVAL; 2265a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 226690478939SJeff Layton goto out; 226790478939SJeff Layton 22685d50ffd7SJeff Layton cmd = F_SETLK; 2269cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 227073a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 22715d50ffd7SJeff Layton break; 22720d3f7a2dSJeff Layton case F_OFD_SETLKW: 227390478939SJeff Layton error = -EINVAL; 2274a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 227590478939SJeff Layton goto out; 227690478939SJeff Layton 22775d50ffd7SJeff Layton cmd = F_SETLKW; 2278cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 227973a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 22805d50ffd7SJeff Layton /* Fallthrough */ 22815d50ffd7SJeff Layton case F_SETLKW: 22821da177e4SLinus Torvalds file_lock->fl_flags |= FL_SLEEP; 22831da177e4SLinus Torvalds } 22841da177e4SLinus Torvalds 2285b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2286c293621bSPeter Staubach 2287c293621bSPeter Staubach /* 22880752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 22890752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 22900752ba80SJeff Layton * unlocking though, or for OFD locks. 2291c293621bSPeter Staubach */ 22920752ba80SJeff Layton if (!error && file_lock->fl_type != F_UNLCK && 22930752ba80SJeff Layton !(file_lock->fl_flags & FL_OFDLCK)) { 22940b2bac2fSAl Viro /* 22957f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 22967f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 22977f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 22980b2bac2fSAl Viro */ 22990b2bac2fSAl Viro spin_lock(¤t->files->file_lock); 23000b2bac2fSAl Viro f = fcheck(fd); 23010b2bac2fSAl Viro spin_unlock(¤t->files->file_lock); 23027f3697e2SJeff Layton if (f != filp) { 23037f3697e2SJeff Layton file_lock->fl_type = F_UNLCK; 23047f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 23057f3697e2SJeff Layton WARN_ON_ONCE(error); 23067f3697e2SJeff Layton error = -EBADF; 2307c293621bSPeter Staubach } 23087f3697e2SJeff Layton } 23091da177e4SLinus Torvalds out: 23101890910fSJeff Layton trace_fcntl_setlk(inode, file_lock, error); 23111da177e4SLinus Torvalds locks_free_lock(file_lock); 23121da177e4SLinus Torvalds return error; 23131da177e4SLinus Torvalds } 23141da177e4SLinus Torvalds 23151da177e4SLinus Torvalds #if BITS_PER_LONG == 32 23161da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 23171da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 23181da177e4SLinus Torvalds */ 2319a75d30c7SChristoph Hellwig int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) 23201da177e4SLinus Torvalds { 232152306e88SBenjamin Coddington struct file_lock *fl; 23221da177e4SLinus Torvalds int error; 23231da177e4SLinus Torvalds 232452306e88SBenjamin Coddington fl = locks_alloc_lock(); 232552306e88SBenjamin Coddington if (fl == NULL) 232652306e88SBenjamin Coddington return -ENOMEM; 232752306e88SBenjamin Coddington 23281da177e4SLinus Torvalds error = -EINVAL; 2329a75d30c7SChristoph Hellwig if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) 23301da177e4SLinus Torvalds goto out; 23311da177e4SLinus Torvalds 233252306e88SBenjamin Coddington error = flock64_to_posix_lock(filp, fl, flock); 23331da177e4SLinus Torvalds if (error) 23341da177e4SLinus Torvalds goto out; 23351da177e4SLinus Torvalds 23360d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 233790478939SJeff Layton error = -EINVAL; 2338a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 233990478939SJeff Layton goto out; 234090478939SJeff Layton 23415d50ffd7SJeff Layton cmd = F_GETLK64; 234252306e88SBenjamin Coddington fl->fl_flags |= FL_OFDLCK; 234352306e88SBenjamin Coddington fl->fl_owner = filp; 23445d50ffd7SJeff Layton } 23455d50ffd7SJeff Layton 234652306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 23473ee17abdSJ. Bruce Fields if (error) 23481da177e4SLinus Torvalds goto out; 23491da177e4SLinus Torvalds 235052306e88SBenjamin Coddington flock->l_type = fl->fl_type; 235152306e88SBenjamin Coddington if (fl->fl_type != F_UNLCK) 235252306e88SBenjamin Coddington posix_lock_to_flock64(flock, fl); 23531da177e4SLinus Torvalds 23541da177e4SLinus Torvalds out: 235552306e88SBenjamin Coddington locks_free_lock(fl); 23561da177e4SLinus Torvalds return error; 23571da177e4SLinus Torvalds } 23581da177e4SLinus Torvalds 23591da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 23601da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 23611da177e4SLinus Torvalds */ 2362c293621bSPeter Staubach int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, 2363a75d30c7SChristoph Hellwig struct flock64 *flock) 23641da177e4SLinus Torvalds { 23651da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 2366a75d30c7SChristoph Hellwig struct inode *inode = locks_inode(filp); 23670b2bac2fSAl Viro struct file *f; 23681da177e4SLinus Torvalds int error; 23691da177e4SLinus Torvalds 23701da177e4SLinus Torvalds if (file_lock == NULL) 23711da177e4SLinus Torvalds return -ENOLCK; 23721da177e4SLinus Torvalds 23731da177e4SLinus Torvalds /* Don't allow mandatory locks on files that may be memory mapped 23741da177e4SLinus Torvalds * and shared. 23751da177e4SLinus Torvalds */ 2376a16877caSPavel Emelyanov if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) { 23771da177e4SLinus Torvalds error = -EAGAIN; 23781da177e4SLinus Torvalds goto out; 23791da177e4SLinus Torvalds } 23801da177e4SLinus Torvalds 2381a75d30c7SChristoph Hellwig error = flock64_to_posix_lock(filp, file_lock, flock); 23821da177e4SLinus Torvalds if (error) 23831da177e4SLinus Torvalds goto out; 23845d50ffd7SJeff Layton 2385cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2386cf01f4eeSJeff Layton if (error) 2387cf01f4eeSJeff Layton goto out; 2388cf01f4eeSJeff Layton 23895d50ffd7SJeff Layton /* 23905d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2391cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 23925d50ffd7SJeff Layton */ 23935d50ffd7SJeff Layton switch (cmd) { 23940d3f7a2dSJeff Layton case F_OFD_SETLK: 239590478939SJeff Layton error = -EINVAL; 2396a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 239790478939SJeff Layton goto out; 239890478939SJeff Layton 23995d50ffd7SJeff Layton cmd = F_SETLK64; 2400cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 240173a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 24025d50ffd7SJeff Layton break; 24030d3f7a2dSJeff Layton case F_OFD_SETLKW: 240490478939SJeff Layton error = -EINVAL; 2405a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 240690478939SJeff Layton goto out; 240790478939SJeff Layton 24085d50ffd7SJeff Layton cmd = F_SETLKW64; 2409cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 241073a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 24115d50ffd7SJeff Layton /* Fallthrough */ 24125d50ffd7SJeff Layton case F_SETLKW64: 24131da177e4SLinus Torvalds file_lock->fl_flags |= FL_SLEEP; 24141da177e4SLinus Torvalds } 24151da177e4SLinus Torvalds 2416b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2417c293621bSPeter Staubach 2418c293621bSPeter Staubach /* 24190752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 24200752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 24210752ba80SJeff Layton * unlocking though, or for OFD locks. 2422c293621bSPeter Staubach */ 24230752ba80SJeff Layton if (!error && file_lock->fl_type != F_UNLCK && 24240752ba80SJeff Layton !(file_lock->fl_flags & FL_OFDLCK)) { 24257f3697e2SJeff Layton /* 24267f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 24277f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 24287f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 24297f3697e2SJeff Layton */ 24300b2bac2fSAl Viro spin_lock(¤t->files->file_lock); 24310b2bac2fSAl Viro f = fcheck(fd); 24320b2bac2fSAl Viro spin_unlock(¤t->files->file_lock); 24337f3697e2SJeff Layton if (f != filp) { 24347f3697e2SJeff Layton file_lock->fl_type = F_UNLCK; 24357f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 24367f3697e2SJeff Layton WARN_ON_ONCE(error); 24377f3697e2SJeff Layton error = -EBADF; 2438c293621bSPeter Staubach } 24397f3697e2SJeff Layton } 24401da177e4SLinus Torvalds out: 24411da177e4SLinus Torvalds locks_free_lock(file_lock); 24421da177e4SLinus Torvalds return error; 24431da177e4SLinus Torvalds } 24441da177e4SLinus Torvalds #endif /* BITS_PER_LONG == 32 */ 24451da177e4SLinus Torvalds 24461da177e4SLinus Torvalds /* 24471da177e4SLinus Torvalds * This function is called when the file is being removed 24481da177e4SLinus Torvalds * from the task's fd array. POSIX locks belonging to this task 24491da177e4SLinus Torvalds * are deleted at this time. 24501da177e4SLinus Torvalds */ 24511da177e4SLinus Torvalds void locks_remove_posix(struct file *filp, fl_owner_t owner) 24521da177e4SLinus Torvalds { 24531890910fSJeff Layton int error; 2454c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 2455ff7b86b8SMiklos Szeredi struct file_lock lock; 2456128a3785SDmitry Vyukov struct file_lock_context *ctx; 24571da177e4SLinus Torvalds 24581da177e4SLinus Torvalds /* 24591da177e4SLinus Torvalds * If there are no locks held on this file, we don't need to call 24601da177e4SLinus Torvalds * posix_lock_file(). Another process could be setting a lock on this 24611da177e4SLinus Torvalds * file at the same time, but we wouldn't remove that lock anyway. 24621da177e4SLinus Torvalds */ 2463c568d683SMiklos Szeredi ctx = smp_load_acquire(&inode->i_flctx); 2464bd61e0a9SJeff Layton if (!ctx || list_empty(&ctx->flc_posix)) 24651da177e4SLinus Torvalds return; 24661da177e4SLinus Torvalds 24671da177e4SLinus Torvalds lock.fl_type = F_UNLCK; 246875e1fcc0SMiklos Szeredi lock.fl_flags = FL_POSIX | FL_CLOSE; 24691da177e4SLinus Torvalds lock.fl_start = 0; 24701da177e4SLinus Torvalds lock.fl_end = OFFSET_MAX; 24711da177e4SLinus Torvalds lock.fl_owner = owner; 24721da177e4SLinus Torvalds lock.fl_pid = current->tgid; 24731da177e4SLinus Torvalds lock.fl_file = filp; 24741da177e4SLinus Torvalds lock.fl_ops = NULL; 24751da177e4SLinus Torvalds lock.fl_lmops = NULL; 24761da177e4SLinus Torvalds 24771890910fSJeff Layton error = vfs_lock_file(filp, F_SETLK, &lock, NULL); 24781da177e4SLinus Torvalds 24791da177e4SLinus Torvalds if (lock.fl_ops && lock.fl_ops->fl_release_private) 24801da177e4SLinus Torvalds lock.fl_ops->fl_release_private(&lock); 2481c568d683SMiklos Szeredi trace_locks_remove_posix(inode, &lock, error); 24821da177e4SLinus Torvalds } 24831da177e4SLinus Torvalds 24841da177e4SLinus Torvalds EXPORT_SYMBOL(locks_remove_posix); 24851da177e4SLinus Torvalds 24863d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 2487dd459bb1SJeff Layton static void 2488128a3785SDmitry Vyukov locks_remove_flock(struct file *filp, struct file_lock_context *flctx) 2489dd459bb1SJeff Layton { 2490dd459bb1SJeff Layton struct file_lock fl = { 2491dd459bb1SJeff Layton .fl_owner = filp, 2492dd459bb1SJeff Layton .fl_pid = current->tgid, 2493dd459bb1SJeff Layton .fl_file = filp, 249450f2112cSBenjamin Coddington .fl_flags = FL_FLOCK | FL_CLOSE, 2495dd459bb1SJeff Layton .fl_type = F_UNLCK, 2496dd459bb1SJeff Layton .fl_end = OFFSET_MAX, 2497dd459bb1SJeff Layton }; 2498c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 2499dd459bb1SJeff Layton 25003d8e560dSJeff Layton if (list_empty(&flctx->flc_flock)) 2501dd459bb1SJeff Layton return; 2502dd459bb1SJeff Layton 2503c568d683SMiklos Szeredi if (filp->f_op->flock && is_remote_lock(filp)) 2504dd459bb1SJeff Layton filp->f_op->flock(filp, F_SETLKW, &fl); 2505dd459bb1SJeff Layton else 2506bcd7f78dSJeff Layton flock_lock_inode(inode, &fl); 2507dd459bb1SJeff Layton 2508dd459bb1SJeff Layton if (fl.fl_ops && fl.fl_ops->fl_release_private) 2509dd459bb1SJeff Layton fl.fl_ops->fl_release_private(&fl); 2510dd459bb1SJeff Layton } 2511dd459bb1SJeff Layton 25123d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 25138634b51fSJeff Layton static void 2514128a3785SDmitry Vyukov locks_remove_lease(struct file *filp, struct file_lock_context *ctx) 25158634b51fSJeff Layton { 25168634b51fSJeff Layton struct file_lock *fl, *tmp; 25178634b51fSJeff Layton LIST_HEAD(dispose); 25188634b51fSJeff Layton 25193d8e560dSJeff Layton if (list_empty(&ctx->flc_lease)) 25208634b51fSJeff Layton return; 25218634b51fSJeff Layton 25225f43086bSPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 25236109c850SJeff Layton spin_lock(&ctx->flc_lock); 25248634b51fSJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) 2525c4e136cdSJeff Layton if (filp == fl->fl_file) 25267448cc37SJeff Layton lease_modify(fl, F_UNLCK, &dispose); 25276109c850SJeff Layton spin_unlock(&ctx->flc_lock); 25285f43086bSPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 25295f43086bSPeter Zijlstra 25308634b51fSJeff Layton locks_dispose_list(&dispose); 25318634b51fSJeff Layton } 25328634b51fSJeff Layton 25331da177e4SLinus Torvalds /* 25341da177e4SLinus Torvalds * This function is called on the last close of an open file. 25351da177e4SLinus Torvalds */ 253678ed8a13SJeff Layton void locks_remove_file(struct file *filp) 25371da177e4SLinus Torvalds { 2538128a3785SDmitry Vyukov struct file_lock_context *ctx; 2539128a3785SDmitry Vyukov 2540c568d683SMiklos Szeredi ctx = smp_load_acquire(&locks_inode(filp)->i_flctx); 2541128a3785SDmitry Vyukov if (!ctx) 25423d8e560dSJeff Layton return; 25433d8e560dSJeff Layton 2544dd459bb1SJeff Layton /* remove any OFD locks */ 254573a8f5f7SChristoph Hellwig locks_remove_posix(filp, filp); 25465d50ffd7SJeff Layton 2547dd459bb1SJeff Layton /* remove flock locks */ 2548128a3785SDmitry Vyukov locks_remove_flock(filp, ctx); 2549dd459bb1SJeff Layton 25508634b51fSJeff Layton /* remove any leases */ 2551128a3785SDmitry Vyukov locks_remove_lease(filp, ctx); 25521da177e4SLinus Torvalds } 25531da177e4SLinus Torvalds 25541da177e4SLinus Torvalds /** 25551da177e4SLinus Torvalds * posix_unblock_lock - stop waiting for a file lock 25561da177e4SLinus Torvalds * @waiter: the lock which was waiting 25571da177e4SLinus Torvalds * 25581da177e4SLinus Torvalds * lockd needs to block waiting for locks. 25591da177e4SLinus Torvalds */ 256064a318eeSJ. Bruce Fields int 2561f891a29fSJeff Layton posix_unblock_lock(struct file_lock *waiter) 25621da177e4SLinus Torvalds { 256364a318eeSJ. Bruce Fields int status = 0; 256464a318eeSJ. Bruce Fields 25657b2296afSJeff Layton spin_lock(&blocked_lock_lock); 25665996a298SJ. Bruce Fields if (waiter->fl_next) 25671da177e4SLinus Torvalds __locks_delete_block(waiter); 256864a318eeSJ. Bruce Fields else 256964a318eeSJ. Bruce Fields status = -ENOENT; 25707b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 257164a318eeSJ. Bruce Fields return status; 25721da177e4SLinus Torvalds } 25731da177e4SLinus Torvalds EXPORT_SYMBOL(posix_unblock_lock); 25741da177e4SLinus Torvalds 25759b9d2ab4SMarc Eshel /** 25769b9d2ab4SMarc Eshel * vfs_cancel_lock - file byte range unblock lock 25779b9d2ab4SMarc Eshel * @filp: The file to apply the unblock to 25789b9d2ab4SMarc Eshel * @fl: The lock to be unblocked 25799b9d2ab4SMarc Eshel * 25809b9d2ab4SMarc Eshel * Used by lock managers to cancel blocked requests 25819b9d2ab4SMarc Eshel */ 25829b9d2ab4SMarc Eshel int vfs_cancel_lock(struct file *filp, struct file_lock *fl) 25839b9d2ab4SMarc Eshel { 2584c568d683SMiklos Szeredi if (filp->f_op->lock && is_remote_lock(filp)) 25859b9d2ab4SMarc Eshel return filp->f_op->lock(filp, F_CANCELLK, fl); 25869b9d2ab4SMarc Eshel return 0; 25879b9d2ab4SMarc Eshel } 25889b9d2ab4SMarc Eshel 25899b9d2ab4SMarc Eshel EXPORT_SYMBOL_GPL(vfs_cancel_lock); 25909b9d2ab4SMarc Eshel 25917f8ada98SPavel Emelyanov #ifdef CONFIG_PROC_FS 2592d8ba7a36SAlexey Dobriyan #include <linux/proc_fs.h> 25937f8ada98SPavel Emelyanov #include <linux/seq_file.h> 25947f8ada98SPavel Emelyanov 25957012b02aSJeff Layton struct locks_iterator { 25967012b02aSJeff Layton int li_cpu; 25977012b02aSJeff Layton loff_t li_pos; 25987012b02aSJeff Layton }; 25997012b02aSJeff Layton 26007f8ada98SPavel Emelyanov static void lock_get_status(struct seq_file *f, struct file_lock *fl, 260199dc8292SJerome Marchand loff_t id, char *pfx) 26021da177e4SLinus Torvalds { 26031da177e4SLinus Torvalds struct inode *inode = NULL; 2604ab1f1611SVitaliy Gusev unsigned int fl_pid; 2605d67fd44fSNikolay Borisov struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info; 2606d67fd44fSNikolay Borisov 2607*9d5b86acSBenjamin Coddington fl_pid = locks_translate_pid(fl, proc_pidns); 2608d67fd44fSNikolay Borisov /* 2609d67fd44fSNikolay Borisov * If there isn't a fl_pid don't display who is waiting on 2610d67fd44fSNikolay Borisov * the lock if we are called from locks_show, or if we are 2611d67fd44fSNikolay Borisov * called from __show_fd_info - skip lock entirely 2612d67fd44fSNikolay Borisov */ 2613d67fd44fSNikolay Borisov if (fl_pid == 0) 2614d67fd44fSNikolay Borisov return; 26151da177e4SLinus Torvalds 26161da177e4SLinus Torvalds if (fl->fl_file != NULL) 2617c568d683SMiklos Szeredi inode = locks_inode(fl->fl_file); 26181da177e4SLinus Torvalds 261999dc8292SJerome Marchand seq_printf(f, "%lld:%s ", id, pfx); 26201da177e4SLinus Torvalds if (IS_POSIX(fl)) { 2621c918d42aSJeff Layton if (fl->fl_flags & FL_ACCESS) 26225315c26aSFabian Frederick seq_puts(f, "ACCESS"); 2623cff2fce5SJeff Layton else if (IS_OFDLCK(fl)) 26245315c26aSFabian Frederick seq_puts(f, "OFDLCK"); 2625c918d42aSJeff Layton else 26265315c26aSFabian Frederick seq_puts(f, "POSIX "); 2627c918d42aSJeff Layton 2628c918d42aSJeff Layton seq_printf(f, " %s ", 26291da177e4SLinus Torvalds (inode == NULL) ? "*NOINODE*" : 2630a16877caSPavel Emelyanov mandatory_lock(inode) ? "MANDATORY" : "ADVISORY "); 26311da177e4SLinus Torvalds } else if (IS_FLOCK(fl)) { 26321da177e4SLinus Torvalds if (fl->fl_type & LOCK_MAND) { 26335315c26aSFabian Frederick seq_puts(f, "FLOCK MSNFS "); 26341da177e4SLinus Torvalds } else { 26355315c26aSFabian Frederick seq_puts(f, "FLOCK ADVISORY "); 26361da177e4SLinus Torvalds } 26371da177e4SLinus Torvalds } else if (IS_LEASE(fl)) { 26388144f1f6SJeff Layton if (fl->fl_flags & FL_DELEG) 26398144f1f6SJeff Layton seq_puts(f, "DELEG "); 26408144f1f6SJeff Layton else 26415315c26aSFabian Frederick seq_puts(f, "LEASE "); 26428144f1f6SJeff Layton 2643ab83fa4bSJ. Bruce Fields if (lease_breaking(fl)) 26445315c26aSFabian Frederick seq_puts(f, "BREAKING "); 26451da177e4SLinus Torvalds else if (fl->fl_file) 26465315c26aSFabian Frederick seq_puts(f, "ACTIVE "); 26471da177e4SLinus Torvalds else 26485315c26aSFabian Frederick seq_puts(f, "BREAKER "); 26491da177e4SLinus Torvalds } else { 26505315c26aSFabian Frederick seq_puts(f, "UNKNOWN UNKNOWN "); 26511da177e4SLinus Torvalds } 26521da177e4SLinus Torvalds if (fl->fl_type & LOCK_MAND) { 26537f8ada98SPavel Emelyanov seq_printf(f, "%s ", 26541da177e4SLinus Torvalds (fl->fl_type & LOCK_READ) 26551da177e4SLinus Torvalds ? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ " 26561da177e4SLinus Torvalds : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE "); 26571da177e4SLinus Torvalds } else { 26587f8ada98SPavel Emelyanov seq_printf(f, "%s ", 2659ab83fa4bSJ. Bruce Fields (lease_breaking(fl)) 26600ee5c6d6SJeff Layton ? (fl->fl_type == F_UNLCK) ? "UNLCK" : "READ " 26610ee5c6d6SJeff Layton : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ "); 26621da177e4SLinus Torvalds } 26631da177e4SLinus Torvalds if (inode) { 26643648888eSJeff Layton /* userspace relies on this representation of dev_t */ 2665ab1f1611SVitaliy Gusev seq_printf(f, "%d %02x:%02x:%ld ", fl_pid, 26661da177e4SLinus Torvalds MAJOR(inode->i_sb->s_dev), 26671da177e4SLinus Torvalds MINOR(inode->i_sb->s_dev), inode->i_ino); 26681da177e4SLinus Torvalds } else { 2669ab1f1611SVitaliy Gusev seq_printf(f, "%d <none>:0 ", fl_pid); 26701da177e4SLinus Torvalds } 26711da177e4SLinus Torvalds if (IS_POSIX(fl)) { 26721da177e4SLinus Torvalds if (fl->fl_end == OFFSET_MAX) 26737f8ada98SPavel Emelyanov seq_printf(f, "%Ld EOF\n", fl->fl_start); 26741da177e4SLinus Torvalds else 26757f8ada98SPavel Emelyanov seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end); 26761da177e4SLinus Torvalds } else { 26775315c26aSFabian Frederick seq_puts(f, "0 EOF\n"); 26781da177e4SLinus Torvalds } 26791da177e4SLinus Torvalds } 26801da177e4SLinus Torvalds 26817f8ada98SPavel Emelyanov static int locks_show(struct seq_file *f, void *v) 26821da177e4SLinus Torvalds { 26837012b02aSJeff Layton struct locks_iterator *iter = f->private; 26847f8ada98SPavel Emelyanov struct file_lock *fl, *bfl; 2685d67fd44fSNikolay Borisov struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info; 26867f8ada98SPavel Emelyanov 2687139ca04eSJeff Layton fl = hlist_entry(v, struct file_lock, fl_link); 26887f8ada98SPavel Emelyanov 2689*9d5b86acSBenjamin Coddington if (locks_translate_pid(fl, proc_pidns) == 0) 2690d67fd44fSNikolay Borisov return 0; 2691d67fd44fSNikolay Borisov 26927012b02aSJeff Layton lock_get_status(f, fl, iter->li_pos, ""); 26937f8ada98SPavel Emelyanov 26947f8ada98SPavel Emelyanov list_for_each_entry(bfl, &fl->fl_block, fl_block) 26957012b02aSJeff Layton lock_get_status(f, bfl, iter->li_pos, " ->"); 26967f8ada98SPavel Emelyanov 26977f8ada98SPavel Emelyanov return 0; 26981da177e4SLinus Torvalds } 26991da177e4SLinus Torvalds 27006c8c9031SAndrey Vagin static void __show_fd_locks(struct seq_file *f, 27016c8c9031SAndrey Vagin struct list_head *head, int *id, 27026c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 27036c8c9031SAndrey Vagin { 27046c8c9031SAndrey Vagin struct file_lock *fl; 27056c8c9031SAndrey Vagin 27066c8c9031SAndrey Vagin list_for_each_entry(fl, head, fl_list) { 27076c8c9031SAndrey Vagin 27086c8c9031SAndrey Vagin if (filp != fl->fl_file) 27096c8c9031SAndrey Vagin continue; 27106c8c9031SAndrey Vagin if (fl->fl_owner != files && 27116c8c9031SAndrey Vagin fl->fl_owner != filp) 27126c8c9031SAndrey Vagin continue; 27136c8c9031SAndrey Vagin 27146c8c9031SAndrey Vagin (*id)++; 27156c8c9031SAndrey Vagin seq_puts(f, "lock:\t"); 27166c8c9031SAndrey Vagin lock_get_status(f, fl, *id, ""); 27176c8c9031SAndrey Vagin } 27186c8c9031SAndrey Vagin } 27196c8c9031SAndrey Vagin 27206c8c9031SAndrey Vagin void show_fd_locks(struct seq_file *f, 27216c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 27226c8c9031SAndrey Vagin { 2723c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 27246c8c9031SAndrey Vagin struct file_lock_context *ctx; 27256c8c9031SAndrey Vagin int id = 0; 27266c8c9031SAndrey Vagin 2727128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 27286c8c9031SAndrey Vagin if (!ctx) 27296c8c9031SAndrey Vagin return; 27306c8c9031SAndrey Vagin 27316c8c9031SAndrey Vagin spin_lock(&ctx->flc_lock); 27326c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_flock, &id, filp, files); 27336c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_posix, &id, filp, files); 27346c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_lease, &id, filp, files); 27356c8c9031SAndrey Vagin spin_unlock(&ctx->flc_lock); 27366c8c9031SAndrey Vagin } 27376c8c9031SAndrey Vagin 27387f8ada98SPavel Emelyanov static void *locks_start(struct seq_file *f, loff_t *pos) 2739b03dfdecSJeff Layton __acquires(&blocked_lock_lock) 27401da177e4SLinus Torvalds { 27417012b02aSJeff Layton struct locks_iterator *iter = f->private; 274299dc8292SJerome Marchand 27437012b02aSJeff Layton iter->li_pos = *pos + 1; 2744aba37660SPeter Zijlstra percpu_down_write(&file_rwsem); 27457b2296afSJeff Layton spin_lock(&blocked_lock_lock); 27467c3f654dSPeter Zijlstra return seq_hlist_start_percpu(&file_lock_list.hlist, &iter->li_cpu, *pos); 27471da177e4SLinus Torvalds } 27487f8ada98SPavel Emelyanov 27497f8ada98SPavel Emelyanov static void *locks_next(struct seq_file *f, void *v, loff_t *pos) 27507f8ada98SPavel Emelyanov { 27517012b02aSJeff Layton struct locks_iterator *iter = f->private; 27527012b02aSJeff Layton 27537012b02aSJeff Layton ++iter->li_pos; 27547c3f654dSPeter Zijlstra return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos); 27551da177e4SLinus Torvalds } 27567f8ada98SPavel Emelyanov 27577f8ada98SPavel Emelyanov static void locks_stop(struct seq_file *f, void *v) 2758b03dfdecSJeff Layton __releases(&blocked_lock_lock) 27597f8ada98SPavel Emelyanov { 27607b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 2761aba37660SPeter Zijlstra percpu_up_write(&file_rwsem); 27621da177e4SLinus Torvalds } 27631da177e4SLinus Torvalds 2764d8ba7a36SAlexey Dobriyan static const struct seq_operations locks_seq_operations = { 27657f8ada98SPavel Emelyanov .start = locks_start, 27667f8ada98SPavel Emelyanov .next = locks_next, 27677f8ada98SPavel Emelyanov .stop = locks_stop, 27687f8ada98SPavel Emelyanov .show = locks_show, 27697f8ada98SPavel Emelyanov }; 2770d8ba7a36SAlexey Dobriyan 2771d8ba7a36SAlexey Dobriyan static int locks_open(struct inode *inode, struct file *filp) 2772d8ba7a36SAlexey Dobriyan { 27737012b02aSJeff Layton return seq_open_private(filp, &locks_seq_operations, 27747012b02aSJeff Layton sizeof(struct locks_iterator)); 2775d8ba7a36SAlexey Dobriyan } 2776d8ba7a36SAlexey Dobriyan 2777d8ba7a36SAlexey Dobriyan static const struct file_operations proc_locks_operations = { 2778d8ba7a36SAlexey Dobriyan .open = locks_open, 2779d8ba7a36SAlexey Dobriyan .read = seq_read, 2780d8ba7a36SAlexey Dobriyan .llseek = seq_lseek, 278199dc8292SJerome Marchand .release = seq_release_private, 2782d8ba7a36SAlexey Dobriyan }; 2783d8ba7a36SAlexey Dobriyan 2784d8ba7a36SAlexey Dobriyan static int __init proc_locks_init(void) 2785d8ba7a36SAlexey Dobriyan { 2786d8ba7a36SAlexey Dobriyan proc_create("locks", 0, NULL, &proc_locks_operations); 2787d8ba7a36SAlexey Dobriyan return 0; 2788d8ba7a36SAlexey Dobriyan } 278991899226SPaul Gortmaker fs_initcall(proc_locks_init); 27907f8ada98SPavel Emelyanov #endif 27917f8ada98SPavel Emelyanov 27921da177e4SLinus Torvalds static int __init filelock_init(void) 27931da177e4SLinus Torvalds { 27947012b02aSJeff Layton int i; 27957012b02aSJeff Layton 27964a075e39SJeff Layton flctx_cache = kmem_cache_create("file_lock_ctx", 27974a075e39SJeff Layton sizeof(struct file_lock_context), 0, SLAB_PANIC, NULL); 27984a075e39SJeff Layton 27991da177e4SLinus Torvalds filelock_cache = kmem_cache_create("file_lock_cache", 2800ee19cc40SMiklos Szeredi sizeof(struct file_lock), 0, SLAB_PANIC, NULL); 2801ee19cc40SMiklos Szeredi 28027012b02aSJeff Layton 28037c3f654dSPeter Zijlstra for_each_possible_cpu(i) { 28047c3f654dSPeter Zijlstra struct file_lock_list_struct *fll = per_cpu_ptr(&file_lock_list, i); 28057c3f654dSPeter Zijlstra 28067c3f654dSPeter Zijlstra spin_lock_init(&fll->lock); 28077c3f654dSPeter Zijlstra INIT_HLIST_HEAD(&fll->hlist); 28087c3f654dSPeter Zijlstra } 28097012b02aSJeff Layton 28101da177e4SLinus Torvalds return 0; 28111da177e4SLinus Torvalds } 28121da177e4SLinus Torvalds 28131da177e4SLinus Torvalds core_initcall(filelock_init); 2814