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) 1409d5b86acSBenjamin Coddington #define IS_REMOTELCK(fl) (fl->fl_pid <= 0) 1411da177e4SLinus Torvalds 142c568d683SMiklos Szeredi static inline bool is_remote_lock(struct file *filp) 143c568d683SMiklos Szeredi { 1441751e8a6SLinus Torvalds return likely(!(filp->f_path.dentry->d_sb->s_flags & SB_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 2743953704fSBenjamin Coddington static void 2753953704fSBenjamin Coddington locks_check_ctx_file_list(struct file *filp, struct list_head *list, 2763953704fSBenjamin Coddington char *list_type) 2773953704fSBenjamin Coddington { 2783953704fSBenjamin Coddington struct file_lock *fl; 2793953704fSBenjamin Coddington struct inode *inode = locks_inode(filp); 2803953704fSBenjamin Coddington 2813953704fSBenjamin Coddington list_for_each_entry(fl, list, fl_list) 2823953704fSBenjamin Coddington if (fl->fl_file == filp) 2833953704fSBenjamin Coddington pr_warn("Leaked %s lock on dev=0x%x:0x%x ino=0x%lx " 2843953704fSBenjamin Coddington " fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n", 2853953704fSBenjamin Coddington list_type, MAJOR(inode->i_sb->s_dev), 2863953704fSBenjamin Coddington MINOR(inode->i_sb->s_dev), inode->i_ino, 2873953704fSBenjamin Coddington fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid); 2883953704fSBenjamin Coddington } 2893953704fSBenjamin Coddington 2904a075e39SJeff Layton void 291f27a0fe0SJeff Layton locks_free_lock_context(struct inode *inode) 2924a075e39SJeff Layton { 293f27a0fe0SJeff Layton struct file_lock_context *ctx = inode->i_flctx; 294f27a0fe0SJeff Layton 295e24dadabSJeff Layton if (unlikely(ctx)) { 296e24dadabSJeff Layton locks_check_ctx_lists(inode); 2974a075e39SJeff Layton kmem_cache_free(flctx_cache, ctx); 2984a075e39SJeff Layton } 2994a075e39SJeff Layton } 3004a075e39SJeff Layton 301ee19cc40SMiklos Szeredi static void locks_init_lock_heads(struct file_lock *fl) 302a51cb91dSMiklos Szeredi { 303139ca04eSJeff Layton INIT_HLIST_NODE(&fl->fl_link); 3046dee60f6SJeff Layton INIT_LIST_HEAD(&fl->fl_list); 305ee19cc40SMiklos Szeredi INIT_LIST_HEAD(&fl->fl_block); 306ee19cc40SMiklos Szeredi init_waitqueue_head(&fl->fl_wait); 307a51cb91dSMiklos Szeredi } 308a51cb91dSMiklos Szeredi 3091da177e4SLinus Torvalds /* Allocate an empty lock structure. */ 310c5b1f0d9SArnd Bergmann struct file_lock *locks_alloc_lock(void) 3111da177e4SLinus Torvalds { 312ee19cc40SMiklos Szeredi struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL); 313a51cb91dSMiklos Szeredi 314a51cb91dSMiklos Szeredi if (fl) 315ee19cc40SMiklos Szeredi locks_init_lock_heads(fl); 316a51cb91dSMiklos Szeredi 317a51cb91dSMiklos Szeredi return fl; 3181da177e4SLinus Torvalds } 319c5b1f0d9SArnd Bergmann EXPORT_SYMBOL_GPL(locks_alloc_lock); 3201da177e4SLinus Torvalds 321a9e61e25SFelix Blyakher void locks_release_private(struct file_lock *fl) 32247831f35STrond Myklebust { 32347831f35STrond Myklebust if (fl->fl_ops) { 32447831f35STrond Myklebust if (fl->fl_ops->fl_release_private) 32547831f35STrond Myklebust fl->fl_ops->fl_release_private(fl); 32647831f35STrond Myklebust fl->fl_ops = NULL; 32747831f35STrond Myklebust } 32847831f35STrond Myklebust 3295c97d7b1SKinglong Mee if (fl->fl_lmops) { 330cae80b30SJeff Layton if (fl->fl_lmops->lm_put_owner) { 331cae80b30SJeff Layton fl->fl_lmops->lm_put_owner(fl->fl_owner); 332cae80b30SJeff Layton fl->fl_owner = NULL; 333cae80b30SJeff Layton } 3345c97d7b1SKinglong Mee fl->fl_lmops = NULL; 3355c97d7b1SKinglong Mee } 33647831f35STrond Myklebust } 337a9e61e25SFelix Blyakher EXPORT_SYMBOL_GPL(locks_release_private); 33847831f35STrond Myklebust 3391da177e4SLinus Torvalds /* Free a lock which is not in use. */ 34005fa3135SJ. Bruce Fields void locks_free_lock(struct file_lock *fl) 3411da177e4SLinus Torvalds { 3425ce29646SMiklos Szeredi BUG_ON(waitqueue_active(&fl->fl_wait)); 3436dee60f6SJeff Layton BUG_ON(!list_empty(&fl->fl_list)); 3445ce29646SMiklos Szeredi BUG_ON(!list_empty(&fl->fl_block)); 345139ca04eSJeff Layton BUG_ON(!hlist_unhashed(&fl->fl_link)); 3461da177e4SLinus Torvalds 34747831f35STrond Myklebust locks_release_private(fl); 3481da177e4SLinus Torvalds kmem_cache_free(filelock_cache, fl); 3491da177e4SLinus Torvalds } 35005fa3135SJ. Bruce Fields EXPORT_SYMBOL(locks_free_lock); 3511da177e4SLinus Torvalds 352ed9814d8SJeff Layton static void 353ed9814d8SJeff Layton locks_dispose_list(struct list_head *dispose) 354ed9814d8SJeff Layton { 355ed9814d8SJeff Layton struct file_lock *fl; 356ed9814d8SJeff Layton 357ed9814d8SJeff Layton while (!list_empty(dispose)) { 3586dee60f6SJeff Layton fl = list_first_entry(dispose, struct file_lock, fl_list); 3596dee60f6SJeff Layton list_del_init(&fl->fl_list); 360ed9814d8SJeff Layton locks_free_lock(fl); 361ed9814d8SJeff Layton } 362ed9814d8SJeff Layton } 363ed9814d8SJeff Layton 3641da177e4SLinus Torvalds void locks_init_lock(struct file_lock *fl) 3651da177e4SLinus Torvalds { 366ee19cc40SMiklos Szeredi memset(fl, 0, sizeof(struct file_lock)); 367ee19cc40SMiklos Szeredi locks_init_lock_heads(fl); 3681da177e4SLinus Torvalds } 3691da177e4SLinus Torvalds 3701da177e4SLinus Torvalds EXPORT_SYMBOL(locks_init_lock); 3711da177e4SLinus Torvalds 3721da177e4SLinus Torvalds /* 3731da177e4SLinus Torvalds * Initialize a new lock from an existing file_lock structure. 3741da177e4SLinus Torvalds */ 3753fe0fff1SKinglong Mee void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) 3761da177e4SLinus Torvalds { 3771da177e4SLinus Torvalds new->fl_owner = fl->fl_owner; 3781da177e4SLinus Torvalds new->fl_pid = fl->fl_pid; 3790996905fSTrond Myklebust new->fl_file = NULL; 3801da177e4SLinus Torvalds new->fl_flags = fl->fl_flags; 3811da177e4SLinus Torvalds new->fl_type = fl->fl_type; 3821da177e4SLinus Torvalds new->fl_start = fl->fl_start; 3831da177e4SLinus Torvalds new->fl_end = fl->fl_end; 384f328296eSKinglong Mee new->fl_lmops = fl->fl_lmops; 3850996905fSTrond Myklebust new->fl_ops = NULL; 386f328296eSKinglong Mee 387f328296eSKinglong Mee if (fl->fl_lmops) { 388f328296eSKinglong Mee if (fl->fl_lmops->lm_get_owner) 389cae80b30SJeff Layton fl->fl_lmops->lm_get_owner(fl->fl_owner); 390f328296eSKinglong Mee } 3910996905fSTrond Myklebust } 3923fe0fff1SKinglong Mee EXPORT_SYMBOL(locks_copy_conflock); 3930996905fSTrond Myklebust 3940996905fSTrond Myklebust void locks_copy_lock(struct file_lock *new, struct file_lock *fl) 3950996905fSTrond Myklebust { 396566709bdSJeff Layton /* "new" must be a freshly-initialized lock */ 397566709bdSJeff Layton WARN_ON_ONCE(new->fl_ops); 3980996905fSTrond Myklebust 3993fe0fff1SKinglong Mee locks_copy_conflock(new, fl); 400f328296eSKinglong Mee 4010996905fSTrond Myklebust new->fl_file = fl->fl_file; 4021da177e4SLinus Torvalds new->fl_ops = fl->fl_ops; 40347831f35STrond Myklebust 404f328296eSKinglong Mee if (fl->fl_ops) { 405f328296eSKinglong Mee if (fl->fl_ops->fl_copy_lock) 406f328296eSKinglong Mee fl->fl_ops->fl_copy_lock(new, fl); 407f328296eSKinglong Mee } 4081da177e4SLinus Torvalds } 4091da177e4SLinus Torvalds 4101da177e4SLinus Torvalds EXPORT_SYMBOL(locks_copy_lock); 4111da177e4SLinus Torvalds 4121da177e4SLinus Torvalds static inline int flock_translate_cmd(int cmd) { 4131da177e4SLinus Torvalds if (cmd & LOCK_MAND) 4141da177e4SLinus Torvalds return cmd & (LOCK_MAND | LOCK_RW); 4151da177e4SLinus Torvalds switch (cmd) { 4161da177e4SLinus Torvalds case LOCK_SH: 4171da177e4SLinus Torvalds return F_RDLCK; 4181da177e4SLinus Torvalds case LOCK_EX: 4191da177e4SLinus Torvalds return F_WRLCK; 4201da177e4SLinus Torvalds case LOCK_UN: 4211da177e4SLinus Torvalds return F_UNLCK; 4221da177e4SLinus Torvalds } 4231da177e4SLinus Torvalds return -EINVAL; 4241da177e4SLinus Torvalds } 4251da177e4SLinus Torvalds 4261da177e4SLinus Torvalds /* Fill in a file_lock structure with an appropriate FLOCK lock. */ 4276e129d00SJeff Layton static struct file_lock * 4286e129d00SJeff Layton flock_make_lock(struct file *filp, unsigned int cmd) 4291da177e4SLinus Torvalds { 4301da177e4SLinus Torvalds struct file_lock *fl; 4311da177e4SLinus Torvalds int type = flock_translate_cmd(cmd); 4326e129d00SJeff Layton 4331da177e4SLinus Torvalds if (type < 0) 4346e129d00SJeff Layton return ERR_PTR(type); 4351da177e4SLinus Torvalds 4361da177e4SLinus Torvalds fl = locks_alloc_lock(); 4371da177e4SLinus Torvalds if (fl == NULL) 4386e129d00SJeff Layton return ERR_PTR(-ENOMEM); 4391da177e4SLinus Torvalds 4401da177e4SLinus Torvalds fl->fl_file = filp; 44173a8f5f7SChristoph Hellwig fl->fl_owner = filp; 4421da177e4SLinus Torvalds fl->fl_pid = current->tgid; 4431da177e4SLinus Torvalds fl->fl_flags = FL_FLOCK; 4441da177e4SLinus Torvalds fl->fl_type = type; 4451da177e4SLinus Torvalds fl->fl_end = OFFSET_MAX; 4461da177e4SLinus Torvalds 4476e129d00SJeff Layton return fl; 4481da177e4SLinus Torvalds } 4491da177e4SLinus Torvalds 4500ec4f431SJ. Bruce Fields static int assign_type(struct file_lock *fl, long type) 4511da177e4SLinus Torvalds { 4521da177e4SLinus Torvalds switch (type) { 4531da177e4SLinus Torvalds case F_RDLCK: 4541da177e4SLinus Torvalds case F_WRLCK: 4551da177e4SLinus Torvalds case F_UNLCK: 4561da177e4SLinus Torvalds fl->fl_type = type; 4571da177e4SLinus Torvalds break; 4581da177e4SLinus Torvalds default: 4591da177e4SLinus Torvalds return -EINVAL; 4601da177e4SLinus Torvalds } 4611da177e4SLinus Torvalds return 0; 4621da177e4SLinus Torvalds } 4631da177e4SLinus Torvalds 464ef12e72aSJ. Bruce Fields static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, 465ef12e72aSJ. Bruce Fields struct flock64 *l) 466ef12e72aSJ. Bruce Fields { 467ef12e72aSJ. Bruce Fields switch (l->l_whence) { 468ef12e72aSJ. Bruce Fields case SEEK_SET: 469ef12e72aSJ. Bruce Fields fl->fl_start = 0; 470ef12e72aSJ. Bruce Fields break; 471ef12e72aSJ. Bruce Fields case SEEK_CUR: 472ef12e72aSJ. Bruce Fields fl->fl_start = filp->f_pos; 473ef12e72aSJ. Bruce Fields break; 474ef12e72aSJ. Bruce Fields case SEEK_END: 475ef12e72aSJ. Bruce Fields fl->fl_start = i_size_read(file_inode(filp)); 476ef12e72aSJ. Bruce Fields break; 477ef12e72aSJ. Bruce Fields default: 478ef12e72aSJ. Bruce Fields return -EINVAL; 479ef12e72aSJ. Bruce Fields } 480ef12e72aSJ. Bruce Fields if (l->l_start > OFFSET_MAX - fl->fl_start) 481ef12e72aSJ. Bruce Fields return -EOVERFLOW; 482ef12e72aSJ. Bruce Fields fl->fl_start += l->l_start; 483ef12e72aSJ. Bruce Fields if (fl->fl_start < 0) 484ef12e72aSJ. Bruce Fields return -EINVAL; 485ef12e72aSJ. Bruce Fields 486ef12e72aSJ. Bruce Fields /* POSIX-1996 leaves the case l->l_len < 0 undefined; 487ef12e72aSJ. Bruce Fields POSIX-2001 defines it. */ 488ef12e72aSJ. Bruce Fields if (l->l_len > 0) { 489ef12e72aSJ. Bruce Fields if (l->l_len - 1 > OFFSET_MAX - fl->fl_start) 490ef12e72aSJ. Bruce Fields return -EOVERFLOW; 491ef12e72aSJ. Bruce Fields fl->fl_end = fl->fl_start + l->l_len - 1; 492ef12e72aSJ. Bruce Fields 493ef12e72aSJ. Bruce Fields } else if (l->l_len < 0) { 494ef12e72aSJ. Bruce Fields if (fl->fl_start + l->l_len < 0) 495ef12e72aSJ. Bruce Fields return -EINVAL; 496ef12e72aSJ. Bruce Fields fl->fl_end = fl->fl_start - 1; 497ef12e72aSJ. Bruce Fields fl->fl_start += l->l_len; 498ef12e72aSJ. Bruce Fields } else 499ef12e72aSJ. Bruce Fields fl->fl_end = OFFSET_MAX; 500ef12e72aSJ. Bruce Fields 501ef12e72aSJ. Bruce Fields fl->fl_owner = current->files; 502ef12e72aSJ. Bruce Fields fl->fl_pid = current->tgid; 503ef12e72aSJ. Bruce Fields fl->fl_file = filp; 504ef12e72aSJ. Bruce Fields fl->fl_flags = FL_POSIX; 505ef12e72aSJ. Bruce Fields fl->fl_ops = NULL; 506ef12e72aSJ. Bruce Fields fl->fl_lmops = NULL; 507ef12e72aSJ. Bruce Fields 508ef12e72aSJ. Bruce Fields return assign_type(fl, l->l_type); 509ef12e72aSJ. Bruce Fields } 510ef12e72aSJ. Bruce Fields 5111da177e4SLinus Torvalds /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX 5121da177e4SLinus Torvalds * style lock. 5131da177e4SLinus Torvalds */ 5141da177e4SLinus Torvalds static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, 5151da177e4SLinus Torvalds struct flock *l) 5161da177e4SLinus Torvalds { 517ef12e72aSJ. Bruce Fields struct flock64 ll = { 518ef12e72aSJ. Bruce Fields .l_type = l->l_type, 519ef12e72aSJ. Bruce Fields .l_whence = l->l_whence, 520ef12e72aSJ. Bruce Fields .l_start = l->l_start, 521ef12e72aSJ. Bruce Fields .l_len = l->l_len, 522ef12e72aSJ. Bruce Fields }; 5231da177e4SLinus Torvalds 524ef12e72aSJ. Bruce Fields return flock64_to_posix_lock(filp, fl, &ll); 5251da177e4SLinus Torvalds } 5261da177e4SLinus Torvalds 5271da177e4SLinus Torvalds /* default lease lock manager operations */ 5284d01b7f5SJeff Layton static bool 5294d01b7f5SJeff Layton lease_break_callback(struct file_lock *fl) 5301da177e4SLinus Torvalds { 5311da177e4SLinus Torvalds kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG); 5324d01b7f5SJeff Layton return false; 5331da177e4SLinus Torvalds } 5341da177e4SLinus Torvalds 5351c7dd2ffSJeff Layton static void 5361c7dd2ffSJeff Layton lease_setup(struct file_lock *fl, void **priv) 5371c7dd2ffSJeff Layton { 5381c7dd2ffSJeff Layton struct file *filp = fl->fl_file; 5391c7dd2ffSJeff Layton struct fasync_struct *fa = *priv; 5401c7dd2ffSJeff Layton 5411c7dd2ffSJeff Layton /* 5421c7dd2ffSJeff Layton * fasync_insert_entry() returns the old entry if any. If there was no 5431c7dd2ffSJeff Layton * old entry, then it used "priv" and inserted it into the fasync list. 5441c7dd2ffSJeff Layton * Clear the pointer to indicate that it shouldn't be freed. 5451c7dd2ffSJeff Layton */ 5461c7dd2ffSJeff Layton if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa)) 5471c7dd2ffSJeff Layton *priv = NULL; 5481c7dd2ffSJeff Layton 5491c7dd2ffSJeff Layton __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); 5501c7dd2ffSJeff Layton } 5511c7dd2ffSJeff Layton 5527b021967SAlexey Dobriyan static const struct lock_manager_operations lease_manager_ops = { 5538fb47a4fSJ. Bruce Fields .lm_break = lease_break_callback, 5548fb47a4fSJ. Bruce Fields .lm_change = lease_modify, 5551c7dd2ffSJeff Layton .lm_setup = lease_setup, 5561da177e4SLinus Torvalds }; 5571da177e4SLinus Torvalds 5581da177e4SLinus Torvalds /* 5591da177e4SLinus Torvalds * Initialize a lease, use the default lock manager operations 5601da177e4SLinus Torvalds */ 5610ec4f431SJ. Bruce Fields static int lease_init(struct file *filp, long type, struct file_lock *fl) 5621da177e4SLinus Torvalds { 56375dff55aSTrond Myklebust if (assign_type(fl, type) != 0) 56475dff55aSTrond Myklebust return -EINVAL; 56575dff55aSTrond Myklebust 5667ca76311SJeff Layton fl->fl_owner = filp; 5671da177e4SLinus Torvalds fl->fl_pid = current->tgid; 5681da177e4SLinus Torvalds 5691da177e4SLinus Torvalds fl->fl_file = filp; 5701da177e4SLinus Torvalds fl->fl_flags = FL_LEASE; 5711da177e4SLinus Torvalds fl->fl_start = 0; 5721da177e4SLinus Torvalds fl->fl_end = OFFSET_MAX; 5731da177e4SLinus Torvalds fl->fl_ops = NULL; 5741da177e4SLinus Torvalds fl->fl_lmops = &lease_manager_ops; 5751da177e4SLinus Torvalds return 0; 5761da177e4SLinus Torvalds } 5771da177e4SLinus Torvalds 5781da177e4SLinus Torvalds /* Allocate a file_lock initialised to this type of lease */ 5790ec4f431SJ. Bruce Fields static struct file_lock *lease_alloc(struct file *filp, long type) 5801da177e4SLinus Torvalds { 5811da177e4SLinus Torvalds struct file_lock *fl = locks_alloc_lock(); 58275dff55aSTrond Myklebust int error = -ENOMEM; 5831da177e4SLinus Torvalds 5841da177e4SLinus Torvalds if (fl == NULL) 585e32b8ee2SJ. Bruce Fields return ERR_PTR(error); 5861da177e4SLinus Torvalds 5871da177e4SLinus Torvalds error = lease_init(filp, type, fl); 58875dff55aSTrond Myklebust if (error) { 58975dff55aSTrond Myklebust locks_free_lock(fl); 590e32b8ee2SJ. Bruce Fields return ERR_PTR(error); 59175dff55aSTrond Myklebust } 592e32b8ee2SJ. Bruce Fields return fl; 5931da177e4SLinus Torvalds } 5941da177e4SLinus Torvalds 5951da177e4SLinus Torvalds /* Check if two locks overlap each other. 5961da177e4SLinus Torvalds */ 5971da177e4SLinus Torvalds static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2) 5981da177e4SLinus Torvalds { 5991da177e4SLinus Torvalds return ((fl1->fl_end >= fl2->fl_start) && 6001da177e4SLinus Torvalds (fl2->fl_end >= fl1->fl_start)); 6011da177e4SLinus Torvalds } 6021da177e4SLinus Torvalds 6031da177e4SLinus Torvalds /* 6041da177e4SLinus Torvalds * Check whether two locks have the same owner. 6051da177e4SLinus Torvalds */ 60633443c42SMatt Mackall static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2) 6071da177e4SLinus Torvalds { 6088fb47a4fSJ. Bruce Fields if (fl1->fl_lmops && fl1->fl_lmops->lm_compare_owner) 6091da177e4SLinus Torvalds return fl2->fl_lmops == fl1->fl_lmops && 6108fb47a4fSJ. Bruce Fields fl1->fl_lmops->lm_compare_owner(fl1, fl2); 6111da177e4SLinus Torvalds return fl1->fl_owner == fl2->fl_owner; 6121da177e4SLinus Torvalds } 6131da177e4SLinus Torvalds 6146109c850SJeff Layton /* Must be called with the flc_lock held! */ 6156ca10ed8SJeff Layton static void locks_insert_global_locks(struct file_lock *fl) 61688974691SJeff Layton { 6177c3f654dSPeter Zijlstra struct file_lock_list_struct *fll = this_cpu_ptr(&file_lock_list); 6187c3f654dSPeter Zijlstra 619aba37660SPeter Zijlstra percpu_rwsem_assert_held(&file_rwsem); 620aba37660SPeter Zijlstra 6217c3f654dSPeter Zijlstra spin_lock(&fll->lock); 6227012b02aSJeff Layton fl->fl_link_cpu = smp_processor_id(); 6237c3f654dSPeter Zijlstra hlist_add_head(&fl->fl_link, &fll->hlist); 6247c3f654dSPeter Zijlstra spin_unlock(&fll->lock); 62588974691SJeff Layton } 62688974691SJeff Layton 6276109c850SJeff Layton /* Must be called with the flc_lock held! */ 6286ca10ed8SJeff Layton static void locks_delete_global_locks(struct file_lock *fl) 62988974691SJeff Layton { 6307c3f654dSPeter Zijlstra struct file_lock_list_struct *fll; 6317c3f654dSPeter Zijlstra 632aba37660SPeter Zijlstra percpu_rwsem_assert_held(&file_rwsem); 633aba37660SPeter Zijlstra 6347012b02aSJeff Layton /* 6357012b02aSJeff Layton * Avoid taking lock if already unhashed. This is safe since this check 6366109c850SJeff Layton * is done while holding the flc_lock, and new insertions into the list 6377012b02aSJeff Layton * also require that it be held. 6387012b02aSJeff Layton */ 6397012b02aSJeff Layton if (hlist_unhashed(&fl->fl_link)) 6407012b02aSJeff Layton return; 6417c3f654dSPeter Zijlstra 6427c3f654dSPeter Zijlstra fll = per_cpu_ptr(&file_lock_list, fl->fl_link_cpu); 6437c3f654dSPeter Zijlstra spin_lock(&fll->lock); 644139ca04eSJeff Layton hlist_del_init(&fl->fl_link); 6457c3f654dSPeter Zijlstra spin_unlock(&fll->lock); 64688974691SJeff Layton } 64788974691SJeff Layton 6483999e493SJeff Layton static unsigned long 6493999e493SJeff Layton posix_owner_key(struct file_lock *fl) 6503999e493SJeff Layton { 6513999e493SJeff Layton if (fl->fl_lmops && fl->fl_lmops->lm_owner_key) 6523999e493SJeff Layton return fl->fl_lmops->lm_owner_key(fl); 6533999e493SJeff Layton return (unsigned long)fl->fl_owner; 6543999e493SJeff Layton } 6553999e493SJeff Layton 6566ca10ed8SJeff Layton static void locks_insert_global_blocked(struct file_lock *waiter) 65788974691SJeff Layton { 658663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 659663d5af7SDaniel Wagner 6603999e493SJeff Layton hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter)); 66188974691SJeff Layton } 66288974691SJeff Layton 6636ca10ed8SJeff Layton static void locks_delete_global_blocked(struct file_lock *waiter) 66488974691SJeff Layton { 665663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 666663d5af7SDaniel Wagner 66748f74186SJeff Layton hash_del(&waiter->fl_link); 66888974691SJeff Layton } 66988974691SJeff Layton 6701da177e4SLinus Torvalds /* Remove waiter from blocker's block list. 6711da177e4SLinus Torvalds * When blocker ends up pointing to itself then the list is empty. 6721c8c601aSJeff Layton * 6737b2296afSJeff Layton * Must be called with blocked_lock_lock held. 6741da177e4SLinus Torvalds */ 67533443c42SMatt Mackall static void __locks_delete_block(struct file_lock *waiter) 6761da177e4SLinus Torvalds { 67788974691SJeff Layton locks_delete_global_blocked(waiter); 6781da177e4SLinus Torvalds list_del_init(&waiter->fl_block); 6791da177e4SLinus Torvalds waiter->fl_next = NULL; 6801da177e4SLinus Torvalds } 6811da177e4SLinus Torvalds 6821a9e64a7SJeff Layton static void locks_delete_block(struct file_lock *waiter) 6831da177e4SLinus Torvalds { 6847b2296afSJeff Layton spin_lock(&blocked_lock_lock); 6851da177e4SLinus Torvalds __locks_delete_block(waiter); 6867b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 6871da177e4SLinus Torvalds } 6881da177e4SLinus Torvalds 6891da177e4SLinus Torvalds /* Insert waiter into blocker's block list. 6901da177e4SLinus Torvalds * We use a circular list so that processes can be easily woken up in 6911da177e4SLinus Torvalds * the order they blocked. The documentation doesn't require this but 6921da177e4SLinus Torvalds * it seems like the reasonable thing to do. 6931c8c601aSJeff Layton * 6946109c850SJeff Layton * Must be called with both the flc_lock and blocked_lock_lock held. The 6956109c850SJeff Layton * fl_block list itself is protected by the blocked_lock_lock, but by ensuring 6966109c850SJeff Layton * that the flc_lock is also held on insertions we can avoid taking the 6976109c850SJeff Layton * blocked_lock_lock in some cases when we see that the fl_block list is empty. 6981da177e4SLinus Torvalds */ 6991c8c601aSJeff Layton static void __locks_insert_block(struct file_lock *blocker, 7001da177e4SLinus Torvalds struct file_lock *waiter) 7011da177e4SLinus Torvalds { 7026dc0fe8fSJ. Bruce Fields BUG_ON(!list_empty(&waiter->fl_block)); 7031da177e4SLinus Torvalds waiter->fl_next = blocker; 70488974691SJeff Layton list_add_tail(&waiter->fl_block, &blocker->fl_block); 705cff2fce5SJeff Layton if (IS_POSIX(blocker) && !IS_OFDLCK(blocker)) 7061c8c601aSJeff Layton locks_insert_global_blocked(waiter); 7071c8c601aSJeff Layton } 7081c8c601aSJeff Layton 7096109c850SJeff Layton /* Must be called with flc_lock held. */ 7101c8c601aSJeff Layton static void locks_insert_block(struct file_lock *blocker, 7111c8c601aSJeff Layton struct file_lock *waiter) 7121c8c601aSJeff Layton { 7137b2296afSJeff Layton spin_lock(&blocked_lock_lock); 7141c8c601aSJeff Layton __locks_insert_block(blocker, waiter); 7157b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 7161da177e4SLinus Torvalds } 7171da177e4SLinus Torvalds 7181cb36012SJeff Layton /* 7191cb36012SJeff Layton * Wake up processes blocked waiting for blocker. 7201cb36012SJeff Layton * 7216109c850SJeff Layton * Must be called with the inode->flc_lock held! 7221da177e4SLinus Torvalds */ 7231da177e4SLinus Torvalds static void locks_wake_up_blocks(struct file_lock *blocker) 7241da177e4SLinus Torvalds { 7254e8c765dSJeff Layton /* 7264e8c765dSJeff Layton * Avoid taking global lock if list is empty. This is safe since new 7276109c850SJeff Layton * blocked requests are only added to the list under the flc_lock, and 7286109c850SJeff Layton * the flc_lock is always held here. Note that removal from the fl_block 7296109c850SJeff Layton * list does not require the flc_lock, so we must recheck list_empty() 7307b2296afSJeff Layton * after acquiring the blocked_lock_lock. 7314e8c765dSJeff Layton */ 7324e8c765dSJeff Layton if (list_empty(&blocker->fl_block)) 7334e8c765dSJeff Layton return; 7344e8c765dSJeff Layton 7357b2296afSJeff Layton spin_lock(&blocked_lock_lock); 7361da177e4SLinus Torvalds while (!list_empty(&blocker->fl_block)) { 737f0c1cd0eSPavel Emelyanov struct file_lock *waiter; 738f0c1cd0eSPavel Emelyanov 739f0c1cd0eSPavel Emelyanov waiter = list_first_entry(&blocker->fl_block, 7401da177e4SLinus Torvalds struct file_lock, fl_block); 7411da177e4SLinus Torvalds __locks_delete_block(waiter); 7428fb47a4fSJ. Bruce Fields if (waiter->fl_lmops && waiter->fl_lmops->lm_notify) 7438fb47a4fSJ. Bruce Fields waiter->fl_lmops->lm_notify(waiter); 7441da177e4SLinus Torvalds else 7451da177e4SLinus Torvalds wake_up(&waiter->fl_wait); 7461da177e4SLinus Torvalds } 7477b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 7481da177e4SLinus Torvalds } 7491da177e4SLinus Torvalds 7505263e31eSJeff Layton static void 751e084c1bdSJeff Layton locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) 7525263e31eSJeff Layton { 7535263e31eSJeff Layton list_add_tail(&fl->fl_list, before); 7545263e31eSJeff Layton locks_insert_global_locks(fl); 7555263e31eSJeff Layton } 7565263e31eSJeff Layton 7578634b51fSJeff Layton static void 758e084c1bdSJeff Layton locks_unlink_lock_ctx(struct file_lock *fl) 7591da177e4SLinus Torvalds { 76088974691SJeff Layton locks_delete_global_locks(fl); 7618634b51fSJeff Layton list_del_init(&fl->fl_list); 7621da177e4SLinus Torvalds locks_wake_up_blocks(fl); 76324cbe784SJeff Layton } 76424cbe784SJeff Layton 7655263e31eSJeff Layton static void 766e084c1bdSJeff Layton locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) 7675263e31eSJeff Layton { 768e084c1bdSJeff Layton locks_unlink_lock_ctx(fl); 7698634b51fSJeff Layton if (dispose) 7708634b51fSJeff Layton list_add(&fl->fl_list, dispose); 7718634b51fSJeff Layton else 7728634b51fSJeff Layton locks_free_lock(fl); 7735263e31eSJeff Layton } 7745263e31eSJeff Layton 7751da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. Common functionality 7761da177e4SLinus Torvalds * checks for shared/exclusive status of overlapping locks. 7771da177e4SLinus Torvalds */ 7781da177e4SLinus Torvalds static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) 7791da177e4SLinus Torvalds { 7801da177e4SLinus Torvalds if (sys_fl->fl_type == F_WRLCK) 7811da177e4SLinus Torvalds return 1; 7821da177e4SLinus Torvalds if (caller_fl->fl_type == F_WRLCK) 7831da177e4SLinus Torvalds return 1; 7841da177e4SLinus Torvalds return 0; 7851da177e4SLinus Torvalds } 7861da177e4SLinus Torvalds 7871da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. POSIX specific 7881da177e4SLinus Torvalds * checking before calling the locks_conflict(). 7891da177e4SLinus Torvalds */ 7901da177e4SLinus Torvalds static int posix_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) 7911da177e4SLinus Torvalds { 7921da177e4SLinus Torvalds /* POSIX locks owned by the same process do not conflict with 7931da177e4SLinus Torvalds * each other. 7941da177e4SLinus Torvalds */ 7959b8c8695SJeff Layton if (posix_same_owner(caller_fl, sys_fl)) 7961da177e4SLinus Torvalds return (0); 7971da177e4SLinus Torvalds 7981da177e4SLinus Torvalds /* Check whether they overlap */ 7991da177e4SLinus Torvalds if (!locks_overlap(caller_fl, sys_fl)) 8001da177e4SLinus Torvalds return 0; 8011da177e4SLinus Torvalds 8021da177e4SLinus Torvalds return (locks_conflict(caller_fl, sys_fl)); 8031da177e4SLinus Torvalds } 8041da177e4SLinus Torvalds 8051da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific 8061da177e4SLinus Torvalds * checking before calling the locks_conflict(). 8071da177e4SLinus Torvalds */ 8081da177e4SLinus Torvalds static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) 8091da177e4SLinus Torvalds { 8101da177e4SLinus Torvalds /* FLOCK locks referring to the same filp do not conflict with 8111da177e4SLinus Torvalds * each other. 8121da177e4SLinus Torvalds */ 8139b8c8695SJeff Layton if (caller_fl->fl_file == sys_fl->fl_file) 8141da177e4SLinus Torvalds return (0); 8151da177e4SLinus Torvalds if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND)) 8161da177e4SLinus Torvalds return 0; 8171da177e4SLinus Torvalds 8181da177e4SLinus Torvalds return (locks_conflict(caller_fl, sys_fl)); 8191da177e4SLinus Torvalds } 8201da177e4SLinus Torvalds 8216d34ac19SJ. Bruce Fields void 8229d6a8c5cSMarc Eshel posix_test_lock(struct file *filp, struct file_lock *fl) 8231da177e4SLinus Torvalds { 8241da177e4SLinus Torvalds struct file_lock *cfl; 825bd61e0a9SJeff Layton struct file_lock_context *ctx; 826c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 8271da177e4SLinus Torvalds 828128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 829bd61e0a9SJeff Layton if (!ctx || list_empty_careful(&ctx->flc_posix)) { 830bd61e0a9SJeff Layton fl->fl_type = F_UNLCK; 831bd61e0a9SJeff Layton return; 8321da177e4SLinus Torvalds } 833bd61e0a9SJeff Layton 8346109c850SJeff Layton spin_lock(&ctx->flc_lock); 835bd61e0a9SJeff Layton list_for_each_entry(cfl, &ctx->flc_posix, fl_list) { 836bd61e0a9SJeff Layton if (posix_locks_conflict(fl, cfl)) { 8373fe0fff1SKinglong Mee locks_copy_conflock(fl, cfl); 838bd61e0a9SJeff Layton goto out; 839bd61e0a9SJeff Layton } 840bd61e0a9SJeff Layton } 841129a84deSJ. Bruce Fields fl->fl_type = F_UNLCK; 842bd61e0a9SJeff Layton out: 8436109c850SJeff Layton spin_unlock(&ctx->flc_lock); 8446d34ac19SJ. Bruce Fields return; 8451da177e4SLinus Torvalds } 8461da177e4SLinus Torvalds EXPORT_SYMBOL(posix_test_lock); 8471da177e4SLinus Torvalds 848b533184fSJ. Bruce Fields /* 849b533184fSJ. Bruce Fields * Deadlock detection: 8501da177e4SLinus Torvalds * 851b533184fSJ. Bruce Fields * We attempt to detect deadlocks that are due purely to posix file 852b533184fSJ. Bruce Fields * locks. 8531da177e4SLinus Torvalds * 854b533184fSJ. Bruce Fields * We assume that a task can be waiting for at most one lock at a time. 855b533184fSJ. Bruce Fields * So for any acquired lock, the process holding that lock may be 856b533184fSJ. Bruce Fields * waiting on at most one other lock. That lock in turns may be held by 857b533184fSJ. Bruce Fields * someone waiting for at most one other lock. Given a requested lock 858b533184fSJ. Bruce Fields * caller_fl which is about to wait for a conflicting lock block_fl, we 859b533184fSJ. Bruce Fields * follow this chain of waiters to ensure we are not about to create a 860b533184fSJ. Bruce Fields * cycle. 86197855b49SJ. Bruce Fields * 862b533184fSJ. Bruce Fields * Since we do this before we ever put a process to sleep on a lock, we 863b533184fSJ. Bruce Fields * are ensured that there is never a cycle; that is what guarantees that 864b533184fSJ. Bruce Fields * the while() loop in posix_locks_deadlock() eventually completes. 865b533184fSJ. Bruce Fields * 866b533184fSJ. Bruce Fields * Note: the above assumption may not be true when handling lock 867b533184fSJ. Bruce Fields * requests from a broken NFS client. It may also fail in the presence 868b533184fSJ. Bruce Fields * of tasks (such as posix threads) sharing the same open file table. 869b533184fSJ. Bruce Fields * To handle those cases, we just bail out after a few iterations. 87057b65325SJeff Layton * 871cff2fce5SJeff Layton * For FL_OFDLCK locks, the owner is the filp, not the files_struct. 87257b65325SJeff Layton * Because the owner is not even nominally tied to a thread of 87357b65325SJeff Layton * execution, the deadlock detection below can't reasonably work well. Just 87457b65325SJeff Layton * skip it for those. 87557b65325SJeff Layton * 876cff2fce5SJeff Layton * In principle, we could do a more limited deadlock detection on FL_OFDLCK 87757b65325SJeff Layton * locks that just checks for the case where two tasks are attempting to 87857b65325SJeff Layton * upgrade from read to write locks on the same inode. 8791da177e4SLinus Torvalds */ 88097855b49SJ. Bruce Fields 88197855b49SJ. Bruce Fields #define MAX_DEADLK_ITERATIONS 10 88297855b49SJ. Bruce Fields 883b533184fSJ. Bruce Fields /* Find a lock that the owner of the given block_fl is blocking on. */ 884b533184fSJ. Bruce Fields static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl) 885b533184fSJ. Bruce Fields { 886b533184fSJ. Bruce Fields struct file_lock *fl; 887b533184fSJ. Bruce Fields 8883999e493SJeff Layton hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) { 889b533184fSJ. Bruce Fields if (posix_same_owner(fl, block_fl)) 890b533184fSJ. Bruce Fields return fl->fl_next; 891b533184fSJ. Bruce Fields } 892b533184fSJ. Bruce Fields return NULL; 893b533184fSJ. Bruce Fields } 894b533184fSJ. Bruce Fields 8957b2296afSJeff Layton /* Must be called with the blocked_lock_lock held! */ 896b0904e14SAdrian Bunk static int posix_locks_deadlock(struct file_lock *caller_fl, 8971da177e4SLinus Torvalds struct file_lock *block_fl) 8981da177e4SLinus Torvalds { 89997855b49SJ. Bruce Fields int i = 0; 9001da177e4SLinus Torvalds 901663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 902663d5af7SDaniel Wagner 90357b65325SJeff Layton /* 90457b65325SJeff Layton * This deadlock detector can't reasonably detect deadlocks with 905cff2fce5SJeff Layton * FL_OFDLCK locks, since they aren't owned by a process, per-se. 90657b65325SJeff Layton */ 907cff2fce5SJeff Layton if (IS_OFDLCK(caller_fl)) 90857b65325SJeff Layton return 0; 90957b65325SJeff Layton 910b533184fSJ. Bruce Fields while ((block_fl = what_owner_is_waiting_for(block_fl))) { 91197855b49SJ. Bruce Fields if (i++ > MAX_DEADLK_ITERATIONS) 91297855b49SJ. Bruce Fields return 0; 913b533184fSJ. Bruce Fields if (posix_same_owner(caller_fl, block_fl)) 914b533184fSJ. Bruce Fields return 1; 9151da177e4SLinus Torvalds } 9161da177e4SLinus Torvalds return 0; 9171da177e4SLinus Torvalds } 9181da177e4SLinus Torvalds 9191da177e4SLinus Torvalds /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 92002888f41SJ. Bruce Fields * after any leases, but before any posix locks. 921f475ae95STrond Myklebust * 922f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 923f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 924f475ae95STrond Myklebust * value for -ENOENT. 9251da177e4SLinus Torvalds */ 926bcd7f78dSJeff Layton static int flock_lock_inode(struct inode *inode, struct file_lock *request) 9271da177e4SLinus Torvalds { 928993dfa87STrond Myklebust struct file_lock *new_fl = NULL; 9295263e31eSJeff Layton struct file_lock *fl; 9305263e31eSJeff Layton struct file_lock_context *ctx; 9311da177e4SLinus Torvalds int error = 0; 9325263e31eSJeff Layton bool found = false; 933ed9814d8SJeff Layton LIST_HEAD(dispose); 9341da177e4SLinus Torvalds 9355c1c669aSJeff Layton ctx = locks_get_lock_context(inode, request->fl_type); 9365c1c669aSJeff Layton if (!ctx) { 9375c1c669aSJeff Layton if (request->fl_type != F_UNLCK) 9385263e31eSJeff Layton return -ENOMEM; 9395c1c669aSJeff Layton return (request->fl_flags & FL_EXISTS) ? -ENOENT : 0; 9405c1c669aSJeff Layton } 9415263e31eSJeff Layton 942b89f4321SArnd Bergmann if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) { 943b89f4321SArnd Bergmann new_fl = locks_alloc_lock(); 944b89f4321SArnd Bergmann if (!new_fl) 945b89f4321SArnd Bergmann return -ENOMEM; 946b89f4321SArnd Bergmann } 947b89f4321SArnd Bergmann 94887709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 9496109c850SJeff Layton spin_lock(&ctx->flc_lock); 950f07f18ddSTrond Myklebust if (request->fl_flags & FL_ACCESS) 951f07f18ddSTrond Myklebust goto find_conflict; 95284d535adSPavel Emelyanov 9535263e31eSJeff Layton list_for_each_entry(fl, &ctx->flc_flock, fl_list) { 954bcd7f78dSJeff Layton if (request->fl_file != fl->fl_file) 9551da177e4SLinus Torvalds continue; 956993dfa87STrond Myklebust if (request->fl_type == fl->fl_type) 9571da177e4SLinus Torvalds goto out; 9585263e31eSJeff Layton found = true; 959e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 9601da177e4SLinus Torvalds break; 9611da177e4SLinus Torvalds } 9621da177e4SLinus Torvalds 963f475ae95STrond Myklebust if (request->fl_type == F_UNLCK) { 964f475ae95STrond Myklebust if ((request->fl_flags & FL_EXISTS) && !found) 965f475ae95STrond Myklebust error = -ENOENT; 966993dfa87STrond Myklebust goto out; 967f475ae95STrond Myklebust } 9681da177e4SLinus Torvalds 969f07f18ddSTrond Myklebust find_conflict: 9705263e31eSJeff Layton list_for_each_entry(fl, &ctx->flc_flock, fl_list) { 971993dfa87STrond Myklebust if (!flock_locks_conflict(request, fl)) 9721da177e4SLinus Torvalds continue; 9731da177e4SLinus Torvalds error = -EAGAIN; 974bde74e4bSMiklos Szeredi if (!(request->fl_flags & FL_SLEEP)) 975bde74e4bSMiklos Szeredi goto out; 976bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 977993dfa87STrond Myklebust locks_insert_block(fl, request); 9781da177e4SLinus Torvalds goto out; 9791da177e4SLinus Torvalds } 980f07f18ddSTrond Myklebust if (request->fl_flags & FL_ACCESS) 981f07f18ddSTrond Myklebust goto out; 982993dfa87STrond Myklebust locks_copy_lock(new_fl, request); 983e084c1bdSJeff Layton locks_insert_lock_ctx(new_fl, &ctx->flc_flock); 984993dfa87STrond Myklebust new_fl = NULL; 9859cedc194SKirill Korotaev error = 0; 9861da177e4SLinus Torvalds 9871da177e4SLinus Torvalds out: 9886109c850SJeff Layton spin_unlock(&ctx->flc_lock); 98987709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 990993dfa87STrond Myklebust if (new_fl) 991993dfa87STrond Myklebust locks_free_lock(new_fl); 992ed9814d8SJeff Layton locks_dispose_list(&dispose); 9931da177e4SLinus Torvalds return error; 9941da177e4SLinus Torvalds } 9951da177e4SLinus Torvalds 996b4d629a3SJeff Layton static int posix_lock_inode(struct inode *inode, struct file_lock *request, 997b4d629a3SJeff Layton struct file_lock *conflock) 9981da177e4SLinus Torvalds { 999bd61e0a9SJeff Layton struct file_lock *fl, *tmp; 100039005d02SMiklos Szeredi struct file_lock *new_fl = NULL; 100139005d02SMiklos Szeredi struct file_lock *new_fl2 = NULL; 10021da177e4SLinus Torvalds struct file_lock *left = NULL; 10031da177e4SLinus Torvalds struct file_lock *right = NULL; 1004bd61e0a9SJeff Layton struct file_lock_context *ctx; 1005b9746ef8SJeff Layton int error; 1006b9746ef8SJeff Layton bool added = false; 1007ed9814d8SJeff Layton LIST_HEAD(dispose); 10081da177e4SLinus Torvalds 10095c1c669aSJeff Layton ctx = locks_get_lock_context(inode, request->fl_type); 1010bd61e0a9SJeff Layton if (!ctx) 10115c1c669aSJeff Layton return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM; 1012bd61e0a9SJeff Layton 10131da177e4SLinus Torvalds /* 10141da177e4SLinus Torvalds * We may need two file_lock structures for this operation, 10151da177e4SLinus Torvalds * so we get them in advance to avoid races. 101639005d02SMiklos Szeredi * 101739005d02SMiklos Szeredi * In some cases we can be sure, that no new locks will be needed 10181da177e4SLinus Torvalds */ 101939005d02SMiklos Szeredi if (!(request->fl_flags & FL_ACCESS) && 102039005d02SMiklos Szeredi (request->fl_type != F_UNLCK || 102139005d02SMiklos Szeredi request->fl_start != 0 || request->fl_end != OFFSET_MAX)) { 10221da177e4SLinus Torvalds new_fl = locks_alloc_lock(); 10231da177e4SLinus Torvalds new_fl2 = locks_alloc_lock(); 102439005d02SMiklos Szeredi } 10251da177e4SLinus Torvalds 102687709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 10276109c850SJeff Layton spin_lock(&ctx->flc_lock); 10281cb36012SJeff Layton /* 10291cb36012SJeff Layton * New lock request. Walk all POSIX locks and look for conflicts. If 10301cb36012SJeff Layton * there are any, either return error or put the request on the 103148f74186SJeff Layton * blocker's list of waiters and the global blocked_hash. 10321cb36012SJeff Layton */ 10331da177e4SLinus Torvalds if (request->fl_type != F_UNLCK) { 1034bd61e0a9SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, fl_list) { 10351da177e4SLinus Torvalds if (!posix_locks_conflict(request, fl)) 10361da177e4SLinus Torvalds continue; 10375842add2SAndy Adamson if (conflock) 10383fe0fff1SKinglong Mee locks_copy_conflock(conflock, fl); 10391da177e4SLinus Torvalds error = -EAGAIN; 10401da177e4SLinus Torvalds if (!(request->fl_flags & FL_SLEEP)) 10411da177e4SLinus Torvalds goto out; 10421c8c601aSJeff Layton /* 10431c8c601aSJeff Layton * Deadlock detection and insertion into the blocked 10441c8c601aSJeff Layton * locks list must be done while holding the same lock! 10451c8c601aSJeff Layton */ 10461da177e4SLinus Torvalds error = -EDEADLK; 10477b2296afSJeff Layton spin_lock(&blocked_lock_lock); 10481c8c601aSJeff Layton if (likely(!posix_locks_deadlock(request, fl))) { 1049bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 10501c8c601aSJeff Layton __locks_insert_block(fl, request); 10511c8c601aSJeff Layton } 10527b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 10531da177e4SLinus Torvalds goto out; 10541da177e4SLinus Torvalds } 10551da177e4SLinus Torvalds } 10561da177e4SLinus Torvalds 10571da177e4SLinus Torvalds /* If we're just looking for a conflict, we're done. */ 10581da177e4SLinus Torvalds error = 0; 10591da177e4SLinus Torvalds if (request->fl_flags & FL_ACCESS) 10601da177e4SLinus Torvalds goto out; 10611da177e4SLinus Torvalds 1062bd61e0a9SJeff Layton /* Find the first old lock with the same owner as the new lock */ 1063bd61e0a9SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, fl_list) { 1064bd61e0a9SJeff Layton if (posix_same_owner(request, fl)) 1065bd61e0a9SJeff Layton break; 10661da177e4SLinus Torvalds } 10671da177e4SLinus Torvalds 10681da177e4SLinus Torvalds /* Process locks with this owner. */ 1069bd61e0a9SJeff Layton list_for_each_entry_safe_from(fl, tmp, &ctx->flc_posix, fl_list) { 1070bd61e0a9SJeff Layton if (!posix_same_owner(request, fl)) 1071bd61e0a9SJeff Layton break; 1072bd61e0a9SJeff Layton 1073bd61e0a9SJeff Layton /* Detect adjacent or overlapping regions (if same lock type) */ 10741da177e4SLinus Torvalds if (request->fl_type == fl->fl_type) { 1075449231d6SOlaf Kirch /* In all comparisons of start vs end, use 1076449231d6SOlaf Kirch * "start - 1" rather than "end + 1". If end 1077449231d6SOlaf Kirch * is OFFSET_MAX, end + 1 will become negative. 1078449231d6SOlaf Kirch */ 10791da177e4SLinus Torvalds if (fl->fl_end < request->fl_start - 1) 1080bd61e0a9SJeff Layton continue; 10811da177e4SLinus Torvalds /* If the next lock in the list has entirely bigger 10821da177e4SLinus Torvalds * addresses than the new one, insert the lock here. 10831da177e4SLinus Torvalds */ 1084449231d6SOlaf Kirch if (fl->fl_start - 1 > request->fl_end) 10851da177e4SLinus Torvalds break; 10861da177e4SLinus Torvalds 10871da177e4SLinus Torvalds /* If we come here, the new and old lock are of the 10881da177e4SLinus Torvalds * same type and adjacent or overlapping. Make one 10891da177e4SLinus Torvalds * lock yielding from the lower start address of both 10901da177e4SLinus Torvalds * locks to the higher end address. 10911da177e4SLinus Torvalds */ 10921da177e4SLinus Torvalds if (fl->fl_start > request->fl_start) 10931da177e4SLinus Torvalds fl->fl_start = request->fl_start; 10941da177e4SLinus Torvalds else 10951da177e4SLinus Torvalds request->fl_start = fl->fl_start; 10961da177e4SLinus Torvalds if (fl->fl_end < request->fl_end) 10971da177e4SLinus Torvalds fl->fl_end = request->fl_end; 10981da177e4SLinus Torvalds else 10991da177e4SLinus Torvalds request->fl_end = fl->fl_end; 11001da177e4SLinus Torvalds if (added) { 1101e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 11021da177e4SLinus Torvalds continue; 11031da177e4SLinus Torvalds } 11041da177e4SLinus Torvalds request = fl; 1105b9746ef8SJeff Layton added = true; 1106bd61e0a9SJeff Layton } else { 11071da177e4SLinus Torvalds /* Processing for different lock types is a bit 11081da177e4SLinus Torvalds * more complex. 11091da177e4SLinus Torvalds */ 11101da177e4SLinus Torvalds if (fl->fl_end < request->fl_start) 1111bd61e0a9SJeff Layton continue; 11121da177e4SLinus Torvalds if (fl->fl_start > request->fl_end) 11131da177e4SLinus Torvalds break; 11141da177e4SLinus Torvalds if (request->fl_type == F_UNLCK) 1115b9746ef8SJeff Layton added = true; 11161da177e4SLinus Torvalds if (fl->fl_start < request->fl_start) 11171da177e4SLinus Torvalds left = fl; 11181da177e4SLinus Torvalds /* If the next lock in the list has a higher end 11191da177e4SLinus Torvalds * address than the new one, insert the new one here. 11201da177e4SLinus Torvalds */ 11211da177e4SLinus Torvalds if (fl->fl_end > request->fl_end) { 11221da177e4SLinus Torvalds right = fl; 11231da177e4SLinus Torvalds break; 11241da177e4SLinus Torvalds } 11251da177e4SLinus Torvalds if (fl->fl_start >= request->fl_start) { 11261da177e4SLinus Torvalds /* The new lock completely replaces an old 11271da177e4SLinus Torvalds * one (This may happen several times). 11281da177e4SLinus Torvalds */ 11291da177e4SLinus Torvalds if (added) { 1130e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 11311da177e4SLinus Torvalds continue; 11321da177e4SLinus Torvalds } 1133b84d49f9SJeff Layton /* 1134b84d49f9SJeff Layton * Replace the old lock with new_fl, and 1135b84d49f9SJeff Layton * remove the old one. It's safe to do the 1136b84d49f9SJeff Layton * insert here since we know that we won't be 1137b84d49f9SJeff Layton * using new_fl later, and that the lock is 1138b84d49f9SJeff Layton * just replacing an existing lock. 11391da177e4SLinus Torvalds */ 1140b84d49f9SJeff Layton error = -ENOLCK; 1141b84d49f9SJeff Layton if (!new_fl) 1142b84d49f9SJeff Layton goto out; 1143b84d49f9SJeff Layton locks_copy_lock(new_fl, request); 1144b84d49f9SJeff Layton request = new_fl; 1145b84d49f9SJeff Layton new_fl = NULL; 1146e084c1bdSJeff Layton locks_insert_lock_ctx(request, &fl->fl_list); 1147e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 1148b9746ef8SJeff Layton added = true; 11491da177e4SLinus Torvalds } 11501da177e4SLinus Torvalds } 11511da177e4SLinus Torvalds } 11521da177e4SLinus Torvalds 11530d9a490aSMiklos Szeredi /* 11541cb36012SJeff Layton * The above code only modifies existing locks in case of merging or 11551cb36012SJeff Layton * replacing. If new lock(s) need to be inserted all modifications are 11561cb36012SJeff Layton * done below this, so it's safe yet to bail out. 11570d9a490aSMiklos Szeredi */ 11580d9a490aSMiklos Szeredi error = -ENOLCK; /* "no luck" */ 11590d9a490aSMiklos Szeredi if (right && left == right && !new_fl2) 11600d9a490aSMiklos Szeredi goto out; 11610d9a490aSMiklos Szeredi 11621da177e4SLinus Torvalds error = 0; 11631da177e4SLinus Torvalds if (!added) { 1164f475ae95STrond Myklebust if (request->fl_type == F_UNLCK) { 1165f475ae95STrond Myklebust if (request->fl_flags & FL_EXISTS) 1166f475ae95STrond Myklebust error = -ENOENT; 11671da177e4SLinus Torvalds goto out; 1168f475ae95STrond Myklebust } 11690d9a490aSMiklos Szeredi 11700d9a490aSMiklos Szeredi if (!new_fl) { 11710d9a490aSMiklos Szeredi error = -ENOLCK; 11720d9a490aSMiklos Szeredi goto out; 11730d9a490aSMiklos Szeredi } 11741da177e4SLinus Torvalds locks_copy_lock(new_fl, request); 1175e084c1bdSJeff Layton locks_insert_lock_ctx(new_fl, &fl->fl_list); 11762e2f756fSJeff Layton fl = new_fl; 11771da177e4SLinus Torvalds new_fl = NULL; 11781da177e4SLinus Torvalds } 11791da177e4SLinus Torvalds if (right) { 11801da177e4SLinus Torvalds if (left == right) { 11811da177e4SLinus Torvalds /* The new lock breaks the old one in two pieces, 11821da177e4SLinus Torvalds * so we have to use the second new lock. 11831da177e4SLinus Torvalds */ 11841da177e4SLinus Torvalds left = new_fl2; 11851da177e4SLinus Torvalds new_fl2 = NULL; 11861da177e4SLinus Torvalds locks_copy_lock(left, right); 1187e084c1bdSJeff Layton locks_insert_lock_ctx(left, &fl->fl_list); 11881da177e4SLinus Torvalds } 11891da177e4SLinus Torvalds right->fl_start = request->fl_end + 1; 11901da177e4SLinus Torvalds locks_wake_up_blocks(right); 11911da177e4SLinus Torvalds } 11921da177e4SLinus Torvalds if (left) { 11931da177e4SLinus Torvalds left->fl_end = request->fl_start - 1; 11941da177e4SLinus Torvalds locks_wake_up_blocks(left); 11951da177e4SLinus Torvalds } 11961da177e4SLinus Torvalds out: 11976109c850SJeff Layton spin_unlock(&ctx->flc_lock); 119887709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 11991da177e4SLinus Torvalds /* 12001da177e4SLinus Torvalds * Free any unused locks. 12011da177e4SLinus Torvalds */ 12021da177e4SLinus Torvalds if (new_fl) 12031da177e4SLinus Torvalds locks_free_lock(new_fl); 12041da177e4SLinus Torvalds if (new_fl2) 12051da177e4SLinus Torvalds locks_free_lock(new_fl2); 1206ed9814d8SJeff Layton locks_dispose_list(&dispose); 12071890910fSJeff Layton trace_posix_lock_inode(inode, request, error); 12081890910fSJeff Layton 12091da177e4SLinus Torvalds return error; 12101da177e4SLinus Torvalds } 12111da177e4SLinus Torvalds 12121da177e4SLinus Torvalds /** 12131da177e4SLinus Torvalds * posix_lock_file - Apply a POSIX-style lock to a file 12141da177e4SLinus Torvalds * @filp: The file to apply the lock to 12151da177e4SLinus Torvalds * @fl: The lock to be applied 1216150b3934SMarc Eshel * @conflock: Place to return a copy of the conflicting lock, if found. 12171da177e4SLinus Torvalds * 12181da177e4SLinus Torvalds * Add a POSIX style lock to a file. 12191da177e4SLinus Torvalds * We merge adjacent & overlapping locks whenever possible. 12201da177e4SLinus Torvalds * POSIX locks are sorted by owner task, then by starting address 1221f475ae95STrond Myklebust * 1222f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 1223f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 1224f475ae95STrond Myklebust * value for -ENOENT. 12251da177e4SLinus Torvalds */ 1226150b3934SMarc Eshel int posix_lock_file(struct file *filp, struct file_lock *fl, 12275842add2SAndy Adamson struct file_lock *conflock) 12285842add2SAndy Adamson { 1229c568d683SMiklos Szeredi return posix_lock_inode(locks_inode(filp), fl, conflock); 12305842add2SAndy Adamson } 1231150b3934SMarc Eshel EXPORT_SYMBOL(posix_lock_file); 12321da177e4SLinus Torvalds 12331da177e4SLinus Torvalds /** 123429d01b22SJeff Layton * posix_lock_inode_wait - Apply a POSIX-style lock to a file 123529d01b22SJeff Layton * @inode: inode of file to which lock request should be applied 12361da177e4SLinus Torvalds * @fl: The lock to be applied 12371da177e4SLinus Torvalds * 1238616fb38fSBenjamin Coddington * Apply a POSIX style lock request to an inode. 12391da177e4SLinus Torvalds */ 1240616fb38fSBenjamin Coddington static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) 12411da177e4SLinus Torvalds { 12421da177e4SLinus Torvalds int error; 12431da177e4SLinus Torvalds might_sleep (); 12441da177e4SLinus Torvalds for (;;) { 1245b4d629a3SJeff Layton error = posix_lock_inode(inode, fl, NULL); 1246bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 12471da177e4SLinus Torvalds break; 12481da177e4SLinus Torvalds error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); 12491da177e4SLinus Torvalds if (!error) 12501da177e4SLinus Torvalds continue; 12511da177e4SLinus Torvalds 12521da177e4SLinus Torvalds locks_delete_block(fl); 12531da177e4SLinus Torvalds break; 12541da177e4SLinus Torvalds } 12551da177e4SLinus Torvalds return error; 12561da177e4SLinus Torvalds } 125729d01b22SJeff Layton 12589e8925b6SJeff Layton #ifdef CONFIG_MANDATORY_FILE_LOCKING 125929d01b22SJeff Layton /** 12601da177e4SLinus Torvalds * locks_mandatory_locked - Check for an active lock 1261d7a06983SJeff Layton * @file: the file to check 12621da177e4SLinus Torvalds * 12631da177e4SLinus Torvalds * Searches the inode's list of locks to find any POSIX locks which conflict. 12641da177e4SLinus Torvalds * This function is called from locks_verify_locked() only. 12651da177e4SLinus Torvalds */ 1266d7a06983SJeff Layton int locks_mandatory_locked(struct file *file) 12671da177e4SLinus Torvalds { 1268bd61e0a9SJeff Layton int ret; 1269c568d683SMiklos Szeredi struct inode *inode = locks_inode(file); 1270bd61e0a9SJeff Layton struct file_lock_context *ctx; 12711da177e4SLinus Torvalds struct file_lock *fl; 12721da177e4SLinus Torvalds 1273128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 1274bd61e0a9SJeff Layton if (!ctx || list_empty_careful(&ctx->flc_posix)) 1275bd61e0a9SJeff Layton return 0; 1276bd61e0a9SJeff Layton 12771da177e4SLinus Torvalds /* 12781da177e4SLinus Torvalds * Search the lock list for this inode for any POSIX locks. 12791da177e4SLinus Torvalds */ 12806109c850SJeff Layton spin_lock(&ctx->flc_lock); 1281bd61e0a9SJeff Layton ret = 0; 1282bd61e0a9SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, fl_list) { 128373a8f5f7SChristoph Hellwig if (fl->fl_owner != current->files && 1284bd61e0a9SJeff Layton fl->fl_owner != file) { 1285bd61e0a9SJeff Layton ret = -EAGAIN; 12861da177e4SLinus Torvalds break; 12871da177e4SLinus Torvalds } 1288bd61e0a9SJeff Layton } 12896109c850SJeff Layton spin_unlock(&ctx->flc_lock); 1290bd61e0a9SJeff Layton return ret; 12911da177e4SLinus Torvalds } 12921da177e4SLinus Torvalds 12931da177e4SLinus Torvalds /** 12941da177e4SLinus Torvalds * locks_mandatory_area - Check for a conflicting lock 12951da177e4SLinus Torvalds * @inode: the file to check 12961da177e4SLinus Torvalds * @filp: how the file was opened (if it was) 1297acc15575SChristoph Hellwig * @start: first byte in the file to check 1298acc15575SChristoph Hellwig * @end: lastbyte in the file to check 1299acc15575SChristoph Hellwig * @type: %F_WRLCK for a write lock, else %F_RDLCK 13001da177e4SLinus Torvalds * 13011da177e4SLinus Torvalds * Searches the inode's list of locks to find any POSIX locks which conflict. 13021da177e4SLinus Torvalds */ 1303acc15575SChristoph Hellwig int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start, 1304acc15575SChristoph Hellwig loff_t end, unsigned char type) 13051da177e4SLinus Torvalds { 13061da177e4SLinus Torvalds struct file_lock fl; 13071da177e4SLinus Torvalds int error; 130829723adeSJeff Layton bool sleep = false; 13091da177e4SLinus Torvalds 13101da177e4SLinus Torvalds locks_init_lock(&fl); 13111da177e4SLinus Torvalds fl.fl_pid = current->tgid; 13121da177e4SLinus Torvalds fl.fl_file = filp; 13131da177e4SLinus Torvalds fl.fl_flags = FL_POSIX | FL_ACCESS; 13141da177e4SLinus Torvalds if (filp && !(filp->f_flags & O_NONBLOCK)) 131529723adeSJeff Layton sleep = true; 1316acc15575SChristoph Hellwig fl.fl_type = type; 1317acc15575SChristoph Hellwig fl.fl_start = start; 1318acc15575SChristoph Hellwig fl.fl_end = end; 13191da177e4SLinus Torvalds 13201da177e4SLinus Torvalds for (;;) { 132129723adeSJeff Layton if (filp) { 132273a8f5f7SChristoph Hellwig fl.fl_owner = filp; 132329723adeSJeff Layton fl.fl_flags &= ~FL_SLEEP; 1324b4d629a3SJeff Layton error = posix_lock_inode(inode, &fl, NULL); 132529723adeSJeff Layton if (!error) 132629723adeSJeff Layton break; 132729723adeSJeff Layton } 132829723adeSJeff Layton 132929723adeSJeff Layton if (sleep) 133029723adeSJeff Layton fl.fl_flags |= FL_SLEEP; 133129723adeSJeff Layton fl.fl_owner = current->files; 1332b4d629a3SJeff Layton error = posix_lock_inode(inode, &fl, NULL); 1333bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 13341da177e4SLinus Torvalds break; 13351da177e4SLinus Torvalds error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); 13361da177e4SLinus Torvalds if (!error) { 13371da177e4SLinus Torvalds /* 13381da177e4SLinus Torvalds * If we've been sleeping someone might have 13391da177e4SLinus Torvalds * changed the permissions behind our back. 13401da177e4SLinus Torvalds */ 1341a16877caSPavel Emelyanov if (__mandatory_lock(inode)) 13421da177e4SLinus Torvalds continue; 13431da177e4SLinus Torvalds } 13441da177e4SLinus Torvalds 13451da177e4SLinus Torvalds locks_delete_block(&fl); 13461da177e4SLinus Torvalds break; 13471da177e4SLinus Torvalds } 13481da177e4SLinus Torvalds 13491da177e4SLinus Torvalds return error; 13501da177e4SLinus Torvalds } 13511da177e4SLinus Torvalds 13521da177e4SLinus Torvalds EXPORT_SYMBOL(locks_mandatory_area); 13539e8925b6SJeff Layton #endif /* CONFIG_MANDATORY_FILE_LOCKING */ 13541da177e4SLinus Torvalds 1355778fc546SJ. Bruce Fields static void lease_clear_pending(struct file_lock *fl, int arg) 1356778fc546SJ. Bruce Fields { 1357778fc546SJ. Bruce Fields switch (arg) { 1358778fc546SJ. Bruce Fields case F_UNLCK: 1359778fc546SJ. Bruce Fields fl->fl_flags &= ~FL_UNLOCK_PENDING; 1360778fc546SJ. Bruce Fields /* fall through: */ 1361778fc546SJ. Bruce Fields case F_RDLCK: 1362778fc546SJ. Bruce Fields fl->fl_flags &= ~FL_DOWNGRADE_PENDING; 1363778fc546SJ. Bruce Fields } 1364778fc546SJ. Bruce Fields } 1365778fc546SJ. Bruce Fields 13661da177e4SLinus Torvalds /* We already had a lease on this file; just change its type */ 13677448cc37SJeff Layton int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) 13681da177e4SLinus Torvalds { 13691da177e4SLinus Torvalds int error = assign_type(fl, arg); 13701da177e4SLinus Torvalds 13711da177e4SLinus Torvalds if (error) 13721da177e4SLinus Torvalds return error; 1373778fc546SJ. Bruce Fields lease_clear_pending(fl, arg); 13741da177e4SLinus Torvalds locks_wake_up_blocks(fl); 13753b6e2723SFilipe Brandenburger if (arg == F_UNLCK) { 13763b6e2723SFilipe Brandenburger struct file *filp = fl->fl_file; 13773b6e2723SFilipe Brandenburger 13783b6e2723SFilipe Brandenburger f_delown(filp); 13793b6e2723SFilipe Brandenburger filp->f_owner.signum = 0; 138096d6d59cSJ. Bruce Fields fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync); 138196d6d59cSJ. Bruce Fields if (fl->fl_fasync != NULL) { 138296d6d59cSJ. Bruce Fields printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); 138396d6d59cSJ. Bruce Fields fl->fl_fasync = NULL; 138496d6d59cSJ. Bruce Fields } 1385e084c1bdSJeff Layton locks_delete_lock_ctx(fl, dispose); 13863b6e2723SFilipe Brandenburger } 13871da177e4SLinus Torvalds return 0; 13881da177e4SLinus Torvalds } 13891da177e4SLinus Torvalds EXPORT_SYMBOL(lease_modify); 13901da177e4SLinus Torvalds 1391778fc546SJ. Bruce Fields static bool past_time(unsigned long then) 1392778fc546SJ. Bruce Fields { 1393778fc546SJ. Bruce Fields if (!then) 1394778fc546SJ. Bruce Fields /* 0 is a special value meaning "this never expires": */ 1395778fc546SJ. Bruce Fields return false; 1396778fc546SJ. Bruce Fields return time_after(jiffies, then); 1397778fc546SJ. Bruce Fields } 1398778fc546SJ. Bruce Fields 1399c45198edSJeff Layton static void time_out_leases(struct inode *inode, struct list_head *dispose) 14001da177e4SLinus Torvalds { 14018634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 14028634b51fSJeff Layton struct file_lock *fl, *tmp; 14031da177e4SLinus Torvalds 14046109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 1405f82b4b67SJeff Layton 14068634b51fSJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) { 140762af4f1fSJeff Layton trace_time_out_leases(inode, fl); 1408778fc546SJ. Bruce Fields if (past_time(fl->fl_downgrade_time)) 14097448cc37SJeff Layton lease_modify(fl, F_RDLCK, dispose); 1410778fc546SJ. Bruce Fields if (past_time(fl->fl_break_time)) 14117448cc37SJeff Layton lease_modify(fl, F_UNLCK, dispose); 14121da177e4SLinus Torvalds } 14131da177e4SLinus Torvalds } 14141da177e4SLinus Torvalds 1415df4e8d2cSJ. Bruce Fields static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker) 1416df4e8d2cSJ. Bruce Fields { 141711afe9f7SChristoph Hellwig if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT)) 141811afe9f7SChristoph Hellwig return false; 1419df4e8d2cSJ. Bruce Fields if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE)) 1420df4e8d2cSJ. Bruce Fields return false; 1421df4e8d2cSJ. Bruce Fields return locks_conflict(breaker, lease); 1422df4e8d2cSJ. Bruce Fields } 1423df4e8d2cSJ. Bruce Fields 142403d12ddfSJeff Layton static bool 142503d12ddfSJeff Layton any_leases_conflict(struct inode *inode, struct file_lock *breaker) 142603d12ddfSJeff Layton { 14278634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 142803d12ddfSJeff Layton struct file_lock *fl; 142903d12ddfSJeff Layton 14306109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 143103d12ddfSJeff Layton 14328634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 143303d12ddfSJeff Layton if (leases_conflict(fl, breaker)) 143403d12ddfSJeff Layton return true; 143503d12ddfSJeff Layton } 143603d12ddfSJeff Layton return false; 143703d12ddfSJeff Layton } 143803d12ddfSJeff Layton 14391da177e4SLinus Torvalds /** 14401da177e4SLinus Torvalds * __break_lease - revoke all outstanding leases on file 14411da177e4SLinus Torvalds * @inode: the inode of the file to return 1442df4e8d2cSJ. Bruce Fields * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR: 1443df4e8d2cSJ. Bruce Fields * break all leases 1444df4e8d2cSJ. Bruce Fields * @type: FL_LEASE: break leases and delegations; FL_DELEG: break 1445df4e8d2cSJ. Bruce Fields * only delegations 14461da177e4SLinus Torvalds * 144787250dd2Sdavid m. richter * break_lease (inlined for speed) has checked there already is at least 144887250dd2Sdavid m. richter * some kind of lock (maybe a lease) on this file. Leases are broken on 144987250dd2Sdavid m. richter * a call to open() or truncate(). This function can sleep unless you 14501da177e4SLinus Torvalds * specified %O_NONBLOCK to your open(). 14511da177e4SLinus Torvalds */ 1452df4e8d2cSJ. Bruce Fields int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) 14531da177e4SLinus Torvalds { 1454778fc546SJ. Bruce Fields int error = 0; 1455128a3785SDmitry Vyukov struct file_lock_context *ctx; 1456a901125cSYan, Zheng struct file_lock *new_fl, *fl, *tmp; 14571da177e4SLinus Torvalds unsigned long break_time; 14588737c930SAl Viro int want_write = (mode & O_ACCMODE) != O_RDONLY; 1459c45198edSJeff Layton LIST_HEAD(dispose); 14601da177e4SLinus Torvalds 14618737c930SAl Viro new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); 14626d4b9e38SLinus Torvalds if (IS_ERR(new_fl)) 14636d4b9e38SLinus Torvalds return PTR_ERR(new_fl); 1464df4e8d2cSJ. Bruce Fields new_fl->fl_flags = type; 14651da177e4SLinus Torvalds 14668634b51fSJeff Layton /* typically we will check that ctx is non-NULL before calling */ 1467128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 14688634b51fSJeff Layton if (!ctx) { 14698634b51fSJeff Layton WARN_ON_ONCE(1); 14708634b51fSJeff Layton return error; 14718634b51fSJeff Layton } 14728634b51fSJeff Layton 147387709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 14746109c850SJeff Layton spin_lock(&ctx->flc_lock); 14751da177e4SLinus Torvalds 1476c45198edSJeff Layton time_out_leases(inode, &dispose); 14771da177e4SLinus Torvalds 147803d12ddfSJeff Layton if (!any_leases_conflict(inode, new_fl)) 1479df4e8d2cSJ. Bruce Fields goto out; 14801da177e4SLinus Torvalds 14811da177e4SLinus Torvalds break_time = 0; 14821da177e4SLinus Torvalds if (lease_break_time > 0) { 14831da177e4SLinus Torvalds break_time = jiffies + lease_break_time * HZ; 14841da177e4SLinus Torvalds if (break_time == 0) 14851da177e4SLinus Torvalds break_time++; /* so that 0 means no break time */ 14861da177e4SLinus Torvalds } 14871da177e4SLinus Torvalds 1488a901125cSYan, Zheng list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) { 1489df4e8d2cSJ. Bruce Fields if (!leases_conflict(fl, new_fl)) 1490df4e8d2cSJ. Bruce Fields continue; 1491778fc546SJ. Bruce Fields if (want_write) { 1492778fc546SJ. Bruce Fields if (fl->fl_flags & FL_UNLOCK_PENDING) 1493778fc546SJ. Bruce Fields continue; 1494778fc546SJ. Bruce Fields fl->fl_flags |= FL_UNLOCK_PENDING; 14951da177e4SLinus Torvalds fl->fl_break_time = break_time; 1496778fc546SJ. Bruce Fields } else { 14978634b51fSJeff Layton if (lease_breaking(fl)) 1498778fc546SJ. Bruce Fields continue; 1499778fc546SJ. Bruce Fields fl->fl_flags |= FL_DOWNGRADE_PENDING; 1500778fc546SJ. Bruce Fields fl->fl_downgrade_time = break_time; 15011da177e4SLinus Torvalds } 15024d01b7f5SJeff Layton if (fl->fl_lmops->lm_break(fl)) 1503e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 15041da177e4SLinus Torvalds } 15051da177e4SLinus Torvalds 15068634b51fSJeff Layton if (list_empty(&ctx->flc_lease)) 15074d01b7f5SJeff Layton goto out; 15084d01b7f5SJeff Layton 1509843c6b2fSJeff Layton if (mode & O_NONBLOCK) { 151062af4f1fSJeff Layton trace_break_lease_noblock(inode, new_fl); 15111da177e4SLinus Torvalds error = -EWOULDBLOCK; 15121da177e4SLinus Torvalds goto out; 15131da177e4SLinus Torvalds } 15141da177e4SLinus Torvalds 15151da177e4SLinus Torvalds restart: 15168634b51fSJeff Layton fl = list_first_entry(&ctx->flc_lease, struct file_lock, fl_list); 15178634b51fSJeff Layton break_time = fl->fl_break_time; 1518f1c6bb2cSJeff Layton if (break_time != 0) 15191da177e4SLinus Torvalds break_time -= jiffies; 15201da177e4SLinus Torvalds if (break_time == 0) 15211da177e4SLinus Torvalds break_time++; 15228634b51fSJeff Layton locks_insert_block(fl, new_fl); 152362af4f1fSJeff Layton trace_break_lease_block(inode, new_fl); 15246109c850SJeff Layton spin_unlock(&ctx->flc_lock); 152587709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1526aba37660SPeter Zijlstra 1527c45198edSJeff Layton locks_dispose_list(&dispose); 15284321e01eSMatthew Wilcox error = wait_event_interruptible_timeout(new_fl->fl_wait, 15294321e01eSMatthew Wilcox !new_fl->fl_next, break_time); 1530aba37660SPeter Zijlstra 153187709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 15326109c850SJeff Layton spin_lock(&ctx->flc_lock); 153362af4f1fSJeff Layton trace_break_lease_unblock(inode, new_fl); 15341c8c601aSJeff Layton locks_delete_block(new_fl); 15351da177e4SLinus Torvalds if (error >= 0) { 1536778fc546SJ. Bruce Fields /* 1537778fc546SJ. Bruce Fields * Wait for the next conflicting lease that has not been 1538778fc546SJ. Bruce Fields * broken yet 1539778fc546SJ. Bruce Fields */ 154003d12ddfSJeff Layton if (error == 0) 154103d12ddfSJeff Layton time_out_leases(inode, &dispose); 154203d12ddfSJeff Layton if (any_leases_conflict(inode, new_fl)) 15431da177e4SLinus Torvalds goto restart; 15441da177e4SLinus Torvalds error = 0; 15451da177e4SLinus Torvalds } 15461da177e4SLinus Torvalds out: 15476109c850SJeff Layton spin_unlock(&ctx->flc_lock); 154887709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1549c45198edSJeff Layton locks_dispose_list(&dispose); 15501da177e4SLinus Torvalds locks_free_lock(new_fl); 15511da177e4SLinus Torvalds return error; 15521da177e4SLinus Torvalds } 15531da177e4SLinus Torvalds 15541da177e4SLinus Torvalds EXPORT_SYMBOL(__break_lease); 15551da177e4SLinus Torvalds 15561da177e4SLinus Torvalds /** 155776c47948SAmir Goldstein * lease_get_mtime - update modified time of an inode with exclusive lease 15581da177e4SLinus Torvalds * @inode: the inode 155976c47948SAmir Goldstein * @time: pointer to a timespec which contains the last modified time 15601da177e4SLinus Torvalds * 15611da177e4SLinus Torvalds * This is to force NFS clients to flush their caches for files with 15621da177e4SLinus Torvalds * exclusive leases. The justification is that if someone has an 1563a6b91919SRandy Dunlap * exclusive lease, then they could be modifying it. 15641da177e4SLinus Torvalds */ 156595582b00SDeepa Dinamani void lease_get_mtime(struct inode *inode, struct timespec64 *time) 15661da177e4SLinus Torvalds { 1567bfe86024SJeff Layton bool has_lease = false; 1568128a3785SDmitry Vyukov struct file_lock_context *ctx; 15698634b51fSJeff Layton struct file_lock *fl; 1570bfe86024SJeff Layton 1571128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 15728634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 15736109c850SJeff Layton spin_lock(&ctx->flc_lock); 15748ace5dfbSGeliang Tang fl = list_first_entry_or_null(&ctx->flc_lease, 15758634b51fSJeff Layton struct file_lock, fl_list); 15768ace5dfbSGeliang Tang if (fl && (fl->fl_type == F_WRLCK)) 1577bfe86024SJeff Layton has_lease = true; 15786109c850SJeff Layton spin_unlock(&ctx->flc_lock); 1579bfe86024SJeff Layton } 1580bfe86024SJeff Layton 1581bfe86024SJeff Layton if (has_lease) 1582c2050a45SDeepa Dinamani *time = current_time(inode); 15831da177e4SLinus Torvalds } 15841da177e4SLinus Torvalds 15851da177e4SLinus Torvalds EXPORT_SYMBOL(lease_get_mtime); 15861da177e4SLinus Torvalds 15871da177e4SLinus Torvalds /** 15881da177e4SLinus Torvalds * fcntl_getlease - Enquire what lease is currently active 15891da177e4SLinus Torvalds * @filp: the file 15901da177e4SLinus Torvalds * 15911da177e4SLinus Torvalds * The value returned by this function will be one of 15921da177e4SLinus Torvalds * (if no lease break is pending): 15931da177e4SLinus Torvalds * 15941da177e4SLinus Torvalds * %F_RDLCK to indicate a shared lease is held. 15951da177e4SLinus Torvalds * 15961da177e4SLinus Torvalds * %F_WRLCK to indicate an exclusive lease is held. 15971da177e4SLinus Torvalds * 15981da177e4SLinus Torvalds * %F_UNLCK to indicate no lease is held. 15991da177e4SLinus Torvalds * 16001da177e4SLinus Torvalds * (if a lease break is pending): 16011da177e4SLinus Torvalds * 16021da177e4SLinus Torvalds * %F_RDLCK to indicate an exclusive lease needs to be 16031da177e4SLinus Torvalds * changed to a shared lease (or removed). 16041da177e4SLinus Torvalds * 16051da177e4SLinus Torvalds * %F_UNLCK to indicate the lease needs to be removed. 16061da177e4SLinus Torvalds * 16071da177e4SLinus Torvalds * XXX: sfr & willy disagree over whether F_INPROGRESS 16081da177e4SLinus Torvalds * should be returned to userspace. 16091da177e4SLinus Torvalds */ 16101da177e4SLinus Torvalds int fcntl_getlease(struct file *filp) 16111da177e4SLinus Torvalds { 16121da177e4SLinus Torvalds struct file_lock *fl; 1613c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 1614128a3785SDmitry Vyukov struct file_lock_context *ctx; 16151da177e4SLinus Torvalds int type = F_UNLCK; 1616c45198edSJeff Layton LIST_HEAD(dispose); 16171da177e4SLinus Torvalds 1618128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 16198634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 16205f43086bSPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 16216109c850SJeff Layton spin_lock(&ctx->flc_lock); 1622c568d683SMiklos Szeredi time_out_leases(inode, &dispose); 16238634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 16248634b51fSJeff Layton if (fl->fl_file != filp) 16258634b51fSJeff Layton continue; 1626778fc546SJ. Bruce Fields type = target_leasetype(fl); 16271da177e4SLinus Torvalds break; 16281da177e4SLinus Torvalds } 16296109c850SJeff Layton spin_unlock(&ctx->flc_lock); 16305f43086bSPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 16315f43086bSPeter Zijlstra 1632c45198edSJeff Layton locks_dispose_list(&dispose); 16338634b51fSJeff Layton } 16341da177e4SLinus Torvalds return type; 16351da177e4SLinus Torvalds } 16361da177e4SLinus Torvalds 163724cbe784SJeff Layton /** 163824cbe784SJeff Layton * check_conflicting_open - see if the given dentry points to a file that has 163924cbe784SJeff Layton * an existing open that would conflict with the 164024cbe784SJeff Layton * desired lease. 164124cbe784SJeff Layton * @dentry: dentry to check 164224cbe784SJeff Layton * @arg: type of lease that we're trying to acquire 16437fadc59cSRandy Dunlap * @flags: current lock flags 164424cbe784SJeff Layton * 164524cbe784SJeff Layton * Check to see if there's an existing open fd on this file that would 164624cbe784SJeff Layton * conflict with the lease we're trying to set. 164724cbe784SJeff Layton */ 164824cbe784SJeff Layton static int 164911afe9f7SChristoph Hellwig check_conflicting_open(const struct dentry *dentry, const long arg, int flags) 165024cbe784SJeff Layton { 165124cbe784SJeff Layton int ret = 0; 165224cbe784SJeff Layton struct inode *inode = dentry->d_inode; 165324cbe784SJeff Layton 165411afe9f7SChristoph Hellwig if (flags & FL_LAYOUT) 165511afe9f7SChristoph Hellwig return 0; 165611afe9f7SChristoph Hellwig 1657*8cf9ee50SMiklos Szeredi if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) 165824cbe784SJeff Layton return -EAGAIN; 165924cbe784SJeff Layton 166024cbe784SJeff Layton if ((arg == F_WRLCK) && ((d_count(dentry) > 1) || 166124cbe784SJeff Layton (atomic_read(&inode->i_count) > 1))) 166224cbe784SJeff Layton ret = -EAGAIN; 166324cbe784SJeff Layton 166424cbe784SJeff Layton return ret; 166524cbe784SJeff Layton } 166624cbe784SJeff Layton 1667e6f5c789SJeff Layton static int 1668e6f5c789SJeff Layton generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **priv) 16691da177e4SLinus Torvalds { 16708634b51fSJeff Layton struct file_lock *fl, *my_fl = NULL, *lease; 16710f7fc9e4SJosef "Jeff" Sipek struct dentry *dentry = filp->f_path.dentry; 1672c568d683SMiklos Szeredi struct inode *inode = dentry->d_inode; 16738634b51fSJeff Layton struct file_lock_context *ctx; 1674df4e8d2cSJ. Bruce Fields bool is_deleg = (*flp)->fl_flags & FL_DELEG; 1675c1f24ef4SJ. Bruce Fields int error; 1676c45198edSJeff Layton LIST_HEAD(dispose); 16771da177e4SLinus Torvalds 1678096657b6SJ. Bruce Fields lease = *flp; 167962af4f1fSJeff Layton trace_generic_add_lease(inode, lease); 168062af4f1fSJeff Layton 16815c1c669aSJeff Layton /* Note that arg is never F_UNLCK here */ 16825c1c669aSJeff Layton ctx = locks_get_lock_context(inode, arg); 16838634b51fSJeff Layton if (!ctx) 16848634b51fSJeff Layton return -ENOMEM; 16858634b51fSJeff Layton 1686df4e8d2cSJ. Bruce Fields /* 1687df4e8d2cSJ. Bruce Fields * In the delegation case we need mutual exclusion with 1688df4e8d2cSJ. Bruce Fields * a number of operations that take the i_mutex. We trylock 1689df4e8d2cSJ. Bruce Fields * because delegations are an optional optimization, and if 1690df4e8d2cSJ. Bruce Fields * there's some chance of a conflict--we'd rather not 1691df4e8d2cSJ. Bruce Fields * bother, maybe that's a sign this just isn't a good file to 1692df4e8d2cSJ. Bruce Fields * hand out a delegation on. 1693df4e8d2cSJ. Bruce Fields */ 16945955102cSAl Viro if (is_deleg && !inode_trylock(inode)) 1695df4e8d2cSJ. Bruce Fields return -EAGAIN; 1696df4e8d2cSJ. Bruce Fields 1697df4e8d2cSJ. Bruce Fields if (is_deleg && arg == F_WRLCK) { 1698df4e8d2cSJ. Bruce Fields /* Write delegations are not currently supported: */ 16995955102cSAl Viro inode_unlock(inode); 1700df4e8d2cSJ. Bruce Fields WARN_ON_ONCE(1); 1701df4e8d2cSJ. Bruce Fields return -EINVAL; 1702df4e8d2cSJ. Bruce Fields } 1703096657b6SJ. Bruce Fields 170487709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 17056109c850SJeff Layton spin_lock(&ctx->flc_lock); 1706c45198edSJeff Layton time_out_leases(inode, &dispose); 170711afe9f7SChristoph Hellwig error = check_conflicting_open(dentry, arg, lease->fl_flags); 170824cbe784SJeff Layton if (error) 17091da177e4SLinus Torvalds goto out; 171085c59580SPavel Emelyanov 17111da177e4SLinus Torvalds /* 17121da177e4SLinus Torvalds * At this point, we know that if there is an exclusive 17131da177e4SLinus Torvalds * lease on this file, then we hold it on this filp 17141da177e4SLinus Torvalds * (otherwise our open of this file would have blocked). 17151da177e4SLinus Torvalds * And if we are trying to acquire an exclusive lease, 17161da177e4SLinus Torvalds * then the file is not open by anyone (including us) 17171da177e4SLinus Torvalds * except for this filp. 17181da177e4SLinus Torvalds */ 1719c1f24ef4SJ. Bruce Fields error = -EAGAIN; 17208634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 17212ab99ee1SChristoph Hellwig if (fl->fl_file == filp && 17222ab99ee1SChristoph Hellwig fl->fl_owner == lease->fl_owner) { 17238634b51fSJeff Layton my_fl = fl; 1724c1f24ef4SJ. Bruce Fields continue; 17251da177e4SLinus Torvalds } 17268634b51fSJeff Layton 1727c1f24ef4SJ. Bruce Fields /* 1728c1f24ef4SJ. Bruce Fields * No exclusive leases if someone else has a lease on 1729c1f24ef4SJ. Bruce Fields * this file: 1730c1f24ef4SJ. Bruce Fields */ 1731c1f24ef4SJ. Bruce Fields if (arg == F_WRLCK) 17321da177e4SLinus Torvalds goto out; 1733c1f24ef4SJ. Bruce Fields /* 1734c1f24ef4SJ. Bruce Fields * Modifying our existing lease is OK, but no getting a 1735c1f24ef4SJ. Bruce Fields * new lease if someone else is opening for write: 1736c1f24ef4SJ. Bruce Fields */ 1737c1f24ef4SJ. Bruce Fields if (fl->fl_flags & FL_UNLOCK_PENDING) 1738c1f24ef4SJ. Bruce Fields goto out; 1739c1f24ef4SJ. Bruce Fields } 17401da177e4SLinus Torvalds 17418634b51fSJeff Layton if (my_fl != NULL) { 17420164bf02SJeff Layton lease = my_fl; 17430164bf02SJeff Layton error = lease->fl_lmops->lm_change(lease, arg, &dispose); 17441c7dd2ffSJeff Layton if (error) 17451da177e4SLinus Torvalds goto out; 17461c7dd2ffSJeff Layton goto out_setup; 17471da177e4SLinus Torvalds } 17481da177e4SLinus Torvalds 17491da177e4SLinus Torvalds error = -EINVAL; 17501da177e4SLinus Torvalds if (!leases_enable) 17511da177e4SLinus Torvalds goto out; 17521da177e4SLinus Torvalds 1753e084c1bdSJeff Layton locks_insert_lock_ctx(lease, &ctx->flc_lease); 175424cbe784SJeff Layton /* 175524cbe784SJeff Layton * The check in break_lease() is lockless. It's possible for another 175624cbe784SJeff Layton * open to race in after we did the earlier check for a conflicting 175724cbe784SJeff Layton * open but before the lease was inserted. Check again for a 175824cbe784SJeff Layton * conflicting open and cancel the lease if there is one. 175924cbe784SJeff Layton * 176024cbe784SJeff Layton * We also add a barrier here to ensure that the insertion of the lock 176124cbe784SJeff Layton * precedes these checks. 176224cbe784SJeff Layton */ 176324cbe784SJeff Layton smp_mb(); 176411afe9f7SChristoph Hellwig error = check_conflicting_open(dentry, arg, lease->fl_flags); 17658634b51fSJeff Layton if (error) { 1766e084c1bdSJeff Layton locks_unlink_lock_ctx(lease); 17678634b51fSJeff Layton goto out; 17688634b51fSJeff Layton } 17691c7dd2ffSJeff Layton 17701c7dd2ffSJeff Layton out_setup: 17711c7dd2ffSJeff Layton if (lease->fl_lmops->lm_setup) 17721c7dd2ffSJeff Layton lease->fl_lmops->lm_setup(lease, priv); 17731da177e4SLinus Torvalds out: 17746109c850SJeff Layton spin_unlock(&ctx->flc_lock); 177587709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1776c45198edSJeff Layton locks_dispose_list(&dispose); 1777df4e8d2cSJ. Bruce Fields if (is_deleg) 17785955102cSAl Viro inode_unlock(inode); 17798634b51fSJeff Layton if (!error && !my_fl) 17801c7dd2ffSJeff Layton *flp = NULL; 17811da177e4SLinus Torvalds return error; 17821da177e4SLinus Torvalds } 17838335ebd9SJ. Bruce Fields 17842ab99ee1SChristoph Hellwig static int generic_delete_lease(struct file *filp, void *owner) 17858335ebd9SJ. Bruce Fields { 17860efaa7e8SJeff Layton int error = -EAGAIN; 17878634b51fSJeff Layton struct file_lock *fl, *victim = NULL; 1788c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 1789128a3785SDmitry Vyukov struct file_lock_context *ctx; 1790c45198edSJeff Layton LIST_HEAD(dispose); 17918335ebd9SJ. Bruce Fields 1792128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 17938634b51fSJeff Layton if (!ctx) { 17948634b51fSJeff Layton trace_generic_delete_lease(inode, NULL); 17958634b51fSJeff Layton return error; 17968634b51fSJeff Layton } 17978634b51fSJeff Layton 179887709e28SPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 17996109c850SJeff Layton spin_lock(&ctx->flc_lock); 18008634b51fSJeff Layton list_for_each_entry(fl, &ctx->flc_lease, fl_list) { 18012ab99ee1SChristoph Hellwig if (fl->fl_file == filp && 18022ab99ee1SChristoph Hellwig fl->fl_owner == owner) { 18038634b51fSJeff Layton victim = fl; 18040efaa7e8SJeff Layton break; 18058335ebd9SJ. Bruce Fields } 18068634b51fSJeff Layton } 1807a9b1b455SJeff Layton trace_generic_delete_lease(inode, victim); 18088634b51fSJeff Layton if (victim) 18097448cc37SJeff Layton error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose); 18106109c850SJeff Layton spin_unlock(&ctx->flc_lock); 181187709e28SPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 1812c45198edSJeff Layton locks_dispose_list(&dispose); 18130efaa7e8SJeff Layton return error; 18148335ebd9SJ. Bruce Fields } 18158335ebd9SJ. Bruce Fields 18161da177e4SLinus Torvalds /** 18171da177e4SLinus Torvalds * generic_setlease - sets a lease on an open file 18181da177e4SLinus Torvalds * @filp: file pointer 18191da177e4SLinus Torvalds * @arg: type of lease to obtain 18201da177e4SLinus Torvalds * @flp: input - file_lock to use, output - file_lock inserted 18211c7dd2ffSJeff Layton * @priv: private data for lm_setup (may be NULL if lm_setup 18221c7dd2ffSJeff Layton * doesn't require it) 18231da177e4SLinus Torvalds * 18241da177e4SLinus Torvalds * The (input) flp->fl_lmops->lm_break function is required 18251da177e4SLinus Torvalds * by break_lease(). 18261da177e4SLinus Torvalds */ 1827e6f5c789SJeff Layton int generic_setlease(struct file *filp, long arg, struct file_lock **flp, 1828e6f5c789SJeff Layton void **priv) 18291da177e4SLinus Torvalds { 1830c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 18318335ebd9SJ. Bruce Fields int error; 18321da177e4SLinus Torvalds 18338e96e3b7SEric W. Biederman if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE)) 18348335ebd9SJ. Bruce Fields return -EACCES; 18351da177e4SLinus Torvalds if (!S_ISREG(inode->i_mode)) 18368335ebd9SJ. Bruce Fields return -EINVAL; 18371da177e4SLinus Torvalds error = security_file_lock(filp, arg); 18381da177e4SLinus Torvalds if (error) 18398335ebd9SJ. Bruce Fields return error; 18401da177e4SLinus Torvalds 18418335ebd9SJ. Bruce Fields switch (arg) { 18428335ebd9SJ. Bruce Fields case F_UNLCK: 18432ab99ee1SChristoph Hellwig return generic_delete_lease(filp, *priv); 18448335ebd9SJ. Bruce Fields case F_RDLCK: 18458335ebd9SJ. Bruce Fields case F_WRLCK: 18460efaa7e8SJeff Layton if (!(*flp)->fl_lmops->lm_break) { 18470efaa7e8SJeff Layton WARN_ON_ONCE(1); 18480efaa7e8SJeff Layton return -ENOLCK; 18490efaa7e8SJeff Layton } 185011afe9f7SChristoph Hellwig 1851e6f5c789SJeff Layton return generic_add_lease(filp, arg, flp, priv); 18528335ebd9SJ. Bruce Fields default: 18538d657eb3SDave Jones return -EINVAL; 18541da177e4SLinus Torvalds } 18551da177e4SLinus Torvalds } 18560af1a450SChristoph Hellwig EXPORT_SYMBOL(generic_setlease); 18571da177e4SLinus Torvalds 18581da177e4SLinus Torvalds /** 1859a9933ceaSJ. Bruce Fields * vfs_setlease - sets a lease on an open file 18601da177e4SLinus Torvalds * @filp: file pointer 18611da177e4SLinus Torvalds * @arg: type of lease to obtain 1862e51673aaSJeff Layton * @lease: file_lock to use when adding a lease 18631c7dd2ffSJeff Layton * @priv: private info for lm_setup when adding a lease (may be 18641c7dd2ffSJeff Layton * NULL if lm_setup doesn't require it) 18651da177e4SLinus Torvalds * 1866e51673aaSJeff Layton * Call this to establish a lease on the file. The "lease" argument is not 1867e51673aaSJeff Layton * used for F_UNLCK requests and may be NULL. For commands that set or alter 186880b79dd0SMauro Carvalho Chehab * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be 186980b79dd0SMauro Carvalho Chehab * set; if not, this function will return -ENOLCK (and generate a scary-looking 1870e51673aaSJeff Layton * stack trace). 18711c7dd2ffSJeff Layton * 18721c7dd2ffSJeff Layton * The "priv" pointer is passed directly to the lm_setup function as-is. It 18731c7dd2ffSJeff Layton * may be NULL if the lm_setup operation doesn't require it. 18741da177e4SLinus Torvalds */ 1875e6f5c789SJeff Layton int 1876e6f5c789SJeff Layton vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) 18771da177e4SLinus Torvalds { 1878c568d683SMiklos Szeredi if (filp->f_op->setlease && is_remote_lock(filp)) 1879f82b4b67SJeff Layton return filp->f_op->setlease(filp, arg, lease, priv); 18801c7dd2ffSJeff Layton else 1881f82b4b67SJeff Layton return generic_setlease(filp, arg, lease, priv); 18821da177e4SLinus Torvalds } 1883a9933ceaSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_setlease); 18841da177e4SLinus Torvalds 18850ceaf6c7SJ. Bruce Fields static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) 18861da177e4SLinus Torvalds { 18871c7dd2ffSJeff Layton struct file_lock *fl; 1888f7347ce4SLinus Torvalds struct fasync_struct *new; 18891da177e4SLinus Torvalds int error; 18901da177e4SLinus Torvalds 1891c5b1f0d9SArnd Bergmann fl = lease_alloc(filp, arg); 1892c5b1f0d9SArnd Bergmann if (IS_ERR(fl)) 1893c5b1f0d9SArnd Bergmann return PTR_ERR(fl); 18941da177e4SLinus Torvalds 1895f7347ce4SLinus Torvalds new = fasync_alloc(); 1896f7347ce4SLinus Torvalds if (!new) { 1897f7347ce4SLinus Torvalds locks_free_lock(fl); 1898f7347ce4SLinus Torvalds return -ENOMEM; 1899f7347ce4SLinus Torvalds } 19001c7dd2ffSJeff Layton new->fa_fd = fd; 19011da177e4SLinus Torvalds 19021c7dd2ffSJeff Layton error = vfs_setlease(filp, arg, &fl, (void **)&new); 19032dfb928fSJeff Layton if (fl) 19042dfb928fSJeff Layton locks_free_lock(fl); 1905f7347ce4SLinus Torvalds if (new) 1906f7347ce4SLinus Torvalds fasync_free(new); 19071da177e4SLinus Torvalds return error; 19081da177e4SLinus Torvalds } 19091da177e4SLinus Torvalds 19101da177e4SLinus Torvalds /** 19110ceaf6c7SJ. Bruce Fields * fcntl_setlease - sets a lease on an open file 19120ceaf6c7SJ. Bruce Fields * @fd: open file descriptor 19130ceaf6c7SJ. Bruce Fields * @filp: file pointer 19140ceaf6c7SJ. Bruce Fields * @arg: type of lease to obtain 19150ceaf6c7SJ. Bruce Fields * 19160ceaf6c7SJ. Bruce Fields * Call this fcntl to establish a lease on the file. 19170ceaf6c7SJ. Bruce Fields * Note that you also need to call %F_SETSIG to 19180ceaf6c7SJ. Bruce Fields * receive a signal when the lease is broken. 19190ceaf6c7SJ. Bruce Fields */ 19200ceaf6c7SJ. Bruce Fields int fcntl_setlease(unsigned int fd, struct file *filp, long arg) 19210ceaf6c7SJ. Bruce Fields { 19220ceaf6c7SJ. Bruce Fields if (arg == F_UNLCK) 19232ab99ee1SChristoph Hellwig return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); 19240ceaf6c7SJ. Bruce Fields return do_fcntl_add_lease(fd, filp, arg); 19250ceaf6c7SJ. Bruce Fields } 19260ceaf6c7SJ. Bruce Fields 19270ceaf6c7SJ. Bruce Fields /** 192829d01b22SJeff Layton * flock_lock_inode_wait - Apply a FLOCK-style lock to a file 192929d01b22SJeff Layton * @inode: inode of the file to apply to 19301da177e4SLinus Torvalds * @fl: The lock to be applied 19311da177e4SLinus Torvalds * 193229d01b22SJeff Layton * Apply a FLOCK style lock request to an inode. 19331da177e4SLinus Torvalds */ 1934616fb38fSBenjamin Coddington static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) 19351da177e4SLinus Torvalds { 19361da177e4SLinus Torvalds int error; 19371da177e4SLinus Torvalds might_sleep(); 19381da177e4SLinus Torvalds for (;;) { 193929d01b22SJeff Layton error = flock_lock_inode(inode, fl); 1940bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 19411da177e4SLinus Torvalds break; 19421da177e4SLinus Torvalds error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); 19431da177e4SLinus Torvalds if (!error) 19441da177e4SLinus Torvalds continue; 19451da177e4SLinus Torvalds 19461da177e4SLinus Torvalds locks_delete_block(fl); 19471da177e4SLinus Torvalds break; 19481da177e4SLinus Torvalds } 19491da177e4SLinus Torvalds return error; 19501da177e4SLinus Torvalds } 19511da177e4SLinus Torvalds 195229d01b22SJeff Layton /** 1953e55c34a6SBenjamin Coddington * locks_lock_inode_wait - Apply a lock to an inode 1954e55c34a6SBenjamin Coddington * @inode: inode of the file to apply to 1955e55c34a6SBenjamin Coddington * @fl: The lock to be applied 1956e55c34a6SBenjamin Coddington * 1957e55c34a6SBenjamin Coddington * Apply a POSIX or FLOCK style lock request to an inode. 1958e55c34a6SBenjamin Coddington */ 1959e55c34a6SBenjamin Coddington int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl) 1960e55c34a6SBenjamin Coddington { 1961e55c34a6SBenjamin Coddington int res = 0; 1962e55c34a6SBenjamin Coddington switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) { 1963e55c34a6SBenjamin Coddington case FL_POSIX: 1964e55c34a6SBenjamin Coddington res = posix_lock_inode_wait(inode, fl); 1965e55c34a6SBenjamin Coddington break; 1966e55c34a6SBenjamin Coddington case FL_FLOCK: 1967e55c34a6SBenjamin Coddington res = flock_lock_inode_wait(inode, fl); 1968e55c34a6SBenjamin Coddington break; 1969e55c34a6SBenjamin Coddington default: 1970e55c34a6SBenjamin Coddington BUG(); 1971e55c34a6SBenjamin Coddington } 1972e55c34a6SBenjamin Coddington return res; 1973e55c34a6SBenjamin Coddington } 1974e55c34a6SBenjamin Coddington EXPORT_SYMBOL(locks_lock_inode_wait); 1975e55c34a6SBenjamin Coddington 1976e55c34a6SBenjamin Coddington /** 19771da177e4SLinus Torvalds * sys_flock: - flock() system call. 19781da177e4SLinus Torvalds * @fd: the file descriptor to lock. 19791da177e4SLinus Torvalds * @cmd: the type of lock to apply. 19801da177e4SLinus Torvalds * 19811da177e4SLinus Torvalds * Apply a %FL_FLOCK style lock to an open file descriptor. 198280b79dd0SMauro Carvalho Chehab * The @cmd can be one of: 19831da177e4SLinus Torvalds * 198480b79dd0SMauro Carvalho Chehab * - %LOCK_SH -- a shared lock. 198580b79dd0SMauro Carvalho Chehab * - %LOCK_EX -- an exclusive lock. 198680b79dd0SMauro Carvalho Chehab * - %LOCK_UN -- remove an existing lock. 198780b79dd0SMauro Carvalho Chehab * - %LOCK_MAND -- a 'mandatory' flock. 198880b79dd0SMauro Carvalho Chehab * This exists to emulate Windows Share Modes. 19891da177e4SLinus Torvalds * 19901da177e4SLinus Torvalds * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other 19911da177e4SLinus Torvalds * processes read and write access respectively. 19921da177e4SLinus Torvalds */ 1993002c8976SHeiko Carstens SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) 19941da177e4SLinus Torvalds { 19952903ff01SAl Viro struct fd f = fdget(fd); 19961da177e4SLinus Torvalds struct file_lock *lock; 19971da177e4SLinus Torvalds int can_sleep, unlock; 19981da177e4SLinus Torvalds int error; 19991da177e4SLinus Torvalds 20001da177e4SLinus Torvalds error = -EBADF; 20012903ff01SAl Viro if (!f.file) 20021da177e4SLinus Torvalds goto out; 20031da177e4SLinus Torvalds 20041da177e4SLinus Torvalds can_sleep = !(cmd & LOCK_NB); 20051da177e4SLinus Torvalds cmd &= ~LOCK_NB; 20061da177e4SLinus Torvalds unlock = (cmd == LOCK_UN); 20071da177e4SLinus Torvalds 2008aeb5d727SAl Viro if (!unlock && !(cmd & LOCK_MAND) && 20092903ff01SAl Viro !(f.file->f_mode & (FMODE_READ|FMODE_WRITE))) 20101da177e4SLinus Torvalds goto out_putf; 20111da177e4SLinus Torvalds 20126e129d00SJeff Layton lock = flock_make_lock(f.file, cmd); 20136e129d00SJeff Layton if (IS_ERR(lock)) { 20146e129d00SJeff Layton error = PTR_ERR(lock); 20151da177e4SLinus Torvalds goto out_putf; 20166e129d00SJeff Layton } 20176e129d00SJeff Layton 20181da177e4SLinus Torvalds if (can_sleep) 20191da177e4SLinus Torvalds lock->fl_flags |= FL_SLEEP; 20201da177e4SLinus Torvalds 20212903ff01SAl Viro error = security_file_lock(f.file, lock->fl_type); 20221da177e4SLinus Torvalds if (error) 20231da177e4SLinus Torvalds goto out_free; 20241da177e4SLinus Torvalds 2025c568d683SMiklos Szeredi if (f.file->f_op->flock && is_remote_lock(f.file)) 20262903ff01SAl Viro error = f.file->f_op->flock(f.file, 20271da177e4SLinus Torvalds (can_sleep) ? F_SETLKW : F_SETLK, 20281da177e4SLinus Torvalds lock); 20291da177e4SLinus Torvalds else 20304f656367SBenjamin Coddington error = locks_lock_file_wait(f.file, lock); 20311da177e4SLinus Torvalds 20321da177e4SLinus Torvalds out_free: 20331da177e4SLinus Torvalds locks_free_lock(lock); 20341da177e4SLinus Torvalds 20351da177e4SLinus Torvalds out_putf: 20362903ff01SAl Viro fdput(f); 20371da177e4SLinus Torvalds out: 20381da177e4SLinus Torvalds return error; 20391da177e4SLinus Torvalds } 20401da177e4SLinus Torvalds 20413ee17abdSJ. Bruce Fields /** 20423ee17abdSJ. Bruce Fields * vfs_test_lock - test file byte range lock 20433ee17abdSJ. Bruce Fields * @filp: The file to test lock for 20446924c554SJ. Bruce Fields * @fl: The lock to test; also used to hold result 20453ee17abdSJ. Bruce Fields * 20463ee17abdSJ. Bruce Fields * Returns -ERRNO on failure. Indicates presence of conflicting lock by 20473ee17abdSJ. Bruce Fields * setting conf->fl_type to something other than F_UNLCK. 20483ee17abdSJ. Bruce Fields */ 20493ee17abdSJ. Bruce Fields int vfs_test_lock(struct file *filp, struct file_lock *fl) 20503ee17abdSJ. Bruce Fields { 2051c568d683SMiklos Szeredi if (filp->f_op->lock && is_remote_lock(filp)) 20523ee17abdSJ. Bruce Fields return filp->f_op->lock(filp, F_GETLK, fl); 20533ee17abdSJ. Bruce Fields posix_test_lock(filp, fl); 20543ee17abdSJ. Bruce Fields return 0; 20553ee17abdSJ. Bruce Fields } 20563ee17abdSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_test_lock); 20573ee17abdSJ. Bruce Fields 20589d5b86acSBenjamin Coddington /** 20599d5b86acSBenjamin Coddington * locks_translate_pid - translate a file_lock's fl_pid number into a namespace 20609d5b86acSBenjamin Coddington * @fl: The file_lock who's fl_pid should be translated 20619d5b86acSBenjamin Coddington * @ns: The namespace into which the pid should be translated 20629d5b86acSBenjamin Coddington * 20639d5b86acSBenjamin Coddington * Used to tranlate a fl_pid into a namespace virtual pid number 20649d5b86acSBenjamin Coddington */ 20659d5b86acSBenjamin Coddington static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns) 20669d5b86acSBenjamin Coddington { 20679d5b86acSBenjamin Coddington pid_t vnr; 20689d5b86acSBenjamin Coddington struct pid *pid; 20699d5b86acSBenjamin Coddington 20709d5b86acSBenjamin Coddington if (IS_OFDLCK(fl)) 20719d5b86acSBenjamin Coddington return -1; 20729d5b86acSBenjamin Coddington if (IS_REMOTELCK(fl)) 20739d5b86acSBenjamin Coddington return fl->fl_pid; 20749d5b86acSBenjamin Coddington 20759d5b86acSBenjamin Coddington rcu_read_lock(); 20769d5b86acSBenjamin Coddington pid = find_pid_ns(fl->fl_pid, &init_pid_ns); 20779d5b86acSBenjamin Coddington vnr = pid_nr_ns(pid, ns); 20789d5b86acSBenjamin Coddington rcu_read_unlock(); 20799d5b86acSBenjamin Coddington return vnr; 20809d5b86acSBenjamin Coddington } 20819d5b86acSBenjamin Coddington 2082c2fa1b8aSJ. Bruce Fields static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) 2083c2fa1b8aSJ. Bruce Fields { 20849d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 2085c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2086c2fa1b8aSJ. Bruce Fields /* 2087c2fa1b8aSJ. Bruce Fields * Make sure we can represent the posix lock via 2088c2fa1b8aSJ. Bruce Fields * legacy 32bit flock. 2089c2fa1b8aSJ. Bruce Fields */ 2090c2fa1b8aSJ. Bruce Fields if (fl->fl_start > OFFT_OFFSET_MAX) 2091c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2092c2fa1b8aSJ. Bruce Fields if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX) 2093c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2094c2fa1b8aSJ. Bruce Fields #endif 2095c2fa1b8aSJ. Bruce Fields flock->l_start = fl->fl_start; 2096c2fa1b8aSJ. Bruce Fields flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2097c2fa1b8aSJ. Bruce Fields fl->fl_end - fl->fl_start + 1; 2098c2fa1b8aSJ. Bruce Fields flock->l_whence = 0; 2099129a84deSJ. Bruce Fields flock->l_type = fl->fl_type; 2100c2fa1b8aSJ. Bruce Fields return 0; 2101c2fa1b8aSJ. Bruce Fields } 2102c2fa1b8aSJ. Bruce Fields 2103c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2104c2fa1b8aSJ. Bruce Fields static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) 2105c2fa1b8aSJ. Bruce Fields { 21069d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 2107c2fa1b8aSJ. Bruce Fields flock->l_start = fl->fl_start; 2108c2fa1b8aSJ. Bruce Fields flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2109c2fa1b8aSJ. Bruce Fields fl->fl_end - fl->fl_start + 1; 2110c2fa1b8aSJ. Bruce Fields flock->l_whence = 0; 2111c2fa1b8aSJ. Bruce Fields flock->l_type = fl->fl_type; 2112c2fa1b8aSJ. Bruce Fields } 2113c2fa1b8aSJ. Bruce Fields #endif 2114c2fa1b8aSJ. Bruce Fields 21151da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 21161da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 21171da177e4SLinus Torvalds */ 2118a75d30c7SChristoph Hellwig int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) 21191da177e4SLinus Torvalds { 212052306e88SBenjamin Coddington struct file_lock *fl; 21211da177e4SLinus Torvalds int error; 21221da177e4SLinus Torvalds 212352306e88SBenjamin Coddington fl = locks_alloc_lock(); 212452306e88SBenjamin Coddington if (fl == NULL) 212552306e88SBenjamin Coddington return -ENOMEM; 21261da177e4SLinus Torvalds error = -EINVAL; 2127a75d30c7SChristoph Hellwig if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) 21281da177e4SLinus Torvalds goto out; 21291da177e4SLinus Torvalds 213052306e88SBenjamin Coddington error = flock_to_posix_lock(filp, fl, flock); 21311da177e4SLinus Torvalds if (error) 21321da177e4SLinus Torvalds goto out; 21331da177e4SLinus Torvalds 21340d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 213590478939SJeff Layton error = -EINVAL; 2136a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 213790478939SJeff Layton goto out; 213890478939SJeff Layton 21395d50ffd7SJeff Layton cmd = F_GETLK; 214052306e88SBenjamin Coddington fl->fl_flags |= FL_OFDLCK; 214152306e88SBenjamin Coddington fl->fl_owner = filp; 21425d50ffd7SJeff Layton } 21435d50ffd7SJeff Layton 214452306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 21453ee17abdSJ. Bruce Fields if (error) 21461da177e4SLinus Torvalds goto out; 21471da177e4SLinus Torvalds 214852306e88SBenjamin Coddington flock->l_type = fl->fl_type; 214952306e88SBenjamin Coddington if (fl->fl_type != F_UNLCK) { 215052306e88SBenjamin Coddington error = posix_lock_to_flock(flock, fl); 2151c2fa1b8aSJ. Bruce Fields if (error) 215252306e88SBenjamin Coddington goto out; 21531da177e4SLinus Torvalds } 21541da177e4SLinus Torvalds out: 215552306e88SBenjamin Coddington locks_free_lock(fl); 21561da177e4SLinus Torvalds return error; 21571da177e4SLinus Torvalds } 21581da177e4SLinus Torvalds 21597723ec97SMarc Eshel /** 21607723ec97SMarc Eshel * vfs_lock_file - file byte range lock 21617723ec97SMarc Eshel * @filp: The file to apply the lock to 21627723ec97SMarc Eshel * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.) 21637723ec97SMarc Eshel * @fl: The lock to be applied 2164150b3934SMarc Eshel * @conf: Place to return a copy of the conflicting lock, if found. 2165150b3934SMarc Eshel * 2166150b3934SMarc Eshel * A caller that doesn't care about the conflicting lock may pass NULL 2167150b3934SMarc Eshel * as the final argument. 2168150b3934SMarc Eshel * 2169150b3934SMarc Eshel * If the filesystem defines a private ->lock() method, then @conf will 2170150b3934SMarc Eshel * be left unchanged; so a caller that cares should initialize it to 2171150b3934SMarc Eshel * some acceptable default. 21722beb6614SMarc Eshel * 21732beb6614SMarc Eshel * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX 21742beb6614SMarc Eshel * locks, the ->lock() interface may return asynchronously, before the lock has 21752beb6614SMarc Eshel * been granted or denied by the underlying filesystem, if (and only if) 21768fb47a4fSJ. Bruce Fields * lm_grant is set. Callers expecting ->lock() to return asynchronously 21772beb6614SMarc Eshel * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if) 21782beb6614SMarc Eshel * the request is for a blocking lock. When ->lock() does return asynchronously, 21798fb47a4fSJ. Bruce Fields * it must return FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock 21802beb6614SMarc Eshel * request completes. 21812beb6614SMarc Eshel * If the request is for non-blocking lock the file system should return 2182bde74e4bSMiklos Szeredi * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine 2183bde74e4bSMiklos Szeredi * with the result. If the request timed out the callback routine will return a 21842beb6614SMarc Eshel * nonzero return code and the file system should release the lock. The file 21852beb6614SMarc Eshel * system is also responsible to keep a corresponding posix lock when it 21862beb6614SMarc Eshel * grants a lock so the VFS can find out which locks are locally held and do 21872beb6614SMarc Eshel * the correct lock cleanup when required. 21882beb6614SMarc Eshel * The underlying filesystem must not drop the kernel lock or call 21898fb47a4fSJ. Bruce Fields * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED 21902beb6614SMarc Eshel * return code. 21917723ec97SMarc Eshel */ 2192150b3934SMarc Eshel int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) 21937723ec97SMarc Eshel { 2194c568d683SMiklos Szeredi if (filp->f_op->lock && is_remote_lock(filp)) 21957723ec97SMarc Eshel return filp->f_op->lock(filp, cmd, fl); 21967723ec97SMarc Eshel else 2197150b3934SMarc Eshel return posix_lock_file(filp, fl, conf); 21987723ec97SMarc Eshel } 21997723ec97SMarc Eshel EXPORT_SYMBOL_GPL(vfs_lock_file); 22007723ec97SMarc Eshel 2201b648a6deSMiklos Szeredi static int do_lock_file_wait(struct file *filp, unsigned int cmd, 2202b648a6deSMiklos Szeredi struct file_lock *fl) 2203b648a6deSMiklos Szeredi { 2204b648a6deSMiklos Szeredi int error; 2205b648a6deSMiklos Szeredi 2206b648a6deSMiklos Szeredi error = security_file_lock(filp, fl->fl_type); 2207b648a6deSMiklos Szeredi if (error) 2208b648a6deSMiklos Szeredi return error; 2209b648a6deSMiklos Szeredi 2210b648a6deSMiklos Szeredi for (;;) { 2211764c76b3SMiklos Szeredi error = vfs_lock_file(filp, cmd, fl, NULL); 2212b648a6deSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 2213b648a6deSMiklos Szeredi break; 2214764c76b3SMiklos Szeredi error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); 2215b648a6deSMiklos Szeredi if (!error) 2216b648a6deSMiklos Szeredi continue; 2217b648a6deSMiklos Szeredi 2218b648a6deSMiklos Szeredi locks_delete_block(fl); 2219b648a6deSMiklos Szeredi break; 2220b648a6deSMiklos Szeredi } 2221b648a6deSMiklos Szeredi 2222b648a6deSMiklos Szeredi return error; 2223b648a6deSMiklos Szeredi } 2224b648a6deSMiklos Szeredi 22256ca7d910SBenjamin Coddington /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */ 2226cf01f4eeSJeff Layton static int 2227cf01f4eeSJeff Layton check_fmode_for_setlk(struct file_lock *fl) 2228cf01f4eeSJeff Layton { 2229cf01f4eeSJeff Layton switch (fl->fl_type) { 2230cf01f4eeSJeff Layton case F_RDLCK: 2231cf01f4eeSJeff Layton if (!(fl->fl_file->f_mode & FMODE_READ)) 2232cf01f4eeSJeff Layton return -EBADF; 2233cf01f4eeSJeff Layton break; 2234cf01f4eeSJeff Layton case F_WRLCK: 2235cf01f4eeSJeff Layton if (!(fl->fl_file->f_mode & FMODE_WRITE)) 2236cf01f4eeSJeff Layton return -EBADF; 2237cf01f4eeSJeff Layton } 2238cf01f4eeSJeff Layton return 0; 2239cf01f4eeSJeff Layton } 2240cf01f4eeSJeff Layton 22411da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 22421da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 22431da177e4SLinus Torvalds */ 2244c293621bSPeter Staubach int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, 2245a75d30c7SChristoph Hellwig struct flock *flock) 22461da177e4SLinus Torvalds { 22471da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 2248a75d30c7SChristoph Hellwig struct inode *inode = locks_inode(filp); 22490b2bac2fSAl Viro struct file *f; 22501da177e4SLinus Torvalds int error; 22511da177e4SLinus Torvalds 22521da177e4SLinus Torvalds if (file_lock == NULL) 22531da177e4SLinus Torvalds return -ENOLCK; 22541da177e4SLinus Torvalds 22551da177e4SLinus Torvalds /* Don't allow mandatory locks on files that may be memory mapped 22561da177e4SLinus Torvalds * and shared. 22571da177e4SLinus Torvalds */ 2258a16877caSPavel Emelyanov if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) { 22591da177e4SLinus Torvalds error = -EAGAIN; 22601da177e4SLinus Torvalds goto out; 22611da177e4SLinus Torvalds } 22621da177e4SLinus Torvalds 2263a75d30c7SChristoph Hellwig error = flock_to_posix_lock(filp, file_lock, flock); 22641da177e4SLinus Torvalds if (error) 22651da177e4SLinus Torvalds goto out; 22665d50ffd7SJeff Layton 2267cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2268cf01f4eeSJeff Layton if (error) 2269cf01f4eeSJeff Layton goto out; 2270cf01f4eeSJeff Layton 22715d50ffd7SJeff Layton /* 22725d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2273cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 22745d50ffd7SJeff Layton */ 22755d50ffd7SJeff Layton switch (cmd) { 22760d3f7a2dSJeff Layton case F_OFD_SETLK: 227790478939SJeff Layton error = -EINVAL; 2278a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 227990478939SJeff Layton goto out; 228090478939SJeff Layton 22815d50ffd7SJeff Layton cmd = F_SETLK; 2282cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 228373a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 22845d50ffd7SJeff Layton break; 22850d3f7a2dSJeff Layton case F_OFD_SETLKW: 228690478939SJeff Layton error = -EINVAL; 2287a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 228890478939SJeff Layton goto out; 228990478939SJeff Layton 22905d50ffd7SJeff Layton cmd = F_SETLKW; 2291cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 229273a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 22935d50ffd7SJeff Layton /* Fallthrough */ 22945d50ffd7SJeff Layton case F_SETLKW: 22951da177e4SLinus Torvalds file_lock->fl_flags |= FL_SLEEP; 22961da177e4SLinus Torvalds } 22971da177e4SLinus Torvalds 2298b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2299c293621bSPeter Staubach 2300c293621bSPeter Staubach /* 23010752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 23020752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 23030752ba80SJeff Layton * unlocking though, or for OFD locks. 2304c293621bSPeter Staubach */ 23050752ba80SJeff Layton if (!error && file_lock->fl_type != F_UNLCK && 23060752ba80SJeff Layton !(file_lock->fl_flags & FL_OFDLCK)) { 23070b2bac2fSAl Viro /* 23087f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 23097f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 23107f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 23110b2bac2fSAl Viro */ 23120b2bac2fSAl Viro spin_lock(¤t->files->file_lock); 23130b2bac2fSAl Viro f = fcheck(fd); 23140b2bac2fSAl Viro spin_unlock(¤t->files->file_lock); 23157f3697e2SJeff Layton if (f != filp) { 23167f3697e2SJeff Layton file_lock->fl_type = F_UNLCK; 23177f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 23187f3697e2SJeff Layton WARN_ON_ONCE(error); 23197f3697e2SJeff Layton error = -EBADF; 2320c293621bSPeter Staubach } 23217f3697e2SJeff Layton } 23221da177e4SLinus Torvalds out: 23231890910fSJeff Layton trace_fcntl_setlk(inode, file_lock, error); 23241da177e4SLinus Torvalds locks_free_lock(file_lock); 23251da177e4SLinus Torvalds return error; 23261da177e4SLinus Torvalds } 23271da177e4SLinus Torvalds 23281da177e4SLinus Torvalds #if BITS_PER_LONG == 32 23291da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 23301da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 23311da177e4SLinus Torvalds */ 2332a75d30c7SChristoph Hellwig int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) 23331da177e4SLinus Torvalds { 233452306e88SBenjamin Coddington struct file_lock *fl; 23351da177e4SLinus Torvalds int error; 23361da177e4SLinus Torvalds 233752306e88SBenjamin Coddington fl = locks_alloc_lock(); 233852306e88SBenjamin Coddington if (fl == NULL) 233952306e88SBenjamin Coddington return -ENOMEM; 234052306e88SBenjamin Coddington 23411da177e4SLinus Torvalds error = -EINVAL; 2342a75d30c7SChristoph Hellwig if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) 23431da177e4SLinus Torvalds goto out; 23441da177e4SLinus Torvalds 234552306e88SBenjamin Coddington error = flock64_to_posix_lock(filp, fl, flock); 23461da177e4SLinus Torvalds if (error) 23471da177e4SLinus Torvalds goto out; 23481da177e4SLinus Torvalds 23490d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 235090478939SJeff Layton error = -EINVAL; 2351a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 235290478939SJeff Layton goto out; 235390478939SJeff Layton 23545d50ffd7SJeff Layton cmd = F_GETLK64; 235552306e88SBenjamin Coddington fl->fl_flags |= FL_OFDLCK; 235652306e88SBenjamin Coddington fl->fl_owner = filp; 23575d50ffd7SJeff Layton } 23585d50ffd7SJeff Layton 235952306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 23603ee17abdSJ. Bruce Fields if (error) 23611da177e4SLinus Torvalds goto out; 23621da177e4SLinus Torvalds 236352306e88SBenjamin Coddington flock->l_type = fl->fl_type; 236452306e88SBenjamin Coddington if (fl->fl_type != F_UNLCK) 236552306e88SBenjamin Coddington posix_lock_to_flock64(flock, fl); 23661da177e4SLinus Torvalds 23671da177e4SLinus Torvalds out: 236852306e88SBenjamin Coddington locks_free_lock(fl); 23691da177e4SLinus Torvalds return error; 23701da177e4SLinus Torvalds } 23711da177e4SLinus Torvalds 23721da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 23731da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 23741da177e4SLinus Torvalds */ 2375c293621bSPeter Staubach int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, 2376a75d30c7SChristoph Hellwig struct flock64 *flock) 23771da177e4SLinus Torvalds { 23781da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 2379a75d30c7SChristoph Hellwig struct inode *inode = locks_inode(filp); 23800b2bac2fSAl Viro struct file *f; 23811da177e4SLinus Torvalds int error; 23821da177e4SLinus Torvalds 23831da177e4SLinus Torvalds if (file_lock == NULL) 23841da177e4SLinus Torvalds return -ENOLCK; 23851da177e4SLinus Torvalds 23861da177e4SLinus Torvalds /* Don't allow mandatory locks on files that may be memory mapped 23871da177e4SLinus Torvalds * and shared. 23881da177e4SLinus Torvalds */ 2389a16877caSPavel Emelyanov if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) { 23901da177e4SLinus Torvalds error = -EAGAIN; 23911da177e4SLinus Torvalds goto out; 23921da177e4SLinus Torvalds } 23931da177e4SLinus Torvalds 2394a75d30c7SChristoph Hellwig error = flock64_to_posix_lock(filp, file_lock, flock); 23951da177e4SLinus Torvalds if (error) 23961da177e4SLinus Torvalds goto out; 23975d50ffd7SJeff Layton 2398cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2399cf01f4eeSJeff Layton if (error) 2400cf01f4eeSJeff Layton goto out; 2401cf01f4eeSJeff Layton 24025d50ffd7SJeff Layton /* 24035d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2404cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 24055d50ffd7SJeff Layton */ 24065d50ffd7SJeff Layton switch (cmd) { 24070d3f7a2dSJeff Layton case F_OFD_SETLK: 240890478939SJeff Layton error = -EINVAL; 2409a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 241090478939SJeff Layton goto out; 241190478939SJeff Layton 24125d50ffd7SJeff Layton cmd = F_SETLK64; 2413cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 241473a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 24155d50ffd7SJeff Layton break; 24160d3f7a2dSJeff Layton case F_OFD_SETLKW: 241790478939SJeff Layton error = -EINVAL; 2418a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 241990478939SJeff Layton goto out; 242090478939SJeff Layton 24215d50ffd7SJeff Layton cmd = F_SETLKW64; 2422cff2fce5SJeff Layton file_lock->fl_flags |= FL_OFDLCK; 242373a8f5f7SChristoph Hellwig file_lock->fl_owner = filp; 24245d50ffd7SJeff Layton /* Fallthrough */ 24255d50ffd7SJeff Layton case F_SETLKW64: 24261da177e4SLinus Torvalds file_lock->fl_flags |= FL_SLEEP; 24271da177e4SLinus Torvalds } 24281da177e4SLinus Torvalds 2429b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2430c293621bSPeter Staubach 2431c293621bSPeter Staubach /* 24320752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 24330752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 24340752ba80SJeff Layton * unlocking though, or for OFD locks. 2435c293621bSPeter Staubach */ 24360752ba80SJeff Layton if (!error && file_lock->fl_type != F_UNLCK && 24370752ba80SJeff Layton !(file_lock->fl_flags & FL_OFDLCK)) { 24387f3697e2SJeff Layton /* 24397f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 24407f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 24417f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 24427f3697e2SJeff Layton */ 24430b2bac2fSAl Viro spin_lock(¤t->files->file_lock); 24440b2bac2fSAl Viro f = fcheck(fd); 24450b2bac2fSAl Viro spin_unlock(¤t->files->file_lock); 24467f3697e2SJeff Layton if (f != filp) { 24477f3697e2SJeff Layton file_lock->fl_type = F_UNLCK; 24487f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 24497f3697e2SJeff Layton WARN_ON_ONCE(error); 24507f3697e2SJeff Layton error = -EBADF; 2451c293621bSPeter Staubach } 24527f3697e2SJeff Layton } 24531da177e4SLinus Torvalds out: 24541da177e4SLinus Torvalds locks_free_lock(file_lock); 24551da177e4SLinus Torvalds return error; 24561da177e4SLinus Torvalds } 24571da177e4SLinus Torvalds #endif /* BITS_PER_LONG == 32 */ 24581da177e4SLinus Torvalds 24591da177e4SLinus Torvalds /* 24601da177e4SLinus Torvalds * This function is called when the file is being removed 24611da177e4SLinus Torvalds * from the task's fd array. POSIX locks belonging to this task 24621da177e4SLinus Torvalds * are deleted at this time. 24631da177e4SLinus Torvalds */ 24641da177e4SLinus Torvalds void locks_remove_posix(struct file *filp, fl_owner_t owner) 24651da177e4SLinus Torvalds { 24661890910fSJeff Layton int error; 2467c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 2468ff7b86b8SMiklos Szeredi struct file_lock lock; 2469128a3785SDmitry Vyukov struct file_lock_context *ctx; 24701da177e4SLinus Torvalds 24711da177e4SLinus Torvalds /* 24721da177e4SLinus Torvalds * If there are no locks held on this file, we don't need to call 24731da177e4SLinus Torvalds * posix_lock_file(). Another process could be setting a lock on this 24741da177e4SLinus Torvalds * file at the same time, but we wouldn't remove that lock anyway. 24751da177e4SLinus Torvalds */ 2476c568d683SMiklos Szeredi ctx = smp_load_acquire(&inode->i_flctx); 2477bd61e0a9SJeff Layton if (!ctx || list_empty(&ctx->flc_posix)) 24781da177e4SLinus Torvalds return; 24791da177e4SLinus Torvalds 24801da177e4SLinus Torvalds lock.fl_type = F_UNLCK; 248175e1fcc0SMiklos Szeredi lock.fl_flags = FL_POSIX | FL_CLOSE; 24821da177e4SLinus Torvalds lock.fl_start = 0; 24831da177e4SLinus Torvalds lock.fl_end = OFFSET_MAX; 24841da177e4SLinus Torvalds lock.fl_owner = owner; 24851da177e4SLinus Torvalds lock.fl_pid = current->tgid; 24861da177e4SLinus Torvalds lock.fl_file = filp; 24871da177e4SLinus Torvalds lock.fl_ops = NULL; 24881da177e4SLinus Torvalds lock.fl_lmops = NULL; 24891da177e4SLinus Torvalds 24901890910fSJeff Layton error = vfs_lock_file(filp, F_SETLK, &lock, NULL); 24911da177e4SLinus Torvalds 24921da177e4SLinus Torvalds if (lock.fl_ops && lock.fl_ops->fl_release_private) 24931da177e4SLinus Torvalds lock.fl_ops->fl_release_private(&lock); 2494c568d683SMiklos Szeredi trace_locks_remove_posix(inode, &lock, error); 24951da177e4SLinus Torvalds } 24961da177e4SLinus Torvalds 24971da177e4SLinus Torvalds EXPORT_SYMBOL(locks_remove_posix); 24981da177e4SLinus Torvalds 24993d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 2500dd459bb1SJeff Layton static void 2501128a3785SDmitry Vyukov locks_remove_flock(struct file *filp, struct file_lock_context *flctx) 2502dd459bb1SJeff Layton { 2503dd459bb1SJeff Layton struct file_lock fl = { 2504dd459bb1SJeff Layton .fl_owner = filp, 2505dd459bb1SJeff Layton .fl_pid = current->tgid, 2506dd459bb1SJeff Layton .fl_file = filp, 250750f2112cSBenjamin Coddington .fl_flags = FL_FLOCK | FL_CLOSE, 2508dd459bb1SJeff Layton .fl_type = F_UNLCK, 2509dd459bb1SJeff Layton .fl_end = OFFSET_MAX, 2510dd459bb1SJeff Layton }; 2511c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 2512dd459bb1SJeff Layton 25133d8e560dSJeff Layton if (list_empty(&flctx->flc_flock)) 2514dd459bb1SJeff Layton return; 2515dd459bb1SJeff Layton 2516c568d683SMiklos Szeredi if (filp->f_op->flock && is_remote_lock(filp)) 2517dd459bb1SJeff Layton filp->f_op->flock(filp, F_SETLKW, &fl); 2518dd459bb1SJeff Layton else 2519bcd7f78dSJeff Layton flock_lock_inode(inode, &fl); 2520dd459bb1SJeff Layton 2521dd459bb1SJeff Layton if (fl.fl_ops && fl.fl_ops->fl_release_private) 2522dd459bb1SJeff Layton fl.fl_ops->fl_release_private(&fl); 2523dd459bb1SJeff Layton } 2524dd459bb1SJeff Layton 25253d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 25268634b51fSJeff Layton static void 2527128a3785SDmitry Vyukov locks_remove_lease(struct file *filp, struct file_lock_context *ctx) 25288634b51fSJeff Layton { 25298634b51fSJeff Layton struct file_lock *fl, *tmp; 25308634b51fSJeff Layton LIST_HEAD(dispose); 25318634b51fSJeff Layton 25323d8e560dSJeff Layton if (list_empty(&ctx->flc_lease)) 25338634b51fSJeff Layton return; 25348634b51fSJeff Layton 25355f43086bSPeter Zijlstra percpu_down_read_preempt_disable(&file_rwsem); 25366109c850SJeff Layton spin_lock(&ctx->flc_lock); 25378634b51fSJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) 2538c4e136cdSJeff Layton if (filp == fl->fl_file) 25397448cc37SJeff Layton lease_modify(fl, F_UNLCK, &dispose); 25406109c850SJeff Layton spin_unlock(&ctx->flc_lock); 25415f43086bSPeter Zijlstra percpu_up_read_preempt_enable(&file_rwsem); 25425f43086bSPeter Zijlstra 25438634b51fSJeff Layton locks_dispose_list(&dispose); 25448634b51fSJeff Layton } 25458634b51fSJeff Layton 25461da177e4SLinus Torvalds /* 25471da177e4SLinus Torvalds * This function is called on the last close of an open file. 25481da177e4SLinus Torvalds */ 254978ed8a13SJeff Layton void locks_remove_file(struct file *filp) 25501da177e4SLinus Torvalds { 2551128a3785SDmitry Vyukov struct file_lock_context *ctx; 2552128a3785SDmitry Vyukov 2553c568d683SMiklos Szeredi ctx = smp_load_acquire(&locks_inode(filp)->i_flctx); 2554128a3785SDmitry Vyukov if (!ctx) 25553d8e560dSJeff Layton return; 25563d8e560dSJeff Layton 2557dd459bb1SJeff Layton /* remove any OFD locks */ 255873a8f5f7SChristoph Hellwig locks_remove_posix(filp, filp); 25595d50ffd7SJeff Layton 2560dd459bb1SJeff Layton /* remove flock locks */ 2561128a3785SDmitry Vyukov locks_remove_flock(filp, ctx); 2562dd459bb1SJeff Layton 25638634b51fSJeff Layton /* remove any leases */ 2564128a3785SDmitry Vyukov locks_remove_lease(filp, ctx); 25653953704fSBenjamin Coddington 25663953704fSBenjamin Coddington spin_lock(&ctx->flc_lock); 25673953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX"); 25683953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK"); 25693953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE"); 25703953704fSBenjamin Coddington spin_unlock(&ctx->flc_lock); 25711da177e4SLinus Torvalds } 25721da177e4SLinus Torvalds 25731da177e4SLinus Torvalds /** 25741da177e4SLinus Torvalds * posix_unblock_lock - stop waiting for a file lock 25751da177e4SLinus Torvalds * @waiter: the lock which was waiting 25761da177e4SLinus Torvalds * 25771da177e4SLinus Torvalds * lockd needs to block waiting for locks. 25781da177e4SLinus Torvalds */ 257964a318eeSJ. Bruce Fields int 2580f891a29fSJeff Layton posix_unblock_lock(struct file_lock *waiter) 25811da177e4SLinus Torvalds { 258264a318eeSJ. Bruce Fields int status = 0; 258364a318eeSJ. Bruce Fields 25847b2296afSJeff Layton spin_lock(&blocked_lock_lock); 25855996a298SJ. Bruce Fields if (waiter->fl_next) 25861da177e4SLinus Torvalds __locks_delete_block(waiter); 258764a318eeSJ. Bruce Fields else 258864a318eeSJ. Bruce Fields status = -ENOENT; 25897b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 259064a318eeSJ. Bruce Fields return status; 25911da177e4SLinus Torvalds } 25921da177e4SLinus Torvalds EXPORT_SYMBOL(posix_unblock_lock); 25931da177e4SLinus Torvalds 25949b9d2ab4SMarc Eshel /** 25959b9d2ab4SMarc Eshel * vfs_cancel_lock - file byte range unblock lock 25969b9d2ab4SMarc Eshel * @filp: The file to apply the unblock to 25979b9d2ab4SMarc Eshel * @fl: The lock to be unblocked 25989b9d2ab4SMarc Eshel * 25999b9d2ab4SMarc Eshel * Used by lock managers to cancel blocked requests 26009b9d2ab4SMarc Eshel */ 26019b9d2ab4SMarc Eshel int vfs_cancel_lock(struct file *filp, struct file_lock *fl) 26029b9d2ab4SMarc Eshel { 2603c568d683SMiklos Szeredi if (filp->f_op->lock && is_remote_lock(filp)) 26049b9d2ab4SMarc Eshel return filp->f_op->lock(filp, F_CANCELLK, fl); 26059b9d2ab4SMarc Eshel return 0; 26069b9d2ab4SMarc Eshel } 26079b9d2ab4SMarc Eshel 26089b9d2ab4SMarc Eshel EXPORT_SYMBOL_GPL(vfs_cancel_lock); 26099b9d2ab4SMarc Eshel 26107f8ada98SPavel Emelyanov #ifdef CONFIG_PROC_FS 2611d8ba7a36SAlexey Dobriyan #include <linux/proc_fs.h> 26127f8ada98SPavel Emelyanov #include <linux/seq_file.h> 26137f8ada98SPavel Emelyanov 26147012b02aSJeff Layton struct locks_iterator { 26157012b02aSJeff Layton int li_cpu; 26167012b02aSJeff Layton loff_t li_pos; 26177012b02aSJeff Layton }; 26187012b02aSJeff Layton 26197f8ada98SPavel Emelyanov static void lock_get_status(struct seq_file *f, struct file_lock *fl, 262099dc8292SJerome Marchand loff_t id, char *pfx) 26211da177e4SLinus Torvalds { 26221da177e4SLinus Torvalds struct inode *inode = NULL; 2623ab1f1611SVitaliy Gusev unsigned int fl_pid; 2624d67fd44fSNikolay Borisov struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info; 2625d67fd44fSNikolay Borisov 26269d5b86acSBenjamin Coddington fl_pid = locks_translate_pid(fl, proc_pidns); 2627d67fd44fSNikolay Borisov /* 2628d67fd44fSNikolay Borisov * If there isn't a fl_pid don't display who is waiting on 2629d67fd44fSNikolay Borisov * the lock if we are called from locks_show, or if we are 2630d67fd44fSNikolay Borisov * called from __show_fd_info - skip lock entirely 2631d67fd44fSNikolay Borisov */ 2632d67fd44fSNikolay Borisov if (fl_pid == 0) 2633d67fd44fSNikolay Borisov return; 26341da177e4SLinus Torvalds 26351da177e4SLinus Torvalds if (fl->fl_file != NULL) 2636c568d683SMiklos Szeredi inode = locks_inode(fl->fl_file); 26371da177e4SLinus Torvalds 263899dc8292SJerome Marchand seq_printf(f, "%lld:%s ", id, pfx); 26391da177e4SLinus Torvalds if (IS_POSIX(fl)) { 2640c918d42aSJeff Layton if (fl->fl_flags & FL_ACCESS) 26415315c26aSFabian Frederick seq_puts(f, "ACCESS"); 2642cff2fce5SJeff Layton else if (IS_OFDLCK(fl)) 26435315c26aSFabian Frederick seq_puts(f, "OFDLCK"); 2644c918d42aSJeff Layton else 26455315c26aSFabian Frederick seq_puts(f, "POSIX "); 2646c918d42aSJeff Layton 2647c918d42aSJeff Layton seq_printf(f, " %s ", 26481da177e4SLinus Torvalds (inode == NULL) ? "*NOINODE*" : 2649a16877caSPavel Emelyanov mandatory_lock(inode) ? "MANDATORY" : "ADVISORY "); 26501da177e4SLinus Torvalds } else if (IS_FLOCK(fl)) { 26511da177e4SLinus Torvalds if (fl->fl_type & LOCK_MAND) { 26525315c26aSFabian Frederick seq_puts(f, "FLOCK MSNFS "); 26531da177e4SLinus Torvalds } else { 26545315c26aSFabian Frederick seq_puts(f, "FLOCK ADVISORY "); 26551da177e4SLinus Torvalds } 26561da177e4SLinus Torvalds } else if (IS_LEASE(fl)) { 26578144f1f6SJeff Layton if (fl->fl_flags & FL_DELEG) 26588144f1f6SJeff Layton seq_puts(f, "DELEG "); 26598144f1f6SJeff Layton else 26605315c26aSFabian Frederick seq_puts(f, "LEASE "); 26618144f1f6SJeff Layton 2662ab83fa4bSJ. Bruce Fields if (lease_breaking(fl)) 26635315c26aSFabian Frederick seq_puts(f, "BREAKING "); 26641da177e4SLinus Torvalds else if (fl->fl_file) 26655315c26aSFabian Frederick seq_puts(f, "ACTIVE "); 26661da177e4SLinus Torvalds else 26675315c26aSFabian Frederick seq_puts(f, "BREAKER "); 26681da177e4SLinus Torvalds } else { 26695315c26aSFabian Frederick seq_puts(f, "UNKNOWN UNKNOWN "); 26701da177e4SLinus Torvalds } 26711da177e4SLinus Torvalds if (fl->fl_type & LOCK_MAND) { 26727f8ada98SPavel Emelyanov seq_printf(f, "%s ", 26731da177e4SLinus Torvalds (fl->fl_type & LOCK_READ) 26741da177e4SLinus Torvalds ? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ " 26751da177e4SLinus Torvalds : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE "); 26761da177e4SLinus Torvalds } else { 26777f8ada98SPavel Emelyanov seq_printf(f, "%s ", 2678ab83fa4bSJ. Bruce Fields (lease_breaking(fl)) 26790ee5c6d6SJeff Layton ? (fl->fl_type == F_UNLCK) ? "UNLCK" : "READ " 26800ee5c6d6SJeff Layton : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ "); 26811da177e4SLinus Torvalds } 26821da177e4SLinus Torvalds if (inode) { 26833648888eSJeff Layton /* userspace relies on this representation of dev_t */ 2684ab1f1611SVitaliy Gusev seq_printf(f, "%d %02x:%02x:%ld ", fl_pid, 26851da177e4SLinus Torvalds MAJOR(inode->i_sb->s_dev), 26861da177e4SLinus Torvalds MINOR(inode->i_sb->s_dev), inode->i_ino); 26871da177e4SLinus Torvalds } else { 2688ab1f1611SVitaliy Gusev seq_printf(f, "%d <none>:0 ", fl_pid); 26891da177e4SLinus Torvalds } 26901da177e4SLinus Torvalds if (IS_POSIX(fl)) { 26911da177e4SLinus Torvalds if (fl->fl_end == OFFSET_MAX) 26927f8ada98SPavel Emelyanov seq_printf(f, "%Ld EOF\n", fl->fl_start); 26931da177e4SLinus Torvalds else 26947f8ada98SPavel Emelyanov seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end); 26951da177e4SLinus Torvalds } else { 26965315c26aSFabian Frederick seq_puts(f, "0 EOF\n"); 26971da177e4SLinus Torvalds } 26981da177e4SLinus Torvalds } 26991da177e4SLinus Torvalds 27007f8ada98SPavel Emelyanov static int locks_show(struct seq_file *f, void *v) 27011da177e4SLinus Torvalds { 27027012b02aSJeff Layton struct locks_iterator *iter = f->private; 27037f8ada98SPavel Emelyanov struct file_lock *fl, *bfl; 2704d67fd44fSNikolay Borisov struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info; 27057f8ada98SPavel Emelyanov 2706139ca04eSJeff Layton fl = hlist_entry(v, struct file_lock, fl_link); 27077f8ada98SPavel Emelyanov 27089d5b86acSBenjamin Coddington if (locks_translate_pid(fl, proc_pidns) == 0) 2709d67fd44fSNikolay Borisov return 0; 2710d67fd44fSNikolay Borisov 27117012b02aSJeff Layton lock_get_status(f, fl, iter->li_pos, ""); 27127f8ada98SPavel Emelyanov 27137f8ada98SPavel Emelyanov list_for_each_entry(bfl, &fl->fl_block, fl_block) 27147012b02aSJeff Layton lock_get_status(f, bfl, iter->li_pos, " ->"); 27157f8ada98SPavel Emelyanov 27167f8ada98SPavel Emelyanov return 0; 27171da177e4SLinus Torvalds } 27181da177e4SLinus Torvalds 27196c8c9031SAndrey Vagin static void __show_fd_locks(struct seq_file *f, 27206c8c9031SAndrey Vagin struct list_head *head, int *id, 27216c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 27226c8c9031SAndrey Vagin { 27236c8c9031SAndrey Vagin struct file_lock *fl; 27246c8c9031SAndrey Vagin 27256c8c9031SAndrey Vagin list_for_each_entry(fl, head, fl_list) { 27266c8c9031SAndrey Vagin 27276c8c9031SAndrey Vagin if (filp != fl->fl_file) 27286c8c9031SAndrey Vagin continue; 27296c8c9031SAndrey Vagin if (fl->fl_owner != files && 27306c8c9031SAndrey Vagin fl->fl_owner != filp) 27316c8c9031SAndrey Vagin continue; 27326c8c9031SAndrey Vagin 27336c8c9031SAndrey Vagin (*id)++; 27346c8c9031SAndrey Vagin seq_puts(f, "lock:\t"); 27356c8c9031SAndrey Vagin lock_get_status(f, fl, *id, ""); 27366c8c9031SAndrey Vagin } 27376c8c9031SAndrey Vagin } 27386c8c9031SAndrey Vagin 27396c8c9031SAndrey Vagin void show_fd_locks(struct seq_file *f, 27406c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 27416c8c9031SAndrey Vagin { 2742c568d683SMiklos Szeredi struct inode *inode = locks_inode(filp); 27436c8c9031SAndrey Vagin struct file_lock_context *ctx; 27446c8c9031SAndrey Vagin int id = 0; 27456c8c9031SAndrey Vagin 2746128a3785SDmitry Vyukov ctx = smp_load_acquire(&inode->i_flctx); 27476c8c9031SAndrey Vagin if (!ctx) 27486c8c9031SAndrey Vagin return; 27496c8c9031SAndrey Vagin 27506c8c9031SAndrey Vagin spin_lock(&ctx->flc_lock); 27516c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_flock, &id, filp, files); 27526c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_posix, &id, filp, files); 27536c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_lease, &id, filp, files); 27546c8c9031SAndrey Vagin spin_unlock(&ctx->flc_lock); 27556c8c9031SAndrey Vagin } 27566c8c9031SAndrey Vagin 27577f8ada98SPavel Emelyanov static void *locks_start(struct seq_file *f, loff_t *pos) 2758b03dfdecSJeff Layton __acquires(&blocked_lock_lock) 27591da177e4SLinus Torvalds { 27607012b02aSJeff Layton struct locks_iterator *iter = f->private; 276199dc8292SJerome Marchand 27627012b02aSJeff Layton iter->li_pos = *pos + 1; 2763aba37660SPeter Zijlstra percpu_down_write(&file_rwsem); 27647b2296afSJeff Layton spin_lock(&blocked_lock_lock); 27657c3f654dSPeter Zijlstra return seq_hlist_start_percpu(&file_lock_list.hlist, &iter->li_cpu, *pos); 27661da177e4SLinus Torvalds } 27677f8ada98SPavel Emelyanov 27687f8ada98SPavel Emelyanov static void *locks_next(struct seq_file *f, void *v, loff_t *pos) 27697f8ada98SPavel Emelyanov { 27707012b02aSJeff Layton struct locks_iterator *iter = f->private; 27717012b02aSJeff Layton 27727012b02aSJeff Layton ++iter->li_pos; 27737c3f654dSPeter Zijlstra return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos); 27741da177e4SLinus Torvalds } 27757f8ada98SPavel Emelyanov 27767f8ada98SPavel Emelyanov static void locks_stop(struct seq_file *f, void *v) 2777b03dfdecSJeff Layton __releases(&blocked_lock_lock) 27787f8ada98SPavel Emelyanov { 27797b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 2780aba37660SPeter Zijlstra percpu_up_write(&file_rwsem); 27811da177e4SLinus Torvalds } 27821da177e4SLinus Torvalds 2783d8ba7a36SAlexey Dobriyan static const struct seq_operations locks_seq_operations = { 27847f8ada98SPavel Emelyanov .start = locks_start, 27857f8ada98SPavel Emelyanov .next = locks_next, 27867f8ada98SPavel Emelyanov .stop = locks_stop, 27877f8ada98SPavel Emelyanov .show = locks_show, 27887f8ada98SPavel Emelyanov }; 2789d8ba7a36SAlexey Dobriyan 2790d8ba7a36SAlexey Dobriyan static int __init proc_locks_init(void) 2791d8ba7a36SAlexey Dobriyan { 279244414d82SChristoph Hellwig proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, 279344414d82SChristoph Hellwig sizeof(struct locks_iterator), NULL); 2794d8ba7a36SAlexey Dobriyan return 0; 2795d8ba7a36SAlexey Dobriyan } 279691899226SPaul Gortmaker fs_initcall(proc_locks_init); 27977f8ada98SPavel Emelyanov #endif 27987f8ada98SPavel Emelyanov 27991da177e4SLinus Torvalds static int __init filelock_init(void) 28001da177e4SLinus Torvalds { 28017012b02aSJeff Layton int i; 28027012b02aSJeff Layton 28034a075e39SJeff Layton flctx_cache = kmem_cache_create("file_lock_ctx", 28044a075e39SJeff Layton sizeof(struct file_lock_context), 0, SLAB_PANIC, NULL); 28054a075e39SJeff Layton 28061da177e4SLinus Torvalds filelock_cache = kmem_cache_create("file_lock_cache", 2807ee19cc40SMiklos Szeredi sizeof(struct file_lock), 0, SLAB_PANIC, NULL); 2808ee19cc40SMiklos Szeredi 28097012b02aSJeff Layton 28107c3f654dSPeter Zijlstra for_each_possible_cpu(i) { 28117c3f654dSPeter Zijlstra struct file_lock_list_struct *fll = per_cpu_ptr(&file_lock_list, i); 28127c3f654dSPeter Zijlstra 28137c3f654dSPeter Zijlstra spin_lock_init(&fll->lock); 28147c3f654dSPeter Zijlstra INIT_HLIST_HEAD(&fll->hlist); 28157c3f654dSPeter Zijlstra } 28167012b02aSJeff Layton 28171da177e4SLinus Torvalds return 0; 28181da177e4SLinus Torvalds } 28191da177e4SLinus Torvalds 28201da177e4SLinus Torvalds core_initcall(filelock_init); 2821