1457c8996SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * linux/fs/locks.c 41da177e4SLinus Torvalds * 5e9728cc7SJ. Bruce Fields * We implement four types of file locks: BSD locks, posix locks, open 6e9728cc7SJ. Bruce Fields * file description locks, and leases. For details about BSD locks, 7e9728cc7SJ. Bruce Fields * see the flock(2) man page; for details about the other three, see 8e9728cc7SJ. Bruce Fields * fcntl(2). 91da177e4SLinus Torvalds * 10fd7732e0SNeilBrown * 11fd7732e0SNeilBrown * Locking conflicts and dependencies: 12fd7732e0SNeilBrown * If multiple threads attempt to lock the same byte (or flock the same file) 13fd7732e0SNeilBrown * only one can be granted the lock, and other must wait their turn. 14fd7732e0SNeilBrown * The first lock has been "applied" or "granted", the others are "waiting" 15fd7732e0SNeilBrown * and are "blocked" by the "applied" lock.. 16fd7732e0SNeilBrown * 17fd7732e0SNeilBrown * Waiting and applied locks are all kept in trees whose properties are: 18fd7732e0SNeilBrown * 19fd7732e0SNeilBrown * - the root of a tree may be an applied or waiting lock. 20fd7732e0SNeilBrown * - every other node in the tree is a waiting lock that 21fd7732e0SNeilBrown * conflicts with every ancestor of that node. 22fd7732e0SNeilBrown * 23fd7732e0SNeilBrown * Every such tree begins life as a waiting singleton which obviously 24fd7732e0SNeilBrown * satisfies the above properties. 25fd7732e0SNeilBrown * 26fd7732e0SNeilBrown * The only ways we modify trees preserve these properties: 27fd7732e0SNeilBrown * 28fd7732e0SNeilBrown * 1. We may add a new leaf node, but only after first verifying that it 29fd7732e0SNeilBrown * conflicts with all of its ancestors. 30fd7732e0SNeilBrown * 2. We may remove the root of a tree, creating a new singleton 31fd7732e0SNeilBrown * tree from the root and N new trees rooted in the immediate 32fd7732e0SNeilBrown * children. 33fd7732e0SNeilBrown * 3. If the root of a tree is not currently an applied lock, we may 34fd7732e0SNeilBrown * apply it (if possible). 35fd7732e0SNeilBrown * 4. We may upgrade the root of the tree (either extend its range, 36fd7732e0SNeilBrown * or upgrade its entire range from read to write). 37fd7732e0SNeilBrown * 38fd7732e0SNeilBrown * When an applied lock is modified in a way that reduces or downgrades any 39fd7732e0SNeilBrown * part of its range, we remove all its children (2 above). This particularly 40fd7732e0SNeilBrown * happens when a lock is unlocked. 41fd7732e0SNeilBrown * 42fd7732e0SNeilBrown * For each of those child trees we "wake up" the thread which is 43fd7732e0SNeilBrown * waiting for the lock so it can continue handling as follows: if the 44fd7732e0SNeilBrown * root of the tree applies, we do so (3). If it doesn't, it must 45fd7732e0SNeilBrown * conflict with some applied lock. We remove (wake up) all of its children 46fd7732e0SNeilBrown * (2), and add it is a new leaf to the tree rooted in the applied 47fd7732e0SNeilBrown * lock (1). We then repeat the process recursively with those 48fd7732e0SNeilBrown * children. 49fd7732e0SNeilBrown * 501da177e4SLinus Torvalds */ 511da177e4SLinus Torvalds #include <linux/capability.h> 521da177e4SLinus Torvalds #include <linux/file.h> 539f3acc31SAl Viro #include <linux/fdtable.h> 545970e15dSJeff Layton #include <linux/filelock.h> 551da177e4SLinus Torvalds #include <linux/fs.h> 561da177e4SLinus Torvalds #include <linux/init.h> 571da177e4SLinus Torvalds #include <linux/security.h> 581da177e4SLinus Torvalds #include <linux/slab.h> 591da177e4SLinus Torvalds #include <linux/syscalls.h> 601da177e4SLinus Torvalds #include <linux/time.h> 614fb3a538SDipankar Sarma #include <linux/rcupdate.h> 62ab1f1611SVitaliy Gusev #include <linux/pid_namespace.h> 6348f74186SJeff Layton #include <linux/hashtable.h> 647012b02aSJeff Layton #include <linux/percpu.h> 65dd81faa8SLuis Chamberlain #include <linux/sysctl.h> 661da177e4SLinus Torvalds 6762af4f1fSJeff Layton #define CREATE_TRACE_POINTS 6862af4f1fSJeff Layton #include <trace/events/filelock.h> 6962af4f1fSJeff Layton 707c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 711da177e4SLinus Torvalds 721a62c22aSJeff Layton static struct file_lock *file_lock(struct file_lock_core *flc) 731a62c22aSJeff Layton { 741a62c22aSJeff Layton return container_of(flc, struct file_lock, c); 751a62c22aSJeff Layton } 761a62c22aSJeff Layton 77ab83fa4bSJ. Bruce Fields static bool lease_breaking(struct file_lock *fl) 78ab83fa4bSJ. Bruce Fields { 794ca52f53SJeff Layton return fl->c.flc_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING); 80778fc546SJ. Bruce Fields } 81778fc546SJ. Bruce Fields 82778fc546SJ. Bruce Fields static int target_leasetype(struct file_lock *fl) 83778fc546SJ. Bruce Fields { 844ca52f53SJeff Layton if (fl->c.flc_flags & FL_UNLOCK_PENDING) 85778fc546SJ. Bruce Fields return F_UNLCK; 864ca52f53SJeff Layton if (fl->c.flc_flags & FL_DOWNGRADE_PENDING) 87778fc546SJ. Bruce Fields return F_RDLCK; 884ca52f53SJeff Layton return fl->c.flc_type; 89ab83fa4bSJ. Bruce Fields } 90ab83fa4bSJ. Bruce Fields 91dd81faa8SLuis Chamberlain static int leases_enable = 1; 92dd81faa8SLuis Chamberlain static int lease_break_time = 45; 93dd81faa8SLuis Chamberlain 94dd81faa8SLuis Chamberlain #ifdef CONFIG_SYSCTL 95dd81faa8SLuis Chamberlain static struct ctl_table locks_sysctls[] = { 96dd81faa8SLuis Chamberlain { 97dd81faa8SLuis Chamberlain .procname = "leases-enable", 98dd81faa8SLuis Chamberlain .data = &leases_enable, 99dd81faa8SLuis Chamberlain .maxlen = sizeof(int), 100dd81faa8SLuis Chamberlain .mode = 0644, 101dd81faa8SLuis Chamberlain .proc_handler = proc_dointvec, 102dd81faa8SLuis Chamberlain }, 103dd81faa8SLuis Chamberlain #ifdef CONFIG_MMU 104dd81faa8SLuis Chamberlain { 105dd81faa8SLuis Chamberlain .procname = "lease-break-time", 106dd81faa8SLuis Chamberlain .data = &lease_break_time, 107dd81faa8SLuis Chamberlain .maxlen = sizeof(int), 108dd81faa8SLuis Chamberlain .mode = 0644, 109dd81faa8SLuis Chamberlain .proc_handler = proc_dointvec, 110dd81faa8SLuis Chamberlain }, 111dd81faa8SLuis Chamberlain #endif /* CONFIG_MMU */ 112dd81faa8SLuis Chamberlain }; 113dd81faa8SLuis Chamberlain 114dd81faa8SLuis Chamberlain static int __init init_fs_locks_sysctls(void) 115dd81faa8SLuis Chamberlain { 116dd81faa8SLuis Chamberlain register_sysctl_init("fs", locks_sysctls); 117dd81faa8SLuis Chamberlain return 0; 118dd81faa8SLuis Chamberlain } 119dd81faa8SLuis Chamberlain early_initcall(init_fs_locks_sysctls); 120dd81faa8SLuis Chamberlain #endif /* CONFIG_SYSCTL */ 1211da177e4SLinus Torvalds 1221c8c601aSJeff Layton /* 1237012b02aSJeff Layton * The global file_lock_list is only used for displaying /proc/locks, so we 1247c3f654dSPeter Zijlstra * keep a list on each CPU, with each list protected by its own spinlock. 1257c3f654dSPeter Zijlstra * Global serialization is done using file_rwsem. 1267c3f654dSPeter Zijlstra * 1277c3f654dSPeter Zijlstra * Note that alterations to the list also require that the relevant flc_lock is 1287c3f654dSPeter Zijlstra * held. 1291c8c601aSJeff Layton */ 1307c3f654dSPeter Zijlstra struct file_lock_list_struct { 1317c3f654dSPeter Zijlstra spinlock_t lock; 1327c3f654dSPeter Zijlstra struct hlist_head hlist; 1337c3f654dSPeter Zijlstra }; 1347c3f654dSPeter Zijlstra static DEFINE_PER_CPU(struct file_lock_list_struct, file_lock_list); 135aba37660SPeter Zijlstra DEFINE_STATIC_PERCPU_RWSEM(file_rwsem); 13688974691SJeff Layton 137eb82dd39SJeff Layton 1381c8c601aSJeff Layton /* 13948f74186SJeff Layton * The blocked_hash is used to find POSIX lock loops for deadlock detection. 1407b2296afSJeff Layton * It is protected by blocked_lock_lock. 14148f74186SJeff Layton * 14248f74186SJeff Layton * We hash locks by lockowner in order to optimize searching for the lock a 14348f74186SJeff Layton * particular lockowner is waiting on. 14448f74186SJeff Layton * 14548f74186SJeff Layton * FIXME: make this value scale via some heuristic? We generally will want more 14648f74186SJeff Layton * buckets when we have more lockowners holding locks, but that's a little 14748f74186SJeff Layton * difficult to determine without knowing what the workload will look like. 1481c8c601aSJeff Layton */ 14948f74186SJeff Layton #define BLOCKED_HASH_BITS 7 15048f74186SJeff Layton static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS); 15188974691SJeff Layton 1521c8c601aSJeff Layton /* 1537b2296afSJeff Layton * This lock protects the blocked_hash. Generally, if you're accessing it, you 1547b2296afSJeff Layton * want to be holding this lock. 1551c8c601aSJeff Layton * 156ada5c1daSNeilBrown * In addition, it also protects the fl->fl_blocked_requests list, and the 157ada5c1daSNeilBrown * fl->fl_blocker pointer for file_lock structures that are acting as lock 158ada5c1daSNeilBrown * requests (in contrast to those that are acting as records of acquired locks). 1591c8c601aSJeff Layton * 1601c8c601aSJeff Layton * Note that when we acquire this lock in order to change the above fields, 1616109c850SJeff Layton * we often hold the flc_lock as well. In certain cases, when reading the fields 1621c8c601aSJeff Layton * protected by this lock, we can skip acquiring it iff we already hold the 1636109c850SJeff Layton * flc_lock. 1641c8c601aSJeff Layton */ 1657b2296afSJeff Layton static DEFINE_SPINLOCK(blocked_lock_lock); 1661da177e4SLinus Torvalds 16768279f9cSAlexey Dobriyan static struct kmem_cache *flctx_cache __ro_after_init; 16868279f9cSAlexey Dobriyan static struct kmem_cache *filelock_cache __ro_after_init; 1691da177e4SLinus Torvalds 1704a075e39SJeff Layton static struct file_lock_context * 1715c1c669aSJeff Layton locks_get_lock_context(struct inode *inode, int type) 1724a075e39SJeff Layton { 173128a3785SDmitry Vyukov struct file_lock_context *ctx; 1744a075e39SJeff Layton 175128a3785SDmitry Vyukov /* paired with cmpxchg() below */ 176401a8b8fSJeff Layton ctx = locks_inode_context(inode); 177128a3785SDmitry Vyukov if (likely(ctx) || type == F_UNLCK) 1784a075e39SJeff Layton goto out; 1794a075e39SJeff Layton 180128a3785SDmitry Vyukov ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL); 181128a3785SDmitry Vyukov if (!ctx) 1824a075e39SJeff Layton goto out; 1834a075e39SJeff Layton 184128a3785SDmitry Vyukov spin_lock_init(&ctx->flc_lock); 185128a3785SDmitry Vyukov INIT_LIST_HEAD(&ctx->flc_flock); 186128a3785SDmitry Vyukov INIT_LIST_HEAD(&ctx->flc_posix); 187128a3785SDmitry Vyukov INIT_LIST_HEAD(&ctx->flc_lease); 1884a075e39SJeff Layton 1894a075e39SJeff Layton /* 1904a075e39SJeff Layton * Assign the pointer if it's not already assigned. If it is, then 1914a075e39SJeff Layton * free the context we just allocated. 1924a075e39SJeff Layton */ 193128a3785SDmitry Vyukov if (cmpxchg(&inode->i_flctx, NULL, ctx)) { 194128a3785SDmitry Vyukov kmem_cache_free(flctx_cache, ctx); 195401a8b8fSJeff Layton ctx = locks_inode_context(inode); 196128a3785SDmitry Vyukov } 1974a075e39SJeff Layton out: 1981890910fSJeff Layton trace_locks_get_lock_context(inode, type, ctx); 199128a3785SDmitry Vyukov return ctx; 2004a075e39SJeff Layton } 2014a075e39SJeff Layton 202e24dadabSJeff Layton static void 203e24dadabSJeff Layton locks_dump_ctx_list(struct list_head *list, char *list_type) 204e24dadabSJeff Layton { 205fde49518SJeff Layton struct file_lock_core *flc; 206e24dadabSJeff Layton 207fde49518SJeff Layton list_for_each_entry(flc, list, flc_list) 208fde49518SJeff Layton pr_warn("%s: fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n", 209fde49518SJeff Layton list_type, flc->flc_owner, flc->flc_flags, 210fde49518SJeff Layton flc->flc_type, flc->flc_pid); 211e24dadabSJeff Layton } 212e24dadabSJeff Layton 213e24dadabSJeff Layton static void 214e24dadabSJeff Layton locks_check_ctx_lists(struct inode *inode) 215e24dadabSJeff Layton { 216e24dadabSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 217e24dadabSJeff Layton 218e24dadabSJeff Layton if (unlikely(!list_empty(&ctx->flc_flock) || 219e24dadabSJeff Layton !list_empty(&ctx->flc_posix) || 220e24dadabSJeff Layton !list_empty(&ctx->flc_lease))) { 221e24dadabSJeff Layton pr_warn("Leaked locks on dev=0x%x:0x%x ino=0x%lx:\n", 222e24dadabSJeff Layton MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev), 223e24dadabSJeff Layton inode->i_ino); 224e24dadabSJeff Layton locks_dump_ctx_list(&ctx->flc_flock, "FLOCK"); 225e24dadabSJeff Layton locks_dump_ctx_list(&ctx->flc_posix, "POSIX"); 226e24dadabSJeff Layton locks_dump_ctx_list(&ctx->flc_lease, "LEASE"); 227e24dadabSJeff Layton } 228e24dadabSJeff Layton } 229e24dadabSJeff Layton 2303953704fSBenjamin Coddington static void 231fde49518SJeff Layton locks_check_ctx_file_list(struct file *filp, struct list_head *list, char *list_type) 2323953704fSBenjamin Coddington { 233fde49518SJeff Layton struct file_lock_core *flc; 234c65454a9SJeff Layton struct inode *inode = file_inode(filp); 2353953704fSBenjamin Coddington 236fde49518SJeff Layton list_for_each_entry(flc, list, flc_list) 237fde49518SJeff Layton if (flc->flc_file == filp) 2383953704fSBenjamin Coddington pr_warn("Leaked %s lock on dev=0x%x:0x%x ino=0x%lx " 2393953704fSBenjamin Coddington " fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n", 2403953704fSBenjamin Coddington list_type, MAJOR(inode->i_sb->s_dev), 2413953704fSBenjamin Coddington MINOR(inode->i_sb->s_dev), inode->i_ino, 242fde49518SJeff Layton flc->flc_owner, flc->flc_flags, 243fde49518SJeff Layton flc->flc_type, flc->flc_pid); 2443953704fSBenjamin Coddington } 2453953704fSBenjamin Coddington 2464a075e39SJeff Layton void 247f27a0fe0SJeff Layton locks_free_lock_context(struct inode *inode) 2484a075e39SJeff Layton { 249401a8b8fSJeff Layton struct file_lock_context *ctx = locks_inode_context(inode); 250f27a0fe0SJeff Layton 251e24dadabSJeff Layton if (unlikely(ctx)) { 252e24dadabSJeff Layton locks_check_ctx_lists(inode); 2534a075e39SJeff Layton kmem_cache_free(flctx_cache, ctx); 2544a075e39SJeff Layton } 2554a075e39SJeff Layton } 2564a075e39SJeff Layton 2574ca52f53SJeff Layton static void locks_init_lock_heads(struct file_lock_core *flc) 258a51cb91dSMiklos Szeredi { 2594ca52f53SJeff Layton INIT_HLIST_NODE(&flc->flc_link); 2604ca52f53SJeff Layton INIT_LIST_HEAD(&flc->flc_list); 2614ca52f53SJeff Layton INIT_LIST_HEAD(&flc->flc_blocked_requests); 2624ca52f53SJeff Layton INIT_LIST_HEAD(&flc->flc_blocked_member); 2634ca52f53SJeff Layton init_waitqueue_head(&flc->flc_wait); 264a51cb91dSMiklos Szeredi } 265a51cb91dSMiklos Szeredi 2661da177e4SLinus Torvalds /* Allocate an empty lock structure. */ 267c5b1f0d9SArnd Bergmann struct file_lock *locks_alloc_lock(void) 2681da177e4SLinus Torvalds { 269ee19cc40SMiklos Szeredi struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL); 270a51cb91dSMiklos Szeredi 271a51cb91dSMiklos Szeredi if (fl) 2724ca52f53SJeff Layton locks_init_lock_heads(&fl->c); 273a51cb91dSMiklos Szeredi 274a51cb91dSMiklos Szeredi return fl; 2751da177e4SLinus Torvalds } 276c5b1f0d9SArnd Bergmann EXPORT_SYMBOL_GPL(locks_alloc_lock); 2771da177e4SLinus Torvalds 278a9e61e25SFelix Blyakher void locks_release_private(struct file_lock *fl) 27947831f35STrond Myklebust { 280fde49518SJeff Layton struct file_lock_core *flc = &fl->c; 281fde49518SJeff Layton 282fde49518SJeff Layton BUG_ON(waitqueue_active(&flc->flc_wait)); 283fde49518SJeff Layton BUG_ON(!list_empty(&flc->flc_list)); 284fde49518SJeff Layton BUG_ON(!list_empty(&flc->flc_blocked_requests)); 285fde49518SJeff Layton BUG_ON(!list_empty(&flc->flc_blocked_member)); 286fde49518SJeff Layton BUG_ON(!hlist_unhashed(&flc->flc_link)); 2875926459eSNeilBrown 28847831f35STrond Myklebust if (fl->fl_ops) { 28947831f35STrond Myklebust if (fl->fl_ops->fl_release_private) 29047831f35STrond Myklebust fl->fl_ops->fl_release_private(fl); 29147831f35STrond Myklebust fl->fl_ops = NULL; 29247831f35STrond Myklebust } 29347831f35STrond Myklebust 2945c97d7b1SKinglong Mee if (fl->fl_lmops) { 295cae80b30SJeff Layton if (fl->fl_lmops->lm_put_owner) { 296fde49518SJeff Layton fl->fl_lmops->lm_put_owner(flc->flc_owner); 297fde49518SJeff Layton flc->flc_owner = NULL; 298cae80b30SJeff Layton } 2995c97d7b1SKinglong Mee fl->fl_lmops = NULL; 3005c97d7b1SKinglong Mee } 30147831f35STrond Myklebust } 302a9e61e25SFelix Blyakher EXPORT_SYMBOL_GPL(locks_release_private); 30347831f35STrond Myklebust 304591502c5SDai Ngo /** 305591502c5SDai Ngo * locks_owner_has_blockers - Check for blocking lock requests 306591502c5SDai Ngo * @flctx: file lock context 307591502c5SDai Ngo * @owner: lock owner 308591502c5SDai Ngo * 309591502c5SDai Ngo * Return values: 310591502c5SDai Ngo * %true: @owner has at least one blocker 311591502c5SDai Ngo * %false: @owner has no blockers 312591502c5SDai Ngo */ 313fde49518SJeff Layton bool locks_owner_has_blockers(struct file_lock_context *flctx, fl_owner_t owner) 314591502c5SDai Ngo { 315fde49518SJeff Layton struct file_lock_core *flc; 316591502c5SDai Ngo 317591502c5SDai Ngo spin_lock(&flctx->flc_lock); 318fde49518SJeff Layton list_for_each_entry(flc, &flctx->flc_posix, flc_list) { 319fde49518SJeff Layton if (flc->flc_owner != owner) 320591502c5SDai Ngo continue; 321fde49518SJeff Layton if (!list_empty(&flc->flc_blocked_requests)) { 322591502c5SDai Ngo spin_unlock(&flctx->flc_lock); 323591502c5SDai Ngo return true; 324591502c5SDai Ngo } 325591502c5SDai Ngo } 326591502c5SDai Ngo spin_unlock(&flctx->flc_lock); 327591502c5SDai Ngo return false; 328591502c5SDai Ngo } 329591502c5SDai Ngo EXPORT_SYMBOL_GPL(locks_owner_has_blockers); 330591502c5SDai Ngo 3311da177e4SLinus Torvalds /* Free a lock which is not in use. */ 33205fa3135SJ. Bruce Fields void locks_free_lock(struct file_lock *fl) 3331da177e4SLinus Torvalds { 33447831f35STrond Myklebust locks_release_private(fl); 3351da177e4SLinus Torvalds kmem_cache_free(filelock_cache, fl); 3361da177e4SLinus Torvalds } 33705fa3135SJ. Bruce Fields EXPORT_SYMBOL(locks_free_lock); 3381da177e4SLinus Torvalds 339ed9814d8SJeff Layton static void 340ed9814d8SJeff Layton locks_dispose_list(struct list_head *dispose) 341ed9814d8SJeff Layton { 342ed9814d8SJeff Layton struct file_lock *fl; 343ed9814d8SJeff Layton 344ed9814d8SJeff Layton while (!list_empty(dispose)) { 3454ca52f53SJeff Layton fl = list_first_entry(dispose, struct file_lock, c.flc_list); 3464ca52f53SJeff Layton list_del_init(&fl->c.flc_list); 347ed9814d8SJeff Layton locks_free_lock(fl); 348ed9814d8SJeff Layton } 349ed9814d8SJeff Layton } 350ed9814d8SJeff Layton 3511da177e4SLinus Torvalds void locks_init_lock(struct file_lock *fl) 3521da177e4SLinus Torvalds { 353ee19cc40SMiklos Szeredi memset(fl, 0, sizeof(struct file_lock)); 3544ca52f53SJeff Layton locks_init_lock_heads(&fl->c); 3551da177e4SLinus Torvalds } 3561da177e4SLinus Torvalds EXPORT_SYMBOL(locks_init_lock); 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds /* 3591da177e4SLinus Torvalds * Initialize a new lock from an existing file_lock structure. 3601da177e4SLinus Torvalds */ 3613fe0fff1SKinglong Mee void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) 3621da177e4SLinus Torvalds { 3634ca52f53SJeff Layton new->c.flc_owner = fl->c.flc_owner; 3644ca52f53SJeff Layton new->c.flc_pid = fl->c.flc_pid; 3654ca52f53SJeff Layton new->c.flc_file = NULL; 3664ca52f53SJeff Layton new->c.flc_flags = fl->c.flc_flags; 3674ca52f53SJeff Layton new->c.flc_type = fl->c.flc_type; 3681da177e4SLinus Torvalds new->fl_start = fl->fl_start; 3691da177e4SLinus Torvalds new->fl_end = fl->fl_end; 370f328296eSKinglong Mee new->fl_lmops = fl->fl_lmops; 3710996905fSTrond Myklebust new->fl_ops = NULL; 372f328296eSKinglong Mee 373f328296eSKinglong Mee if (fl->fl_lmops) { 374f328296eSKinglong Mee if (fl->fl_lmops->lm_get_owner) 3754ca52f53SJeff Layton fl->fl_lmops->lm_get_owner(fl->c.flc_owner); 376f328296eSKinglong Mee } 3770996905fSTrond Myklebust } 3783fe0fff1SKinglong Mee EXPORT_SYMBOL(locks_copy_conflock); 3790996905fSTrond Myklebust 3800996905fSTrond Myklebust void locks_copy_lock(struct file_lock *new, struct file_lock *fl) 3810996905fSTrond Myklebust { 382566709bdSJeff Layton /* "new" must be a freshly-initialized lock */ 383566709bdSJeff Layton WARN_ON_ONCE(new->fl_ops); 3840996905fSTrond Myklebust 3853fe0fff1SKinglong Mee locks_copy_conflock(new, fl); 386f328296eSKinglong Mee 3874ca52f53SJeff Layton new->c.flc_file = fl->c.flc_file; 3881da177e4SLinus Torvalds new->fl_ops = fl->fl_ops; 38947831f35STrond Myklebust 390f328296eSKinglong Mee if (fl->fl_ops) { 391f328296eSKinglong Mee if (fl->fl_ops->fl_copy_lock) 392f328296eSKinglong Mee fl->fl_ops->fl_copy_lock(new, fl); 393f328296eSKinglong Mee } 3941da177e4SLinus Torvalds } 3951da177e4SLinus Torvalds EXPORT_SYMBOL(locks_copy_lock); 3961da177e4SLinus Torvalds 3975946c431SNeilBrown static void locks_move_blocks(struct file_lock *new, struct file_lock *fl) 3985946c431SNeilBrown { 3995946c431SNeilBrown struct file_lock *f; 4005946c431SNeilBrown 4015946c431SNeilBrown /* 4025946c431SNeilBrown * As ctx->flc_lock is held, new requests cannot be added to 403*b6aaba5bSJeff Layton * ->flc_blocked_requests, so we don't need a lock to check if it 4045946c431SNeilBrown * is empty. 4055946c431SNeilBrown */ 4064ca52f53SJeff Layton if (list_empty(&fl->c.flc_blocked_requests)) 4075946c431SNeilBrown return; 4085946c431SNeilBrown spin_lock(&blocked_lock_lock); 4094ca52f53SJeff Layton list_splice_init(&fl->c.flc_blocked_requests, 4104ca52f53SJeff Layton &new->c.flc_blocked_requests); 4114ca52f53SJeff Layton list_for_each_entry(f, &new->c.flc_blocked_requests, 4124ca52f53SJeff Layton c.flc_blocked_member) 413*b6aaba5bSJeff Layton f->c.flc_blocker = &new->c; 4145946c431SNeilBrown spin_unlock(&blocked_lock_lock); 4155946c431SNeilBrown } 4165946c431SNeilBrown 4171da177e4SLinus Torvalds static inline int flock_translate_cmd(int cmd) { 4181da177e4SLinus Torvalds switch (cmd) { 4191da177e4SLinus Torvalds case LOCK_SH: 4201da177e4SLinus Torvalds return F_RDLCK; 4211da177e4SLinus Torvalds case LOCK_EX: 4221da177e4SLinus Torvalds return F_WRLCK; 4231da177e4SLinus Torvalds case LOCK_UN: 4241da177e4SLinus Torvalds return F_UNLCK; 4251da177e4SLinus Torvalds } 4261da177e4SLinus Torvalds return -EINVAL; 4271da177e4SLinus Torvalds } 4281da177e4SLinus Torvalds 4291da177e4SLinus Torvalds /* Fill in a file_lock structure with an appropriate FLOCK lock. */ 4304149be7bSKuniyuki Iwashima static void flock_make_lock(struct file *filp, struct file_lock *fl, int type) 4311da177e4SLinus Torvalds { 432d6367d62SNeilBrown locks_init_lock(fl); 4331da177e4SLinus Torvalds 4344ca52f53SJeff Layton fl->c.flc_file = filp; 4354ca52f53SJeff Layton fl->c.flc_owner = filp; 4364ca52f53SJeff Layton fl->c.flc_pid = current->tgid; 4374ca52f53SJeff Layton fl->c.flc_flags = FL_FLOCK; 4384ca52f53SJeff Layton fl->c.flc_type = type; 4391da177e4SLinus Torvalds fl->fl_end = OFFSET_MAX; 4401da177e4SLinus Torvalds } 4411da177e4SLinus Torvalds 442ed5f17f6SLuca Vizzarro static int assign_type(struct file_lock *fl, int type) 4431da177e4SLinus Torvalds { 4441da177e4SLinus Torvalds switch (type) { 4451da177e4SLinus Torvalds case F_RDLCK: 4461da177e4SLinus Torvalds case F_WRLCK: 4471da177e4SLinus Torvalds case F_UNLCK: 4484ca52f53SJeff Layton fl->c.flc_type = type; 4491da177e4SLinus Torvalds break; 4501da177e4SLinus Torvalds default: 4511da177e4SLinus Torvalds return -EINVAL; 4521da177e4SLinus Torvalds } 4531da177e4SLinus Torvalds return 0; 4541da177e4SLinus Torvalds } 4551da177e4SLinus Torvalds 456ef12e72aSJ. Bruce Fields static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, 457ef12e72aSJ. Bruce Fields struct flock64 *l) 458ef12e72aSJ. Bruce Fields { 459ef12e72aSJ. Bruce Fields switch (l->l_whence) { 460ef12e72aSJ. Bruce Fields case SEEK_SET: 461ef12e72aSJ. Bruce Fields fl->fl_start = 0; 462ef12e72aSJ. Bruce Fields break; 463ef12e72aSJ. Bruce Fields case SEEK_CUR: 464ef12e72aSJ. Bruce Fields fl->fl_start = filp->f_pos; 465ef12e72aSJ. Bruce Fields break; 466ef12e72aSJ. Bruce Fields case SEEK_END: 467ef12e72aSJ. Bruce Fields fl->fl_start = i_size_read(file_inode(filp)); 468ef12e72aSJ. Bruce Fields break; 469ef12e72aSJ. Bruce Fields default: 470ef12e72aSJ. Bruce Fields return -EINVAL; 471ef12e72aSJ. Bruce Fields } 472ef12e72aSJ. Bruce Fields if (l->l_start > OFFSET_MAX - fl->fl_start) 473ef12e72aSJ. Bruce Fields return -EOVERFLOW; 474ef12e72aSJ. Bruce Fields fl->fl_start += l->l_start; 475ef12e72aSJ. Bruce Fields if (fl->fl_start < 0) 476ef12e72aSJ. Bruce Fields return -EINVAL; 477ef12e72aSJ. Bruce Fields 478ef12e72aSJ. Bruce Fields /* POSIX-1996 leaves the case l->l_len < 0 undefined; 479ef12e72aSJ. Bruce Fields POSIX-2001 defines it. */ 480ef12e72aSJ. Bruce Fields if (l->l_len > 0) { 481ef12e72aSJ. Bruce Fields if (l->l_len - 1 > OFFSET_MAX - fl->fl_start) 482ef12e72aSJ. Bruce Fields return -EOVERFLOW; 48316238415SLuo Meng fl->fl_end = fl->fl_start + (l->l_len - 1); 484ef12e72aSJ. Bruce Fields 485ef12e72aSJ. Bruce Fields } else if (l->l_len < 0) { 486ef12e72aSJ. Bruce Fields if (fl->fl_start + l->l_len < 0) 487ef12e72aSJ. Bruce Fields return -EINVAL; 488ef12e72aSJ. Bruce Fields fl->fl_end = fl->fl_start - 1; 489ef12e72aSJ. Bruce Fields fl->fl_start += l->l_len; 490ef12e72aSJ. Bruce Fields } else 491ef12e72aSJ. Bruce Fields fl->fl_end = OFFSET_MAX; 492ef12e72aSJ. Bruce Fields 4934ca52f53SJeff Layton fl->c.flc_owner = current->files; 4944ca52f53SJeff Layton fl->c.flc_pid = current->tgid; 4954ca52f53SJeff Layton fl->c.flc_file = filp; 4964ca52f53SJeff Layton fl->c.flc_flags = FL_POSIX; 497ef12e72aSJ. Bruce Fields fl->fl_ops = NULL; 498ef12e72aSJ. Bruce Fields fl->fl_lmops = NULL; 499ef12e72aSJ. Bruce Fields 500ef12e72aSJ. Bruce Fields return assign_type(fl, l->l_type); 501ef12e72aSJ. Bruce Fields } 502ef12e72aSJ. Bruce Fields 5031da177e4SLinus Torvalds /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX 5041da177e4SLinus Torvalds * style lock. 5051da177e4SLinus Torvalds */ 5061da177e4SLinus Torvalds static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, 5071da177e4SLinus Torvalds struct flock *l) 5081da177e4SLinus Torvalds { 509ef12e72aSJ. Bruce Fields struct flock64 ll = { 510ef12e72aSJ. Bruce Fields .l_type = l->l_type, 511ef12e72aSJ. Bruce Fields .l_whence = l->l_whence, 512ef12e72aSJ. Bruce Fields .l_start = l->l_start, 513ef12e72aSJ. Bruce Fields .l_len = l->l_len, 514ef12e72aSJ. Bruce Fields }; 5151da177e4SLinus Torvalds 516ef12e72aSJ. Bruce Fields return flock64_to_posix_lock(filp, fl, &ll); 5171da177e4SLinus Torvalds } 5181da177e4SLinus Torvalds 5191da177e4SLinus Torvalds /* default lease lock manager operations */ 5204d01b7f5SJeff Layton static bool 5214d01b7f5SJeff Layton lease_break_callback(struct file_lock *fl) 5221da177e4SLinus Torvalds { 5231da177e4SLinus Torvalds kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG); 5244d01b7f5SJeff Layton return false; 5251da177e4SLinus Torvalds } 5261da177e4SLinus Torvalds 5271c7dd2ffSJeff Layton static void 5281c7dd2ffSJeff Layton lease_setup(struct file_lock *fl, void **priv) 5291c7dd2ffSJeff Layton { 5304ca52f53SJeff Layton struct file *filp = fl->c.flc_file; 5311c7dd2ffSJeff Layton struct fasync_struct *fa = *priv; 5321c7dd2ffSJeff Layton 5331c7dd2ffSJeff Layton /* 5341c7dd2ffSJeff Layton * fasync_insert_entry() returns the old entry if any. If there was no 5351c7dd2ffSJeff Layton * old entry, then it used "priv" and inserted it into the fasync list. 5361c7dd2ffSJeff Layton * Clear the pointer to indicate that it shouldn't be freed. 5371c7dd2ffSJeff Layton */ 5381c7dd2ffSJeff Layton if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa)) 5391c7dd2ffSJeff Layton *priv = NULL; 5401c7dd2ffSJeff Layton 54101919134SEric W. Biederman __f_setown(filp, task_pid(current), PIDTYPE_TGID, 0); 5421c7dd2ffSJeff Layton } 5431c7dd2ffSJeff Layton 5447b021967SAlexey Dobriyan static const struct lock_manager_operations lease_manager_ops = { 5458fb47a4fSJ. Bruce Fields .lm_break = lease_break_callback, 5468fb47a4fSJ. Bruce Fields .lm_change = lease_modify, 5471c7dd2ffSJeff Layton .lm_setup = lease_setup, 5481da177e4SLinus Torvalds }; 5491da177e4SLinus Torvalds 5501da177e4SLinus Torvalds /* 5511da177e4SLinus Torvalds * Initialize a lease, use the default lock manager operations 5521da177e4SLinus Torvalds */ 553ed5f17f6SLuca Vizzarro static int lease_init(struct file *filp, int type, struct file_lock *fl) 5541da177e4SLinus Torvalds { 55575dff55aSTrond Myklebust if (assign_type(fl, type) != 0) 55675dff55aSTrond Myklebust return -EINVAL; 55775dff55aSTrond Myklebust 5584ca52f53SJeff Layton fl->c.flc_owner = filp; 5594ca52f53SJeff Layton fl->c.flc_pid = current->tgid; 5601da177e4SLinus Torvalds 5614ca52f53SJeff Layton fl->c.flc_file = filp; 5624ca52f53SJeff Layton fl->c.flc_flags = FL_LEASE; 5631da177e4SLinus Torvalds fl->fl_start = 0; 5641da177e4SLinus Torvalds fl->fl_end = OFFSET_MAX; 5651da177e4SLinus Torvalds fl->fl_ops = NULL; 5661da177e4SLinus Torvalds fl->fl_lmops = &lease_manager_ops; 5671da177e4SLinus Torvalds return 0; 5681da177e4SLinus Torvalds } 5691da177e4SLinus Torvalds 5701da177e4SLinus Torvalds /* Allocate a file_lock initialised to this type of lease */ 571ed5f17f6SLuca Vizzarro static struct file_lock *lease_alloc(struct file *filp, int type) 5721da177e4SLinus Torvalds { 5731da177e4SLinus Torvalds struct file_lock *fl = locks_alloc_lock(); 57475dff55aSTrond Myklebust int error = -ENOMEM; 5751da177e4SLinus Torvalds 5761da177e4SLinus Torvalds if (fl == NULL) 577e32b8ee2SJ. Bruce Fields return ERR_PTR(error); 5781da177e4SLinus Torvalds 5791da177e4SLinus Torvalds error = lease_init(filp, type, fl); 58075dff55aSTrond Myklebust if (error) { 58175dff55aSTrond Myklebust locks_free_lock(fl); 582e32b8ee2SJ. Bruce Fields return ERR_PTR(error); 58375dff55aSTrond Myklebust } 584e32b8ee2SJ. Bruce Fields return fl; 5851da177e4SLinus Torvalds } 5861da177e4SLinus Torvalds 5871da177e4SLinus Torvalds /* Check if two locks overlap each other. 5881da177e4SLinus Torvalds */ 5891da177e4SLinus Torvalds static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2) 5901da177e4SLinus Torvalds { 5911da177e4SLinus Torvalds return ((fl1->fl_end >= fl2->fl_start) && 5921da177e4SLinus Torvalds (fl2->fl_end >= fl1->fl_start)); 5931da177e4SLinus Torvalds } 5941da177e4SLinus Torvalds 5951da177e4SLinus Torvalds /* 5961da177e4SLinus Torvalds * Check whether two locks have the same owner. 5971da177e4SLinus Torvalds */ 5989bb430a8SJeff Layton static int posix_same_owner(struct file_lock_core *fl1, struct file_lock_core *fl2) 5991da177e4SLinus Torvalds { 6009bb430a8SJeff Layton return fl1->flc_owner == fl2->flc_owner; 6011da177e4SLinus Torvalds } 6021da177e4SLinus Torvalds 6036109c850SJeff Layton /* Must be called with the flc_lock held! */ 6044629172fSJeff Layton static void locks_insert_global_locks(struct file_lock_core *flc) 60588974691SJeff Layton { 6067c3f654dSPeter Zijlstra struct file_lock_list_struct *fll = this_cpu_ptr(&file_lock_list); 6077c3f654dSPeter Zijlstra 608aba37660SPeter Zijlstra percpu_rwsem_assert_held(&file_rwsem); 609aba37660SPeter Zijlstra 6107c3f654dSPeter Zijlstra spin_lock(&fll->lock); 6114629172fSJeff Layton flc->flc_link_cpu = smp_processor_id(); 6124629172fSJeff Layton hlist_add_head(&flc->flc_link, &fll->hlist); 6137c3f654dSPeter Zijlstra spin_unlock(&fll->lock); 61488974691SJeff Layton } 61588974691SJeff Layton 6166109c850SJeff Layton /* Must be called with the flc_lock held! */ 6174629172fSJeff Layton static void locks_delete_global_locks(struct file_lock_core *flc) 61888974691SJeff Layton { 6197c3f654dSPeter Zijlstra struct file_lock_list_struct *fll; 6207c3f654dSPeter Zijlstra 621aba37660SPeter Zijlstra percpu_rwsem_assert_held(&file_rwsem); 622aba37660SPeter Zijlstra 6237012b02aSJeff Layton /* 6247012b02aSJeff Layton * Avoid taking lock if already unhashed. This is safe since this check 6256109c850SJeff Layton * is done while holding the flc_lock, and new insertions into the list 6267012b02aSJeff Layton * also require that it be held. 6277012b02aSJeff Layton */ 6284629172fSJeff Layton if (hlist_unhashed(&flc->flc_link)) 6297012b02aSJeff Layton return; 6307c3f654dSPeter Zijlstra 6314629172fSJeff Layton fll = per_cpu_ptr(&file_lock_list, flc->flc_link_cpu); 6327c3f654dSPeter Zijlstra spin_lock(&fll->lock); 6334629172fSJeff Layton hlist_del_init(&flc->flc_link); 6347c3f654dSPeter Zijlstra spin_unlock(&fll->lock); 63588974691SJeff Layton } 63688974691SJeff Layton 6373999e493SJeff Layton static unsigned long 638ad399740SJeff Layton posix_owner_key(struct file_lock_core *flc) 6393999e493SJeff Layton { 640ad399740SJeff Layton return (unsigned long) flc->flc_owner; 6413999e493SJeff Layton } 6423999e493SJeff Layton 6431a6c75d4SJeff Layton static void locks_insert_global_blocked(struct file_lock_core *waiter) 64488974691SJeff Layton { 645663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 646663d5af7SDaniel Wagner 6471a6c75d4SJeff Layton hash_add(blocked_hash, &waiter->flc_link, posix_owner_key(waiter)); 64888974691SJeff Layton } 64988974691SJeff Layton 6501a6c75d4SJeff Layton static void locks_delete_global_blocked(struct file_lock_core *waiter) 65188974691SJeff Layton { 652663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 653663d5af7SDaniel Wagner 6541a6c75d4SJeff Layton hash_del(&waiter->flc_link); 65588974691SJeff Layton } 65688974691SJeff Layton 6571da177e4SLinus Torvalds /* Remove waiter from blocker's block list. 6581da177e4SLinus Torvalds * When blocker ends up pointing to itself then the list is empty. 6591c8c601aSJeff Layton * 6607b2296afSJeff Layton * Must be called with blocked_lock_lock held. 6611da177e4SLinus Torvalds */ 6621a62c22aSJeff Layton static void __locks_delete_block(struct file_lock_core *waiter) 6631da177e4SLinus Torvalds { 6641a62c22aSJeff Layton locks_delete_global_blocked(waiter); 6651a62c22aSJeff Layton list_del_init(&waiter->flc_blocked_member); 6661da177e4SLinus Torvalds } 6671da177e4SLinus Torvalds 6681a62c22aSJeff Layton static void __locks_wake_up_blocks(struct file_lock_core *blocker) 669ad6bbd8bSNeilBrown { 6701a62c22aSJeff Layton while (!list_empty(&blocker->flc_blocked_requests)) { 6711a62c22aSJeff Layton struct file_lock_core *waiter; 6721a62c22aSJeff Layton struct file_lock *fl; 673ad6bbd8bSNeilBrown 6741a62c22aSJeff Layton waiter = list_first_entry(&blocker->flc_blocked_requests, 6751a62c22aSJeff Layton struct file_lock_core, flc_blocked_member); 6761a62c22aSJeff Layton 6771a62c22aSJeff Layton fl = file_lock(waiter); 678ad6bbd8bSNeilBrown __locks_delete_block(waiter); 6791a62c22aSJeff Layton if ((waiter->flc_flags & (FL_POSIX | FL_FLOCK)) && 6801a62c22aSJeff Layton fl->fl_lmops && fl->fl_lmops->lm_notify) 6811a62c22aSJeff Layton fl->fl_lmops->lm_notify(fl); 682ad6bbd8bSNeilBrown else 6831a62c22aSJeff Layton locks_wake_up(fl); 684dcf23ac3SLinus Torvalds 685dcf23ac3SLinus Torvalds /* 6861a62c22aSJeff Layton * The setting of flc_blocker to NULL marks the "done" 687dcf23ac3SLinus Torvalds * point in deleting a block. Paired with acquire at the top 688dcf23ac3SLinus Torvalds * of locks_delete_block(). 689dcf23ac3SLinus Torvalds */ 6901a62c22aSJeff Layton smp_store_release(&waiter->flc_blocker, NULL); 691ad6bbd8bSNeilBrown } 692ad6bbd8bSNeilBrown } 693ad6bbd8bSNeilBrown 694cb03f94fSNeilBrown /** 695529adfe8SMauro Carvalho Chehab * locks_delete_block - stop waiting for a file lock 696cb03f94fSNeilBrown * @waiter: the lock which was waiting 697cb03f94fSNeilBrown * 698cb03f94fSNeilBrown * lockd/nfsd need to disconnect the lock while working on it. 699cb03f94fSNeilBrown */ 700cb03f94fSNeilBrown int locks_delete_block(struct file_lock *waiter) 7011da177e4SLinus Torvalds { 702cb03f94fSNeilBrown int status = -ENOENT; 703cb03f94fSNeilBrown 704dcf23ac3SLinus Torvalds /* 705dcf23ac3SLinus Torvalds * If fl_blocker is NULL, it won't be set again as this thread "owns" 706dcf23ac3SLinus Torvalds * the lock and is the only one that might try to claim the lock. 707dcf23ac3SLinus Torvalds * 708dcf23ac3SLinus Torvalds * We use acquire/release to manage fl_blocker so that we can 709dcf23ac3SLinus Torvalds * optimize away taking the blocked_lock_lock in many cases. 710dcf23ac3SLinus Torvalds * 711dcf23ac3SLinus Torvalds * The smp_load_acquire guarantees two things: 712dcf23ac3SLinus Torvalds * 713dcf23ac3SLinus Torvalds * 1/ that fl_blocked_requests can be tested locklessly. If something 714dcf23ac3SLinus Torvalds * was recently added to that list it must have been in a locked region 715dcf23ac3SLinus Torvalds * *before* the locked region when fl_blocker was set to NULL. 716dcf23ac3SLinus Torvalds * 717dcf23ac3SLinus Torvalds * 2/ that no other thread is accessing 'waiter', so it is safe to free 718dcf23ac3SLinus Torvalds * it. __locks_wake_up_blocks is careful not to touch waiter after 719dcf23ac3SLinus Torvalds * fl_blocker is released. 720dcf23ac3SLinus Torvalds * 721dcf23ac3SLinus Torvalds * If a lockless check of fl_blocker shows it to be NULL, we know that 722dcf23ac3SLinus Torvalds * no new locks can be inserted into its fl_blocked_requests list, and 723dcf23ac3SLinus Torvalds * can avoid doing anything further if the list is empty. 724dcf23ac3SLinus Torvalds */ 7254ca52f53SJeff Layton if (!smp_load_acquire(&waiter->c.flc_blocker) && 7264ca52f53SJeff Layton list_empty(&waiter->c.flc_blocked_requests)) 727dcf23ac3SLinus Torvalds return status; 728dcf23ac3SLinus Torvalds 7297b2296afSJeff Layton spin_lock(&blocked_lock_lock); 7304ca52f53SJeff Layton if (waiter->c.flc_blocker) 731cb03f94fSNeilBrown status = 0; 7321a62c22aSJeff Layton __locks_wake_up_blocks(&waiter->c); 7331a62c22aSJeff Layton __locks_delete_block(&waiter->c); 734dcf23ac3SLinus Torvalds 735dcf23ac3SLinus Torvalds /* 736dcf23ac3SLinus Torvalds * The setting of fl_blocker to NULL marks the "done" point in deleting 737dcf23ac3SLinus Torvalds * a block. Paired with acquire at the top of this function. 738dcf23ac3SLinus Torvalds */ 7394ca52f53SJeff Layton smp_store_release(&waiter->c.flc_blocker, NULL); 7407b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 741cb03f94fSNeilBrown return status; 7421da177e4SLinus Torvalds } 743cb03f94fSNeilBrown EXPORT_SYMBOL(locks_delete_block); 7441da177e4SLinus Torvalds 7451da177e4SLinus Torvalds /* Insert waiter into blocker's block list. 7461da177e4SLinus Torvalds * We use a circular list so that processes can be easily woken up in 7471da177e4SLinus Torvalds * the order they blocked. The documentation doesn't require this but 7481da177e4SLinus Torvalds * it seems like the reasonable thing to do. 7491c8c601aSJeff Layton * 7506109c850SJeff Layton * Must be called with both the flc_lock and blocked_lock_lock held. The 751ada5c1daSNeilBrown * fl_blocked_requests list itself is protected by the blocked_lock_lock, 752ada5c1daSNeilBrown * but by ensuring that the flc_lock is also held on insertions we can avoid 753ada5c1daSNeilBrown * taking the blocked_lock_lock in some cases when we see that the 754ada5c1daSNeilBrown * fl_blocked_requests list is empty. 755fd7732e0SNeilBrown * 756fd7732e0SNeilBrown * Rather than just adding to the list, we check for conflicts with any existing 757fd7732e0SNeilBrown * waiters, and add beneath any waiter that blocks the new waiter. 758fd7732e0SNeilBrown * Thus wakeups don't happen until needed. 7591da177e4SLinus Torvalds */ 760b6be3714SJeff Layton static void __locks_insert_block(struct file_lock *blocker_fl, 761b6be3714SJeff Layton struct file_lock *waiter_fl, 762b6be3714SJeff Layton bool conflict(struct file_lock_core *, 763b6be3714SJeff Layton struct file_lock_core *)) 7641da177e4SLinus Torvalds { 765b6be3714SJeff Layton struct file_lock_core *blocker = &blocker_fl->c; 766b6be3714SJeff Layton struct file_lock_core *waiter = &waiter_fl->c; 767b6be3714SJeff Layton struct file_lock_core *flc; 768fd7732e0SNeilBrown 769b6be3714SJeff Layton BUG_ON(!list_empty(&waiter->flc_blocked_member)); 770fd7732e0SNeilBrown new_blocker: 771b6be3714SJeff Layton list_for_each_entry(flc, &blocker->flc_blocked_requests, flc_blocked_member) 772b6be3714SJeff Layton if (conflict(flc, waiter)) { 773b6be3714SJeff Layton blocker = flc; 774fd7732e0SNeilBrown goto new_blocker; 775fd7732e0SNeilBrown } 776*b6aaba5bSJeff Layton waiter->flc_blocker = blocker; 777b6be3714SJeff Layton list_add_tail(&waiter->flc_blocked_member, 778b6be3714SJeff Layton &blocker->flc_blocked_requests); 7795946c431SNeilBrown 780b6be3714SJeff Layton if ((blocker->flc_flags & (FL_POSIX|FL_OFDLCK)) == (FL_POSIX|FL_OFDLCK)) 781b6be3714SJeff Layton locks_insert_global_blocked(waiter); 782b6be3714SJeff Layton 783b6be3714SJeff Layton /* The requests in waiter->flc_blocked are known to conflict with 7845946c431SNeilBrown * waiter, but might not conflict with blocker, or the requests 7855946c431SNeilBrown * and lock which block it. So they all need to be woken. 7865946c431SNeilBrown */ 787b6be3714SJeff Layton __locks_wake_up_blocks(waiter); 7881c8c601aSJeff Layton } 7891c8c601aSJeff Layton 7906109c850SJeff Layton /* Must be called with flc_lock held. */ 7911c8c601aSJeff Layton static void locks_insert_block(struct file_lock *blocker, 792fd7732e0SNeilBrown struct file_lock *waiter, 793b6be3714SJeff Layton bool conflict(struct file_lock_core *, 794b6be3714SJeff Layton struct file_lock_core *)) 7951c8c601aSJeff Layton { 7967b2296afSJeff Layton spin_lock(&blocked_lock_lock); 797fd7732e0SNeilBrown __locks_insert_block(blocker, waiter, conflict); 7987b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 7991da177e4SLinus Torvalds } 8001da177e4SLinus Torvalds 8011cb36012SJeff Layton /* 8021cb36012SJeff Layton * Wake up processes blocked waiting for blocker. 8031cb36012SJeff Layton * 8046109c850SJeff Layton * Must be called with the inode->flc_lock held! 8051da177e4SLinus Torvalds */ 8061da177e4SLinus Torvalds static void locks_wake_up_blocks(struct file_lock *blocker) 8071da177e4SLinus Torvalds { 8084e8c765dSJeff Layton /* 8094e8c765dSJeff Layton * Avoid taking global lock if list is empty. This is safe since new 8106109c850SJeff Layton * blocked requests are only added to the list under the flc_lock, and 811ada5c1daSNeilBrown * the flc_lock is always held here. Note that removal from the 812ada5c1daSNeilBrown * fl_blocked_requests list does not require the flc_lock, so we must 813ada5c1daSNeilBrown * recheck list_empty() after acquiring the blocked_lock_lock. 8144e8c765dSJeff Layton */ 8154ca52f53SJeff Layton if (list_empty(&blocker->c.flc_blocked_requests)) 8164e8c765dSJeff Layton return; 8174e8c765dSJeff Layton 8187b2296afSJeff Layton spin_lock(&blocked_lock_lock); 8191a62c22aSJeff Layton __locks_wake_up_blocks(&blocker->c); 8207b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 8211da177e4SLinus Torvalds } 8221da177e4SLinus Torvalds 8235263e31eSJeff Layton static void 824e084c1bdSJeff Layton locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) 8255263e31eSJeff Layton { 8264ca52f53SJeff Layton list_add_tail(&fl->c.flc_list, before); 8274629172fSJeff Layton locks_insert_global_locks(&fl->c); 8285263e31eSJeff Layton } 8295263e31eSJeff Layton 8308634b51fSJeff Layton static void 831e084c1bdSJeff Layton locks_unlink_lock_ctx(struct file_lock *fl) 8321da177e4SLinus Torvalds { 8334629172fSJeff Layton locks_delete_global_locks(&fl->c); 8344ca52f53SJeff Layton list_del_init(&fl->c.flc_list); 8351da177e4SLinus Torvalds locks_wake_up_blocks(fl); 83624cbe784SJeff Layton } 83724cbe784SJeff Layton 8385263e31eSJeff Layton static void 839e084c1bdSJeff Layton locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) 8405263e31eSJeff Layton { 841e084c1bdSJeff Layton locks_unlink_lock_ctx(fl); 8428634b51fSJeff Layton if (dispose) 8434ca52f53SJeff Layton list_add(&fl->c.flc_list, dispose); 8448634b51fSJeff Layton else 8458634b51fSJeff Layton locks_free_lock(fl); 8465263e31eSJeff Layton } 8475263e31eSJeff Layton 8481da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. Common functionality 8491da177e4SLinus Torvalds * checks for shared/exclusive status of overlapping locks. 8501da177e4SLinus Torvalds */ 851b6be3714SJeff Layton static bool locks_conflict(struct file_lock_core *caller_flc, 852b6be3714SJeff Layton struct file_lock_core *sys_flc) 8531da177e4SLinus Torvalds { 854b6be3714SJeff Layton if (sys_flc->flc_type == F_WRLCK) 855c0e15908SNeilBrown return true; 856b6be3714SJeff Layton if (caller_flc->flc_type == F_WRLCK) 857c0e15908SNeilBrown return true; 858c0e15908SNeilBrown return false; 8591da177e4SLinus Torvalds } 8601da177e4SLinus Torvalds 8611da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. POSIX specific 8621da177e4SLinus Torvalds * checking before calling the locks_conflict(). 8631da177e4SLinus Torvalds */ 864b6be3714SJeff Layton static bool posix_locks_conflict(struct file_lock_core *caller_flc, 865b6be3714SJeff Layton struct file_lock_core *sys_flc) 8661da177e4SLinus Torvalds { 867b6be3714SJeff Layton struct file_lock *caller_fl = file_lock(caller_flc); 868b6be3714SJeff Layton struct file_lock *sys_fl = file_lock(sys_flc); 869b6be3714SJeff Layton 8701da177e4SLinus Torvalds /* POSIX locks owned by the same process do not conflict with 8711da177e4SLinus Torvalds * each other. 8721da177e4SLinus Torvalds */ 873b6be3714SJeff Layton if (posix_same_owner(caller_flc, sys_flc)) 874c0e15908SNeilBrown return false; 8751da177e4SLinus Torvalds 8761da177e4SLinus Torvalds /* Check whether they overlap */ 8771da177e4SLinus Torvalds if (!locks_overlap(caller_fl, sys_fl)) 878c0e15908SNeilBrown return false; 8791da177e4SLinus Torvalds 880b6be3714SJeff Layton return locks_conflict(caller_flc, sys_flc); 8811da177e4SLinus Torvalds } 8821da177e4SLinus Torvalds 8836c9007f6SStas Sergeev /* Determine if lock sys_fl blocks lock caller_fl. Used on xx_GETLK 8846c9007f6SStas Sergeev * path so checks for additional GETLK-specific things like F_UNLCK. 8856c9007f6SStas Sergeev */ 8866c9007f6SStas Sergeev static bool posix_test_locks_conflict(struct file_lock *caller_fl, 8876c9007f6SStas Sergeev struct file_lock *sys_fl) 8886c9007f6SStas Sergeev { 889b6be3714SJeff Layton struct file_lock_core *caller = &caller_fl->c; 890b6be3714SJeff Layton struct file_lock_core *sys = &sys_fl->c; 891b6be3714SJeff Layton 8926c9007f6SStas Sergeev /* F_UNLCK checks any locks on the same fd. */ 89375cabec0SJeff Layton if (lock_is_unlock(caller_fl)) { 894b6be3714SJeff Layton if (!posix_same_owner(caller, sys)) 8956c9007f6SStas Sergeev return false; 8966c9007f6SStas Sergeev return locks_overlap(caller_fl, sys_fl); 8976c9007f6SStas Sergeev } 898b6be3714SJeff Layton return posix_locks_conflict(caller, sys); 8996c9007f6SStas Sergeev } 9006c9007f6SStas Sergeev 9011da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific 9021da177e4SLinus Torvalds * checking before calling the locks_conflict(). 9031da177e4SLinus Torvalds */ 904b6be3714SJeff Layton static bool flock_locks_conflict(struct file_lock_core *caller_flc, 905b6be3714SJeff Layton struct file_lock_core *sys_flc) 9061da177e4SLinus Torvalds { 9071da177e4SLinus Torvalds /* FLOCK locks referring to the same filp do not conflict with 9081da177e4SLinus Torvalds * each other. 9091da177e4SLinus Torvalds */ 910b6be3714SJeff Layton if (caller_flc->flc_file == sys_flc->flc_file) 911c0e15908SNeilBrown return false; 9121da177e4SLinus Torvalds 913b6be3714SJeff Layton return locks_conflict(caller_flc, sys_flc); 9141da177e4SLinus Torvalds } 9151da177e4SLinus Torvalds 9166d34ac19SJ. Bruce Fields void 9179d6a8c5cSMarc Eshel posix_test_lock(struct file *filp, struct file_lock *fl) 9181da177e4SLinus Torvalds { 9191da177e4SLinus Torvalds struct file_lock *cfl; 920bd61e0a9SJeff Layton struct file_lock_context *ctx; 921c65454a9SJeff Layton struct inode *inode = file_inode(filp); 9222443da22SDai Ngo void *owner; 9232443da22SDai Ngo void (*func)(void); 9241da177e4SLinus Torvalds 925401a8b8fSJeff Layton ctx = locks_inode_context(inode); 926bd61e0a9SJeff Layton if (!ctx || list_empty_careful(&ctx->flc_posix)) { 9274ca52f53SJeff Layton fl->c.flc_type = F_UNLCK; 928bd61e0a9SJeff Layton return; 9291da177e4SLinus Torvalds } 930bd61e0a9SJeff Layton 9312443da22SDai Ngo retry: 9326109c850SJeff Layton spin_lock(&ctx->flc_lock); 9334ca52f53SJeff Layton list_for_each_entry(cfl, &ctx->flc_posix, c.flc_list) { 9346c9007f6SStas Sergeev if (!posix_test_locks_conflict(fl, cfl)) 9352443da22SDai Ngo continue; 9362443da22SDai Ngo if (cfl->fl_lmops && cfl->fl_lmops->lm_lock_expirable 9372443da22SDai Ngo && (*cfl->fl_lmops->lm_lock_expirable)(cfl)) { 9382443da22SDai Ngo owner = cfl->fl_lmops->lm_mod_owner; 9392443da22SDai Ngo func = cfl->fl_lmops->lm_expire_lock; 9402443da22SDai Ngo __module_get(owner); 9412443da22SDai Ngo spin_unlock(&ctx->flc_lock); 9422443da22SDai Ngo (*func)(); 9432443da22SDai Ngo module_put(owner); 9442443da22SDai Ngo goto retry; 9452443da22SDai Ngo } 9463fe0fff1SKinglong Mee locks_copy_conflock(fl, cfl); 947bd61e0a9SJeff Layton goto out; 948bd61e0a9SJeff Layton } 9494ca52f53SJeff Layton fl->c.flc_type = F_UNLCK; 950bd61e0a9SJeff Layton out: 9516109c850SJeff Layton spin_unlock(&ctx->flc_lock); 9526d34ac19SJ. Bruce Fields return; 9531da177e4SLinus Torvalds } 9541da177e4SLinus Torvalds EXPORT_SYMBOL(posix_test_lock); 9551da177e4SLinus Torvalds 956b533184fSJ. Bruce Fields /* 957b533184fSJ. Bruce Fields * Deadlock detection: 9581da177e4SLinus Torvalds * 959b533184fSJ. Bruce Fields * We attempt to detect deadlocks that are due purely to posix file 960b533184fSJ. Bruce Fields * locks. 9611da177e4SLinus Torvalds * 962b533184fSJ. Bruce Fields * We assume that a task can be waiting for at most one lock at a time. 963b533184fSJ. Bruce Fields * So for any acquired lock, the process holding that lock may be 964b533184fSJ. Bruce Fields * waiting on at most one other lock. That lock in turns may be held by 965b533184fSJ. Bruce Fields * someone waiting for at most one other lock. Given a requested lock 966b533184fSJ. Bruce Fields * caller_fl which is about to wait for a conflicting lock block_fl, we 967b533184fSJ. Bruce Fields * follow this chain of waiters to ensure we are not about to create a 968b533184fSJ. Bruce Fields * cycle. 96997855b49SJ. Bruce Fields * 970b533184fSJ. Bruce Fields * Since we do this before we ever put a process to sleep on a lock, we 971b533184fSJ. Bruce Fields * are ensured that there is never a cycle; that is what guarantees that 972b533184fSJ. Bruce Fields * the while() loop in posix_locks_deadlock() eventually completes. 973b533184fSJ. Bruce Fields * 974b533184fSJ. Bruce Fields * Note: the above assumption may not be true when handling lock 975b533184fSJ. Bruce Fields * requests from a broken NFS client. It may also fail in the presence 976b533184fSJ. Bruce Fields * of tasks (such as posix threads) sharing the same open file table. 977b533184fSJ. Bruce Fields * To handle those cases, we just bail out after a few iterations. 97857b65325SJeff Layton * 979cff2fce5SJeff Layton * For FL_OFDLCK locks, the owner is the filp, not the files_struct. 98057b65325SJeff Layton * Because the owner is not even nominally tied to a thread of 98157b65325SJeff Layton * execution, the deadlock detection below can't reasonably work well. Just 98257b65325SJeff Layton * skip it for those. 98357b65325SJeff Layton * 984cff2fce5SJeff Layton * In principle, we could do a more limited deadlock detection on FL_OFDLCK 98557b65325SJeff Layton * locks that just checks for the case where two tasks are attempting to 98657b65325SJeff Layton * upgrade from read to write locks on the same inode. 9871da177e4SLinus Torvalds */ 98897855b49SJ. Bruce Fields 98997855b49SJ. Bruce Fields #define MAX_DEADLK_ITERATIONS 10 99097855b49SJ. Bruce Fields 991b6be3714SJeff Layton /* Find a lock that the owner of the given @blocker is blocking on. */ 992b6be3714SJeff Layton static struct file_lock_core *what_owner_is_waiting_for(struct file_lock_core *blocker) 993b533184fSJ. Bruce Fields { 994b6be3714SJeff Layton struct file_lock_core *flc; 995b533184fSJ. Bruce Fields 996b6be3714SJeff Layton hash_for_each_possible(blocked_hash, flc, flc_link, posix_owner_key(blocker)) { 997b6be3714SJeff Layton if (posix_same_owner(flc, blocker)) { 998b6be3714SJeff Layton while (flc->flc_blocker) 999*b6aaba5bSJeff Layton flc = flc->flc_blocker; 1000b6be3714SJeff Layton return flc; 10015946c431SNeilBrown } 1002b533184fSJ. Bruce Fields } 1003b533184fSJ. Bruce Fields return NULL; 1004b533184fSJ. Bruce Fields } 1005b533184fSJ. Bruce Fields 10067b2296afSJeff Layton /* Must be called with the blocked_lock_lock held! */ 1007b6be3714SJeff Layton static bool posix_locks_deadlock(struct file_lock *caller_fl, 10081da177e4SLinus Torvalds struct file_lock *block_fl) 10091da177e4SLinus Torvalds { 1010b6be3714SJeff Layton struct file_lock_core *caller = &caller_fl->c; 1011b6be3714SJeff Layton struct file_lock_core *blocker = &block_fl->c; 101297855b49SJ. Bruce Fields int i = 0; 10131da177e4SLinus Torvalds 1014663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 1015663d5af7SDaniel Wagner 101657b65325SJeff Layton /* 101757b65325SJeff Layton * This deadlock detector can't reasonably detect deadlocks with 1018cff2fce5SJeff Layton * FL_OFDLCK locks, since they aren't owned by a process, per-se. 101957b65325SJeff Layton */ 1020b6be3714SJeff Layton if (caller->flc_flags & FL_OFDLCK) 1021b6be3714SJeff Layton return false; 102257b65325SJeff Layton 1023b6be3714SJeff Layton while ((blocker = what_owner_is_waiting_for(blocker))) { 102497855b49SJ. Bruce Fields if (i++ > MAX_DEADLK_ITERATIONS) 1025b6be3714SJeff Layton return false; 1026b6be3714SJeff Layton if (posix_same_owner(caller, blocker)) 1027b6be3714SJeff Layton return true; 10281da177e4SLinus Torvalds } 1029b6be3714SJeff Layton return false; 10301da177e4SLinus Torvalds } 10311da177e4SLinus Torvalds 10321da177e4SLinus Torvalds /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 103302888f41SJ. Bruce Fields * after any leases, but before any posix locks. 1034f475ae95STrond Myklebust * 1035f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 1036f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 1037f475ae95STrond Myklebust * value for -ENOENT. 10381da177e4SLinus Torvalds */ 1039bcd7f78dSJeff Layton static int flock_lock_inode(struct inode *inode, struct file_lock *request) 10401da177e4SLinus Torvalds { 1041993dfa87STrond Myklebust struct file_lock *new_fl = NULL; 10425263e31eSJeff Layton struct file_lock *fl; 10435263e31eSJeff Layton struct file_lock_context *ctx; 10441da177e4SLinus Torvalds int error = 0; 10455263e31eSJeff Layton bool found = false; 1046ed9814d8SJeff Layton LIST_HEAD(dispose); 10471da177e4SLinus Torvalds 10484ca52f53SJeff Layton ctx = locks_get_lock_context(inode, request->c.flc_type); 10495c1c669aSJeff Layton if (!ctx) { 10504ca52f53SJeff Layton if (request->c.flc_type != F_UNLCK) 10515263e31eSJeff Layton return -ENOMEM; 10524ca52f53SJeff Layton return (request->c.flc_flags & FL_EXISTS) ? -ENOENT : 0; 10535c1c669aSJeff Layton } 10545263e31eSJeff Layton 10554ca52f53SJeff Layton if (!(request->c.flc_flags & FL_ACCESS) && (request->c.flc_type != F_UNLCK)) { 1056b89f4321SArnd Bergmann new_fl = locks_alloc_lock(); 1057b89f4321SArnd Bergmann if (!new_fl) 1058b89f4321SArnd Bergmann return -ENOMEM; 1059b89f4321SArnd Bergmann } 1060b89f4321SArnd Bergmann 106102e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 10626109c850SJeff Layton spin_lock(&ctx->flc_lock); 10634ca52f53SJeff Layton if (request->c.flc_flags & FL_ACCESS) 1064f07f18ddSTrond Myklebust goto find_conflict; 106584d535adSPavel Emelyanov 10664ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_flock, c.flc_list) { 10674ca52f53SJeff Layton if (request->c.flc_file != fl->c.flc_file) 10681da177e4SLinus Torvalds continue; 10694ca52f53SJeff Layton if (request->c.flc_type == fl->c.flc_type) 10701da177e4SLinus Torvalds goto out; 10715263e31eSJeff Layton found = true; 1072e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 10731da177e4SLinus Torvalds break; 10741da177e4SLinus Torvalds } 10751da177e4SLinus Torvalds 107675cabec0SJeff Layton if (lock_is_unlock(request)) { 10774ca52f53SJeff Layton if ((request->c.flc_flags & FL_EXISTS) && !found) 1078f475ae95STrond Myklebust error = -ENOENT; 1079993dfa87STrond Myklebust goto out; 1080f475ae95STrond Myklebust } 10811da177e4SLinus Torvalds 1082f07f18ddSTrond Myklebust find_conflict: 10834ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_flock, c.flc_list) { 1084b6be3714SJeff Layton if (!flock_locks_conflict(&request->c, &fl->c)) 10851da177e4SLinus Torvalds continue; 10861da177e4SLinus Torvalds error = -EAGAIN; 10874ca52f53SJeff Layton if (!(request->c.flc_flags & FL_SLEEP)) 1088bde74e4bSMiklos Szeredi goto out; 1089bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 1090fd7732e0SNeilBrown locks_insert_block(fl, request, flock_locks_conflict); 10911da177e4SLinus Torvalds goto out; 10921da177e4SLinus Torvalds } 10934ca52f53SJeff Layton if (request->c.flc_flags & FL_ACCESS) 1094f07f18ddSTrond Myklebust goto out; 1095993dfa87STrond Myklebust locks_copy_lock(new_fl, request); 10965946c431SNeilBrown locks_move_blocks(new_fl, request); 1097e084c1bdSJeff Layton locks_insert_lock_ctx(new_fl, &ctx->flc_flock); 1098993dfa87STrond Myklebust new_fl = NULL; 10999cedc194SKirill Korotaev error = 0; 11001da177e4SLinus Torvalds 11011da177e4SLinus Torvalds out: 11026109c850SJeff Layton spin_unlock(&ctx->flc_lock); 110302e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1104993dfa87STrond Myklebust if (new_fl) 1105993dfa87STrond Myklebust locks_free_lock(new_fl); 1106ed9814d8SJeff Layton locks_dispose_list(&dispose); 1107c883da31SJeff Layton trace_flock_lock_inode(inode, request, error); 11081da177e4SLinus Torvalds return error; 11091da177e4SLinus Torvalds } 11101da177e4SLinus Torvalds 1111b4d629a3SJeff Layton static int posix_lock_inode(struct inode *inode, struct file_lock *request, 1112b4d629a3SJeff Layton struct file_lock *conflock) 11131da177e4SLinus Torvalds { 1114bd61e0a9SJeff Layton struct file_lock *fl, *tmp; 111539005d02SMiklos Szeredi struct file_lock *new_fl = NULL; 111639005d02SMiklos Szeredi struct file_lock *new_fl2 = NULL; 11171da177e4SLinus Torvalds struct file_lock *left = NULL; 11181da177e4SLinus Torvalds struct file_lock *right = NULL; 1119bd61e0a9SJeff Layton struct file_lock_context *ctx; 1120b9746ef8SJeff Layton int error; 1121b9746ef8SJeff Layton bool added = false; 1122ed9814d8SJeff Layton LIST_HEAD(dispose); 11232443da22SDai Ngo void *owner; 11242443da22SDai Ngo void (*func)(void); 11251da177e4SLinus Torvalds 11264ca52f53SJeff Layton ctx = locks_get_lock_context(inode, request->c.flc_type); 1127bd61e0a9SJeff Layton if (!ctx) 112875cabec0SJeff Layton return lock_is_unlock(request) ? 0 : -ENOMEM; 1129bd61e0a9SJeff Layton 11301da177e4SLinus Torvalds /* 11311da177e4SLinus Torvalds * We may need two file_lock structures for this operation, 11321da177e4SLinus Torvalds * so we get them in advance to avoid races. 113339005d02SMiklos Szeredi * 113439005d02SMiklos Szeredi * In some cases we can be sure, that no new locks will be needed 11351da177e4SLinus Torvalds */ 11364ca52f53SJeff Layton if (!(request->c.flc_flags & FL_ACCESS) && 11374ca52f53SJeff Layton (request->c.flc_type != F_UNLCK || 113839005d02SMiklos Szeredi request->fl_start != 0 || request->fl_end != OFFSET_MAX)) { 11391da177e4SLinus Torvalds new_fl = locks_alloc_lock(); 11401da177e4SLinus Torvalds new_fl2 = locks_alloc_lock(); 114139005d02SMiklos Szeredi } 11421da177e4SLinus Torvalds 11432443da22SDai Ngo retry: 114402e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 11456109c850SJeff Layton spin_lock(&ctx->flc_lock); 11461cb36012SJeff Layton /* 11471cb36012SJeff Layton * New lock request. Walk all POSIX locks and look for conflicts. If 11481cb36012SJeff Layton * there are any, either return error or put the request on the 114948f74186SJeff Layton * blocker's list of waiters and the global blocked_hash. 11501cb36012SJeff Layton */ 11514ca52f53SJeff Layton if (request->c.flc_type != F_UNLCK) { 11524ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, c.flc_list) { 1153b6be3714SJeff Layton if (!posix_locks_conflict(&request->c, &fl->c)) 11541da177e4SLinus Torvalds continue; 11552443da22SDai Ngo if (fl->fl_lmops && fl->fl_lmops->lm_lock_expirable 11562443da22SDai Ngo && (*fl->fl_lmops->lm_lock_expirable)(fl)) { 11572443da22SDai Ngo owner = fl->fl_lmops->lm_mod_owner; 11582443da22SDai Ngo func = fl->fl_lmops->lm_expire_lock; 11592443da22SDai Ngo __module_get(owner); 11602443da22SDai Ngo spin_unlock(&ctx->flc_lock); 11612443da22SDai Ngo percpu_up_read(&file_rwsem); 11622443da22SDai Ngo (*func)(); 11632443da22SDai Ngo module_put(owner); 11642443da22SDai Ngo goto retry; 11652443da22SDai Ngo } 11665842add2SAndy Adamson if (conflock) 11673fe0fff1SKinglong Mee locks_copy_conflock(conflock, fl); 11681da177e4SLinus Torvalds error = -EAGAIN; 11694ca52f53SJeff Layton if (!(request->c.flc_flags & FL_SLEEP)) 11701da177e4SLinus Torvalds goto out; 11711c8c601aSJeff Layton /* 11721c8c601aSJeff Layton * Deadlock detection and insertion into the blocked 11731c8c601aSJeff Layton * locks list must be done while holding the same lock! 11741c8c601aSJeff Layton */ 11751da177e4SLinus Torvalds error = -EDEADLK; 11767b2296afSJeff Layton spin_lock(&blocked_lock_lock); 1177945ab8f6SJeff Layton /* 1178945ab8f6SJeff Layton * Ensure that we don't find any locks blocked on this 1179945ab8f6SJeff Layton * request during deadlock detection. 1180945ab8f6SJeff Layton */ 11811a62c22aSJeff Layton __locks_wake_up_blocks(&request->c); 11821c8c601aSJeff Layton if (likely(!posix_locks_deadlock(request, fl))) { 1183bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 1184fd7732e0SNeilBrown __locks_insert_block(fl, request, 1185fd7732e0SNeilBrown posix_locks_conflict); 11861c8c601aSJeff Layton } 11877b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 11881da177e4SLinus Torvalds goto out; 11891da177e4SLinus Torvalds } 11901da177e4SLinus Torvalds } 11911da177e4SLinus Torvalds 11921da177e4SLinus Torvalds /* If we're just looking for a conflict, we're done. */ 11931da177e4SLinus Torvalds error = 0; 11944ca52f53SJeff Layton if (request->c.flc_flags & FL_ACCESS) 11951da177e4SLinus Torvalds goto out; 11961da177e4SLinus Torvalds 1197bd61e0a9SJeff Layton /* Find the first old lock with the same owner as the new lock */ 11984ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, c.flc_list) { 11999bb430a8SJeff Layton if (posix_same_owner(&request->c, &fl->c)) 1200bd61e0a9SJeff Layton break; 12011da177e4SLinus Torvalds } 12021da177e4SLinus Torvalds 12031da177e4SLinus Torvalds /* Process locks with this owner. */ 12044ca52f53SJeff Layton list_for_each_entry_safe_from(fl, tmp, &ctx->flc_posix, c.flc_list) { 12059bb430a8SJeff Layton if (!posix_same_owner(&request->c, &fl->c)) 1206bd61e0a9SJeff Layton break; 1207bd61e0a9SJeff Layton 1208bd61e0a9SJeff Layton /* Detect adjacent or overlapping regions (if same lock type) */ 12094ca52f53SJeff Layton if (request->c.flc_type == fl->c.flc_type) { 1210449231d6SOlaf Kirch /* In all comparisons of start vs end, use 1211449231d6SOlaf Kirch * "start - 1" rather than "end + 1". If end 1212449231d6SOlaf Kirch * is OFFSET_MAX, end + 1 will become negative. 1213449231d6SOlaf Kirch */ 12141da177e4SLinus Torvalds if (fl->fl_end < request->fl_start - 1) 1215bd61e0a9SJeff Layton continue; 12161da177e4SLinus Torvalds /* If the next lock in the list has entirely bigger 12171da177e4SLinus Torvalds * addresses than the new one, insert the lock here. 12181da177e4SLinus Torvalds */ 1219449231d6SOlaf Kirch if (fl->fl_start - 1 > request->fl_end) 12201da177e4SLinus Torvalds break; 12211da177e4SLinus Torvalds 12221da177e4SLinus Torvalds /* If we come here, the new and old lock are of the 12231da177e4SLinus Torvalds * same type and adjacent or overlapping. Make one 12241da177e4SLinus Torvalds * lock yielding from the lower start address of both 12251da177e4SLinus Torvalds * locks to the higher end address. 12261da177e4SLinus Torvalds */ 12271da177e4SLinus Torvalds if (fl->fl_start > request->fl_start) 12281da177e4SLinus Torvalds fl->fl_start = request->fl_start; 12291da177e4SLinus Torvalds else 12301da177e4SLinus Torvalds request->fl_start = fl->fl_start; 12311da177e4SLinus Torvalds if (fl->fl_end < request->fl_end) 12321da177e4SLinus Torvalds fl->fl_end = request->fl_end; 12331da177e4SLinus Torvalds else 12341da177e4SLinus Torvalds request->fl_end = fl->fl_end; 12351da177e4SLinus Torvalds if (added) { 1236e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 12371da177e4SLinus Torvalds continue; 12381da177e4SLinus Torvalds } 12391da177e4SLinus Torvalds request = fl; 1240b9746ef8SJeff Layton added = true; 1241bd61e0a9SJeff Layton } else { 12421da177e4SLinus Torvalds /* Processing for different lock types is a bit 12431da177e4SLinus Torvalds * more complex. 12441da177e4SLinus Torvalds */ 12451da177e4SLinus Torvalds if (fl->fl_end < request->fl_start) 1246bd61e0a9SJeff Layton continue; 12471da177e4SLinus Torvalds if (fl->fl_start > request->fl_end) 12481da177e4SLinus Torvalds break; 124975cabec0SJeff Layton if (lock_is_unlock(request)) 1250b9746ef8SJeff Layton added = true; 12511da177e4SLinus Torvalds if (fl->fl_start < request->fl_start) 12521da177e4SLinus Torvalds left = fl; 12531da177e4SLinus Torvalds /* If the next lock in the list has a higher end 12541da177e4SLinus Torvalds * address than the new one, insert the new one here. 12551da177e4SLinus Torvalds */ 12561da177e4SLinus Torvalds if (fl->fl_end > request->fl_end) { 12571da177e4SLinus Torvalds right = fl; 12581da177e4SLinus Torvalds break; 12591da177e4SLinus Torvalds } 12601da177e4SLinus Torvalds if (fl->fl_start >= request->fl_start) { 12611da177e4SLinus Torvalds /* The new lock completely replaces an old 12621da177e4SLinus Torvalds * one (This may happen several times). 12631da177e4SLinus Torvalds */ 12641da177e4SLinus Torvalds if (added) { 1265e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 12661da177e4SLinus Torvalds continue; 12671da177e4SLinus Torvalds } 1268b84d49f9SJeff Layton /* 1269b84d49f9SJeff Layton * Replace the old lock with new_fl, and 1270b84d49f9SJeff Layton * remove the old one. It's safe to do the 1271b84d49f9SJeff Layton * insert here since we know that we won't be 1272b84d49f9SJeff Layton * using new_fl later, and that the lock is 1273b84d49f9SJeff Layton * just replacing an existing lock. 12741da177e4SLinus Torvalds */ 1275b84d49f9SJeff Layton error = -ENOLCK; 1276b84d49f9SJeff Layton if (!new_fl) 1277b84d49f9SJeff Layton goto out; 1278b84d49f9SJeff Layton locks_copy_lock(new_fl, request); 12795ef15968Syangerkun locks_move_blocks(new_fl, request); 1280b84d49f9SJeff Layton request = new_fl; 1281b84d49f9SJeff Layton new_fl = NULL; 12824ca52f53SJeff Layton locks_insert_lock_ctx(request, 12834ca52f53SJeff Layton &fl->c.flc_list); 1284e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 1285b9746ef8SJeff Layton added = true; 12861da177e4SLinus Torvalds } 12871da177e4SLinus Torvalds } 12881da177e4SLinus Torvalds } 12891da177e4SLinus Torvalds 12900d9a490aSMiklos Szeredi /* 12911cb36012SJeff Layton * The above code only modifies existing locks in case of merging or 12921cb36012SJeff Layton * replacing. If new lock(s) need to be inserted all modifications are 12931cb36012SJeff Layton * done below this, so it's safe yet to bail out. 12940d9a490aSMiklos Szeredi */ 12950d9a490aSMiklos Szeredi error = -ENOLCK; /* "no luck" */ 12960d9a490aSMiklos Szeredi if (right && left == right && !new_fl2) 12970d9a490aSMiklos Szeredi goto out; 12980d9a490aSMiklos Szeredi 12991da177e4SLinus Torvalds error = 0; 13001da177e4SLinus Torvalds if (!added) { 130175cabec0SJeff Layton if (lock_is_unlock(request)) { 13024ca52f53SJeff Layton if (request->c.flc_flags & FL_EXISTS) 1303f475ae95STrond Myklebust error = -ENOENT; 13041da177e4SLinus Torvalds goto out; 1305f475ae95STrond Myklebust } 13060d9a490aSMiklos Szeredi 13070d9a490aSMiklos Szeredi if (!new_fl) { 13080d9a490aSMiklos Szeredi error = -ENOLCK; 13090d9a490aSMiklos Szeredi goto out; 13100d9a490aSMiklos Szeredi } 13111da177e4SLinus Torvalds locks_copy_lock(new_fl, request); 13125946c431SNeilBrown locks_move_blocks(new_fl, request); 13134ca52f53SJeff Layton locks_insert_lock_ctx(new_fl, &fl->c.flc_list); 13142e2f756fSJeff Layton fl = new_fl; 13151da177e4SLinus Torvalds new_fl = NULL; 13161da177e4SLinus Torvalds } 13171da177e4SLinus Torvalds if (right) { 13181da177e4SLinus Torvalds if (left == right) { 13191da177e4SLinus Torvalds /* The new lock breaks the old one in two pieces, 13201da177e4SLinus Torvalds * so we have to use the second new lock. 13211da177e4SLinus Torvalds */ 13221da177e4SLinus Torvalds left = new_fl2; 13231da177e4SLinus Torvalds new_fl2 = NULL; 13241da177e4SLinus Torvalds locks_copy_lock(left, right); 13254ca52f53SJeff Layton locks_insert_lock_ctx(left, &fl->c.flc_list); 13261da177e4SLinus Torvalds } 13271da177e4SLinus Torvalds right->fl_start = request->fl_end + 1; 13281da177e4SLinus Torvalds locks_wake_up_blocks(right); 13291da177e4SLinus Torvalds } 13301da177e4SLinus Torvalds if (left) { 13311da177e4SLinus Torvalds left->fl_end = request->fl_start - 1; 13321da177e4SLinus Torvalds locks_wake_up_blocks(left); 13331da177e4SLinus Torvalds } 13341da177e4SLinus Torvalds out: 13356109c850SJeff Layton spin_unlock(&ctx->flc_lock); 133602e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 133774f6f591SWill Shiu trace_posix_lock_inode(inode, request, error); 13381da177e4SLinus Torvalds /* 13391da177e4SLinus Torvalds * Free any unused locks. 13401da177e4SLinus Torvalds */ 13411da177e4SLinus Torvalds if (new_fl) 13421da177e4SLinus Torvalds locks_free_lock(new_fl); 13431da177e4SLinus Torvalds if (new_fl2) 13441da177e4SLinus Torvalds locks_free_lock(new_fl2); 1345ed9814d8SJeff Layton locks_dispose_list(&dispose); 13461890910fSJeff Layton 13471da177e4SLinus Torvalds return error; 13481da177e4SLinus Torvalds } 13491da177e4SLinus Torvalds 13501da177e4SLinus Torvalds /** 13511da177e4SLinus Torvalds * posix_lock_file - Apply a POSIX-style lock to a file 13521da177e4SLinus Torvalds * @filp: The file to apply the lock to 13531da177e4SLinus Torvalds * @fl: The lock to be applied 1354150b3934SMarc Eshel * @conflock: Place to return a copy of the conflicting lock, if found. 13551da177e4SLinus Torvalds * 13561da177e4SLinus Torvalds * Add a POSIX style lock to a file. 13571da177e4SLinus Torvalds * We merge adjacent & overlapping locks whenever possible. 13581da177e4SLinus Torvalds * POSIX locks are sorted by owner task, then by starting address 1359f475ae95STrond Myklebust * 1360f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 1361f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 1362f475ae95STrond Myklebust * value for -ENOENT. 13631da177e4SLinus Torvalds */ 1364150b3934SMarc Eshel int posix_lock_file(struct file *filp, struct file_lock *fl, 13655842add2SAndy Adamson struct file_lock *conflock) 13665842add2SAndy Adamson { 1367c65454a9SJeff Layton return posix_lock_inode(file_inode(filp), fl, conflock); 13685842add2SAndy Adamson } 1369150b3934SMarc Eshel EXPORT_SYMBOL(posix_lock_file); 13701da177e4SLinus Torvalds 13711da177e4SLinus Torvalds /** 137229d01b22SJeff Layton * posix_lock_inode_wait - Apply a POSIX-style lock to a file 137329d01b22SJeff Layton * @inode: inode of file to which lock request should be applied 13741da177e4SLinus Torvalds * @fl: The lock to be applied 13751da177e4SLinus Torvalds * 1376616fb38fSBenjamin Coddington * Apply a POSIX style lock request to an inode. 13771da177e4SLinus Torvalds */ 1378616fb38fSBenjamin Coddington static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) 13791da177e4SLinus Torvalds { 13801da177e4SLinus Torvalds int error; 13811da177e4SLinus Torvalds might_sleep (); 13821da177e4SLinus Torvalds for (;;) { 1383b4d629a3SJeff Layton error = posix_lock_inode(inode, fl, NULL); 1384bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 13851da177e4SLinus Torvalds break; 13864ca52f53SJeff Layton error = wait_event_interruptible(fl->c.flc_wait, 13874ca52f53SJeff Layton list_empty(&fl->c.flc_blocked_member)); 138816306a61SNeilBrown if (error) 13891da177e4SLinus Torvalds break; 13901da177e4SLinus Torvalds } 139116306a61SNeilBrown locks_delete_block(fl); 13921da177e4SLinus Torvalds return error; 13931da177e4SLinus Torvalds } 139429d01b22SJeff Layton 1395778fc546SJ. Bruce Fields static void lease_clear_pending(struct file_lock *fl, int arg) 1396778fc546SJ. Bruce Fields { 1397778fc546SJ. Bruce Fields switch (arg) { 1398778fc546SJ. Bruce Fields case F_UNLCK: 13994ca52f53SJeff Layton fl->c.flc_flags &= ~FL_UNLOCK_PENDING; 1400df561f66SGustavo A. R. Silva fallthrough; 1401778fc546SJ. Bruce Fields case F_RDLCK: 14024ca52f53SJeff Layton fl->c.flc_flags &= ~FL_DOWNGRADE_PENDING; 1403778fc546SJ. Bruce Fields } 1404778fc546SJ. Bruce Fields } 1405778fc546SJ. Bruce Fields 14061da177e4SLinus Torvalds /* We already had a lease on this file; just change its type */ 14077448cc37SJeff Layton int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) 14081da177e4SLinus Torvalds { 14091da177e4SLinus Torvalds int error = assign_type(fl, arg); 14101da177e4SLinus Torvalds 14111da177e4SLinus Torvalds if (error) 14121da177e4SLinus Torvalds return error; 1413778fc546SJ. Bruce Fields lease_clear_pending(fl, arg); 14141da177e4SLinus Torvalds locks_wake_up_blocks(fl); 14153b6e2723SFilipe Brandenburger if (arg == F_UNLCK) { 14164ca52f53SJeff Layton struct file *filp = fl->c.flc_file; 14173b6e2723SFilipe Brandenburger 14183b6e2723SFilipe Brandenburger f_delown(filp); 14193b6e2723SFilipe Brandenburger filp->f_owner.signum = 0; 14204ca52f53SJeff Layton fasync_helper(0, fl->c.flc_file, 0, &fl->fl_fasync); 142196d6d59cSJ. Bruce Fields if (fl->fl_fasync != NULL) { 142296d6d59cSJ. Bruce Fields printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); 142396d6d59cSJ. Bruce Fields fl->fl_fasync = NULL; 142496d6d59cSJ. Bruce Fields } 1425e084c1bdSJeff Layton locks_delete_lock_ctx(fl, dispose); 14263b6e2723SFilipe Brandenburger } 14271da177e4SLinus Torvalds return 0; 14281da177e4SLinus Torvalds } 14291da177e4SLinus Torvalds EXPORT_SYMBOL(lease_modify); 14301da177e4SLinus Torvalds 1431778fc546SJ. Bruce Fields static bool past_time(unsigned long then) 1432778fc546SJ. Bruce Fields { 1433778fc546SJ. Bruce Fields if (!then) 1434778fc546SJ. Bruce Fields /* 0 is a special value meaning "this never expires": */ 1435778fc546SJ. Bruce Fields return false; 1436778fc546SJ. Bruce Fields return time_after(jiffies, then); 1437778fc546SJ. Bruce Fields } 1438778fc546SJ. Bruce Fields 1439c45198edSJeff Layton static void time_out_leases(struct inode *inode, struct list_head *dispose) 14401da177e4SLinus Torvalds { 14418634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 14428634b51fSJeff Layton struct file_lock *fl, *tmp; 14431da177e4SLinus Torvalds 14446109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 1445f82b4b67SJeff Layton 14464ca52f53SJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { 144762af4f1fSJeff Layton trace_time_out_leases(inode, fl); 1448778fc546SJ. Bruce Fields if (past_time(fl->fl_downgrade_time)) 14497448cc37SJeff Layton lease_modify(fl, F_RDLCK, dispose); 1450778fc546SJ. Bruce Fields if (past_time(fl->fl_break_time)) 14517448cc37SJeff Layton lease_modify(fl, F_UNLCK, dispose); 14521da177e4SLinus Torvalds } 14531da177e4SLinus Torvalds } 14541da177e4SLinus Torvalds 1455b6be3714SJeff Layton static bool leases_conflict(struct file_lock_core *lc, struct file_lock_core *bc) 1456df4e8d2cSJ. Bruce Fields { 1457d51f527fSIra Weiny bool rc; 1458b6be3714SJeff Layton struct file_lock *lease = file_lock(lc); 1459b6be3714SJeff Layton struct file_lock *breaker = file_lock(bc); 1460d51f527fSIra Weiny 146128df3d15SJ. Bruce Fields if (lease->fl_lmops->lm_breaker_owns_lease 146228df3d15SJ. Bruce Fields && lease->fl_lmops->lm_breaker_owns_lease(lease)) 146328df3d15SJ. Bruce Fields return false; 1464b6be3714SJeff Layton if ((bc->flc_flags & FL_LAYOUT) != (lc->flc_flags & FL_LAYOUT)) { 1465d51f527fSIra Weiny rc = false; 1466d51f527fSIra Weiny goto trace; 1467d51f527fSIra Weiny } 1468b6be3714SJeff Layton if ((bc->flc_flags & FL_DELEG) && (lc->flc_flags & FL_LEASE)) { 1469d51f527fSIra Weiny rc = false; 1470d51f527fSIra Weiny goto trace; 1471d51f527fSIra Weiny } 1472d51f527fSIra Weiny 1473b6be3714SJeff Layton rc = locks_conflict(bc, lc); 1474d51f527fSIra Weiny trace: 1475d51f527fSIra Weiny trace_leases_conflict(rc, lease, breaker); 1476d51f527fSIra Weiny return rc; 1477df4e8d2cSJ. Bruce Fields } 1478df4e8d2cSJ. Bruce Fields 147903d12ddfSJeff Layton static bool 148003d12ddfSJeff Layton any_leases_conflict(struct inode *inode, struct file_lock *breaker) 148103d12ddfSJeff Layton { 14828634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 1483b6be3714SJeff Layton struct file_lock_core *flc; 148403d12ddfSJeff Layton 14856109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 148603d12ddfSJeff Layton 1487b6be3714SJeff Layton list_for_each_entry(flc, &ctx->flc_lease, flc_list) { 1488b6be3714SJeff Layton if (leases_conflict(flc, &breaker->c)) 148903d12ddfSJeff Layton return true; 149003d12ddfSJeff Layton } 149103d12ddfSJeff Layton return false; 149203d12ddfSJeff Layton } 149303d12ddfSJeff Layton 14941da177e4SLinus Torvalds /** 14951da177e4SLinus Torvalds * __break_lease - revoke all outstanding leases on file 14961da177e4SLinus Torvalds * @inode: the inode of the file to return 1497df4e8d2cSJ. Bruce Fields * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR: 1498df4e8d2cSJ. Bruce Fields * break all leases 1499df4e8d2cSJ. Bruce Fields * @type: FL_LEASE: break leases and delegations; FL_DELEG: break 1500df4e8d2cSJ. Bruce Fields * only delegations 15011da177e4SLinus Torvalds * 150287250dd2Sdavid m. richter * break_lease (inlined for speed) has checked there already is at least 150387250dd2Sdavid m. richter * some kind of lock (maybe a lease) on this file. Leases are broken on 150487250dd2Sdavid m. richter * a call to open() or truncate(). This function can sleep unless you 15051da177e4SLinus Torvalds * specified %O_NONBLOCK to your open(). 15061da177e4SLinus Torvalds */ 1507df4e8d2cSJ. Bruce Fields int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) 15081da177e4SLinus Torvalds { 1509778fc546SJ. Bruce Fields int error = 0; 1510128a3785SDmitry Vyukov struct file_lock_context *ctx; 1511a901125cSYan, Zheng struct file_lock *new_fl, *fl, *tmp; 15121da177e4SLinus Torvalds unsigned long break_time; 15138737c930SAl Viro int want_write = (mode & O_ACCMODE) != O_RDONLY; 1514c45198edSJeff Layton LIST_HEAD(dispose); 15151da177e4SLinus Torvalds 15168737c930SAl Viro new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); 15176d4b9e38SLinus Torvalds if (IS_ERR(new_fl)) 15186d4b9e38SLinus Torvalds return PTR_ERR(new_fl); 15194ca52f53SJeff Layton new_fl->c.flc_flags = type; 15201da177e4SLinus Torvalds 15218634b51fSJeff Layton /* typically we will check that ctx is non-NULL before calling */ 1522401a8b8fSJeff Layton ctx = locks_inode_context(inode); 15238634b51fSJeff Layton if (!ctx) { 15248634b51fSJeff Layton WARN_ON_ONCE(1); 1525cfddf9f4SWenwen Wang goto free_lock; 15268634b51fSJeff Layton } 15278634b51fSJeff Layton 152802e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 15296109c850SJeff Layton spin_lock(&ctx->flc_lock); 15301da177e4SLinus Torvalds 1531c45198edSJeff Layton time_out_leases(inode, &dispose); 15321da177e4SLinus Torvalds 153303d12ddfSJeff Layton if (!any_leases_conflict(inode, new_fl)) 1534df4e8d2cSJ. Bruce Fields goto out; 15351da177e4SLinus Torvalds 15361da177e4SLinus Torvalds break_time = 0; 15371da177e4SLinus Torvalds if (lease_break_time > 0) { 15381da177e4SLinus Torvalds break_time = jiffies + lease_break_time * HZ; 15391da177e4SLinus Torvalds if (break_time == 0) 15401da177e4SLinus Torvalds break_time++; /* so that 0 means no break time */ 15411da177e4SLinus Torvalds } 15421da177e4SLinus Torvalds 15434ca52f53SJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { 1544b6be3714SJeff Layton if (!leases_conflict(&fl->c, &new_fl->c)) 1545df4e8d2cSJ. Bruce Fields continue; 1546778fc546SJ. Bruce Fields if (want_write) { 15474ca52f53SJeff Layton if (fl->c.flc_flags & FL_UNLOCK_PENDING) 1548778fc546SJ. Bruce Fields continue; 15494ca52f53SJeff Layton fl->c.flc_flags |= FL_UNLOCK_PENDING; 15501da177e4SLinus Torvalds fl->fl_break_time = break_time; 1551778fc546SJ. Bruce Fields } else { 15528634b51fSJeff Layton if (lease_breaking(fl)) 1553778fc546SJ. Bruce Fields continue; 15544ca52f53SJeff Layton fl->c.flc_flags |= FL_DOWNGRADE_PENDING; 1555778fc546SJ. Bruce Fields fl->fl_downgrade_time = break_time; 15561da177e4SLinus Torvalds } 15574d01b7f5SJeff Layton if (fl->fl_lmops->lm_break(fl)) 1558e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 15591da177e4SLinus Torvalds } 15601da177e4SLinus Torvalds 15618634b51fSJeff Layton if (list_empty(&ctx->flc_lease)) 15624d01b7f5SJeff Layton goto out; 15634d01b7f5SJeff Layton 1564843c6b2fSJeff Layton if (mode & O_NONBLOCK) { 156562af4f1fSJeff Layton trace_break_lease_noblock(inode, new_fl); 15661da177e4SLinus Torvalds error = -EWOULDBLOCK; 15671da177e4SLinus Torvalds goto out; 15681da177e4SLinus Torvalds } 15691da177e4SLinus Torvalds 15701da177e4SLinus Torvalds restart: 15714ca52f53SJeff Layton fl = list_first_entry(&ctx->flc_lease, struct file_lock, c.flc_list); 15728634b51fSJeff Layton break_time = fl->fl_break_time; 1573f1c6bb2cSJeff Layton if (break_time != 0) 15741da177e4SLinus Torvalds break_time -= jiffies; 15751da177e4SLinus Torvalds if (break_time == 0) 15761da177e4SLinus Torvalds break_time++; 1577fd7732e0SNeilBrown locks_insert_block(fl, new_fl, leases_conflict); 157862af4f1fSJeff Layton trace_break_lease_block(inode, new_fl); 15796109c850SJeff Layton spin_unlock(&ctx->flc_lock); 158002e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1581aba37660SPeter Zijlstra 1582c45198edSJeff Layton locks_dispose_list(&dispose); 15834ca52f53SJeff Layton error = wait_event_interruptible_timeout(new_fl->c.flc_wait, 15844ca52f53SJeff Layton list_empty(&new_fl->c.flc_blocked_member), 1585dcf23ac3SLinus Torvalds break_time); 1586aba37660SPeter Zijlstra 158702e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 15886109c850SJeff Layton spin_lock(&ctx->flc_lock); 158962af4f1fSJeff Layton trace_break_lease_unblock(inode, new_fl); 15901c8c601aSJeff Layton locks_delete_block(new_fl); 15911da177e4SLinus Torvalds if (error >= 0) { 1592778fc546SJ. Bruce Fields /* 1593778fc546SJ. Bruce Fields * Wait for the next conflicting lease that has not been 1594778fc546SJ. Bruce Fields * broken yet 1595778fc546SJ. Bruce Fields */ 159603d12ddfSJeff Layton if (error == 0) 159703d12ddfSJeff Layton time_out_leases(inode, &dispose); 159803d12ddfSJeff Layton if (any_leases_conflict(inode, new_fl)) 15991da177e4SLinus Torvalds goto restart; 16001da177e4SLinus Torvalds error = 0; 16011da177e4SLinus Torvalds } 16021da177e4SLinus Torvalds out: 16036109c850SJeff Layton spin_unlock(&ctx->flc_lock); 160402e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1605c45198edSJeff Layton locks_dispose_list(&dispose); 1606cfddf9f4SWenwen Wang free_lock: 16071da177e4SLinus Torvalds locks_free_lock(new_fl); 16081da177e4SLinus Torvalds return error; 16091da177e4SLinus Torvalds } 16101da177e4SLinus Torvalds EXPORT_SYMBOL(__break_lease); 16111da177e4SLinus Torvalds 16121da177e4SLinus Torvalds /** 161376c47948SAmir Goldstein * lease_get_mtime - update modified time of an inode with exclusive lease 16141da177e4SLinus Torvalds * @inode: the inode 161576c47948SAmir Goldstein * @time: pointer to a timespec which contains the last modified time 16161da177e4SLinus Torvalds * 16171da177e4SLinus Torvalds * This is to force NFS clients to flush their caches for files with 16181da177e4SLinus Torvalds * exclusive leases. The justification is that if someone has an 1619a6b91919SRandy Dunlap * exclusive lease, then they could be modifying it. 16201da177e4SLinus Torvalds */ 162195582b00SDeepa Dinamani void lease_get_mtime(struct inode *inode, struct timespec64 *time) 16221da177e4SLinus Torvalds { 1623bfe86024SJeff Layton bool has_lease = false; 1624128a3785SDmitry Vyukov struct file_lock_context *ctx; 16258634b51fSJeff Layton struct file_lock *fl; 1626bfe86024SJeff Layton 1627401a8b8fSJeff Layton ctx = locks_inode_context(inode); 16288634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 16296109c850SJeff Layton spin_lock(&ctx->flc_lock); 16308ace5dfbSGeliang Tang fl = list_first_entry_or_null(&ctx->flc_lease, 16314ca52f53SJeff Layton struct file_lock, c.flc_list); 163275cabec0SJeff Layton if (fl && lock_is_write(fl)) 1633bfe86024SJeff Layton has_lease = true; 16346109c850SJeff Layton spin_unlock(&ctx->flc_lock); 1635bfe86024SJeff Layton } 1636bfe86024SJeff Layton 1637bfe86024SJeff Layton if (has_lease) 1638c2050a45SDeepa Dinamani *time = current_time(inode); 16391da177e4SLinus Torvalds } 16401da177e4SLinus Torvalds EXPORT_SYMBOL(lease_get_mtime); 16411da177e4SLinus Torvalds 16421da177e4SLinus Torvalds /** 16431da177e4SLinus Torvalds * fcntl_getlease - Enquire what lease is currently active 16441da177e4SLinus Torvalds * @filp: the file 16451da177e4SLinus Torvalds * 16461da177e4SLinus Torvalds * The value returned by this function will be one of 16471da177e4SLinus Torvalds * (if no lease break is pending): 16481da177e4SLinus Torvalds * 16491da177e4SLinus Torvalds * %F_RDLCK to indicate a shared lease is held. 16501da177e4SLinus Torvalds * 16511da177e4SLinus Torvalds * %F_WRLCK to indicate an exclusive lease is held. 16521da177e4SLinus Torvalds * 16531da177e4SLinus Torvalds * %F_UNLCK to indicate no lease is held. 16541da177e4SLinus Torvalds * 16551da177e4SLinus Torvalds * (if a lease break is pending): 16561da177e4SLinus Torvalds * 16571da177e4SLinus Torvalds * %F_RDLCK to indicate an exclusive lease needs to be 16581da177e4SLinus Torvalds * changed to a shared lease (or removed). 16591da177e4SLinus Torvalds * 16601da177e4SLinus Torvalds * %F_UNLCK to indicate the lease needs to be removed. 16611da177e4SLinus Torvalds * 16621da177e4SLinus Torvalds * XXX: sfr & willy disagree over whether F_INPROGRESS 16631da177e4SLinus Torvalds * should be returned to userspace. 16641da177e4SLinus Torvalds */ 16651da177e4SLinus Torvalds int fcntl_getlease(struct file *filp) 16661da177e4SLinus Torvalds { 16671da177e4SLinus Torvalds struct file_lock *fl; 1668c65454a9SJeff Layton struct inode *inode = file_inode(filp); 1669128a3785SDmitry Vyukov struct file_lock_context *ctx; 16701da177e4SLinus Torvalds int type = F_UNLCK; 1671c45198edSJeff Layton LIST_HEAD(dispose); 16721da177e4SLinus Torvalds 1673401a8b8fSJeff Layton ctx = locks_inode_context(inode); 16748634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 167502e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 16766109c850SJeff Layton spin_lock(&ctx->flc_lock); 1677c568d683SMiklos Szeredi time_out_leases(inode, &dispose); 16784ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { 16794ca52f53SJeff Layton if (fl->c.flc_file != filp) 16808634b51fSJeff Layton continue; 1681778fc546SJ. Bruce Fields type = target_leasetype(fl); 16821da177e4SLinus Torvalds break; 16831da177e4SLinus Torvalds } 16846109c850SJeff Layton spin_unlock(&ctx->flc_lock); 168502e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 16865f43086bSPeter Zijlstra 1687c45198edSJeff Layton locks_dispose_list(&dispose); 16888634b51fSJeff Layton } 16891da177e4SLinus Torvalds return type; 16901da177e4SLinus Torvalds } 16911da177e4SLinus Torvalds 169224cbe784SJeff Layton /** 1693387e3746SAmir Goldstein * check_conflicting_open - see if the given file points to an inode that has 169424cbe784SJeff Layton * an existing open that would conflict with the 169524cbe784SJeff Layton * desired lease. 1696387e3746SAmir Goldstein * @filp: file to check 169724cbe784SJeff Layton * @arg: type of lease that we're trying to acquire 16987fadc59cSRandy Dunlap * @flags: current lock flags 169924cbe784SJeff Layton * 170024cbe784SJeff Layton * Check to see if there's an existing open fd on this file that would 170124cbe784SJeff Layton * conflict with the lease we're trying to set. 170224cbe784SJeff Layton */ 170324cbe784SJeff Layton static int 1704ed5f17f6SLuca Vizzarro check_conflicting_open(struct file *filp, const int arg, int flags) 170524cbe784SJeff Layton { 1706c65454a9SJeff Layton struct inode *inode = file_inode(filp); 1707387e3746SAmir Goldstein int self_wcount = 0, self_rcount = 0; 170824cbe784SJeff Layton 170911afe9f7SChristoph Hellwig if (flags & FL_LAYOUT) 171011afe9f7SChristoph Hellwig return 0; 1711aba2072fSJ. Bruce Fields if (flags & FL_DELEG) 1712aba2072fSJ. Bruce Fields /* We leave these checks to the caller */ 1713aba2072fSJ. Bruce Fields return 0; 171411afe9f7SChristoph Hellwig 1715387e3746SAmir Goldstein if (arg == F_RDLCK) 1716387e3746SAmir Goldstein return inode_is_open_for_write(inode) ? -EAGAIN : 0; 1717387e3746SAmir Goldstein else if (arg != F_WRLCK) 1718387e3746SAmir Goldstein return 0; 1719387e3746SAmir Goldstein 1720387e3746SAmir Goldstein /* 1721387e3746SAmir Goldstein * Make sure that only read/write count is from lease requestor. 1722387e3746SAmir Goldstein * Note that this will result in denying write leases when i_writecount 1723387e3746SAmir Goldstein * is negative, which is what we want. (We shouldn't grant write leases 1724387e3746SAmir Goldstein * on files open for execution.) 1725387e3746SAmir Goldstein */ 1726387e3746SAmir Goldstein if (filp->f_mode & FMODE_WRITE) 1727387e3746SAmir Goldstein self_wcount = 1; 1728387e3746SAmir Goldstein else if (filp->f_mode & FMODE_READ) 1729387e3746SAmir Goldstein self_rcount = 1; 1730387e3746SAmir Goldstein 1731387e3746SAmir Goldstein if (atomic_read(&inode->i_writecount) != self_wcount || 1732387e3746SAmir Goldstein atomic_read(&inode->i_readcount) != self_rcount) 173324cbe784SJeff Layton return -EAGAIN; 173424cbe784SJeff Layton 1735387e3746SAmir Goldstein return 0; 173624cbe784SJeff Layton } 173724cbe784SJeff Layton 1738e6f5c789SJeff Layton static int 1739ed5f17f6SLuca Vizzarro generic_add_lease(struct file *filp, int arg, struct file_lock **flp, void **priv) 17401da177e4SLinus Torvalds { 17418634b51fSJeff Layton struct file_lock *fl, *my_fl = NULL, *lease; 1742c65454a9SJeff Layton struct inode *inode = file_inode(filp); 17438634b51fSJeff Layton struct file_lock_context *ctx; 17444ca52f53SJeff Layton bool is_deleg = (*flp)->c.flc_flags & FL_DELEG; 1745c1f24ef4SJ. Bruce Fields int error; 1746c45198edSJeff Layton LIST_HEAD(dispose); 17471da177e4SLinus Torvalds 1748096657b6SJ. Bruce Fields lease = *flp; 174962af4f1fSJeff Layton trace_generic_add_lease(inode, lease); 175062af4f1fSJeff Layton 17515c1c669aSJeff Layton /* Note that arg is never F_UNLCK here */ 17525c1c669aSJeff Layton ctx = locks_get_lock_context(inode, arg); 17538634b51fSJeff Layton if (!ctx) 17548634b51fSJeff Layton return -ENOMEM; 17558634b51fSJeff Layton 1756df4e8d2cSJ. Bruce Fields /* 1757df4e8d2cSJ. Bruce Fields * In the delegation case we need mutual exclusion with 1758df4e8d2cSJ. Bruce Fields * a number of operations that take the i_mutex. We trylock 1759df4e8d2cSJ. Bruce Fields * because delegations are an optional optimization, and if 1760df4e8d2cSJ. Bruce Fields * there's some chance of a conflict--we'd rather not 1761df4e8d2cSJ. Bruce Fields * bother, maybe that's a sign this just isn't a good file to 1762df4e8d2cSJ. Bruce Fields * hand out a delegation on. 1763df4e8d2cSJ. Bruce Fields */ 17645955102cSAl Viro if (is_deleg && !inode_trylock(inode)) 1765df4e8d2cSJ. Bruce Fields return -EAGAIN; 1766df4e8d2cSJ. Bruce Fields 176702e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 17686109c850SJeff Layton spin_lock(&ctx->flc_lock); 1769c45198edSJeff Layton time_out_leases(inode, &dispose); 17704ca52f53SJeff Layton error = check_conflicting_open(filp, arg, lease->c.flc_flags); 177124cbe784SJeff Layton if (error) 17721da177e4SLinus Torvalds goto out; 177385c59580SPavel Emelyanov 17741da177e4SLinus Torvalds /* 17751da177e4SLinus Torvalds * At this point, we know that if there is an exclusive 17761da177e4SLinus Torvalds * lease on this file, then we hold it on this filp 17771da177e4SLinus Torvalds * (otherwise our open of this file would have blocked). 17781da177e4SLinus Torvalds * And if we are trying to acquire an exclusive lease, 17791da177e4SLinus Torvalds * then the file is not open by anyone (including us) 17801da177e4SLinus Torvalds * except for this filp. 17811da177e4SLinus Torvalds */ 1782c1f24ef4SJ. Bruce Fields error = -EAGAIN; 17834ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { 17844ca52f53SJeff Layton if (fl->c.flc_file == filp && 17854ca52f53SJeff Layton fl->c.flc_owner == lease->c.flc_owner) { 17868634b51fSJeff Layton my_fl = fl; 1787c1f24ef4SJ. Bruce Fields continue; 17881da177e4SLinus Torvalds } 17898634b51fSJeff Layton 1790c1f24ef4SJ. Bruce Fields /* 1791c1f24ef4SJ. Bruce Fields * No exclusive leases if someone else has a lease on 1792c1f24ef4SJ. Bruce Fields * this file: 1793c1f24ef4SJ. Bruce Fields */ 1794c1f24ef4SJ. Bruce Fields if (arg == F_WRLCK) 17951da177e4SLinus Torvalds goto out; 1796c1f24ef4SJ. Bruce Fields /* 1797c1f24ef4SJ. Bruce Fields * Modifying our existing lease is OK, but no getting a 1798c1f24ef4SJ. Bruce Fields * new lease if someone else is opening for write: 1799c1f24ef4SJ. Bruce Fields */ 18004ca52f53SJeff Layton if (fl->c.flc_flags & FL_UNLOCK_PENDING) 1801c1f24ef4SJ. Bruce Fields goto out; 1802c1f24ef4SJ. Bruce Fields } 18031da177e4SLinus Torvalds 18048634b51fSJeff Layton if (my_fl != NULL) { 18050164bf02SJeff Layton lease = my_fl; 18060164bf02SJeff Layton error = lease->fl_lmops->lm_change(lease, arg, &dispose); 18071c7dd2ffSJeff Layton if (error) 18081da177e4SLinus Torvalds goto out; 18091c7dd2ffSJeff Layton goto out_setup; 18101da177e4SLinus Torvalds } 18111da177e4SLinus Torvalds 18121da177e4SLinus Torvalds error = -EINVAL; 18131da177e4SLinus Torvalds if (!leases_enable) 18141da177e4SLinus Torvalds goto out; 18151da177e4SLinus Torvalds 1816e084c1bdSJeff Layton locks_insert_lock_ctx(lease, &ctx->flc_lease); 181724cbe784SJeff Layton /* 181824cbe784SJeff Layton * The check in break_lease() is lockless. It's possible for another 181924cbe784SJeff Layton * open to race in after we did the earlier check for a conflicting 182024cbe784SJeff Layton * open but before the lease was inserted. Check again for a 182124cbe784SJeff Layton * conflicting open and cancel the lease if there is one. 182224cbe784SJeff Layton * 182324cbe784SJeff Layton * We also add a barrier here to ensure that the insertion of the lock 182424cbe784SJeff Layton * precedes these checks. 182524cbe784SJeff Layton */ 182624cbe784SJeff Layton smp_mb(); 18274ca52f53SJeff Layton error = check_conflicting_open(filp, arg, lease->c.flc_flags); 18288634b51fSJeff Layton if (error) { 1829e084c1bdSJeff Layton locks_unlink_lock_ctx(lease); 18308634b51fSJeff Layton goto out; 18318634b51fSJeff Layton } 18321c7dd2ffSJeff Layton 18331c7dd2ffSJeff Layton out_setup: 18341c7dd2ffSJeff Layton if (lease->fl_lmops->lm_setup) 18351c7dd2ffSJeff Layton lease->fl_lmops->lm_setup(lease, priv); 18361da177e4SLinus Torvalds out: 18376109c850SJeff Layton spin_unlock(&ctx->flc_lock); 183802e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1839c45198edSJeff Layton locks_dispose_list(&dispose); 1840df4e8d2cSJ. Bruce Fields if (is_deleg) 18415955102cSAl Viro inode_unlock(inode); 18428634b51fSJeff Layton if (!error && !my_fl) 18431c7dd2ffSJeff Layton *flp = NULL; 18441da177e4SLinus Torvalds return error; 18451da177e4SLinus Torvalds } 18468335ebd9SJ. Bruce Fields 18472ab99ee1SChristoph Hellwig static int generic_delete_lease(struct file *filp, void *owner) 18488335ebd9SJ. Bruce Fields { 18490efaa7e8SJeff Layton int error = -EAGAIN; 18508634b51fSJeff Layton struct file_lock *fl, *victim = NULL; 1851c65454a9SJeff Layton struct inode *inode = file_inode(filp); 1852128a3785SDmitry Vyukov struct file_lock_context *ctx; 1853c45198edSJeff Layton LIST_HEAD(dispose); 18548335ebd9SJ. Bruce Fields 1855401a8b8fSJeff Layton ctx = locks_inode_context(inode); 18568634b51fSJeff Layton if (!ctx) { 18578634b51fSJeff Layton trace_generic_delete_lease(inode, NULL); 18588634b51fSJeff Layton return error; 18598634b51fSJeff Layton } 18608634b51fSJeff Layton 186102e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 18626109c850SJeff Layton spin_lock(&ctx->flc_lock); 18634ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { 18644ca52f53SJeff Layton if (fl->c.flc_file == filp && 18654ca52f53SJeff Layton fl->c.flc_owner == owner) { 18668634b51fSJeff Layton victim = fl; 18670efaa7e8SJeff Layton break; 18688335ebd9SJ. Bruce Fields } 18698634b51fSJeff Layton } 1870a9b1b455SJeff Layton trace_generic_delete_lease(inode, victim); 18718634b51fSJeff Layton if (victim) 18727448cc37SJeff Layton error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose); 18736109c850SJeff Layton spin_unlock(&ctx->flc_lock); 187402e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1875c45198edSJeff Layton locks_dispose_list(&dispose); 18760efaa7e8SJeff Layton return error; 18778335ebd9SJ. Bruce Fields } 18788335ebd9SJ. Bruce Fields 18791da177e4SLinus Torvalds /** 18801da177e4SLinus Torvalds * generic_setlease - sets a lease on an open file 18811da177e4SLinus Torvalds * @filp: file pointer 18821da177e4SLinus Torvalds * @arg: type of lease to obtain 18831da177e4SLinus Torvalds * @flp: input - file_lock to use, output - file_lock inserted 18841c7dd2ffSJeff Layton * @priv: private data for lm_setup (may be NULL if lm_setup 18851c7dd2ffSJeff Layton * doesn't require it) 18861da177e4SLinus Torvalds * 18871da177e4SLinus Torvalds * The (input) flp->fl_lmops->lm_break function is required 18881da177e4SLinus Torvalds * by break_lease(). 18891da177e4SLinus Torvalds */ 1890ed5f17f6SLuca Vizzarro int generic_setlease(struct file *filp, int arg, struct file_lock **flp, 1891e6f5c789SJeff Layton void **priv) 18921da177e4SLinus Torvalds { 1893c65454a9SJeff Layton struct inode *inode = file_inode(filp); 189442d0c4bdSSeth Forshee vfsuid_t vfsuid = i_uid_into_vfsuid(file_mnt_idmap(filp), inode); 18958335ebd9SJ. Bruce Fields int error; 18961da177e4SLinus Torvalds 189742d0c4bdSSeth Forshee if ((!vfsuid_eq_kuid(vfsuid, current_fsuid())) && !capable(CAP_LEASE)) 18988335ebd9SJ. Bruce Fields return -EACCES; 18991da177e4SLinus Torvalds if (!S_ISREG(inode->i_mode)) 19008335ebd9SJ. Bruce Fields return -EINVAL; 19011da177e4SLinus Torvalds error = security_file_lock(filp, arg); 19021da177e4SLinus Torvalds if (error) 19038335ebd9SJ. Bruce Fields return error; 19041da177e4SLinus Torvalds 19058335ebd9SJ. Bruce Fields switch (arg) { 19068335ebd9SJ. Bruce Fields case F_UNLCK: 19072ab99ee1SChristoph Hellwig return generic_delete_lease(filp, *priv); 19088335ebd9SJ. Bruce Fields case F_RDLCK: 19098335ebd9SJ. Bruce Fields case F_WRLCK: 19100efaa7e8SJeff Layton if (!(*flp)->fl_lmops->lm_break) { 19110efaa7e8SJeff Layton WARN_ON_ONCE(1); 19120efaa7e8SJeff Layton return -ENOLCK; 19130efaa7e8SJeff Layton } 191411afe9f7SChristoph Hellwig 1915e6f5c789SJeff Layton return generic_add_lease(filp, arg, flp, priv); 19168335ebd9SJ. Bruce Fields default: 19178d657eb3SDave Jones return -EINVAL; 19181da177e4SLinus Torvalds } 19191da177e4SLinus Torvalds } 19200af1a450SChristoph Hellwig EXPORT_SYMBOL(generic_setlease); 19211da177e4SLinus Torvalds 192218f6622eSJeff Layton /* 192318f6622eSJeff Layton * Kernel subsystems can register to be notified on any attempt to set 192418f6622eSJeff Layton * a new lease with the lease_notifier_chain. This is used by (e.g.) nfsd 192518f6622eSJeff Layton * to close files that it may have cached when there is an attempt to set a 192618f6622eSJeff Layton * conflicting lease. 192718f6622eSJeff Layton */ 192818f6622eSJeff Layton static struct srcu_notifier_head lease_notifier_chain; 192918f6622eSJeff Layton 193018f6622eSJeff Layton static inline void 193118f6622eSJeff Layton lease_notifier_chain_init(void) 193218f6622eSJeff Layton { 193318f6622eSJeff Layton srcu_init_notifier_head(&lease_notifier_chain); 193418f6622eSJeff Layton } 193518f6622eSJeff Layton 193618f6622eSJeff Layton static inline void 1937ed5f17f6SLuca Vizzarro setlease_notifier(int arg, struct file_lock *lease) 193818f6622eSJeff Layton { 193918f6622eSJeff Layton if (arg != F_UNLCK) 194018f6622eSJeff Layton srcu_notifier_call_chain(&lease_notifier_chain, arg, lease); 194118f6622eSJeff Layton } 194218f6622eSJeff Layton 194318f6622eSJeff Layton int lease_register_notifier(struct notifier_block *nb) 194418f6622eSJeff Layton { 194518f6622eSJeff Layton return srcu_notifier_chain_register(&lease_notifier_chain, nb); 194618f6622eSJeff Layton } 194718f6622eSJeff Layton EXPORT_SYMBOL_GPL(lease_register_notifier); 194818f6622eSJeff Layton 194918f6622eSJeff Layton void lease_unregister_notifier(struct notifier_block *nb) 195018f6622eSJeff Layton { 195118f6622eSJeff Layton srcu_notifier_chain_unregister(&lease_notifier_chain, nb); 195218f6622eSJeff Layton } 195318f6622eSJeff Layton EXPORT_SYMBOL_GPL(lease_unregister_notifier); 195418f6622eSJeff Layton 19551da177e4SLinus Torvalds /** 1956a9933ceaSJ. Bruce Fields * vfs_setlease - sets a lease on an open file 19571da177e4SLinus Torvalds * @filp: file pointer 19581da177e4SLinus Torvalds * @arg: type of lease to obtain 1959e51673aaSJeff Layton * @lease: file_lock to use when adding a lease 19601c7dd2ffSJeff Layton * @priv: private info for lm_setup when adding a lease (may be 19611c7dd2ffSJeff Layton * NULL if lm_setup doesn't require it) 19621da177e4SLinus Torvalds * 1963e51673aaSJeff Layton * Call this to establish a lease on the file. The "lease" argument is not 1964e51673aaSJeff Layton * used for F_UNLCK requests and may be NULL. For commands that set or alter 196580b79dd0SMauro Carvalho Chehab * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be 196680b79dd0SMauro Carvalho Chehab * set; if not, this function will return -ENOLCK (and generate a scary-looking 1967e51673aaSJeff Layton * stack trace). 19681c7dd2ffSJeff Layton * 19691c7dd2ffSJeff Layton * The "priv" pointer is passed directly to the lm_setup function as-is. It 19701c7dd2ffSJeff Layton * may be NULL if the lm_setup operation doesn't require it. 19711da177e4SLinus Torvalds */ 1972e6f5c789SJeff Layton int 1973ed5f17f6SLuca Vizzarro vfs_setlease(struct file *filp, int arg, struct file_lock **lease, void **priv) 19741da177e4SLinus Torvalds { 197518f6622eSJeff Layton if (lease) 197618f6622eSJeff Layton setlease_notifier(arg, *lease); 1977de2a4a50SMiklos Szeredi if (filp->f_op->setlease) 1978f82b4b67SJeff Layton return filp->f_op->setlease(filp, arg, lease, priv); 19791c7dd2ffSJeff Layton else 1980f82b4b67SJeff Layton return generic_setlease(filp, arg, lease, priv); 19811da177e4SLinus Torvalds } 1982a9933ceaSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_setlease); 19831da177e4SLinus Torvalds 1984ed5f17f6SLuca Vizzarro static int do_fcntl_add_lease(unsigned int fd, struct file *filp, int arg) 19851da177e4SLinus Torvalds { 19861c7dd2ffSJeff Layton struct file_lock *fl; 1987f7347ce4SLinus Torvalds struct fasync_struct *new; 19881da177e4SLinus Torvalds int error; 19891da177e4SLinus Torvalds 1990c5b1f0d9SArnd Bergmann fl = lease_alloc(filp, arg); 1991c5b1f0d9SArnd Bergmann if (IS_ERR(fl)) 1992c5b1f0d9SArnd Bergmann return PTR_ERR(fl); 19931da177e4SLinus Torvalds 1994f7347ce4SLinus Torvalds new = fasync_alloc(); 1995f7347ce4SLinus Torvalds if (!new) { 1996f7347ce4SLinus Torvalds locks_free_lock(fl); 1997f7347ce4SLinus Torvalds return -ENOMEM; 1998f7347ce4SLinus Torvalds } 19991c7dd2ffSJeff Layton new->fa_fd = fd; 20001da177e4SLinus Torvalds 20011c7dd2ffSJeff Layton error = vfs_setlease(filp, arg, &fl, (void **)&new); 20022dfb928fSJeff Layton if (fl) 20032dfb928fSJeff Layton locks_free_lock(fl); 2004f7347ce4SLinus Torvalds if (new) 2005f7347ce4SLinus Torvalds fasync_free(new); 20061da177e4SLinus Torvalds return error; 20071da177e4SLinus Torvalds } 20081da177e4SLinus Torvalds 20091da177e4SLinus Torvalds /** 20100ceaf6c7SJ. Bruce Fields * fcntl_setlease - sets a lease on an open file 20110ceaf6c7SJ. Bruce Fields * @fd: open file descriptor 20120ceaf6c7SJ. Bruce Fields * @filp: file pointer 20130ceaf6c7SJ. Bruce Fields * @arg: type of lease to obtain 20140ceaf6c7SJ. Bruce Fields * 20150ceaf6c7SJ. Bruce Fields * Call this fcntl to establish a lease on the file. 20160ceaf6c7SJ. Bruce Fields * Note that you also need to call %F_SETSIG to 20170ceaf6c7SJ. Bruce Fields * receive a signal when the lease is broken. 20180ceaf6c7SJ. Bruce Fields */ 2019ed5f17f6SLuca Vizzarro int fcntl_setlease(unsigned int fd, struct file *filp, int arg) 20200ceaf6c7SJ. Bruce Fields { 20210ceaf6c7SJ. Bruce Fields if (arg == F_UNLCK) 20222ab99ee1SChristoph Hellwig return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); 20230ceaf6c7SJ. Bruce Fields return do_fcntl_add_lease(fd, filp, arg); 20240ceaf6c7SJ. Bruce Fields } 20250ceaf6c7SJ. Bruce Fields 20260ceaf6c7SJ. Bruce Fields /** 202729d01b22SJeff Layton * flock_lock_inode_wait - Apply a FLOCK-style lock to a file 202829d01b22SJeff Layton * @inode: inode of the file to apply to 20291da177e4SLinus Torvalds * @fl: The lock to be applied 20301da177e4SLinus Torvalds * 203129d01b22SJeff Layton * Apply a FLOCK style lock request to an inode. 20321da177e4SLinus Torvalds */ 2033616fb38fSBenjamin Coddington static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) 20341da177e4SLinus Torvalds { 20351da177e4SLinus Torvalds int error; 20361da177e4SLinus Torvalds might_sleep(); 20371da177e4SLinus Torvalds for (;;) { 203829d01b22SJeff Layton error = flock_lock_inode(inode, fl); 2039bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 20401da177e4SLinus Torvalds break; 20414ca52f53SJeff Layton error = wait_event_interruptible(fl->c.flc_wait, 20424ca52f53SJeff Layton list_empty(&fl->c.flc_blocked_member)); 204316306a61SNeilBrown if (error) 20441da177e4SLinus Torvalds break; 20451da177e4SLinus Torvalds } 204616306a61SNeilBrown locks_delete_block(fl); 20471da177e4SLinus Torvalds return error; 20481da177e4SLinus Torvalds } 20491da177e4SLinus Torvalds 205029d01b22SJeff Layton /** 2051e55c34a6SBenjamin Coddington * locks_lock_inode_wait - Apply a lock to an inode 2052e55c34a6SBenjamin Coddington * @inode: inode of the file to apply to 2053e55c34a6SBenjamin Coddington * @fl: The lock to be applied 2054e55c34a6SBenjamin Coddington * 2055e55c34a6SBenjamin Coddington * Apply a POSIX or FLOCK style lock request to an inode. 2056e55c34a6SBenjamin Coddington */ 2057e55c34a6SBenjamin Coddington int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl) 2058e55c34a6SBenjamin Coddington { 2059e55c34a6SBenjamin Coddington int res = 0; 20604ca52f53SJeff Layton switch (fl->c.flc_flags & (FL_POSIX|FL_FLOCK)) { 2061e55c34a6SBenjamin Coddington case FL_POSIX: 2062e55c34a6SBenjamin Coddington res = posix_lock_inode_wait(inode, fl); 2063e55c34a6SBenjamin Coddington break; 2064e55c34a6SBenjamin Coddington case FL_FLOCK: 2065e55c34a6SBenjamin Coddington res = flock_lock_inode_wait(inode, fl); 2066e55c34a6SBenjamin Coddington break; 2067e55c34a6SBenjamin Coddington default: 2068e55c34a6SBenjamin Coddington BUG(); 2069e55c34a6SBenjamin Coddington } 2070e55c34a6SBenjamin Coddington return res; 2071e55c34a6SBenjamin Coddington } 2072e55c34a6SBenjamin Coddington EXPORT_SYMBOL(locks_lock_inode_wait); 2073e55c34a6SBenjamin Coddington 2074e55c34a6SBenjamin Coddington /** 20751da177e4SLinus Torvalds * sys_flock: - flock() system call. 20761da177e4SLinus Torvalds * @fd: the file descriptor to lock. 20771da177e4SLinus Torvalds * @cmd: the type of lock to apply. 20781da177e4SLinus Torvalds * 20791da177e4SLinus Torvalds * Apply a %FL_FLOCK style lock to an open file descriptor. 208080b79dd0SMauro Carvalho Chehab * The @cmd can be one of: 20811da177e4SLinus Torvalds * 208280b79dd0SMauro Carvalho Chehab * - %LOCK_SH -- a shared lock. 208380b79dd0SMauro Carvalho Chehab * - %LOCK_EX -- an exclusive lock. 208480b79dd0SMauro Carvalho Chehab * - %LOCK_UN -- remove an existing lock. 208590f7d7a0SJeff Layton * - %LOCK_MAND -- a 'mandatory' flock. (DEPRECATED) 20861da177e4SLinus Torvalds * 208790f7d7a0SJeff Layton * %LOCK_MAND support has been removed from the kernel. 20881da177e4SLinus Torvalds */ 2089002c8976SHeiko Carstens SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) 20901da177e4SLinus Torvalds { 2091db4abb4aSKuniyuki Iwashima int can_sleep, error, type; 20924149be7bSKuniyuki Iwashima struct file_lock fl; 2093db4abb4aSKuniyuki Iwashima struct fd f; 20941da177e4SLinus Torvalds 209590f7d7a0SJeff Layton /* 209690f7d7a0SJeff Layton * LOCK_MAND locks were broken for a long time in that they never 209790f7d7a0SJeff Layton * conflicted with one another and didn't prevent any sort of open, 209890f7d7a0SJeff Layton * read or write activity. 209990f7d7a0SJeff Layton * 210090f7d7a0SJeff Layton * Just ignore these requests now, to preserve legacy behavior, but 210190f7d7a0SJeff Layton * throw a warning to let people know that they don't actually work. 210290f7d7a0SJeff Layton */ 210390f7d7a0SJeff Layton if (cmd & LOCK_MAND) { 2104f2f2494cSAndi Kleen pr_warn_once("%s(%d): Attempt to set a LOCK_MAND lock via flock(2). This support has been removed and the request ignored.\n", current->comm, current->pid); 2105db4abb4aSKuniyuki Iwashima return 0; 210690f7d7a0SJeff Layton } 210790f7d7a0SJeff Layton 2108db4abb4aSKuniyuki Iwashima type = flock_translate_cmd(cmd & ~LOCK_NB); 2109db4abb4aSKuniyuki Iwashima if (type < 0) 2110db4abb4aSKuniyuki Iwashima return type; 2111db4abb4aSKuniyuki Iwashima 2112db4abb4aSKuniyuki Iwashima error = -EBADF; 2113db4abb4aSKuniyuki Iwashima f = fdget(fd); 2114db4abb4aSKuniyuki Iwashima if (!f.file) 2115db4abb4aSKuniyuki Iwashima return error; 2116db4abb4aSKuniyuki Iwashima 2117db4abb4aSKuniyuki Iwashima if (type != F_UNLCK && !(f.file->f_mode & (FMODE_READ | FMODE_WRITE))) 21181da177e4SLinus Torvalds goto out_putf; 21196e129d00SJeff Layton 21204149be7bSKuniyuki Iwashima flock_make_lock(f.file, &fl, type); 21211da177e4SLinus Torvalds 21224ca52f53SJeff Layton error = security_file_lock(f.file, fl.c.flc_type); 21231da177e4SLinus Torvalds if (error) 21244149be7bSKuniyuki Iwashima goto out_putf; 21251da177e4SLinus Torvalds 2126db4abb4aSKuniyuki Iwashima can_sleep = !(cmd & LOCK_NB); 2127db4abb4aSKuniyuki Iwashima if (can_sleep) 21284ca52f53SJeff Layton fl.c.flc_flags |= FL_SLEEP; 2129db4abb4aSKuniyuki Iwashima 2130de2a4a50SMiklos Szeredi if (f.file->f_op->flock) 21312903ff01SAl Viro error = f.file->f_op->flock(f.file, 21321da177e4SLinus Torvalds (can_sleep) ? F_SETLKW : F_SETLK, 21334149be7bSKuniyuki Iwashima &fl); 21341da177e4SLinus Torvalds else 21354149be7bSKuniyuki Iwashima error = locks_lock_file_wait(f.file, &fl); 21361da177e4SLinus Torvalds 2137932c29a1SDavid Howells locks_release_private(&fl); 21381da177e4SLinus Torvalds out_putf: 21392903ff01SAl Viro fdput(f); 2140db4abb4aSKuniyuki Iwashima 21411da177e4SLinus Torvalds return error; 21421da177e4SLinus Torvalds } 21431da177e4SLinus Torvalds 21443ee17abdSJ. Bruce Fields /** 21453ee17abdSJ. Bruce Fields * vfs_test_lock - test file byte range lock 21463ee17abdSJ. Bruce Fields * @filp: The file to test lock for 21476924c554SJ. Bruce Fields * @fl: The lock to test; also used to hold result 21483ee17abdSJ. Bruce Fields * 21493ee17abdSJ. Bruce Fields * Returns -ERRNO on failure. Indicates presence of conflicting lock by 21503ee17abdSJ. Bruce Fields * setting conf->fl_type to something other than F_UNLCK. 21513ee17abdSJ. Bruce Fields */ 21523ee17abdSJ. Bruce Fields int vfs_test_lock(struct file *filp, struct file_lock *fl) 21533ee17abdSJ. Bruce Fields { 21544ca52f53SJeff Layton WARN_ON_ONCE(filp != fl->c.flc_file); 2155de2a4a50SMiklos Szeredi if (filp->f_op->lock) 21563ee17abdSJ. Bruce Fields return filp->f_op->lock(filp, F_GETLK, fl); 21573ee17abdSJ. Bruce Fields posix_test_lock(filp, fl); 21583ee17abdSJ. Bruce Fields return 0; 21593ee17abdSJ. Bruce Fields } 21603ee17abdSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_test_lock); 21613ee17abdSJ. Bruce Fields 21629d5b86acSBenjamin Coddington /** 21639d5b86acSBenjamin Coddington * locks_translate_pid - translate a file_lock's fl_pid number into a namespace 21649d5b86acSBenjamin Coddington * @fl: The file_lock who's fl_pid should be translated 21659d5b86acSBenjamin Coddington * @ns: The namespace into which the pid should be translated 21669d5b86acSBenjamin Coddington * 2167bd4c4680SJakub Wilk * Used to translate a fl_pid into a namespace virtual pid number 21689d5b86acSBenjamin Coddington */ 21699d5b86acSBenjamin Coddington static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns) 21709d5b86acSBenjamin Coddington { 21719d5b86acSBenjamin Coddington pid_t vnr; 21729d5b86acSBenjamin Coddington struct pid *pid; 21739d5b86acSBenjamin Coddington 21744ca52f53SJeff Layton if (fl->c.flc_flags & FL_OFDLCK) 21759d5b86acSBenjamin Coddington return -1; 21763d40f781SJeff Layton 21773d40f781SJeff Layton /* Remote locks report a negative pid value */ 21784ca52f53SJeff Layton if (fl->c.flc_pid <= 0) 21794ca52f53SJeff Layton return fl->c.flc_pid; 21803d40f781SJeff Layton 2181826d7bc9SKonstantin Khorenko /* 2182826d7bc9SKonstantin Khorenko * If the flock owner process is dead and its pid has been already 2183826d7bc9SKonstantin Khorenko * freed, the translation below won't work, but we still want to show 2184826d7bc9SKonstantin Khorenko * flock owner pid number in init pidns. 2185826d7bc9SKonstantin Khorenko */ 2186826d7bc9SKonstantin Khorenko if (ns == &init_pid_ns) 21874ca52f53SJeff Layton return (pid_t) fl->c.flc_pid; 21889d5b86acSBenjamin Coddington 21899d5b86acSBenjamin Coddington rcu_read_lock(); 21904ca52f53SJeff Layton pid = find_pid_ns(fl->c.flc_pid, &init_pid_ns); 21919d5b86acSBenjamin Coddington vnr = pid_nr_ns(pid, ns); 21929d5b86acSBenjamin Coddington rcu_read_unlock(); 21939d5b86acSBenjamin Coddington return vnr; 21949d5b86acSBenjamin Coddington } 21959d5b86acSBenjamin Coddington 2196c2fa1b8aSJ. Bruce Fields static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) 2197c2fa1b8aSJ. Bruce Fields { 21989d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 2199c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2200c2fa1b8aSJ. Bruce Fields /* 2201c2fa1b8aSJ. Bruce Fields * Make sure we can represent the posix lock via 2202c2fa1b8aSJ. Bruce Fields * legacy 32bit flock. 2203c2fa1b8aSJ. Bruce Fields */ 2204c2fa1b8aSJ. Bruce Fields if (fl->fl_start > OFFT_OFFSET_MAX) 2205c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2206c2fa1b8aSJ. Bruce Fields if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX) 2207c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2208c2fa1b8aSJ. Bruce Fields #endif 2209c2fa1b8aSJ. Bruce Fields flock->l_start = fl->fl_start; 2210c2fa1b8aSJ. Bruce Fields flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2211c2fa1b8aSJ. Bruce Fields fl->fl_end - fl->fl_start + 1; 2212c2fa1b8aSJ. Bruce Fields flock->l_whence = 0; 22134ca52f53SJeff Layton flock->l_type = fl->c.flc_type; 2214c2fa1b8aSJ. Bruce Fields return 0; 2215c2fa1b8aSJ. Bruce Fields } 2216c2fa1b8aSJ. Bruce Fields 2217c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2218c2fa1b8aSJ. Bruce Fields static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) 2219c2fa1b8aSJ. Bruce Fields { 22209d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 2221c2fa1b8aSJ. Bruce Fields flock->l_start = fl->fl_start; 2222c2fa1b8aSJ. Bruce Fields flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2223c2fa1b8aSJ. Bruce Fields fl->fl_end - fl->fl_start + 1; 2224c2fa1b8aSJ. Bruce Fields flock->l_whence = 0; 22254ca52f53SJeff Layton flock->l_type = fl->c.flc_type; 2226c2fa1b8aSJ. Bruce Fields } 2227c2fa1b8aSJ. Bruce Fields #endif 2228c2fa1b8aSJ. Bruce Fields 22291da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 22301da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 22311da177e4SLinus Torvalds */ 2232a75d30c7SChristoph Hellwig int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) 22331da177e4SLinus Torvalds { 223452306e88SBenjamin Coddington struct file_lock *fl; 22351da177e4SLinus Torvalds int error; 22361da177e4SLinus Torvalds 223752306e88SBenjamin Coddington fl = locks_alloc_lock(); 223852306e88SBenjamin Coddington if (fl == NULL) 223952306e88SBenjamin Coddington return -ENOMEM; 22401da177e4SLinus Torvalds error = -EINVAL; 22416c9007f6SStas Sergeev if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK 22426c9007f6SStas Sergeev && flock->l_type != F_WRLCK) 22431da177e4SLinus Torvalds goto out; 22441da177e4SLinus Torvalds 224552306e88SBenjamin Coddington error = flock_to_posix_lock(filp, fl, flock); 22461da177e4SLinus Torvalds if (error) 22471da177e4SLinus Torvalds goto out; 22481da177e4SLinus Torvalds 22490d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 225090478939SJeff Layton error = -EINVAL; 2251a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 225290478939SJeff Layton goto out; 225390478939SJeff Layton 22544ca52f53SJeff Layton fl->c.flc_flags |= FL_OFDLCK; 22554ca52f53SJeff Layton fl->c.flc_owner = filp; 22565d50ffd7SJeff Layton } 22575d50ffd7SJeff Layton 225852306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 22593ee17abdSJ. Bruce Fields if (error) 22601da177e4SLinus Torvalds goto out; 22611da177e4SLinus Torvalds 22624ca52f53SJeff Layton flock->l_type = fl->c.flc_type; 22634ca52f53SJeff Layton if (fl->c.flc_type != F_UNLCK) { 226452306e88SBenjamin Coddington error = posix_lock_to_flock(flock, fl); 2265c2fa1b8aSJ. Bruce Fields if (error) 226652306e88SBenjamin Coddington goto out; 22671da177e4SLinus Torvalds } 22681da177e4SLinus Torvalds out: 226952306e88SBenjamin Coddington locks_free_lock(fl); 22701da177e4SLinus Torvalds return error; 22711da177e4SLinus Torvalds } 22721da177e4SLinus Torvalds 22737723ec97SMarc Eshel /** 22747723ec97SMarc Eshel * vfs_lock_file - file byte range lock 22757723ec97SMarc Eshel * @filp: The file to apply the lock to 22767723ec97SMarc Eshel * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.) 22777723ec97SMarc Eshel * @fl: The lock to be applied 2278150b3934SMarc Eshel * @conf: Place to return a copy of the conflicting lock, if found. 2279150b3934SMarc Eshel * 2280150b3934SMarc Eshel * A caller that doesn't care about the conflicting lock may pass NULL 2281150b3934SMarc Eshel * as the final argument. 2282150b3934SMarc Eshel * 2283150b3934SMarc Eshel * If the filesystem defines a private ->lock() method, then @conf will 2284150b3934SMarc Eshel * be left unchanged; so a caller that cares should initialize it to 2285150b3934SMarc Eshel * some acceptable default. 22862beb6614SMarc Eshel * 22872beb6614SMarc Eshel * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX 22882beb6614SMarc Eshel * locks, the ->lock() interface may return asynchronously, before the lock has 22892beb6614SMarc Eshel * been granted or denied by the underlying filesystem, if (and only if) 2290e70da176SAlexander Aring * lm_grant is set. Additionally EXPORT_OP_ASYNC_LOCK in export_operations 2291e70da176SAlexander Aring * flags need to be set. 2292e70da176SAlexander Aring * 2293e70da176SAlexander Aring * Callers expecting ->lock() to return asynchronously will only use F_SETLK, 2294e70da176SAlexander Aring * not F_SETLKW; they will set FL_SLEEP if (and only if) the request is for a 2295e70da176SAlexander Aring * blocking lock. When ->lock() does return asynchronously, it must return 2296e70da176SAlexander Aring * FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock request completes. 22972beb6614SMarc Eshel * If the request is for non-blocking lock the file system should return 2298bde74e4bSMiklos Szeredi * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine 2299bde74e4bSMiklos Szeredi * with the result. If the request timed out the callback routine will return a 23002beb6614SMarc Eshel * nonzero return code and the file system should release the lock. The file 23012beb6614SMarc Eshel * system is also responsible to keep a corresponding posix lock when it 23022beb6614SMarc Eshel * grants a lock so the VFS can find out which locks are locally held and do 23032beb6614SMarc Eshel * the correct lock cleanup when required. 23042beb6614SMarc Eshel * The underlying filesystem must not drop the kernel lock or call 23058fb47a4fSJ. Bruce Fields * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED 23062beb6614SMarc Eshel * return code. 23077723ec97SMarc Eshel */ 2308150b3934SMarc Eshel int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) 23097723ec97SMarc Eshel { 23104ca52f53SJeff Layton WARN_ON_ONCE(filp != fl->c.flc_file); 2311de2a4a50SMiklos Szeredi if (filp->f_op->lock) 23127723ec97SMarc Eshel return filp->f_op->lock(filp, cmd, fl); 23137723ec97SMarc Eshel else 2314150b3934SMarc Eshel return posix_lock_file(filp, fl, conf); 23157723ec97SMarc Eshel } 23167723ec97SMarc Eshel EXPORT_SYMBOL_GPL(vfs_lock_file); 23177723ec97SMarc Eshel 2318b648a6deSMiklos Szeredi static int do_lock_file_wait(struct file *filp, unsigned int cmd, 2319b648a6deSMiklos Szeredi struct file_lock *fl) 2320b648a6deSMiklos Szeredi { 2321b648a6deSMiklos Szeredi int error; 2322b648a6deSMiklos Szeredi 23234ca52f53SJeff Layton error = security_file_lock(filp, fl->c.flc_type); 2324b648a6deSMiklos Szeredi if (error) 2325b648a6deSMiklos Szeredi return error; 2326b648a6deSMiklos Szeredi 2327b648a6deSMiklos Szeredi for (;;) { 2328764c76b3SMiklos Szeredi error = vfs_lock_file(filp, cmd, fl, NULL); 2329b648a6deSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 2330b648a6deSMiklos Szeredi break; 23314ca52f53SJeff Layton error = wait_event_interruptible(fl->c.flc_wait, 23324ca52f53SJeff Layton list_empty(&fl->c.flc_blocked_member)); 233316306a61SNeilBrown if (error) 2334b648a6deSMiklos Szeredi break; 2335b648a6deSMiklos Szeredi } 233616306a61SNeilBrown locks_delete_block(fl); 2337b648a6deSMiklos Szeredi 2338b648a6deSMiklos Szeredi return error; 2339b648a6deSMiklos Szeredi } 2340b648a6deSMiklos Szeredi 23416ca7d910SBenjamin Coddington /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */ 2342cf01f4eeSJeff Layton static int 2343cf01f4eeSJeff Layton check_fmode_for_setlk(struct file_lock *fl) 2344cf01f4eeSJeff Layton { 23454ca52f53SJeff Layton switch (fl->c.flc_type) { 2346cf01f4eeSJeff Layton case F_RDLCK: 23474ca52f53SJeff Layton if (!(fl->c.flc_file->f_mode & FMODE_READ)) 2348cf01f4eeSJeff Layton return -EBADF; 2349cf01f4eeSJeff Layton break; 2350cf01f4eeSJeff Layton case F_WRLCK: 23514ca52f53SJeff Layton if (!(fl->c.flc_file->f_mode & FMODE_WRITE)) 2352cf01f4eeSJeff Layton return -EBADF; 2353cf01f4eeSJeff Layton } 2354cf01f4eeSJeff Layton return 0; 2355cf01f4eeSJeff Layton } 2356cf01f4eeSJeff Layton 23571da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 23581da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 23591da177e4SLinus Torvalds */ 2360c293621bSPeter Staubach int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, 2361a75d30c7SChristoph Hellwig struct flock *flock) 23621da177e4SLinus Torvalds { 23631da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 2364c65454a9SJeff Layton struct inode *inode = file_inode(filp); 23650b2bac2fSAl Viro struct file *f; 23661da177e4SLinus Torvalds int error; 23671da177e4SLinus Torvalds 23681da177e4SLinus Torvalds if (file_lock == NULL) 23691da177e4SLinus Torvalds return -ENOLCK; 23701da177e4SLinus Torvalds 2371a75d30c7SChristoph Hellwig error = flock_to_posix_lock(filp, file_lock, flock); 23721da177e4SLinus Torvalds if (error) 23731da177e4SLinus Torvalds goto out; 23745d50ffd7SJeff Layton 2375cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2376cf01f4eeSJeff Layton if (error) 2377cf01f4eeSJeff Layton goto out; 2378cf01f4eeSJeff Layton 23795d50ffd7SJeff Layton /* 23805d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2381cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 23825d50ffd7SJeff Layton */ 23835d50ffd7SJeff Layton switch (cmd) { 23840d3f7a2dSJeff Layton case F_OFD_SETLK: 238590478939SJeff Layton error = -EINVAL; 2386a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 238790478939SJeff Layton goto out; 238890478939SJeff Layton 23895d50ffd7SJeff Layton cmd = F_SETLK; 23904ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 23914ca52f53SJeff Layton file_lock->c.flc_owner = filp; 23925d50ffd7SJeff Layton break; 23930d3f7a2dSJeff Layton case F_OFD_SETLKW: 239490478939SJeff Layton error = -EINVAL; 2395a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 239690478939SJeff Layton goto out; 239790478939SJeff Layton 23985d50ffd7SJeff Layton cmd = F_SETLKW; 23994ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 24004ca52f53SJeff Layton file_lock->c.flc_owner = filp; 2401df561f66SGustavo A. R. Silva fallthrough; 24025d50ffd7SJeff Layton case F_SETLKW: 24034ca52f53SJeff Layton file_lock->c.flc_flags |= FL_SLEEP; 24041da177e4SLinus Torvalds } 24051da177e4SLinus Torvalds 2406b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2407c293621bSPeter Staubach 2408c293621bSPeter Staubach /* 24090752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 24100752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 24110752ba80SJeff Layton * unlocking though, or for OFD locks. 2412c293621bSPeter Staubach */ 24134ca52f53SJeff Layton if (!error && file_lock->c.flc_type != F_UNLCK && 24144ca52f53SJeff Layton !(file_lock->c.flc_flags & FL_OFDLCK)) { 2415120ce2b0SEric W. Biederman struct files_struct *files = current->files; 24160b2bac2fSAl Viro /* 24177f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 24187f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 24197f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 24200b2bac2fSAl Viro */ 2421120ce2b0SEric W. Biederman spin_lock(&files->file_lock); 2422120ce2b0SEric W. Biederman f = files_lookup_fd_locked(files, fd); 2423120ce2b0SEric W. Biederman spin_unlock(&files->file_lock); 24247f3697e2SJeff Layton if (f != filp) { 24254ca52f53SJeff Layton file_lock->c.flc_type = F_UNLCK; 24267f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 24277f3697e2SJeff Layton WARN_ON_ONCE(error); 24287f3697e2SJeff Layton error = -EBADF; 2429c293621bSPeter Staubach } 24307f3697e2SJeff Layton } 24311da177e4SLinus Torvalds out: 24321890910fSJeff Layton trace_fcntl_setlk(inode, file_lock, error); 24331da177e4SLinus Torvalds locks_free_lock(file_lock); 24341da177e4SLinus Torvalds return error; 24351da177e4SLinus Torvalds } 24361da177e4SLinus Torvalds 24371da177e4SLinus Torvalds #if BITS_PER_LONG == 32 24381da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 24391da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 24401da177e4SLinus Torvalds */ 2441a75d30c7SChristoph Hellwig int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) 24421da177e4SLinus Torvalds { 244352306e88SBenjamin Coddington struct file_lock *fl; 24441da177e4SLinus Torvalds int error; 24451da177e4SLinus Torvalds 244652306e88SBenjamin Coddington fl = locks_alloc_lock(); 244752306e88SBenjamin Coddington if (fl == NULL) 244852306e88SBenjamin Coddington return -ENOMEM; 244952306e88SBenjamin Coddington 24501da177e4SLinus Torvalds error = -EINVAL; 24516c9007f6SStas Sergeev if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK 24526c9007f6SStas Sergeev && flock->l_type != F_WRLCK) 24531da177e4SLinus Torvalds goto out; 24541da177e4SLinus Torvalds 245552306e88SBenjamin Coddington error = flock64_to_posix_lock(filp, fl, flock); 24561da177e4SLinus Torvalds if (error) 24571da177e4SLinus Torvalds goto out; 24581da177e4SLinus Torvalds 24590d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 246090478939SJeff Layton error = -EINVAL; 2461a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 246290478939SJeff Layton goto out; 246390478939SJeff Layton 24644ca52f53SJeff Layton fl->c.flc_flags |= FL_OFDLCK; 24654ca52f53SJeff Layton fl->c.flc_owner = filp; 24665d50ffd7SJeff Layton } 24675d50ffd7SJeff Layton 246852306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 24693ee17abdSJ. Bruce Fields if (error) 24701da177e4SLinus Torvalds goto out; 24711da177e4SLinus Torvalds 24724ca52f53SJeff Layton flock->l_type = fl->c.flc_type; 24734ca52f53SJeff Layton if (fl->c.flc_type != F_UNLCK) 247452306e88SBenjamin Coddington posix_lock_to_flock64(flock, fl); 24751da177e4SLinus Torvalds 24761da177e4SLinus Torvalds out: 247752306e88SBenjamin Coddington locks_free_lock(fl); 24781da177e4SLinus Torvalds return error; 24791da177e4SLinus Torvalds } 24801da177e4SLinus Torvalds 24811da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 24821da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 24831da177e4SLinus Torvalds */ 2484c293621bSPeter Staubach int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, 2485a75d30c7SChristoph Hellwig struct flock64 *flock) 24861da177e4SLinus Torvalds { 24871da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 24880b2bac2fSAl Viro struct file *f; 24891da177e4SLinus Torvalds int error; 24901da177e4SLinus Torvalds 24911da177e4SLinus Torvalds if (file_lock == NULL) 24921da177e4SLinus Torvalds return -ENOLCK; 24931da177e4SLinus Torvalds 2494a75d30c7SChristoph Hellwig error = flock64_to_posix_lock(filp, file_lock, flock); 24951da177e4SLinus Torvalds if (error) 24961da177e4SLinus Torvalds goto out; 24975d50ffd7SJeff Layton 2498cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2499cf01f4eeSJeff Layton if (error) 2500cf01f4eeSJeff Layton goto out; 2501cf01f4eeSJeff Layton 25025d50ffd7SJeff Layton /* 25035d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2504cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 25055d50ffd7SJeff Layton */ 25065d50ffd7SJeff Layton switch (cmd) { 25070d3f7a2dSJeff Layton case F_OFD_SETLK: 250890478939SJeff Layton error = -EINVAL; 2509a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 251090478939SJeff Layton goto out; 251190478939SJeff Layton 25125d50ffd7SJeff Layton cmd = F_SETLK64; 25134ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 25144ca52f53SJeff Layton file_lock->c.flc_owner = filp; 25155d50ffd7SJeff Layton break; 25160d3f7a2dSJeff Layton case F_OFD_SETLKW: 251790478939SJeff Layton error = -EINVAL; 2518a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 251990478939SJeff Layton goto out; 252090478939SJeff Layton 25215d50ffd7SJeff Layton cmd = F_SETLKW64; 25224ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 25234ca52f53SJeff Layton file_lock->c.flc_owner = filp; 2524df561f66SGustavo A. R. Silva fallthrough; 25255d50ffd7SJeff Layton case F_SETLKW64: 25264ca52f53SJeff Layton file_lock->c.flc_flags |= FL_SLEEP; 25271da177e4SLinus Torvalds } 25281da177e4SLinus Torvalds 2529b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2530c293621bSPeter Staubach 2531c293621bSPeter Staubach /* 25320752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 25330752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 25340752ba80SJeff Layton * unlocking though, or for OFD locks. 2535c293621bSPeter Staubach */ 25364ca52f53SJeff Layton if (!error && file_lock->c.flc_type != F_UNLCK && 25374ca52f53SJeff Layton !(file_lock->c.flc_flags & FL_OFDLCK)) { 2538120ce2b0SEric W. Biederman struct files_struct *files = current->files; 25397f3697e2SJeff Layton /* 25407f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 25417f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 25427f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 25437f3697e2SJeff Layton */ 2544120ce2b0SEric W. Biederman spin_lock(&files->file_lock); 2545120ce2b0SEric W. Biederman f = files_lookup_fd_locked(files, fd); 2546120ce2b0SEric W. Biederman spin_unlock(&files->file_lock); 25477f3697e2SJeff Layton if (f != filp) { 25484ca52f53SJeff Layton file_lock->c.flc_type = F_UNLCK; 25497f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 25507f3697e2SJeff Layton WARN_ON_ONCE(error); 25517f3697e2SJeff Layton error = -EBADF; 2552c293621bSPeter Staubach } 25537f3697e2SJeff Layton } 25541da177e4SLinus Torvalds out: 25551da177e4SLinus Torvalds locks_free_lock(file_lock); 25561da177e4SLinus Torvalds return error; 25571da177e4SLinus Torvalds } 25581da177e4SLinus Torvalds #endif /* BITS_PER_LONG == 32 */ 25591da177e4SLinus Torvalds 25601da177e4SLinus Torvalds /* 25611da177e4SLinus Torvalds * This function is called when the file is being removed 25621da177e4SLinus Torvalds * from the task's fd array. POSIX locks belonging to this task 25631da177e4SLinus Torvalds * are deleted at this time. 25641da177e4SLinus Torvalds */ 25651da177e4SLinus Torvalds void locks_remove_posix(struct file *filp, fl_owner_t owner) 25661da177e4SLinus Torvalds { 25671890910fSJeff Layton int error; 2568c65454a9SJeff Layton struct inode *inode = file_inode(filp); 2569ff7b86b8SMiklos Szeredi struct file_lock lock; 2570128a3785SDmitry Vyukov struct file_lock_context *ctx; 25711da177e4SLinus Torvalds 25721da177e4SLinus Torvalds /* 25731da177e4SLinus Torvalds * If there are no locks held on this file, we don't need to call 25741da177e4SLinus Torvalds * posix_lock_file(). Another process could be setting a lock on this 25751da177e4SLinus Torvalds * file at the same time, but we wouldn't remove that lock anyway. 25761da177e4SLinus Torvalds */ 2577401a8b8fSJeff Layton ctx = locks_inode_context(inode); 2578bd61e0a9SJeff Layton if (!ctx || list_empty(&ctx->flc_posix)) 25791da177e4SLinus Torvalds return; 25801da177e4SLinus Torvalds 2581d6367d62SNeilBrown locks_init_lock(&lock); 25824ca52f53SJeff Layton lock.c.flc_type = F_UNLCK; 25834ca52f53SJeff Layton lock.c.flc_flags = FL_POSIX | FL_CLOSE; 25841da177e4SLinus Torvalds lock.fl_start = 0; 25851da177e4SLinus Torvalds lock.fl_end = OFFSET_MAX; 25864ca52f53SJeff Layton lock.c.flc_owner = owner; 25874ca52f53SJeff Layton lock.c.flc_pid = current->tgid; 25884ca52f53SJeff Layton lock.c.flc_file = filp; 25891da177e4SLinus Torvalds lock.fl_ops = NULL; 25901da177e4SLinus Torvalds lock.fl_lmops = NULL; 25911da177e4SLinus Torvalds 25921890910fSJeff Layton error = vfs_lock_file(filp, F_SETLK, &lock, NULL); 25931da177e4SLinus Torvalds 25941da177e4SLinus Torvalds if (lock.fl_ops && lock.fl_ops->fl_release_private) 25951da177e4SLinus Torvalds lock.fl_ops->fl_release_private(&lock); 2596c568d683SMiklos Szeredi trace_locks_remove_posix(inode, &lock, error); 25971da177e4SLinus Torvalds } 25981da177e4SLinus Torvalds EXPORT_SYMBOL(locks_remove_posix); 25991da177e4SLinus Torvalds 26003d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 2601dd459bb1SJeff Layton static void 2602128a3785SDmitry Vyukov locks_remove_flock(struct file *filp, struct file_lock_context *flctx) 2603dd459bb1SJeff Layton { 2604d6367d62SNeilBrown struct file_lock fl; 2605c65454a9SJeff Layton struct inode *inode = file_inode(filp); 2606dd459bb1SJeff Layton 26073d8e560dSJeff Layton if (list_empty(&flctx->flc_flock)) 2608dd459bb1SJeff Layton return; 2609dd459bb1SJeff Layton 26104149be7bSKuniyuki Iwashima flock_make_lock(filp, &fl, F_UNLCK); 26114ca52f53SJeff Layton fl.c.flc_flags |= FL_CLOSE; 2612d6367d62SNeilBrown 2613de2a4a50SMiklos Szeredi if (filp->f_op->flock) 2614dd459bb1SJeff Layton filp->f_op->flock(filp, F_SETLKW, &fl); 2615dd459bb1SJeff Layton else 2616bcd7f78dSJeff Layton flock_lock_inode(inode, &fl); 2617dd459bb1SJeff Layton 2618dd459bb1SJeff Layton if (fl.fl_ops && fl.fl_ops->fl_release_private) 2619dd459bb1SJeff Layton fl.fl_ops->fl_release_private(&fl); 2620dd459bb1SJeff Layton } 2621dd459bb1SJeff Layton 26223d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 26238634b51fSJeff Layton static void 2624128a3785SDmitry Vyukov locks_remove_lease(struct file *filp, struct file_lock_context *ctx) 26258634b51fSJeff Layton { 26268634b51fSJeff Layton struct file_lock *fl, *tmp; 26278634b51fSJeff Layton LIST_HEAD(dispose); 26288634b51fSJeff Layton 26293d8e560dSJeff Layton if (list_empty(&ctx->flc_lease)) 26308634b51fSJeff Layton return; 26318634b51fSJeff Layton 263202e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 26336109c850SJeff Layton spin_lock(&ctx->flc_lock); 26344ca52f53SJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) 26354ca52f53SJeff Layton if (filp == fl->c.flc_file) 26367448cc37SJeff Layton lease_modify(fl, F_UNLCK, &dispose); 26376109c850SJeff Layton spin_unlock(&ctx->flc_lock); 263802e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 26395f43086bSPeter Zijlstra 26408634b51fSJeff Layton locks_dispose_list(&dispose); 26418634b51fSJeff Layton } 26428634b51fSJeff Layton 26431da177e4SLinus Torvalds /* 26441da177e4SLinus Torvalds * This function is called on the last close of an open file. 26451da177e4SLinus Torvalds */ 264678ed8a13SJeff Layton void locks_remove_file(struct file *filp) 26471da177e4SLinus Torvalds { 2648128a3785SDmitry Vyukov struct file_lock_context *ctx; 2649128a3785SDmitry Vyukov 2650c65454a9SJeff Layton ctx = locks_inode_context(file_inode(filp)); 2651128a3785SDmitry Vyukov if (!ctx) 26523d8e560dSJeff Layton return; 26533d8e560dSJeff Layton 2654dd459bb1SJeff Layton /* remove any OFD locks */ 265573a8f5f7SChristoph Hellwig locks_remove_posix(filp, filp); 26565d50ffd7SJeff Layton 2657dd459bb1SJeff Layton /* remove flock locks */ 2658128a3785SDmitry Vyukov locks_remove_flock(filp, ctx); 2659dd459bb1SJeff Layton 26608634b51fSJeff Layton /* remove any leases */ 2661128a3785SDmitry Vyukov locks_remove_lease(filp, ctx); 26623953704fSBenjamin Coddington 26633953704fSBenjamin Coddington spin_lock(&ctx->flc_lock); 26643953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX"); 26653953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK"); 26663953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE"); 26673953704fSBenjamin Coddington spin_unlock(&ctx->flc_lock); 26681da177e4SLinus Torvalds } 26691da177e4SLinus Torvalds 26701da177e4SLinus Torvalds /** 26719b9d2ab4SMarc Eshel * vfs_cancel_lock - file byte range unblock lock 26729b9d2ab4SMarc Eshel * @filp: The file to apply the unblock to 26739b9d2ab4SMarc Eshel * @fl: The lock to be unblocked 26749b9d2ab4SMarc Eshel * 26759b9d2ab4SMarc Eshel * Used by lock managers to cancel blocked requests 26769b9d2ab4SMarc Eshel */ 26779b9d2ab4SMarc Eshel int vfs_cancel_lock(struct file *filp, struct file_lock *fl) 26789b9d2ab4SMarc Eshel { 26794ca52f53SJeff Layton WARN_ON_ONCE(filp != fl->c.flc_file); 2680de2a4a50SMiklos Szeredi if (filp->f_op->lock) 26819b9d2ab4SMarc Eshel return filp->f_op->lock(filp, F_CANCELLK, fl); 26829b9d2ab4SMarc Eshel return 0; 26839b9d2ab4SMarc Eshel } 26849b9d2ab4SMarc Eshel EXPORT_SYMBOL_GPL(vfs_cancel_lock); 26859b9d2ab4SMarc Eshel 2686ab1ddef9SJeff Layton /** 2687ab1ddef9SJeff Layton * vfs_inode_has_locks - are any file locks held on @inode? 2688ab1ddef9SJeff Layton * @inode: inode to check for locks 2689ab1ddef9SJeff Layton * 2690ab1ddef9SJeff Layton * Return true if there are any FL_POSIX or FL_FLOCK locks currently 2691ab1ddef9SJeff Layton * set on @inode. 2692ab1ddef9SJeff Layton */ 2693ab1ddef9SJeff Layton bool vfs_inode_has_locks(struct inode *inode) 2694ab1ddef9SJeff Layton { 2695ab1ddef9SJeff Layton struct file_lock_context *ctx; 2696ab1ddef9SJeff Layton bool ret; 2697ab1ddef9SJeff Layton 2698401a8b8fSJeff Layton ctx = locks_inode_context(inode); 2699ab1ddef9SJeff Layton if (!ctx) 2700ab1ddef9SJeff Layton return false; 2701ab1ddef9SJeff Layton 2702ab1ddef9SJeff Layton spin_lock(&ctx->flc_lock); 2703ab1ddef9SJeff Layton ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock); 2704ab1ddef9SJeff Layton spin_unlock(&ctx->flc_lock); 2705ab1ddef9SJeff Layton return ret; 2706ab1ddef9SJeff Layton } 2707ab1ddef9SJeff Layton EXPORT_SYMBOL_GPL(vfs_inode_has_locks); 2708ab1ddef9SJeff Layton 27097f8ada98SPavel Emelyanov #ifdef CONFIG_PROC_FS 2710d8ba7a36SAlexey Dobriyan #include <linux/proc_fs.h> 27117f8ada98SPavel Emelyanov #include <linux/seq_file.h> 27127f8ada98SPavel Emelyanov 27137012b02aSJeff Layton struct locks_iterator { 27147012b02aSJeff Layton int li_cpu; 27157012b02aSJeff Layton loff_t li_pos; 27167012b02aSJeff Layton }; 27177012b02aSJeff Layton 27187f8ada98SPavel Emelyanov static void lock_get_status(struct seq_file *f, struct file_lock *fl, 2719b8da9b10SLuo Longjun loff_t id, char *pfx, int repeat) 27201da177e4SLinus Torvalds { 27211da177e4SLinus Torvalds struct inode *inode = NULL; 27226021d62cSJeff Layton unsigned int pid; 27239d78edeaSAlexey Gladkov struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb); 27244ca52f53SJeff Layton int type = fl->c.flc_type; 2725d67fd44fSNikolay Borisov 27266021d62cSJeff Layton pid = locks_translate_pid(fl, proc_pidns); 2727d67fd44fSNikolay Borisov /* 27281cf8e5deSKonstantin Khorenko * If lock owner is dead (and pid is freed) or not visible in current 27291cf8e5deSKonstantin Khorenko * pidns, zero is shown as a pid value. Check lock info from 27301cf8e5deSKonstantin Khorenko * init_pid_ns to get saved lock pid value. 2731d67fd44fSNikolay Borisov */ 27321da177e4SLinus Torvalds 27334ca52f53SJeff Layton if (fl->c.flc_file != NULL) 27344ca52f53SJeff Layton inode = file_inode(fl->c.flc_file); 27351da177e4SLinus Torvalds 2736b8da9b10SLuo Longjun seq_printf(f, "%lld: ", id); 2737b8da9b10SLuo Longjun 2738b8da9b10SLuo Longjun if (repeat) 2739b8da9b10SLuo Longjun seq_printf(f, "%*s", repeat - 1 + (int)strlen(pfx), pfx); 2740b8da9b10SLuo Longjun 27414ca52f53SJeff Layton if (fl->c.flc_flags & FL_POSIX) { 27424ca52f53SJeff Layton if (fl->c.flc_flags & FL_ACCESS) 27435315c26aSFabian Frederick seq_puts(f, "ACCESS"); 27444ca52f53SJeff Layton else if (fl->c.flc_flags & FL_OFDLCK) 27455315c26aSFabian Frederick seq_puts(f, "OFDLCK"); 2746c918d42aSJeff Layton else 27475315c26aSFabian Frederick seq_puts(f, "POSIX "); 2748c918d42aSJeff Layton 2749c918d42aSJeff Layton seq_printf(f, " %s ", 2750f7e33bdbSJeff Layton (inode == NULL) ? "*NOINODE*" : "ADVISORY "); 27514ca52f53SJeff Layton } else if (fl->c.flc_flags & FL_FLOCK) { 27525315c26aSFabian Frederick seq_puts(f, "FLOCK ADVISORY "); 27534ca52f53SJeff Layton } else if (fl->c.flc_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) { 27543d40f781SJeff Layton type = target_leasetype(fl); 27553d40f781SJeff Layton 27564ca52f53SJeff Layton if (fl->c.flc_flags & FL_DELEG) 27578144f1f6SJeff Layton seq_puts(f, "DELEG "); 27588144f1f6SJeff Layton else 27595315c26aSFabian Frederick seq_puts(f, "LEASE "); 27608144f1f6SJeff Layton 2761ab83fa4bSJ. Bruce Fields if (lease_breaking(fl)) 27625315c26aSFabian Frederick seq_puts(f, "BREAKING "); 27634ca52f53SJeff Layton else if (fl->c.flc_file) 27645315c26aSFabian Frederick seq_puts(f, "ACTIVE "); 27651da177e4SLinus Torvalds else 27665315c26aSFabian Frederick seq_puts(f, "BREAKER "); 27671da177e4SLinus Torvalds } else { 27685315c26aSFabian Frederick seq_puts(f, "UNKNOWN UNKNOWN "); 27691da177e4SLinus Torvalds } 277043e4cb94SPavel Begunkov 277143e4cb94SPavel Begunkov seq_printf(f, "%s ", (type == F_WRLCK) ? "WRITE" : 277243e4cb94SPavel Begunkov (type == F_RDLCK) ? "READ" : "UNLCK"); 27731da177e4SLinus Torvalds if (inode) { 27743648888eSJeff Layton /* userspace relies on this representation of dev_t */ 27756021d62cSJeff Layton seq_printf(f, "%d %02x:%02x:%lu ", pid, 27761da177e4SLinus Torvalds MAJOR(inode->i_sb->s_dev), 27771da177e4SLinus Torvalds MINOR(inode->i_sb->s_dev), inode->i_ino); 27781da177e4SLinus Torvalds } else { 27796021d62cSJeff Layton seq_printf(f, "%d <none>:0 ", pid); 27801da177e4SLinus Torvalds } 27814ca52f53SJeff Layton if (fl->c.flc_flags & FL_POSIX) { 27821da177e4SLinus Torvalds if (fl->fl_end == OFFSET_MAX) 27837f8ada98SPavel Emelyanov seq_printf(f, "%Ld EOF\n", fl->fl_start); 27841da177e4SLinus Torvalds else 27857f8ada98SPavel Emelyanov seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end); 27861da177e4SLinus Torvalds } else { 27875315c26aSFabian Frederick seq_puts(f, "0 EOF\n"); 27881da177e4SLinus Torvalds } 27891da177e4SLinus Torvalds } 27901da177e4SLinus Torvalds 2791b8da9b10SLuo Longjun static struct file_lock *get_next_blocked_member(struct file_lock *node) 2792b8da9b10SLuo Longjun { 2793b8da9b10SLuo Longjun struct file_lock *tmp; 2794b8da9b10SLuo Longjun 2795b8da9b10SLuo Longjun /* NULL node or root node */ 27964ca52f53SJeff Layton if (node == NULL || node->c.flc_blocker == NULL) 2797b8da9b10SLuo Longjun return NULL; 2798b8da9b10SLuo Longjun 2799b8da9b10SLuo Longjun /* Next member in the linked list could be itself */ 28004ca52f53SJeff Layton tmp = list_next_entry(node, c.flc_blocked_member); 2801*b6aaba5bSJeff Layton if (list_entry_is_head(tmp, &node->c.flc_blocker->flc_blocked_requests, 28024ca52f53SJeff Layton c.flc_blocked_member) 2803b8da9b10SLuo Longjun || tmp == node) { 2804b8da9b10SLuo Longjun return NULL; 2805b8da9b10SLuo Longjun } 2806b8da9b10SLuo Longjun 2807b8da9b10SLuo Longjun return tmp; 2808b8da9b10SLuo Longjun } 2809b8da9b10SLuo Longjun 28107f8ada98SPavel Emelyanov static int locks_show(struct seq_file *f, void *v) 28111da177e4SLinus Torvalds { 28127012b02aSJeff Layton struct locks_iterator *iter = f->private; 2813b8da9b10SLuo Longjun struct file_lock *cur, *tmp; 28149d78edeaSAlexey Gladkov struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb); 2815b8da9b10SLuo Longjun int level = 0; 28167f8ada98SPavel Emelyanov 28174ca52f53SJeff Layton cur = hlist_entry(v, struct file_lock, c.flc_link); 28187f8ada98SPavel Emelyanov 2819b8da9b10SLuo Longjun if (locks_translate_pid(cur, proc_pidns) == 0) 2820d67fd44fSNikolay Borisov return 0; 2821d67fd44fSNikolay Borisov 2822b8da9b10SLuo Longjun /* View this crossed linked list as a binary tree, the first member of fl_blocked_requests 28234ca52f53SJeff Layton * is the left child of current node, the next silibing in flc_blocked_member is the 2824b8da9b10SLuo Longjun * right child, we can alse get the parent of current node from fl_blocker, so this 2825b8da9b10SLuo Longjun * question becomes traversal of a binary tree 2826b8da9b10SLuo Longjun */ 2827b8da9b10SLuo Longjun while (cur != NULL) { 2828b8da9b10SLuo Longjun if (level) 2829b8da9b10SLuo Longjun lock_get_status(f, cur, iter->li_pos, "-> ", level); 2830b8da9b10SLuo Longjun else 2831b8da9b10SLuo Longjun lock_get_status(f, cur, iter->li_pos, "", level); 28327f8ada98SPavel Emelyanov 28334ca52f53SJeff Layton if (!list_empty(&cur->c.flc_blocked_requests)) { 2834b8da9b10SLuo Longjun /* Turn left */ 28354ca52f53SJeff Layton cur = list_first_entry_or_null(&cur->c.flc_blocked_requests, 28364ca52f53SJeff Layton struct file_lock, 28374ca52f53SJeff Layton c.flc_blocked_member); 2838b8da9b10SLuo Longjun level++; 2839b8da9b10SLuo Longjun } else { 2840b8da9b10SLuo Longjun /* Turn right */ 2841b8da9b10SLuo Longjun tmp = get_next_blocked_member(cur); 2842b8da9b10SLuo Longjun /* Fall back to parent node */ 28434ca52f53SJeff Layton while (tmp == NULL && cur->c.flc_blocker != NULL) { 2844*b6aaba5bSJeff Layton cur = file_lock(cur->c.flc_blocker); 2845b8da9b10SLuo Longjun level--; 2846b8da9b10SLuo Longjun tmp = get_next_blocked_member(cur); 2847b8da9b10SLuo Longjun } 2848b8da9b10SLuo Longjun cur = tmp; 2849b8da9b10SLuo Longjun } 2850b8da9b10SLuo Longjun } 28517f8ada98SPavel Emelyanov 28527f8ada98SPavel Emelyanov return 0; 28531da177e4SLinus Torvalds } 28541da177e4SLinus Torvalds 28556c8c9031SAndrey Vagin static void __show_fd_locks(struct seq_file *f, 28566c8c9031SAndrey Vagin struct list_head *head, int *id, 28576c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 28586c8c9031SAndrey Vagin { 28596c8c9031SAndrey Vagin struct file_lock *fl; 28606c8c9031SAndrey Vagin 28614ca52f53SJeff Layton list_for_each_entry(fl, head, c.flc_list) { 28626c8c9031SAndrey Vagin 28634ca52f53SJeff Layton if (filp != fl->c.flc_file) 28646c8c9031SAndrey Vagin continue; 28654ca52f53SJeff Layton if (fl->c.flc_owner != files && 28664ca52f53SJeff Layton fl->c.flc_owner != filp) 28676c8c9031SAndrey Vagin continue; 28686c8c9031SAndrey Vagin 28696c8c9031SAndrey Vagin (*id)++; 28706c8c9031SAndrey Vagin seq_puts(f, "lock:\t"); 2871b8da9b10SLuo Longjun lock_get_status(f, fl, *id, "", 0); 28726c8c9031SAndrey Vagin } 28736c8c9031SAndrey Vagin } 28746c8c9031SAndrey Vagin 28756c8c9031SAndrey Vagin void show_fd_locks(struct seq_file *f, 28766c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 28776c8c9031SAndrey Vagin { 2878c65454a9SJeff Layton struct inode *inode = file_inode(filp); 28796c8c9031SAndrey Vagin struct file_lock_context *ctx; 28806c8c9031SAndrey Vagin int id = 0; 28816c8c9031SAndrey Vagin 2882401a8b8fSJeff Layton ctx = locks_inode_context(inode); 28836c8c9031SAndrey Vagin if (!ctx) 28846c8c9031SAndrey Vagin return; 28856c8c9031SAndrey Vagin 28866c8c9031SAndrey Vagin spin_lock(&ctx->flc_lock); 28876c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_flock, &id, filp, files); 28886c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_posix, &id, filp, files); 28896c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_lease, &id, filp, files); 28906c8c9031SAndrey Vagin spin_unlock(&ctx->flc_lock); 28916c8c9031SAndrey Vagin } 28926c8c9031SAndrey Vagin 28937f8ada98SPavel Emelyanov static void *locks_start(struct seq_file *f, loff_t *pos) 2894b03dfdecSJeff Layton __acquires(&blocked_lock_lock) 28951da177e4SLinus Torvalds { 28967012b02aSJeff Layton struct locks_iterator *iter = f->private; 289799dc8292SJerome Marchand 28987012b02aSJeff Layton iter->li_pos = *pos + 1; 2899aba37660SPeter Zijlstra percpu_down_write(&file_rwsem); 29007b2296afSJeff Layton spin_lock(&blocked_lock_lock); 29017c3f654dSPeter Zijlstra return seq_hlist_start_percpu(&file_lock_list.hlist, &iter->li_cpu, *pos); 29021da177e4SLinus Torvalds } 29037f8ada98SPavel Emelyanov 29047f8ada98SPavel Emelyanov static void *locks_next(struct seq_file *f, void *v, loff_t *pos) 29057f8ada98SPavel Emelyanov { 29067012b02aSJeff Layton struct locks_iterator *iter = f->private; 29077012b02aSJeff Layton 29087012b02aSJeff Layton ++iter->li_pos; 29097c3f654dSPeter Zijlstra return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos); 29101da177e4SLinus Torvalds } 29117f8ada98SPavel Emelyanov 29127f8ada98SPavel Emelyanov static void locks_stop(struct seq_file *f, void *v) 2913b03dfdecSJeff Layton __releases(&blocked_lock_lock) 29147f8ada98SPavel Emelyanov { 29157b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 2916aba37660SPeter Zijlstra percpu_up_write(&file_rwsem); 29171da177e4SLinus Torvalds } 29181da177e4SLinus Torvalds 2919d8ba7a36SAlexey Dobriyan static const struct seq_operations locks_seq_operations = { 29207f8ada98SPavel Emelyanov .start = locks_start, 29217f8ada98SPavel Emelyanov .next = locks_next, 29227f8ada98SPavel Emelyanov .stop = locks_stop, 29237f8ada98SPavel Emelyanov .show = locks_show, 29247f8ada98SPavel Emelyanov }; 2925d8ba7a36SAlexey Dobriyan 2926d8ba7a36SAlexey Dobriyan static int __init proc_locks_init(void) 2927d8ba7a36SAlexey Dobriyan { 292844414d82SChristoph Hellwig proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, 292944414d82SChristoph Hellwig sizeof(struct locks_iterator), NULL); 2930d8ba7a36SAlexey Dobriyan return 0; 2931d8ba7a36SAlexey Dobriyan } 293291899226SPaul Gortmaker fs_initcall(proc_locks_init); 29337f8ada98SPavel Emelyanov #endif 29347f8ada98SPavel Emelyanov 29351da177e4SLinus Torvalds static int __init filelock_init(void) 29361da177e4SLinus Torvalds { 29377012b02aSJeff Layton int i; 29387012b02aSJeff Layton 29394a075e39SJeff Layton flctx_cache = kmem_cache_create("file_lock_ctx", 29403754707bSLinus Torvalds sizeof(struct file_lock_context), 0, SLAB_PANIC, NULL); 29414a075e39SJeff Layton 29421da177e4SLinus Torvalds filelock_cache = kmem_cache_create("file_lock_cache", 29433754707bSLinus Torvalds sizeof(struct file_lock), 0, SLAB_PANIC, NULL); 2944ee19cc40SMiklos Szeredi 29457c3f654dSPeter Zijlstra for_each_possible_cpu(i) { 29467c3f654dSPeter Zijlstra struct file_lock_list_struct *fll = per_cpu_ptr(&file_lock_list, i); 29477c3f654dSPeter Zijlstra 29487c3f654dSPeter Zijlstra spin_lock_init(&fll->lock); 29497c3f654dSPeter Zijlstra INIT_HLIST_HEAD(&fll->hlist); 29507c3f654dSPeter Zijlstra } 29517012b02aSJeff Layton 295218f6622eSJeff Layton lease_notifier_chain_init(); 29531da177e4SLinus Torvalds return 0; 29541da177e4SLinus Torvalds } 29551da177e4SLinus Torvalds core_initcall(filelock_init); 2956