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 72*1a62c22aSJeff Layton static struct file_lock *file_lock(struct file_lock_core *flc) 73*1a62c22aSJeff Layton { 74*1a62c22aSJeff Layton return container_of(flc, struct file_lock, c); 75*1a62c22aSJeff Layton } 76*1a62c22aSJeff 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 4035946c431SNeilBrown * ->fl_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) 4134ca52f53SJeff Layton f->c.flc_blocker = new; 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 */ 662*1a62c22aSJeff Layton static void __locks_delete_block(struct file_lock_core *waiter) 6631da177e4SLinus Torvalds { 664*1a62c22aSJeff Layton locks_delete_global_blocked(waiter); 665*1a62c22aSJeff Layton list_del_init(&waiter->flc_blocked_member); 6661da177e4SLinus Torvalds } 6671da177e4SLinus Torvalds 668*1a62c22aSJeff Layton static void __locks_wake_up_blocks(struct file_lock_core *blocker) 669ad6bbd8bSNeilBrown { 670*1a62c22aSJeff Layton while (!list_empty(&blocker->flc_blocked_requests)) { 671*1a62c22aSJeff Layton struct file_lock_core *waiter; 672*1a62c22aSJeff Layton struct file_lock *fl; 673ad6bbd8bSNeilBrown 674*1a62c22aSJeff Layton waiter = list_first_entry(&blocker->flc_blocked_requests, 675*1a62c22aSJeff Layton struct file_lock_core, flc_blocked_member); 676*1a62c22aSJeff Layton 677*1a62c22aSJeff Layton fl = file_lock(waiter); 678ad6bbd8bSNeilBrown __locks_delete_block(waiter); 679*1a62c22aSJeff Layton if ((waiter->flc_flags & (FL_POSIX | FL_FLOCK)) && 680*1a62c22aSJeff Layton fl->fl_lmops && fl->fl_lmops->lm_notify) 681*1a62c22aSJeff Layton fl->fl_lmops->lm_notify(fl); 682ad6bbd8bSNeilBrown else 683*1a62c22aSJeff Layton locks_wake_up(fl); 684dcf23ac3SLinus Torvalds 685dcf23ac3SLinus Torvalds /* 686*1a62c22aSJeff 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 */ 690*1a62c22aSJeff 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; 732*1a62c22aSJeff Layton __locks_wake_up_blocks(&waiter->c); 733*1a62c22aSJeff 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 */ 7601c8c601aSJeff Layton static void __locks_insert_block(struct file_lock *blocker, 761fd7732e0SNeilBrown struct file_lock *waiter, 762fd7732e0SNeilBrown bool conflict(struct file_lock *, 763fd7732e0SNeilBrown struct file_lock *)) 7641da177e4SLinus Torvalds { 765fd7732e0SNeilBrown struct file_lock *fl; 7664ca52f53SJeff Layton BUG_ON(!list_empty(&waiter->c.flc_blocked_member)); 767fd7732e0SNeilBrown 768fd7732e0SNeilBrown new_blocker: 7694ca52f53SJeff Layton list_for_each_entry(fl, &blocker->c.flc_blocked_requests, 7704ca52f53SJeff Layton c.flc_blocked_member) 771fd7732e0SNeilBrown if (conflict(fl, waiter)) { 772fd7732e0SNeilBrown blocker = fl; 773fd7732e0SNeilBrown goto new_blocker; 774fd7732e0SNeilBrown } 7754ca52f53SJeff Layton waiter->c.flc_blocker = blocker; 7764ca52f53SJeff Layton list_add_tail(&waiter->c.flc_blocked_member, 7774ca52f53SJeff Layton &blocker->c.flc_blocked_requests); 7784ca52f53SJeff Layton if ((blocker->c.flc_flags & (FL_POSIX|FL_OFDLCK)) == FL_POSIX) 7791a6c75d4SJeff Layton locks_insert_global_blocked(&waiter->c); 7805946c431SNeilBrown 7815946c431SNeilBrown /* The requests in waiter->fl_blocked are known to conflict with 7825946c431SNeilBrown * waiter, but might not conflict with blocker, or the requests 7835946c431SNeilBrown * and lock which block it. So they all need to be woken. 7845946c431SNeilBrown */ 785*1a62c22aSJeff Layton __locks_wake_up_blocks(&waiter->c); 7861c8c601aSJeff Layton } 7871c8c601aSJeff Layton 7886109c850SJeff Layton /* Must be called with flc_lock held. */ 7891c8c601aSJeff Layton static void locks_insert_block(struct file_lock *blocker, 790fd7732e0SNeilBrown struct file_lock *waiter, 791fd7732e0SNeilBrown bool conflict(struct file_lock *, 792fd7732e0SNeilBrown struct file_lock *)) 7931c8c601aSJeff Layton { 7947b2296afSJeff Layton spin_lock(&blocked_lock_lock); 795fd7732e0SNeilBrown __locks_insert_block(blocker, waiter, conflict); 7967b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 7971da177e4SLinus Torvalds } 7981da177e4SLinus Torvalds 7991cb36012SJeff Layton /* 8001cb36012SJeff Layton * Wake up processes blocked waiting for blocker. 8011cb36012SJeff Layton * 8026109c850SJeff Layton * Must be called with the inode->flc_lock held! 8031da177e4SLinus Torvalds */ 8041da177e4SLinus Torvalds static void locks_wake_up_blocks(struct file_lock *blocker) 8051da177e4SLinus Torvalds { 8064e8c765dSJeff Layton /* 8074e8c765dSJeff Layton * Avoid taking global lock if list is empty. This is safe since new 8086109c850SJeff Layton * blocked requests are only added to the list under the flc_lock, and 809ada5c1daSNeilBrown * the flc_lock is always held here. Note that removal from the 810ada5c1daSNeilBrown * fl_blocked_requests list does not require the flc_lock, so we must 811ada5c1daSNeilBrown * recheck list_empty() after acquiring the blocked_lock_lock. 8124e8c765dSJeff Layton */ 8134ca52f53SJeff Layton if (list_empty(&blocker->c.flc_blocked_requests)) 8144e8c765dSJeff Layton return; 8154e8c765dSJeff Layton 8167b2296afSJeff Layton spin_lock(&blocked_lock_lock); 817*1a62c22aSJeff Layton __locks_wake_up_blocks(&blocker->c); 8187b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 8191da177e4SLinus Torvalds } 8201da177e4SLinus Torvalds 8215263e31eSJeff Layton static void 822e084c1bdSJeff Layton locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) 8235263e31eSJeff Layton { 8244ca52f53SJeff Layton list_add_tail(&fl->c.flc_list, before); 8254629172fSJeff Layton locks_insert_global_locks(&fl->c); 8265263e31eSJeff Layton } 8275263e31eSJeff Layton 8288634b51fSJeff Layton static void 829e084c1bdSJeff Layton locks_unlink_lock_ctx(struct file_lock *fl) 8301da177e4SLinus Torvalds { 8314629172fSJeff Layton locks_delete_global_locks(&fl->c); 8324ca52f53SJeff Layton list_del_init(&fl->c.flc_list); 8331da177e4SLinus Torvalds locks_wake_up_blocks(fl); 83424cbe784SJeff Layton } 83524cbe784SJeff Layton 8365263e31eSJeff Layton static void 837e084c1bdSJeff Layton locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose) 8385263e31eSJeff Layton { 839e084c1bdSJeff Layton locks_unlink_lock_ctx(fl); 8408634b51fSJeff Layton if (dispose) 8414ca52f53SJeff Layton list_add(&fl->c.flc_list, dispose); 8428634b51fSJeff Layton else 8438634b51fSJeff Layton locks_free_lock(fl); 8445263e31eSJeff Layton } 8455263e31eSJeff Layton 8461da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. Common functionality 8471da177e4SLinus Torvalds * checks for shared/exclusive status of overlapping locks. 8481da177e4SLinus Torvalds */ 849c0e15908SNeilBrown static bool locks_conflict(struct file_lock *caller_fl, 850c0e15908SNeilBrown struct file_lock *sys_fl) 8511da177e4SLinus Torvalds { 85275cabec0SJeff Layton if (lock_is_write(sys_fl)) 853c0e15908SNeilBrown return true; 85475cabec0SJeff Layton if (lock_is_write(caller_fl)) 855c0e15908SNeilBrown return true; 856c0e15908SNeilBrown return false; 8571da177e4SLinus Torvalds } 8581da177e4SLinus Torvalds 8591da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. POSIX specific 8601da177e4SLinus Torvalds * checking before calling the locks_conflict(). 8611da177e4SLinus Torvalds */ 862c0e15908SNeilBrown static bool posix_locks_conflict(struct file_lock *caller_fl, 863c0e15908SNeilBrown struct file_lock *sys_fl) 8641da177e4SLinus Torvalds { 8651da177e4SLinus Torvalds /* POSIX locks owned by the same process do not conflict with 8661da177e4SLinus Torvalds * each other. 8671da177e4SLinus Torvalds */ 8689bb430a8SJeff Layton if (posix_same_owner(&caller_fl->c, &sys_fl->c)) 869c0e15908SNeilBrown return false; 8701da177e4SLinus Torvalds 8711da177e4SLinus Torvalds /* Check whether they overlap */ 8721da177e4SLinus Torvalds if (!locks_overlap(caller_fl, sys_fl)) 873c0e15908SNeilBrown return false; 8741da177e4SLinus Torvalds 875c0e15908SNeilBrown return locks_conflict(caller_fl, sys_fl); 8761da177e4SLinus Torvalds } 8771da177e4SLinus Torvalds 8786c9007f6SStas Sergeev /* Determine if lock sys_fl blocks lock caller_fl. Used on xx_GETLK 8796c9007f6SStas Sergeev * path so checks for additional GETLK-specific things like F_UNLCK. 8806c9007f6SStas Sergeev */ 8816c9007f6SStas Sergeev static bool posix_test_locks_conflict(struct file_lock *caller_fl, 8826c9007f6SStas Sergeev struct file_lock *sys_fl) 8836c9007f6SStas Sergeev { 8846c9007f6SStas Sergeev /* F_UNLCK checks any locks on the same fd. */ 88575cabec0SJeff Layton if (lock_is_unlock(caller_fl)) { 8869bb430a8SJeff Layton if (!posix_same_owner(&caller_fl->c, &sys_fl->c)) 8876c9007f6SStas Sergeev return false; 8886c9007f6SStas Sergeev return locks_overlap(caller_fl, sys_fl); 8896c9007f6SStas Sergeev } 8906c9007f6SStas Sergeev return posix_locks_conflict(caller_fl, sys_fl); 8916c9007f6SStas Sergeev } 8926c9007f6SStas Sergeev 8931da177e4SLinus Torvalds /* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific 8941da177e4SLinus Torvalds * checking before calling the locks_conflict(). 8951da177e4SLinus Torvalds */ 896c0e15908SNeilBrown static bool flock_locks_conflict(struct file_lock *caller_fl, 897c0e15908SNeilBrown struct file_lock *sys_fl) 8981da177e4SLinus Torvalds { 8991da177e4SLinus Torvalds /* FLOCK locks referring to the same filp do not conflict with 9001da177e4SLinus Torvalds * each other. 9011da177e4SLinus Torvalds */ 9024ca52f53SJeff Layton if (caller_fl->c.flc_file == sys_fl->c.flc_file) 903c0e15908SNeilBrown return false; 9041da177e4SLinus Torvalds 905c0e15908SNeilBrown return locks_conflict(caller_fl, sys_fl); 9061da177e4SLinus Torvalds } 9071da177e4SLinus Torvalds 9086d34ac19SJ. Bruce Fields void 9099d6a8c5cSMarc Eshel posix_test_lock(struct file *filp, struct file_lock *fl) 9101da177e4SLinus Torvalds { 9111da177e4SLinus Torvalds struct file_lock *cfl; 912bd61e0a9SJeff Layton struct file_lock_context *ctx; 913c65454a9SJeff Layton struct inode *inode = file_inode(filp); 9142443da22SDai Ngo void *owner; 9152443da22SDai Ngo void (*func)(void); 9161da177e4SLinus Torvalds 917401a8b8fSJeff Layton ctx = locks_inode_context(inode); 918bd61e0a9SJeff Layton if (!ctx || list_empty_careful(&ctx->flc_posix)) { 9194ca52f53SJeff Layton fl->c.flc_type = F_UNLCK; 920bd61e0a9SJeff Layton return; 9211da177e4SLinus Torvalds } 922bd61e0a9SJeff Layton 9232443da22SDai Ngo retry: 9246109c850SJeff Layton spin_lock(&ctx->flc_lock); 9254ca52f53SJeff Layton list_for_each_entry(cfl, &ctx->flc_posix, c.flc_list) { 9266c9007f6SStas Sergeev if (!posix_test_locks_conflict(fl, cfl)) 9272443da22SDai Ngo continue; 9282443da22SDai Ngo if (cfl->fl_lmops && cfl->fl_lmops->lm_lock_expirable 9292443da22SDai Ngo && (*cfl->fl_lmops->lm_lock_expirable)(cfl)) { 9302443da22SDai Ngo owner = cfl->fl_lmops->lm_mod_owner; 9312443da22SDai Ngo func = cfl->fl_lmops->lm_expire_lock; 9322443da22SDai Ngo __module_get(owner); 9332443da22SDai Ngo spin_unlock(&ctx->flc_lock); 9342443da22SDai Ngo (*func)(); 9352443da22SDai Ngo module_put(owner); 9362443da22SDai Ngo goto retry; 9372443da22SDai Ngo } 9383fe0fff1SKinglong Mee locks_copy_conflock(fl, cfl); 939bd61e0a9SJeff Layton goto out; 940bd61e0a9SJeff Layton } 9414ca52f53SJeff Layton fl->c.flc_type = F_UNLCK; 942bd61e0a9SJeff Layton out: 9436109c850SJeff Layton spin_unlock(&ctx->flc_lock); 9446d34ac19SJ. Bruce Fields return; 9451da177e4SLinus Torvalds } 9461da177e4SLinus Torvalds EXPORT_SYMBOL(posix_test_lock); 9471da177e4SLinus Torvalds 948b533184fSJ. Bruce Fields /* 949b533184fSJ. Bruce Fields * Deadlock detection: 9501da177e4SLinus Torvalds * 951b533184fSJ. Bruce Fields * We attempt to detect deadlocks that are due purely to posix file 952b533184fSJ. Bruce Fields * locks. 9531da177e4SLinus Torvalds * 954b533184fSJ. Bruce Fields * We assume that a task can be waiting for at most one lock at a time. 955b533184fSJ. Bruce Fields * So for any acquired lock, the process holding that lock may be 956b533184fSJ. Bruce Fields * waiting on at most one other lock. That lock in turns may be held by 957b533184fSJ. Bruce Fields * someone waiting for at most one other lock. Given a requested lock 958b533184fSJ. Bruce Fields * caller_fl which is about to wait for a conflicting lock block_fl, we 959b533184fSJ. Bruce Fields * follow this chain of waiters to ensure we are not about to create a 960b533184fSJ. Bruce Fields * cycle. 96197855b49SJ. Bruce Fields * 962b533184fSJ. Bruce Fields * Since we do this before we ever put a process to sleep on a lock, we 963b533184fSJ. Bruce Fields * are ensured that there is never a cycle; that is what guarantees that 964b533184fSJ. Bruce Fields * the while() loop in posix_locks_deadlock() eventually completes. 965b533184fSJ. Bruce Fields * 966b533184fSJ. Bruce Fields * Note: the above assumption may not be true when handling lock 967b533184fSJ. Bruce Fields * requests from a broken NFS client. It may also fail in the presence 968b533184fSJ. Bruce Fields * of tasks (such as posix threads) sharing the same open file table. 969b533184fSJ. Bruce Fields * To handle those cases, we just bail out after a few iterations. 97057b65325SJeff Layton * 971cff2fce5SJeff Layton * For FL_OFDLCK locks, the owner is the filp, not the files_struct. 97257b65325SJeff Layton * Because the owner is not even nominally tied to a thread of 97357b65325SJeff Layton * execution, the deadlock detection below can't reasonably work well. Just 97457b65325SJeff Layton * skip it for those. 97557b65325SJeff Layton * 976cff2fce5SJeff Layton * In principle, we could do a more limited deadlock detection on FL_OFDLCK 97757b65325SJeff Layton * locks that just checks for the case where two tasks are attempting to 97857b65325SJeff Layton * upgrade from read to write locks on the same inode. 9791da177e4SLinus Torvalds */ 98097855b49SJ. Bruce Fields 98197855b49SJ. Bruce Fields #define MAX_DEADLK_ITERATIONS 10 98297855b49SJ. Bruce Fields 983b533184fSJ. Bruce Fields /* Find a lock that the owner of the given block_fl is blocking on. */ 984b533184fSJ. Bruce Fields static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl) 985b533184fSJ. Bruce Fields { 986b533184fSJ. Bruce Fields struct file_lock *fl; 987b533184fSJ. Bruce Fields 988ad399740SJeff Layton hash_for_each_possible(blocked_hash, fl, c.flc_link, posix_owner_key(&block_fl->c)) { 9899bb430a8SJeff Layton if (posix_same_owner(&fl->c, &block_fl->c)) { 9904ca52f53SJeff Layton while (fl->c.flc_blocker) 9914ca52f53SJeff Layton fl = fl->c.flc_blocker; 9925946c431SNeilBrown return fl; 9935946c431SNeilBrown } 994b533184fSJ. Bruce Fields } 995b533184fSJ. Bruce Fields return NULL; 996b533184fSJ. Bruce Fields } 997b533184fSJ. Bruce Fields 9987b2296afSJeff Layton /* Must be called with the blocked_lock_lock held! */ 999b0904e14SAdrian Bunk static int posix_locks_deadlock(struct file_lock *caller_fl, 10001da177e4SLinus Torvalds struct file_lock *block_fl) 10011da177e4SLinus Torvalds { 100297855b49SJ. Bruce Fields int i = 0; 10031da177e4SLinus Torvalds 1004663d5af7SDaniel Wagner lockdep_assert_held(&blocked_lock_lock); 1005663d5af7SDaniel Wagner 100657b65325SJeff Layton /* 100757b65325SJeff Layton * This deadlock detector can't reasonably detect deadlocks with 1008cff2fce5SJeff Layton * FL_OFDLCK locks, since they aren't owned by a process, per-se. 100957b65325SJeff Layton */ 10104ca52f53SJeff Layton if (caller_fl->c.flc_flags & FL_OFDLCK) 101157b65325SJeff Layton return 0; 101257b65325SJeff Layton 1013b533184fSJ. Bruce Fields while ((block_fl = what_owner_is_waiting_for(block_fl))) { 101497855b49SJ. Bruce Fields if (i++ > MAX_DEADLK_ITERATIONS) 101597855b49SJ. Bruce Fields return 0; 10169bb430a8SJeff Layton if (posix_same_owner(&caller_fl->c, &block_fl->c)) 1017b533184fSJ. Bruce Fields return 1; 10181da177e4SLinus Torvalds } 10191da177e4SLinus Torvalds return 0; 10201da177e4SLinus Torvalds } 10211da177e4SLinus Torvalds 10221da177e4SLinus Torvalds /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 102302888f41SJ. Bruce Fields * after any leases, but before any posix locks. 1024f475ae95STrond Myklebust * 1025f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 1026f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 1027f475ae95STrond Myklebust * value for -ENOENT. 10281da177e4SLinus Torvalds */ 1029bcd7f78dSJeff Layton static int flock_lock_inode(struct inode *inode, struct file_lock *request) 10301da177e4SLinus Torvalds { 1031993dfa87STrond Myklebust struct file_lock *new_fl = NULL; 10325263e31eSJeff Layton struct file_lock *fl; 10335263e31eSJeff Layton struct file_lock_context *ctx; 10341da177e4SLinus Torvalds int error = 0; 10355263e31eSJeff Layton bool found = false; 1036ed9814d8SJeff Layton LIST_HEAD(dispose); 10371da177e4SLinus Torvalds 10384ca52f53SJeff Layton ctx = locks_get_lock_context(inode, request->c.flc_type); 10395c1c669aSJeff Layton if (!ctx) { 10404ca52f53SJeff Layton if (request->c.flc_type != F_UNLCK) 10415263e31eSJeff Layton return -ENOMEM; 10424ca52f53SJeff Layton return (request->c.flc_flags & FL_EXISTS) ? -ENOENT : 0; 10435c1c669aSJeff Layton } 10445263e31eSJeff Layton 10454ca52f53SJeff Layton if (!(request->c.flc_flags & FL_ACCESS) && (request->c.flc_type != F_UNLCK)) { 1046b89f4321SArnd Bergmann new_fl = locks_alloc_lock(); 1047b89f4321SArnd Bergmann if (!new_fl) 1048b89f4321SArnd Bergmann return -ENOMEM; 1049b89f4321SArnd Bergmann } 1050b89f4321SArnd Bergmann 105102e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 10526109c850SJeff Layton spin_lock(&ctx->flc_lock); 10534ca52f53SJeff Layton if (request->c.flc_flags & FL_ACCESS) 1054f07f18ddSTrond Myklebust goto find_conflict; 105584d535adSPavel Emelyanov 10564ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_flock, c.flc_list) { 10574ca52f53SJeff Layton if (request->c.flc_file != fl->c.flc_file) 10581da177e4SLinus Torvalds continue; 10594ca52f53SJeff Layton if (request->c.flc_type == fl->c.flc_type) 10601da177e4SLinus Torvalds goto out; 10615263e31eSJeff Layton found = true; 1062e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 10631da177e4SLinus Torvalds break; 10641da177e4SLinus Torvalds } 10651da177e4SLinus Torvalds 106675cabec0SJeff Layton if (lock_is_unlock(request)) { 10674ca52f53SJeff Layton if ((request->c.flc_flags & FL_EXISTS) && !found) 1068f475ae95STrond Myklebust error = -ENOENT; 1069993dfa87STrond Myklebust goto out; 1070f475ae95STrond Myklebust } 10711da177e4SLinus Torvalds 1072f07f18ddSTrond Myklebust find_conflict: 10734ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_flock, c.flc_list) { 1074993dfa87STrond Myklebust if (!flock_locks_conflict(request, fl)) 10751da177e4SLinus Torvalds continue; 10761da177e4SLinus Torvalds error = -EAGAIN; 10774ca52f53SJeff Layton if (!(request->c.flc_flags & FL_SLEEP)) 1078bde74e4bSMiklos Szeredi goto out; 1079bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 1080fd7732e0SNeilBrown locks_insert_block(fl, request, flock_locks_conflict); 10811da177e4SLinus Torvalds goto out; 10821da177e4SLinus Torvalds } 10834ca52f53SJeff Layton if (request->c.flc_flags & FL_ACCESS) 1084f07f18ddSTrond Myklebust goto out; 1085993dfa87STrond Myklebust locks_copy_lock(new_fl, request); 10865946c431SNeilBrown locks_move_blocks(new_fl, request); 1087e084c1bdSJeff Layton locks_insert_lock_ctx(new_fl, &ctx->flc_flock); 1088993dfa87STrond Myklebust new_fl = NULL; 10899cedc194SKirill Korotaev error = 0; 10901da177e4SLinus Torvalds 10911da177e4SLinus Torvalds out: 10926109c850SJeff Layton spin_unlock(&ctx->flc_lock); 109302e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1094993dfa87STrond Myklebust if (new_fl) 1095993dfa87STrond Myklebust locks_free_lock(new_fl); 1096ed9814d8SJeff Layton locks_dispose_list(&dispose); 1097c883da31SJeff Layton trace_flock_lock_inode(inode, request, error); 10981da177e4SLinus Torvalds return error; 10991da177e4SLinus Torvalds } 11001da177e4SLinus Torvalds 1101b4d629a3SJeff Layton static int posix_lock_inode(struct inode *inode, struct file_lock *request, 1102b4d629a3SJeff Layton struct file_lock *conflock) 11031da177e4SLinus Torvalds { 1104bd61e0a9SJeff Layton struct file_lock *fl, *tmp; 110539005d02SMiklos Szeredi struct file_lock *new_fl = NULL; 110639005d02SMiklos Szeredi struct file_lock *new_fl2 = NULL; 11071da177e4SLinus Torvalds struct file_lock *left = NULL; 11081da177e4SLinus Torvalds struct file_lock *right = NULL; 1109bd61e0a9SJeff Layton struct file_lock_context *ctx; 1110b9746ef8SJeff Layton int error; 1111b9746ef8SJeff Layton bool added = false; 1112ed9814d8SJeff Layton LIST_HEAD(dispose); 11132443da22SDai Ngo void *owner; 11142443da22SDai Ngo void (*func)(void); 11151da177e4SLinus Torvalds 11164ca52f53SJeff Layton ctx = locks_get_lock_context(inode, request->c.flc_type); 1117bd61e0a9SJeff Layton if (!ctx) 111875cabec0SJeff Layton return lock_is_unlock(request) ? 0 : -ENOMEM; 1119bd61e0a9SJeff Layton 11201da177e4SLinus Torvalds /* 11211da177e4SLinus Torvalds * We may need two file_lock structures for this operation, 11221da177e4SLinus Torvalds * so we get them in advance to avoid races. 112339005d02SMiklos Szeredi * 112439005d02SMiklos Szeredi * In some cases we can be sure, that no new locks will be needed 11251da177e4SLinus Torvalds */ 11264ca52f53SJeff Layton if (!(request->c.flc_flags & FL_ACCESS) && 11274ca52f53SJeff Layton (request->c.flc_type != F_UNLCK || 112839005d02SMiklos Szeredi request->fl_start != 0 || request->fl_end != OFFSET_MAX)) { 11291da177e4SLinus Torvalds new_fl = locks_alloc_lock(); 11301da177e4SLinus Torvalds new_fl2 = locks_alloc_lock(); 113139005d02SMiklos Szeredi } 11321da177e4SLinus Torvalds 11332443da22SDai Ngo retry: 113402e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 11356109c850SJeff Layton spin_lock(&ctx->flc_lock); 11361cb36012SJeff Layton /* 11371cb36012SJeff Layton * New lock request. Walk all POSIX locks and look for conflicts. If 11381cb36012SJeff Layton * there are any, either return error or put the request on the 113948f74186SJeff Layton * blocker's list of waiters and the global blocked_hash. 11401cb36012SJeff Layton */ 11414ca52f53SJeff Layton if (request->c.flc_type != F_UNLCK) { 11424ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, c.flc_list) { 11431da177e4SLinus Torvalds if (!posix_locks_conflict(request, fl)) 11441da177e4SLinus Torvalds continue; 11452443da22SDai Ngo if (fl->fl_lmops && fl->fl_lmops->lm_lock_expirable 11462443da22SDai Ngo && (*fl->fl_lmops->lm_lock_expirable)(fl)) { 11472443da22SDai Ngo owner = fl->fl_lmops->lm_mod_owner; 11482443da22SDai Ngo func = fl->fl_lmops->lm_expire_lock; 11492443da22SDai Ngo __module_get(owner); 11502443da22SDai Ngo spin_unlock(&ctx->flc_lock); 11512443da22SDai Ngo percpu_up_read(&file_rwsem); 11522443da22SDai Ngo (*func)(); 11532443da22SDai Ngo module_put(owner); 11542443da22SDai Ngo goto retry; 11552443da22SDai Ngo } 11565842add2SAndy Adamson if (conflock) 11573fe0fff1SKinglong Mee locks_copy_conflock(conflock, fl); 11581da177e4SLinus Torvalds error = -EAGAIN; 11594ca52f53SJeff Layton if (!(request->c.flc_flags & FL_SLEEP)) 11601da177e4SLinus Torvalds goto out; 11611c8c601aSJeff Layton /* 11621c8c601aSJeff Layton * Deadlock detection and insertion into the blocked 11631c8c601aSJeff Layton * locks list must be done while holding the same lock! 11641c8c601aSJeff Layton */ 11651da177e4SLinus Torvalds error = -EDEADLK; 11667b2296afSJeff Layton spin_lock(&blocked_lock_lock); 1167945ab8f6SJeff Layton /* 1168945ab8f6SJeff Layton * Ensure that we don't find any locks blocked on this 1169945ab8f6SJeff Layton * request during deadlock detection. 1170945ab8f6SJeff Layton */ 1171*1a62c22aSJeff Layton __locks_wake_up_blocks(&request->c); 11721c8c601aSJeff Layton if (likely(!posix_locks_deadlock(request, fl))) { 1173bde74e4bSMiklos Szeredi error = FILE_LOCK_DEFERRED; 1174fd7732e0SNeilBrown __locks_insert_block(fl, request, 1175fd7732e0SNeilBrown posix_locks_conflict); 11761c8c601aSJeff Layton } 11777b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 11781da177e4SLinus Torvalds goto out; 11791da177e4SLinus Torvalds } 11801da177e4SLinus Torvalds } 11811da177e4SLinus Torvalds 11821da177e4SLinus Torvalds /* If we're just looking for a conflict, we're done. */ 11831da177e4SLinus Torvalds error = 0; 11844ca52f53SJeff Layton if (request->c.flc_flags & FL_ACCESS) 11851da177e4SLinus Torvalds goto out; 11861da177e4SLinus Torvalds 1187bd61e0a9SJeff Layton /* Find the first old lock with the same owner as the new lock */ 11884ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_posix, c.flc_list) { 11899bb430a8SJeff Layton if (posix_same_owner(&request->c, &fl->c)) 1190bd61e0a9SJeff Layton break; 11911da177e4SLinus Torvalds } 11921da177e4SLinus Torvalds 11931da177e4SLinus Torvalds /* Process locks with this owner. */ 11944ca52f53SJeff Layton list_for_each_entry_safe_from(fl, tmp, &ctx->flc_posix, c.flc_list) { 11959bb430a8SJeff Layton if (!posix_same_owner(&request->c, &fl->c)) 1196bd61e0a9SJeff Layton break; 1197bd61e0a9SJeff Layton 1198bd61e0a9SJeff Layton /* Detect adjacent or overlapping regions (if same lock type) */ 11994ca52f53SJeff Layton if (request->c.flc_type == fl->c.flc_type) { 1200449231d6SOlaf Kirch /* In all comparisons of start vs end, use 1201449231d6SOlaf Kirch * "start - 1" rather than "end + 1". If end 1202449231d6SOlaf Kirch * is OFFSET_MAX, end + 1 will become negative. 1203449231d6SOlaf Kirch */ 12041da177e4SLinus Torvalds if (fl->fl_end < request->fl_start - 1) 1205bd61e0a9SJeff Layton continue; 12061da177e4SLinus Torvalds /* If the next lock in the list has entirely bigger 12071da177e4SLinus Torvalds * addresses than the new one, insert the lock here. 12081da177e4SLinus Torvalds */ 1209449231d6SOlaf Kirch if (fl->fl_start - 1 > request->fl_end) 12101da177e4SLinus Torvalds break; 12111da177e4SLinus Torvalds 12121da177e4SLinus Torvalds /* If we come here, the new and old lock are of the 12131da177e4SLinus Torvalds * same type and adjacent or overlapping. Make one 12141da177e4SLinus Torvalds * lock yielding from the lower start address of both 12151da177e4SLinus Torvalds * locks to the higher end address. 12161da177e4SLinus Torvalds */ 12171da177e4SLinus Torvalds if (fl->fl_start > request->fl_start) 12181da177e4SLinus Torvalds fl->fl_start = request->fl_start; 12191da177e4SLinus Torvalds else 12201da177e4SLinus Torvalds request->fl_start = fl->fl_start; 12211da177e4SLinus Torvalds if (fl->fl_end < request->fl_end) 12221da177e4SLinus Torvalds fl->fl_end = request->fl_end; 12231da177e4SLinus Torvalds else 12241da177e4SLinus Torvalds request->fl_end = fl->fl_end; 12251da177e4SLinus Torvalds if (added) { 1226e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 12271da177e4SLinus Torvalds continue; 12281da177e4SLinus Torvalds } 12291da177e4SLinus Torvalds request = fl; 1230b9746ef8SJeff Layton added = true; 1231bd61e0a9SJeff Layton } else { 12321da177e4SLinus Torvalds /* Processing for different lock types is a bit 12331da177e4SLinus Torvalds * more complex. 12341da177e4SLinus Torvalds */ 12351da177e4SLinus Torvalds if (fl->fl_end < request->fl_start) 1236bd61e0a9SJeff Layton continue; 12371da177e4SLinus Torvalds if (fl->fl_start > request->fl_end) 12381da177e4SLinus Torvalds break; 123975cabec0SJeff Layton if (lock_is_unlock(request)) 1240b9746ef8SJeff Layton added = true; 12411da177e4SLinus Torvalds if (fl->fl_start < request->fl_start) 12421da177e4SLinus Torvalds left = fl; 12431da177e4SLinus Torvalds /* If the next lock in the list has a higher end 12441da177e4SLinus Torvalds * address than the new one, insert the new one here. 12451da177e4SLinus Torvalds */ 12461da177e4SLinus Torvalds if (fl->fl_end > request->fl_end) { 12471da177e4SLinus Torvalds right = fl; 12481da177e4SLinus Torvalds break; 12491da177e4SLinus Torvalds } 12501da177e4SLinus Torvalds if (fl->fl_start >= request->fl_start) { 12511da177e4SLinus Torvalds /* The new lock completely replaces an old 12521da177e4SLinus Torvalds * one (This may happen several times). 12531da177e4SLinus Torvalds */ 12541da177e4SLinus Torvalds if (added) { 1255e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 12561da177e4SLinus Torvalds continue; 12571da177e4SLinus Torvalds } 1258b84d49f9SJeff Layton /* 1259b84d49f9SJeff Layton * Replace the old lock with new_fl, and 1260b84d49f9SJeff Layton * remove the old one. It's safe to do the 1261b84d49f9SJeff Layton * insert here since we know that we won't be 1262b84d49f9SJeff Layton * using new_fl later, and that the lock is 1263b84d49f9SJeff Layton * just replacing an existing lock. 12641da177e4SLinus Torvalds */ 1265b84d49f9SJeff Layton error = -ENOLCK; 1266b84d49f9SJeff Layton if (!new_fl) 1267b84d49f9SJeff Layton goto out; 1268b84d49f9SJeff Layton locks_copy_lock(new_fl, request); 12695ef15968Syangerkun locks_move_blocks(new_fl, request); 1270b84d49f9SJeff Layton request = new_fl; 1271b84d49f9SJeff Layton new_fl = NULL; 12724ca52f53SJeff Layton locks_insert_lock_ctx(request, 12734ca52f53SJeff Layton &fl->c.flc_list); 1274e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 1275b9746ef8SJeff Layton added = true; 12761da177e4SLinus Torvalds } 12771da177e4SLinus Torvalds } 12781da177e4SLinus Torvalds } 12791da177e4SLinus Torvalds 12800d9a490aSMiklos Szeredi /* 12811cb36012SJeff Layton * The above code only modifies existing locks in case of merging or 12821cb36012SJeff Layton * replacing. If new lock(s) need to be inserted all modifications are 12831cb36012SJeff Layton * done below this, so it's safe yet to bail out. 12840d9a490aSMiklos Szeredi */ 12850d9a490aSMiklos Szeredi error = -ENOLCK; /* "no luck" */ 12860d9a490aSMiklos Szeredi if (right && left == right && !new_fl2) 12870d9a490aSMiklos Szeredi goto out; 12880d9a490aSMiklos Szeredi 12891da177e4SLinus Torvalds error = 0; 12901da177e4SLinus Torvalds if (!added) { 129175cabec0SJeff Layton if (lock_is_unlock(request)) { 12924ca52f53SJeff Layton if (request->c.flc_flags & FL_EXISTS) 1293f475ae95STrond Myklebust error = -ENOENT; 12941da177e4SLinus Torvalds goto out; 1295f475ae95STrond Myklebust } 12960d9a490aSMiklos Szeredi 12970d9a490aSMiklos Szeredi if (!new_fl) { 12980d9a490aSMiklos Szeredi error = -ENOLCK; 12990d9a490aSMiklos Szeredi goto out; 13000d9a490aSMiklos Szeredi } 13011da177e4SLinus Torvalds locks_copy_lock(new_fl, request); 13025946c431SNeilBrown locks_move_blocks(new_fl, request); 13034ca52f53SJeff Layton locks_insert_lock_ctx(new_fl, &fl->c.flc_list); 13042e2f756fSJeff Layton fl = new_fl; 13051da177e4SLinus Torvalds new_fl = NULL; 13061da177e4SLinus Torvalds } 13071da177e4SLinus Torvalds if (right) { 13081da177e4SLinus Torvalds if (left == right) { 13091da177e4SLinus Torvalds /* The new lock breaks the old one in two pieces, 13101da177e4SLinus Torvalds * so we have to use the second new lock. 13111da177e4SLinus Torvalds */ 13121da177e4SLinus Torvalds left = new_fl2; 13131da177e4SLinus Torvalds new_fl2 = NULL; 13141da177e4SLinus Torvalds locks_copy_lock(left, right); 13154ca52f53SJeff Layton locks_insert_lock_ctx(left, &fl->c.flc_list); 13161da177e4SLinus Torvalds } 13171da177e4SLinus Torvalds right->fl_start = request->fl_end + 1; 13181da177e4SLinus Torvalds locks_wake_up_blocks(right); 13191da177e4SLinus Torvalds } 13201da177e4SLinus Torvalds if (left) { 13211da177e4SLinus Torvalds left->fl_end = request->fl_start - 1; 13221da177e4SLinus Torvalds locks_wake_up_blocks(left); 13231da177e4SLinus Torvalds } 13241da177e4SLinus Torvalds out: 13256109c850SJeff Layton spin_unlock(&ctx->flc_lock); 132602e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 132774f6f591SWill Shiu trace_posix_lock_inode(inode, request, error); 13281da177e4SLinus Torvalds /* 13291da177e4SLinus Torvalds * Free any unused locks. 13301da177e4SLinus Torvalds */ 13311da177e4SLinus Torvalds if (new_fl) 13321da177e4SLinus Torvalds locks_free_lock(new_fl); 13331da177e4SLinus Torvalds if (new_fl2) 13341da177e4SLinus Torvalds locks_free_lock(new_fl2); 1335ed9814d8SJeff Layton locks_dispose_list(&dispose); 13361890910fSJeff Layton 13371da177e4SLinus Torvalds return error; 13381da177e4SLinus Torvalds } 13391da177e4SLinus Torvalds 13401da177e4SLinus Torvalds /** 13411da177e4SLinus Torvalds * posix_lock_file - Apply a POSIX-style lock to a file 13421da177e4SLinus Torvalds * @filp: The file to apply the lock to 13431da177e4SLinus Torvalds * @fl: The lock to be applied 1344150b3934SMarc Eshel * @conflock: Place to return a copy of the conflicting lock, if found. 13451da177e4SLinus Torvalds * 13461da177e4SLinus Torvalds * Add a POSIX style lock to a file. 13471da177e4SLinus Torvalds * We merge adjacent & overlapping locks whenever possible. 13481da177e4SLinus Torvalds * POSIX locks are sorted by owner task, then by starting address 1349f475ae95STrond Myklebust * 1350f475ae95STrond Myklebust * Note that if called with an FL_EXISTS argument, the caller may determine 1351f475ae95STrond Myklebust * whether or not a lock was successfully freed by testing the return 1352f475ae95STrond Myklebust * value for -ENOENT. 13531da177e4SLinus Torvalds */ 1354150b3934SMarc Eshel int posix_lock_file(struct file *filp, struct file_lock *fl, 13555842add2SAndy Adamson struct file_lock *conflock) 13565842add2SAndy Adamson { 1357c65454a9SJeff Layton return posix_lock_inode(file_inode(filp), fl, conflock); 13585842add2SAndy Adamson } 1359150b3934SMarc Eshel EXPORT_SYMBOL(posix_lock_file); 13601da177e4SLinus Torvalds 13611da177e4SLinus Torvalds /** 136229d01b22SJeff Layton * posix_lock_inode_wait - Apply a POSIX-style lock to a file 136329d01b22SJeff Layton * @inode: inode of file to which lock request should be applied 13641da177e4SLinus Torvalds * @fl: The lock to be applied 13651da177e4SLinus Torvalds * 1366616fb38fSBenjamin Coddington * Apply a POSIX style lock request to an inode. 13671da177e4SLinus Torvalds */ 1368616fb38fSBenjamin Coddington static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) 13691da177e4SLinus Torvalds { 13701da177e4SLinus Torvalds int error; 13711da177e4SLinus Torvalds might_sleep (); 13721da177e4SLinus Torvalds for (;;) { 1373b4d629a3SJeff Layton error = posix_lock_inode(inode, fl, NULL); 1374bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 13751da177e4SLinus Torvalds break; 13764ca52f53SJeff Layton error = wait_event_interruptible(fl->c.flc_wait, 13774ca52f53SJeff Layton list_empty(&fl->c.flc_blocked_member)); 137816306a61SNeilBrown if (error) 13791da177e4SLinus Torvalds break; 13801da177e4SLinus Torvalds } 138116306a61SNeilBrown locks_delete_block(fl); 13821da177e4SLinus Torvalds return error; 13831da177e4SLinus Torvalds } 138429d01b22SJeff Layton 1385778fc546SJ. Bruce Fields static void lease_clear_pending(struct file_lock *fl, int arg) 1386778fc546SJ. Bruce Fields { 1387778fc546SJ. Bruce Fields switch (arg) { 1388778fc546SJ. Bruce Fields case F_UNLCK: 13894ca52f53SJeff Layton fl->c.flc_flags &= ~FL_UNLOCK_PENDING; 1390df561f66SGustavo A. R. Silva fallthrough; 1391778fc546SJ. Bruce Fields case F_RDLCK: 13924ca52f53SJeff Layton fl->c.flc_flags &= ~FL_DOWNGRADE_PENDING; 1393778fc546SJ. Bruce Fields } 1394778fc546SJ. Bruce Fields } 1395778fc546SJ. Bruce Fields 13961da177e4SLinus Torvalds /* We already had a lease on this file; just change its type */ 13977448cc37SJeff Layton int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose) 13981da177e4SLinus Torvalds { 13991da177e4SLinus Torvalds int error = assign_type(fl, arg); 14001da177e4SLinus Torvalds 14011da177e4SLinus Torvalds if (error) 14021da177e4SLinus Torvalds return error; 1403778fc546SJ. Bruce Fields lease_clear_pending(fl, arg); 14041da177e4SLinus Torvalds locks_wake_up_blocks(fl); 14053b6e2723SFilipe Brandenburger if (arg == F_UNLCK) { 14064ca52f53SJeff Layton struct file *filp = fl->c.flc_file; 14073b6e2723SFilipe Brandenburger 14083b6e2723SFilipe Brandenburger f_delown(filp); 14093b6e2723SFilipe Brandenburger filp->f_owner.signum = 0; 14104ca52f53SJeff Layton fasync_helper(0, fl->c.flc_file, 0, &fl->fl_fasync); 141196d6d59cSJ. Bruce Fields if (fl->fl_fasync != NULL) { 141296d6d59cSJ. Bruce Fields printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); 141396d6d59cSJ. Bruce Fields fl->fl_fasync = NULL; 141496d6d59cSJ. Bruce Fields } 1415e084c1bdSJeff Layton locks_delete_lock_ctx(fl, dispose); 14163b6e2723SFilipe Brandenburger } 14171da177e4SLinus Torvalds return 0; 14181da177e4SLinus Torvalds } 14191da177e4SLinus Torvalds EXPORT_SYMBOL(lease_modify); 14201da177e4SLinus Torvalds 1421778fc546SJ. Bruce Fields static bool past_time(unsigned long then) 1422778fc546SJ. Bruce Fields { 1423778fc546SJ. Bruce Fields if (!then) 1424778fc546SJ. Bruce Fields /* 0 is a special value meaning "this never expires": */ 1425778fc546SJ. Bruce Fields return false; 1426778fc546SJ. Bruce Fields return time_after(jiffies, then); 1427778fc546SJ. Bruce Fields } 1428778fc546SJ. Bruce Fields 1429c45198edSJeff Layton static void time_out_leases(struct inode *inode, struct list_head *dispose) 14301da177e4SLinus Torvalds { 14318634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 14328634b51fSJeff Layton struct file_lock *fl, *tmp; 14331da177e4SLinus Torvalds 14346109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 1435f82b4b67SJeff Layton 14364ca52f53SJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { 143762af4f1fSJeff Layton trace_time_out_leases(inode, fl); 1438778fc546SJ. Bruce Fields if (past_time(fl->fl_downgrade_time)) 14397448cc37SJeff Layton lease_modify(fl, F_RDLCK, dispose); 1440778fc546SJ. Bruce Fields if (past_time(fl->fl_break_time)) 14417448cc37SJeff Layton lease_modify(fl, F_UNLCK, dispose); 14421da177e4SLinus Torvalds } 14431da177e4SLinus Torvalds } 14441da177e4SLinus Torvalds 1445df4e8d2cSJ. Bruce Fields static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker) 1446df4e8d2cSJ. Bruce Fields { 1447d51f527fSIra Weiny bool rc; 1448d51f527fSIra Weiny 144928df3d15SJ. Bruce Fields if (lease->fl_lmops->lm_breaker_owns_lease 145028df3d15SJ. Bruce Fields && lease->fl_lmops->lm_breaker_owns_lease(lease)) 145128df3d15SJ. Bruce Fields return false; 14524ca52f53SJeff Layton if ((breaker->c.flc_flags & FL_LAYOUT) != (lease->c.flc_flags & FL_LAYOUT)) { 1453d51f527fSIra Weiny rc = false; 1454d51f527fSIra Weiny goto trace; 1455d51f527fSIra Weiny } 14564ca52f53SJeff Layton if ((breaker->c.flc_flags & FL_DELEG) && (lease->c.flc_flags & FL_LEASE)) { 1457d51f527fSIra Weiny rc = false; 1458d51f527fSIra Weiny goto trace; 1459d51f527fSIra Weiny } 1460d51f527fSIra Weiny 1461d51f527fSIra Weiny rc = locks_conflict(breaker, lease); 1462d51f527fSIra Weiny trace: 1463d51f527fSIra Weiny trace_leases_conflict(rc, lease, breaker); 1464d51f527fSIra Weiny return rc; 1465df4e8d2cSJ. Bruce Fields } 1466df4e8d2cSJ. Bruce Fields 146703d12ddfSJeff Layton static bool 146803d12ddfSJeff Layton any_leases_conflict(struct inode *inode, struct file_lock *breaker) 146903d12ddfSJeff Layton { 14708634b51fSJeff Layton struct file_lock_context *ctx = inode->i_flctx; 147103d12ddfSJeff Layton struct file_lock *fl; 147203d12ddfSJeff Layton 14736109c850SJeff Layton lockdep_assert_held(&ctx->flc_lock); 147403d12ddfSJeff Layton 14754ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { 147603d12ddfSJeff Layton if (leases_conflict(fl, breaker)) 147703d12ddfSJeff Layton return true; 147803d12ddfSJeff Layton } 147903d12ddfSJeff Layton return false; 148003d12ddfSJeff Layton } 148103d12ddfSJeff Layton 14821da177e4SLinus Torvalds /** 14831da177e4SLinus Torvalds * __break_lease - revoke all outstanding leases on file 14841da177e4SLinus Torvalds * @inode: the inode of the file to return 1485df4e8d2cSJ. Bruce Fields * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR: 1486df4e8d2cSJ. Bruce Fields * break all leases 1487df4e8d2cSJ. Bruce Fields * @type: FL_LEASE: break leases and delegations; FL_DELEG: break 1488df4e8d2cSJ. Bruce Fields * only delegations 14891da177e4SLinus Torvalds * 149087250dd2Sdavid m. richter * break_lease (inlined for speed) has checked there already is at least 149187250dd2Sdavid m. richter * some kind of lock (maybe a lease) on this file. Leases are broken on 149287250dd2Sdavid m. richter * a call to open() or truncate(). This function can sleep unless you 14931da177e4SLinus Torvalds * specified %O_NONBLOCK to your open(). 14941da177e4SLinus Torvalds */ 1495df4e8d2cSJ. Bruce Fields int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) 14961da177e4SLinus Torvalds { 1497778fc546SJ. Bruce Fields int error = 0; 1498128a3785SDmitry Vyukov struct file_lock_context *ctx; 1499a901125cSYan, Zheng struct file_lock *new_fl, *fl, *tmp; 15001da177e4SLinus Torvalds unsigned long break_time; 15018737c930SAl Viro int want_write = (mode & O_ACCMODE) != O_RDONLY; 1502c45198edSJeff Layton LIST_HEAD(dispose); 15031da177e4SLinus Torvalds 15048737c930SAl Viro new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); 15056d4b9e38SLinus Torvalds if (IS_ERR(new_fl)) 15066d4b9e38SLinus Torvalds return PTR_ERR(new_fl); 15074ca52f53SJeff Layton new_fl->c.flc_flags = type; 15081da177e4SLinus Torvalds 15098634b51fSJeff Layton /* typically we will check that ctx is non-NULL before calling */ 1510401a8b8fSJeff Layton ctx = locks_inode_context(inode); 15118634b51fSJeff Layton if (!ctx) { 15128634b51fSJeff Layton WARN_ON_ONCE(1); 1513cfddf9f4SWenwen Wang goto free_lock; 15148634b51fSJeff Layton } 15158634b51fSJeff Layton 151602e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 15176109c850SJeff Layton spin_lock(&ctx->flc_lock); 15181da177e4SLinus Torvalds 1519c45198edSJeff Layton time_out_leases(inode, &dispose); 15201da177e4SLinus Torvalds 152103d12ddfSJeff Layton if (!any_leases_conflict(inode, new_fl)) 1522df4e8d2cSJ. Bruce Fields goto out; 15231da177e4SLinus Torvalds 15241da177e4SLinus Torvalds break_time = 0; 15251da177e4SLinus Torvalds if (lease_break_time > 0) { 15261da177e4SLinus Torvalds break_time = jiffies + lease_break_time * HZ; 15271da177e4SLinus Torvalds if (break_time == 0) 15281da177e4SLinus Torvalds break_time++; /* so that 0 means no break time */ 15291da177e4SLinus Torvalds } 15301da177e4SLinus Torvalds 15314ca52f53SJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { 1532df4e8d2cSJ. Bruce Fields if (!leases_conflict(fl, new_fl)) 1533df4e8d2cSJ. Bruce Fields continue; 1534778fc546SJ. Bruce Fields if (want_write) { 15354ca52f53SJeff Layton if (fl->c.flc_flags & FL_UNLOCK_PENDING) 1536778fc546SJ. Bruce Fields continue; 15374ca52f53SJeff Layton fl->c.flc_flags |= FL_UNLOCK_PENDING; 15381da177e4SLinus Torvalds fl->fl_break_time = break_time; 1539778fc546SJ. Bruce Fields } else { 15408634b51fSJeff Layton if (lease_breaking(fl)) 1541778fc546SJ. Bruce Fields continue; 15424ca52f53SJeff Layton fl->c.flc_flags |= FL_DOWNGRADE_PENDING; 1543778fc546SJ. Bruce Fields fl->fl_downgrade_time = break_time; 15441da177e4SLinus Torvalds } 15454d01b7f5SJeff Layton if (fl->fl_lmops->lm_break(fl)) 1546e084c1bdSJeff Layton locks_delete_lock_ctx(fl, &dispose); 15471da177e4SLinus Torvalds } 15481da177e4SLinus Torvalds 15498634b51fSJeff Layton if (list_empty(&ctx->flc_lease)) 15504d01b7f5SJeff Layton goto out; 15514d01b7f5SJeff Layton 1552843c6b2fSJeff Layton if (mode & O_NONBLOCK) { 155362af4f1fSJeff Layton trace_break_lease_noblock(inode, new_fl); 15541da177e4SLinus Torvalds error = -EWOULDBLOCK; 15551da177e4SLinus Torvalds goto out; 15561da177e4SLinus Torvalds } 15571da177e4SLinus Torvalds 15581da177e4SLinus Torvalds restart: 15594ca52f53SJeff Layton fl = list_first_entry(&ctx->flc_lease, struct file_lock, c.flc_list); 15608634b51fSJeff Layton break_time = fl->fl_break_time; 1561f1c6bb2cSJeff Layton if (break_time != 0) 15621da177e4SLinus Torvalds break_time -= jiffies; 15631da177e4SLinus Torvalds if (break_time == 0) 15641da177e4SLinus Torvalds break_time++; 1565fd7732e0SNeilBrown locks_insert_block(fl, new_fl, leases_conflict); 156662af4f1fSJeff Layton trace_break_lease_block(inode, new_fl); 15676109c850SJeff Layton spin_unlock(&ctx->flc_lock); 156802e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1569aba37660SPeter Zijlstra 1570c45198edSJeff Layton locks_dispose_list(&dispose); 15714ca52f53SJeff Layton error = wait_event_interruptible_timeout(new_fl->c.flc_wait, 15724ca52f53SJeff Layton list_empty(&new_fl->c.flc_blocked_member), 1573dcf23ac3SLinus Torvalds break_time); 1574aba37660SPeter Zijlstra 157502e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 15766109c850SJeff Layton spin_lock(&ctx->flc_lock); 157762af4f1fSJeff Layton trace_break_lease_unblock(inode, new_fl); 15781c8c601aSJeff Layton locks_delete_block(new_fl); 15791da177e4SLinus Torvalds if (error >= 0) { 1580778fc546SJ. Bruce Fields /* 1581778fc546SJ. Bruce Fields * Wait for the next conflicting lease that has not been 1582778fc546SJ. Bruce Fields * broken yet 1583778fc546SJ. Bruce Fields */ 158403d12ddfSJeff Layton if (error == 0) 158503d12ddfSJeff Layton time_out_leases(inode, &dispose); 158603d12ddfSJeff Layton if (any_leases_conflict(inode, new_fl)) 15871da177e4SLinus Torvalds goto restart; 15881da177e4SLinus Torvalds error = 0; 15891da177e4SLinus Torvalds } 15901da177e4SLinus Torvalds out: 15916109c850SJeff Layton spin_unlock(&ctx->flc_lock); 159202e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1593c45198edSJeff Layton locks_dispose_list(&dispose); 1594cfddf9f4SWenwen Wang free_lock: 15951da177e4SLinus Torvalds locks_free_lock(new_fl); 15961da177e4SLinus Torvalds return error; 15971da177e4SLinus Torvalds } 15981da177e4SLinus Torvalds EXPORT_SYMBOL(__break_lease); 15991da177e4SLinus Torvalds 16001da177e4SLinus Torvalds /** 160176c47948SAmir Goldstein * lease_get_mtime - update modified time of an inode with exclusive lease 16021da177e4SLinus Torvalds * @inode: the inode 160376c47948SAmir Goldstein * @time: pointer to a timespec which contains the last modified time 16041da177e4SLinus Torvalds * 16051da177e4SLinus Torvalds * This is to force NFS clients to flush their caches for files with 16061da177e4SLinus Torvalds * exclusive leases. The justification is that if someone has an 1607a6b91919SRandy Dunlap * exclusive lease, then they could be modifying it. 16081da177e4SLinus Torvalds */ 160995582b00SDeepa Dinamani void lease_get_mtime(struct inode *inode, struct timespec64 *time) 16101da177e4SLinus Torvalds { 1611bfe86024SJeff Layton bool has_lease = false; 1612128a3785SDmitry Vyukov struct file_lock_context *ctx; 16138634b51fSJeff Layton struct file_lock *fl; 1614bfe86024SJeff Layton 1615401a8b8fSJeff Layton ctx = locks_inode_context(inode); 16168634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 16176109c850SJeff Layton spin_lock(&ctx->flc_lock); 16188ace5dfbSGeliang Tang fl = list_first_entry_or_null(&ctx->flc_lease, 16194ca52f53SJeff Layton struct file_lock, c.flc_list); 162075cabec0SJeff Layton if (fl && lock_is_write(fl)) 1621bfe86024SJeff Layton has_lease = true; 16226109c850SJeff Layton spin_unlock(&ctx->flc_lock); 1623bfe86024SJeff Layton } 1624bfe86024SJeff Layton 1625bfe86024SJeff Layton if (has_lease) 1626c2050a45SDeepa Dinamani *time = current_time(inode); 16271da177e4SLinus Torvalds } 16281da177e4SLinus Torvalds EXPORT_SYMBOL(lease_get_mtime); 16291da177e4SLinus Torvalds 16301da177e4SLinus Torvalds /** 16311da177e4SLinus Torvalds * fcntl_getlease - Enquire what lease is currently active 16321da177e4SLinus Torvalds * @filp: the file 16331da177e4SLinus Torvalds * 16341da177e4SLinus Torvalds * The value returned by this function will be one of 16351da177e4SLinus Torvalds * (if no lease break is pending): 16361da177e4SLinus Torvalds * 16371da177e4SLinus Torvalds * %F_RDLCK to indicate a shared lease is held. 16381da177e4SLinus Torvalds * 16391da177e4SLinus Torvalds * %F_WRLCK to indicate an exclusive lease is held. 16401da177e4SLinus Torvalds * 16411da177e4SLinus Torvalds * %F_UNLCK to indicate no lease is held. 16421da177e4SLinus Torvalds * 16431da177e4SLinus Torvalds * (if a lease break is pending): 16441da177e4SLinus Torvalds * 16451da177e4SLinus Torvalds * %F_RDLCK to indicate an exclusive lease needs to be 16461da177e4SLinus Torvalds * changed to a shared lease (or removed). 16471da177e4SLinus Torvalds * 16481da177e4SLinus Torvalds * %F_UNLCK to indicate the lease needs to be removed. 16491da177e4SLinus Torvalds * 16501da177e4SLinus Torvalds * XXX: sfr & willy disagree over whether F_INPROGRESS 16511da177e4SLinus Torvalds * should be returned to userspace. 16521da177e4SLinus Torvalds */ 16531da177e4SLinus Torvalds int fcntl_getlease(struct file *filp) 16541da177e4SLinus Torvalds { 16551da177e4SLinus Torvalds struct file_lock *fl; 1656c65454a9SJeff Layton struct inode *inode = file_inode(filp); 1657128a3785SDmitry Vyukov struct file_lock_context *ctx; 16581da177e4SLinus Torvalds int type = F_UNLCK; 1659c45198edSJeff Layton LIST_HEAD(dispose); 16601da177e4SLinus Torvalds 1661401a8b8fSJeff Layton ctx = locks_inode_context(inode); 16628634b51fSJeff Layton if (ctx && !list_empty_careful(&ctx->flc_lease)) { 166302e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 16646109c850SJeff Layton spin_lock(&ctx->flc_lock); 1665c568d683SMiklos Szeredi time_out_leases(inode, &dispose); 16664ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { 16674ca52f53SJeff Layton if (fl->c.flc_file != filp) 16688634b51fSJeff Layton continue; 1669778fc546SJ. Bruce Fields type = target_leasetype(fl); 16701da177e4SLinus Torvalds break; 16711da177e4SLinus Torvalds } 16726109c850SJeff Layton spin_unlock(&ctx->flc_lock); 167302e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 16745f43086bSPeter Zijlstra 1675c45198edSJeff Layton locks_dispose_list(&dispose); 16768634b51fSJeff Layton } 16771da177e4SLinus Torvalds return type; 16781da177e4SLinus Torvalds } 16791da177e4SLinus Torvalds 168024cbe784SJeff Layton /** 1681387e3746SAmir Goldstein * check_conflicting_open - see if the given file points to an inode that has 168224cbe784SJeff Layton * an existing open that would conflict with the 168324cbe784SJeff Layton * desired lease. 1684387e3746SAmir Goldstein * @filp: file to check 168524cbe784SJeff Layton * @arg: type of lease that we're trying to acquire 16867fadc59cSRandy Dunlap * @flags: current lock flags 168724cbe784SJeff Layton * 168824cbe784SJeff Layton * Check to see if there's an existing open fd on this file that would 168924cbe784SJeff Layton * conflict with the lease we're trying to set. 169024cbe784SJeff Layton */ 169124cbe784SJeff Layton static int 1692ed5f17f6SLuca Vizzarro check_conflicting_open(struct file *filp, const int arg, int flags) 169324cbe784SJeff Layton { 1694c65454a9SJeff Layton struct inode *inode = file_inode(filp); 1695387e3746SAmir Goldstein int self_wcount = 0, self_rcount = 0; 169624cbe784SJeff Layton 169711afe9f7SChristoph Hellwig if (flags & FL_LAYOUT) 169811afe9f7SChristoph Hellwig return 0; 1699aba2072fSJ. Bruce Fields if (flags & FL_DELEG) 1700aba2072fSJ. Bruce Fields /* We leave these checks to the caller */ 1701aba2072fSJ. Bruce Fields return 0; 170211afe9f7SChristoph Hellwig 1703387e3746SAmir Goldstein if (arg == F_RDLCK) 1704387e3746SAmir Goldstein return inode_is_open_for_write(inode) ? -EAGAIN : 0; 1705387e3746SAmir Goldstein else if (arg != F_WRLCK) 1706387e3746SAmir Goldstein return 0; 1707387e3746SAmir Goldstein 1708387e3746SAmir Goldstein /* 1709387e3746SAmir Goldstein * Make sure that only read/write count is from lease requestor. 1710387e3746SAmir Goldstein * Note that this will result in denying write leases when i_writecount 1711387e3746SAmir Goldstein * is negative, which is what we want. (We shouldn't grant write leases 1712387e3746SAmir Goldstein * on files open for execution.) 1713387e3746SAmir Goldstein */ 1714387e3746SAmir Goldstein if (filp->f_mode & FMODE_WRITE) 1715387e3746SAmir Goldstein self_wcount = 1; 1716387e3746SAmir Goldstein else if (filp->f_mode & FMODE_READ) 1717387e3746SAmir Goldstein self_rcount = 1; 1718387e3746SAmir Goldstein 1719387e3746SAmir Goldstein if (atomic_read(&inode->i_writecount) != self_wcount || 1720387e3746SAmir Goldstein atomic_read(&inode->i_readcount) != self_rcount) 172124cbe784SJeff Layton return -EAGAIN; 172224cbe784SJeff Layton 1723387e3746SAmir Goldstein return 0; 172424cbe784SJeff Layton } 172524cbe784SJeff Layton 1726e6f5c789SJeff Layton static int 1727ed5f17f6SLuca Vizzarro generic_add_lease(struct file *filp, int arg, struct file_lock **flp, void **priv) 17281da177e4SLinus Torvalds { 17298634b51fSJeff Layton struct file_lock *fl, *my_fl = NULL, *lease; 1730c65454a9SJeff Layton struct inode *inode = file_inode(filp); 17318634b51fSJeff Layton struct file_lock_context *ctx; 17324ca52f53SJeff Layton bool is_deleg = (*flp)->c.flc_flags & FL_DELEG; 1733c1f24ef4SJ. Bruce Fields int error; 1734c45198edSJeff Layton LIST_HEAD(dispose); 17351da177e4SLinus Torvalds 1736096657b6SJ. Bruce Fields lease = *flp; 173762af4f1fSJeff Layton trace_generic_add_lease(inode, lease); 173862af4f1fSJeff Layton 17395c1c669aSJeff Layton /* Note that arg is never F_UNLCK here */ 17405c1c669aSJeff Layton ctx = locks_get_lock_context(inode, arg); 17418634b51fSJeff Layton if (!ctx) 17428634b51fSJeff Layton return -ENOMEM; 17438634b51fSJeff Layton 1744df4e8d2cSJ. Bruce Fields /* 1745df4e8d2cSJ. Bruce Fields * In the delegation case we need mutual exclusion with 1746df4e8d2cSJ. Bruce Fields * a number of operations that take the i_mutex. We trylock 1747df4e8d2cSJ. Bruce Fields * because delegations are an optional optimization, and if 1748df4e8d2cSJ. Bruce Fields * there's some chance of a conflict--we'd rather not 1749df4e8d2cSJ. Bruce Fields * bother, maybe that's a sign this just isn't a good file to 1750df4e8d2cSJ. Bruce Fields * hand out a delegation on. 1751df4e8d2cSJ. Bruce Fields */ 17525955102cSAl Viro if (is_deleg && !inode_trylock(inode)) 1753df4e8d2cSJ. Bruce Fields return -EAGAIN; 1754df4e8d2cSJ. Bruce Fields 175502e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 17566109c850SJeff Layton spin_lock(&ctx->flc_lock); 1757c45198edSJeff Layton time_out_leases(inode, &dispose); 17584ca52f53SJeff Layton error = check_conflicting_open(filp, arg, lease->c.flc_flags); 175924cbe784SJeff Layton if (error) 17601da177e4SLinus Torvalds goto out; 176185c59580SPavel Emelyanov 17621da177e4SLinus Torvalds /* 17631da177e4SLinus Torvalds * At this point, we know that if there is an exclusive 17641da177e4SLinus Torvalds * lease on this file, then we hold it on this filp 17651da177e4SLinus Torvalds * (otherwise our open of this file would have blocked). 17661da177e4SLinus Torvalds * And if we are trying to acquire an exclusive lease, 17671da177e4SLinus Torvalds * then the file is not open by anyone (including us) 17681da177e4SLinus Torvalds * except for this filp. 17691da177e4SLinus Torvalds */ 1770c1f24ef4SJ. Bruce Fields error = -EAGAIN; 17714ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { 17724ca52f53SJeff Layton if (fl->c.flc_file == filp && 17734ca52f53SJeff Layton fl->c.flc_owner == lease->c.flc_owner) { 17748634b51fSJeff Layton my_fl = fl; 1775c1f24ef4SJ. Bruce Fields continue; 17761da177e4SLinus Torvalds } 17778634b51fSJeff Layton 1778c1f24ef4SJ. Bruce Fields /* 1779c1f24ef4SJ. Bruce Fields * No exclusive leases if someone else has a lease on 1780c1f24ef4SJ. Bruce Fields * this file: 1781c1f24ef4SJ. Bruce Fields */ 1782c1f24ef4SJ. Bruce Fields if (arg == F_WRLCK) 17831da177e4SLinus Torvalds goto out; 1784c1f24ef4SJ. Bruce Fields /* 1785c1f24ef4SJ. Bruce Fields * Modifying our existing lease is OK, but no getting a 1786c1f24ef4SJ. Bruce Fields * new lease if someone else is opening for write: 1787c1f24ef4SJ. Bruce Fields */ 17884ca52f53SJeff Layton if (fl->c.flc_flags & FL_UNLOCK_PENDING) 1789c1f24ef4SJ. Bruce Fields goto out; 1790c1f24ef4SJ. Bruce Fields } 17911da177e4SLinus Torvalds 17928634b51fSJeff Layton if (my_fl != NULL) { 17930164bf02SJeff Layton lease = my_fl; 17940164bf02SJeff Layton error = lease->fl_lmops->lm_change(lease, arg, &dispose); 17951c7dd2ffSJeff Layton if (error) 17961da177e4SLinus Torvalds goto out; 17971c7dd2ffSJeff Layton goto out_setup; 17981da177e4SLinus Torvalds } 17991da177e4SLinus Torvalds 18001da177e4SLinus Torvalds error = -EINVAL; 18011da177e4SLinus Torvalds if (!leases_enable) 18021da177e4SLinus Torvalds goto out; 18031da177e4SLinus Torvalds 1804e084c1bdSJeff Layton locks_insert_lock_ctx(lease, &ctx->flc_lease); 180524cbe784SJeff Layton /* 180624cbe784SJeff Layton * The check in break_lease() is lockless. It's possible for another 180724cbe784SJeff Layton * open to race in after we did the earlier check for a conflicting 180824cbe784SJeff Layton * open but before the lease was inserted. Check again for a 180924cbe784SJeff Layton * conflicting open and cancel the lease if there is one. 181024cbe784SJeff Layton * 181124cbe784SJeff Layton * We also add a barrier here to ensure that the insertion of the lock 181224cbe784SJeff Layton * precedes these checks. 181324cbe784SJeff Layton */ 181424cbe784SJeff Layton smp_mb(); 18154ca52f53SJeff Layton error = check_conflicting_open(filp, arg, lease->c.flc_flags); 18168634b51fSJeff Layton if (error) { 1817e084c1bdSJeff Layton locks_unlink_lock_ctx(lease); 18188634b51fSJeff Layton goto out; 18198634b51fSJeff Layton } 18201c7dd2ffSJeff Layton 18211c7dd2ffSJeff Layton out_setup: 18221c7dd2ffSJeff Layton if (lease->fl_lmops->lm_setup) 18231c7dd2ffSJeff Layton lease->fl_lmops->lm_setup(lease, priv); 18241da177e4SLinus Torvalds out: 18256109c850SJeff Layton spin_unlock(&ctx->flc_lock); 182602e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1827c45198edSJeff Layton locks_dispose_list(&dispose); 1828df4e8d2cSJ. Bruce Fields if (is_deleg) 18295955102cSAl Viro inode_unlock(inode); 18308634b51fSJeff Layton if (!error && !my_fl) 18311c7dd2ffSJeff Layton *flp = NULL; 18321da177e4SLinus Torvalds return error; 18331da177e4SLinus Torvalds } 18348335ebd9SJ. Bruce Fields 18352ab99ee1SChristoph Hellwig static int generic_delete_lease(struct file *filp, void *owner) 18368335ebd9SJ. Bruce Fields { 18370efaa7e8SJeff Layton int error = -EAGAIN; 18388634b51fSJeff Layton struct file_lock *fl, *victim = NULL; 1839c65454a9SJeff Layton struct inode *inode = file_inode(filp); 1840128a3785SDmitry Vyukov struct file_lock_context *ctx; 1841c45198edSJeff Layton LIST_HEAD(dispose); 18428335ebd9SJ. Bruce Fields 1843401a8b8fSJeff Layton ctx = locks_inode_context(inode); 18448634b51fSJeff Layton if (!ctx) { 18458634b51fSJeff Layton trace_generic_delete_lease(inode, NULL); 18468634b51fSJeff Layton return error; 18478634b51fSJeff Layton } 18488634b51fSJeff Layton 184902e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 18506109c850SJeff Layton spin_lock(&ctx->flc_lock); 18514ca52f53SJeff Layton list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { 18524ca52f53SJeff Layton if (fl->c.flc_file == filp && 18534ca52f53SJeff Layton fl->c.flc_owner == owner) { 18548634b51fSJeff Layton victim = fl; 18550efaa7e8SJeff Layton break; 18568335ebd9SJ. Bruce Fields } 18578634b51fSJeff Layton } 1858a9b1b455SJeff Layton trace_generic_delete_lease(inode, victim); 18598634b51fSJeff Layton if (victim) 18607448cc37SJeff Layton error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose); 18616109c850SJeff Layton spin_unlock(&ctx->flc_lock); 186202e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 1863c45198edSJeff Layton locks_dispose_list(&dispose); 18640efaa7e8SJeff Layton return error; 18658335ebd9SJ. Bruce Fields } 18668335ebd9SJ. Bruce Fields 18671da177e4SLinus Torvalds /** 18681da177e4SLinus Torvalds * generic_setlease - sets a lease on an open file 18691da177e4SLinus Torvalds * @filp: file pointer 18701da177e4SLinus Torvalds * @arg: type of lease to obtain 18711da177e4SLinus Torvalds * @flp: input - file_lock to use, output - file_lock inserted 18721c7dd2ffSJeff Layton * @priv: private data for lm_setup (may be NULL if lm_setup 18731c7dd2ffSJeff Layton * doesn't require it) 18741da177e4SLinus Torvalds * 18751da177e4SLinus Torvalds * The (input) flp->fl_lmops->lm_break function is required 18761da177e4SLinus Torvalds * by break_lease(). 18771da177e4SLinus Torvalds */ 1878ed5f17f6SLuca Vizzarro int generic_setlease(struct file *filp, int arg, struct file_lock **flp, 1879e6f5c789SJeff Layton void **priv) 18801da177e4SLinus Torvalds { 1881c65454a9SJeff Layton struct inode *inode = file_inode(filp); 188242d0c4bdSSeth Forshee vfsuid_t vfsuid = i_uid_into_vfsuid(file_mnt_idmap(filp), inode); 18838335ebd9SJ. Bruce Fields int error; 18841da177e4SLinus Torvalds 188542d0c4bdSSeth Forshee if ((!vfsuid_eq_kuid(vfsuid, current_fsuid())) && !capable(CAP_LEASE)) 18868335ebd9SJ. Bruce Fields return -EACCES; 18871da177e4SLinus Torvalds if (!S_ISREG(inode->i_mode)) 18888335ebd9SJ. Bruce Fields return -EINVAL; 18891da177e4SLinus Torvalds error = security_file_lock(filp, arg); 18901da177e4SLinus Torvalds if (error) 18918335ebd9SJ. Bruce Fields return error; 18921da177e4SLinus Torvalds 18938335ebd9SJ. Bruce Fields switch (arg) { 18948335ebd9SJ. Bruce Fields case F_UNLCK: 18952ab99ee1SChristoph Hellwig return generic_delete_lease(filp, *priv); 18968335ebd9SJ. Bruce Fields case F_RDLCK: 18978335ebd9SJ. Bruce Fields case F_WRLCK: 18980efaa7e8SJeff Layton if (!(*flp)->fl_lmops->lm_break) { 18990efaa7e8SJeff Layton WARN_ON_ONCE(1); 19000efaa7e8SJeff Layton return -ENOLCK; 19010efaa7e8SJeff Layton } 190211afe9f7SChristoph Hellwig 1903e6f5c789SJeff Layton return generic_add_lease(filp, arg, flp, priv); 19048335ebd9SJ. Bruce Fields default: 19058d657eb3SDave Jones return -EINVAL; 19061da177e4SLinus Torvalds } 19071da177e4SLinus Torvalds } 19080af1a450SChristoph Hellwig EXPORT_SYMBOL(generic_setlease); 19091da177e4SLinus Torvalds 191018f6622eSJeff Layton /* 191118f6622eSJeff Layton * Kernel subsystems can register to be notified on any attempt to set 191218f6622eSJeff Layton * a new lease with the lease_notifier_chain. This is used by (e.g.) nfsd 191318f6622eSJeff Layton * to close files that it may have cached when there is an attempt to set a 191418f6622eSJeff Layton * conflicting lease. 191518f6622eSJeff Layton */ 191618f6622eSJeff Layton static struct srcu_notifier_head lease_notifier_chain; 191718f6622eSJeff Layton 191818f6622eSJeff Layton static inline void 191918f6622eSJeff Layton lease_notifier_chain_init(void) 192018f6622eSJeff Layton { 192118f6622eSJeff Layton srcu_init_notifier_head(&lease_notifier_chain); 192218f6622eSJeff Layton } 192318f6622eSJeff Layton 192418f6622eSJeff Layton static inline void 1925ed5f17f6SLuca Vizzarro setlease_notifier(int arg, struct file_lock *lease) 192618f6622eSJeff Layton { 192718f6622eSJeff Layton if (arg != F_UNLCK) 192818f6622eSJeff Layton srcu_notifier_call_chain(&lease_notifier_chain, arg, lease); 192918f6622eSJeff Layton } 193018f6622eSJeff Layton 193118f6622eSJeff Layton int lease_register_notifier(struct notifier_block *nb) 193218f6622eSJeff Layton { 193318f6622eSJeff Layton return srcu_notifier_chain_register(&lease_notifier_chain, nb); 193418f6622eSJeff Layton } 193518f6622eSJeff Layton EXPORT_SYMBOL_GPL(lease_register_notifier); 193618f6622eSJeff Layton 193718f6622eSJeff Layton void lease_unregister_notifier(struct notifier_block *nb) 193818f6622eSJeff Layton { 193918f6622eSJeff Layton srcu_notifier_chain_unregister(&lease_notifier_chain, nb); 194018f6622eSJeff Layton } 194118f6622eSJeff Layton EXPORT_SYMBOL_GPL(lease_unregister_notifier); 194218f6622eSJeff Layton 19431da177e4SLinus Torvalds /** 1944a9933ceaSJ. Bruce Fields * vfs_setlease - sets a lease on an open file 19451da177e4SLinus Torvalds * @filp: file pointer 19461da177e4SLinus Torvalds * @arg: type of lease to obtain 1947e51673aaSJeff Layton * @lease: file_lock to use when adding a lease 19481c7dd2ffSJeff Layton * @priv: private info for lm_setup when adding a lease (may be 19491c7dd2ffSJeff Layton * NULL if lm_setup doesn't require it) 19501da177e4SLinus Torvalds * 1951e51673aaSJeff Layton * Call this to establish a lease on the file. The "lease" argument is not 1952e51673aaSJeff Layton * used for F_UNLCK requests and may be NULL. For commands that set or alter 195380b79dd0SMauro Carvalho Chehab * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be 195480b79dd0SMauro Carvalho Chehab * set; if not, this function will return -ENOLCK (and generate a scary-looking 1955e51673aaSJeff Layton * stack trace). 19561c7dd2ffSJeff Layton * 19571c7dd2ffSJeff Layton * The "priv" pointer is passed directly to the lm_setup function as-is. It 19581c7dd2ffSJeff Layton * may be NULL if the lm_setup operation doesn't require it. 19591da177e4SLinus Torvalds */ 1960e6f5c789SJeff Layton int 1961ed5f17f6SLuca Vizzarro vfs_setlease(struct file *filp, int arg, struct file_lock **lease, void **priv) 19621da177e4SLinus Torvalds { 196318f6622eSJeff Layton if (lease) 196418f6622eSJeff Layton setlease_notifier(arg, *lease); 1965de2a4a50SMiklos Szeredi if (filp->f_op->setlease) 1966f82b4b67SJeff Layton return filp->f_op->setlease(filp, arg, lease, priv); 19671c7dd2ffSJeff Layton else 1968f82b4b67SJeff Layton return generic_setlease(filp, arg, lease, priv); 19691da177e4SLinus Torvalds } 1970a9933ceaSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_setlease); 19711da177e4SLinus Torvalds 1972ed5f17f6SLuca Vizzarro static int do_fcntl_add_lease(unsigned int fd, struct file *filp, int arg) 19731da177e4SLinus Torvalds { 19741c7dd2ffSJeff Layton struct file_lock *fl; 1975f7347ce4SLinus Torvalds struct fasync_struct *new; 19761da177e4SLinus Torvalds int error; 19771da177e4SLinus Torvalds 1978c5b1f0d9SArnd Bergmann fl = lease_alloc(filp, arg); 1979c5b1f0d9SArnd Bergmann if (IS_ERR(fl)) 1980c5b1f0d9SArnd Bergmann return PTR_ERR(fl); 19811da177e4SLinus Torvalds 1982f7347ce4SLinus Torvalds new = fasync_alloc(); 1983f7347ce4SLinus Torvalds if (!new) { 1984f7347ce4SLinus Torvalds locks_free_lock(fl); 1985f7347ce4SLinus Torvalds return -ENOMEM; 1986f7347ce4SLinus Torvalds } 19871c7dd2ffSJeff Layton new->fa_fd = fd; 19881da177e4SLinus Torvalds 19891c7dd2ffSJeff Layton error = vfs_setlease(filp, arg, &fl, (void **)&new); 19902dfb928fSJeff Layton if (fl) 19912dfb928fSJeff Layton locks_free_lock(fl); 1992f7347ce4SLinus Torvalds if (new) 1993f7347ce4SLinus Torvalds fasync_free(new); 19941da177e4SLinus Torvalds return error; 19951da177e4SLinus Torvalds } 19961da177e4SLinus Torvalds 19971da177e4SLinus Torvalds /** 19980ceaf6c7SJ. Bruce Fields * fcntl_setlease - sets a lease on an open file 19990ceaf6c7SJ. Bruce Fields * @fd: open file descriptor 20000ceaf6c7SJ. Bruce Fields * @filp: file pointer 20010ceaf6c7SJ. Bruce Fields * @arg: type of lease to obtain 20020ceaf6c7SJ. Bruce Fields * 20030ceaf6c7SJ. Bruce Fields * Call this fcntl to establish a lease on the file. 20040ceaf6c7SJ. Bruce Fields * Note that you also need to call %F_SETSIG to 20050ceaf6c7SJ. Bruce Fields * receive a signal when the lease is broken. 20060ceaf6c7SJ. Bruce Fields */ 2007ed5f17f6SLuca Vizzarro int fcntl_setlease(unsigned int fd, struct file *filp, int arg) 20080ceaf6c7SJ. Bruce Fields { 20090ceaf6c7SJ. Bruce Fields if (arg == F_UNLCK) 20102ab99ee1SChristoph Hellwig return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp); 20110ceaf6c7SJ. Bruce Fields return do_fcntl_add_lease(fd, filp, arg); 20120ceaf6c7SJ. Bruce Fields } 20130ceaf6c7SJ. Bruce Fields 20140ceaf6c7SJ. Bruce Fields /** 201529d01b22SJeff Layton * flock_lock_inode_wait - Apply a FLOCK-style lock to a file 201629d01b22SJeff Layton * @inode: inode of the file to apply to 20171da177e4SLinus Torvalds * @fl: The lock to be applied 20181da177e4SLinus Torvalds * 201929d01b22SJeff Layton * Apply a FLOCK style lock request to an inode. 20201da177e4SLinus Torvalds */ 2021616fb38fSBenjamin Coddington static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) 20221da177e4SLinus Torvalds { 20231da177e4SLinus Torvalds int error; 20241da177e4SLinus Torvalds might_sleep(); 20251da177e4SLinus Torvalds for (;;) { 202629d01b22SJeff Layton error = flock_lock_inode(inode, fl); 2027bde74e4bSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 20281da177e4SLinus Torvalds break; 20294ca52f53SJeff Layton error = wait_event_interruptible(fl->c.flc_wait, 20304ca52f53SJeff Layton list_empty(&fl->c.flc_blocked_member)); 203116306a61SNeilBrown if (error) 20321da177e4SLinus Torvalds break; 20331da177e4SLinus Torvalds } 203416306a61SNeilBrown locks_delete_block(fl); 20351da177e4SLinus Torvalds return error; 20361da177e4SLinus Torvalds } 20371da177e4SLinus Torvalds 203829d01b22SJeff Layton /** 2039e55c34a6SBenjamin Coddington * locks_lock_inode_wait - Apply a lock to an inode 2040e55c34a6SBenjamin Coddington * @inode: inode of the file to apply to 2041e55c34a6SBenjamin Coddington * @fl: The lock to be applied 2042e55c34a6SBenjamin Coddington * 2043e55c34a6SBenjamin Coddington * Apply a POSIX or FLOCK style lock request to an inode. 2044e55c34a6SBenjamin Coddington */ 2045e55c34a6SBenjamin Coddington int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl) 2046e55c34a6SBenjamin Coddington { 2047e55c34a6SBenjamin Coddington int res = 0; 20484ca52f53SJeff Layton switch (fl->c.flc_flags & (FL_POSIX|FL_FLOCK)) { 2049e55c34a6SBenjamin Coddington case FL_POSIX: 2050e55c34a6SBenjamin Coddington res = posix_lock_inode_wait(inode, fl); 2051e55c34a6SBenjamin Coddington break; 2052e55c34a6SBenjamin Coddington case FL_FLOCK: 2053e55c34a6SBenjamin Coddington res = flock_lock_inode_wait(inode, fl); 2054e55c34a6SBenjamin Coddington break; 2055e55c34a6SBenjamin Coddington default: 2056e55c34a6SBenjamin Coddington BUG(); 2057e55c34a6SBenjamin Coddington } 2058e55c34a6SBenjamin Coddington return res; 2059e55c34a6SBenjamin Coddington } 2060e55c34a6SBenjamin Coddington EXPORT_SYMBOL(locks_lock_inode_wait); 2061e55c34a6SBenjamin Coddington 2062e55c34a6SBenjamin Coddington /** 20631da177e4SLinus Torvalds * sys_flock: - flock() system call. 20641da177e4SLinus Torvalds * @fd: the file descriptor to lock. 20651da177e4SLinus Torvalds * @cmd: the type of lock to apply. 20661da177e4SLinus Torvalds * 20671da177e4SLinus Torvalds * Apply a %FL_FLOCK style lock to an open file descriptor. 206880b79dd0SMauro Carvalho Chehab * The @cmd can be one of: 20691da177e4SLinus Torvalds * 207080b79dd0SMauro Carvalho Chehab * - %LOCK_SH -- a shared lock. 207180b79dd0SMauro Carvalho Chehab * - %LOCK_EX -- an exclusive lock. 207280b79dd0SMauro Carvalho Chehab * - %LOCK_UN -- remove an existing lock. 207390f7d7a0SJeff Layton * - %LOCK_MAND -- a 'mandatory' flock. (DEPRECATED) 20741da177e4SLinus Torvalds * 207590f7d7a0SJeff Layton * %LOCK_MAND support has been removed from the kernel. 20761da177e4SLinus Torvalds */ 2077002c8976SHeiko Carstens SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) 20781da177e4SLinus Torvalds { 2079db4abb4aSKuniyuki Iwashima int can_sleep, error, type; 20804149be7bSKuniyuki Iwashima struct file_lock fl; 2081db4abb4aSKuniyuki Iwashima struct fd f; 20821da177e4SLinus Torvalds 208390f7d7a0SJeff Layton /* 208490f7d7a0SJeff Layton * LOCK_MAND locks were broken for a long time in that they never 208590f7d7a0SJeff Layton * conflicted with one another and didn't prevent any sort of open, 208690f7d7a0SJeff Layton * read or write activity. 208790f7d7a0SJeff Layton * 208890f7d7a0SJeff Layton * Just ignore these requests now, to preserve legacy behavior, but 208990f7d7a0SJeff Layton * throw a warning to let people know that they don't actually work. 209090f7d7a0SJeff Layton */ 209190f7d7a0SJeff Layton if (cmd & LOCK_MAND) { 2092f2f2494cSAndi 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); 2093db4abb4aSKuniyuki Iwashima return 0; 209490f7d7a0SJeff Layton } 209590f7d7a0SJeff Layton 2096db4abb4aSKuniyuki Iwashima type = flock_translate_cmd(cmd & ~LOCK_NB); 2097db4abb4aSKuniyuki Iwashima if (type < 0) 2098db4abb4aSKuniyuki Iwashima return type; 2099db4abb4aSKuniyuki Iwashima 2100db4abb4aSKuniyuki Iwashima error = -EBADF; 2101db4abb4aSKuniyuki Iwashima f = fdget(fd); 2102db4abb4aSKuniyuki Iwashima if (!f.file) 2103db4abb4aSKuniyuki Iwashima return error; 2104db4abb4aSKuniyuki Iwashima 2105db4abb4aSKuniyuki Iwashima if (type != F_UNLCK && !(f.file->f_mode & (FMODE_READ | FMODE_WRITE))) 21061da177e4SLinus Torvalds goto out_putf; 21076e129d00SJeff Layton 21084149be7bSKuniyuki Iwashima flock_make_lock(f.file, &fl, type); 21091da177e4SLinus Torvalds 21104ca52f53SJeff Layton error = security_file_lock(f.file, fl.c.flc_type); 21111da177e4SLinus Torvalds if (error) 21124149be7bSKuniyuki Iwashima goto out_putf; 21131da177e4SLinus Torvalds 2114db4abb4aSKuniyuki Iwashima can_sleep = !(cmd & LOCK_NB); 2115db4abb4aSKuniyuki Iwashima if (can_sleep) 21164ca52f53SJeff Layton fl.c.flc_flags |= FL_SLEEP; 2117db4abb4aSKuniyuki Iwashima 2118de2a4a50SMiklos Szeredi if (f.file->f_op->flock) 21192903ff01SAl Viro error = f.file->f_op->flock(f.file, 21201da177e4SLinus Torvalds (can_sleep) ? F_SETLKW : F_SETLK, 21214149be7bSKuniyuki Iwashima &fl); 21221da177e4SLinus Torvalds else 21234149be7bSKuniyuki Iwashima error = locks_lock_file_wait(f.file, &fl); 21241da177e4SLinus Torvalds 2125932c29a1SDavid Howells locks_release_private(&fl); 21261da177e4SLinus Torvalds out_putf: 21272903ff01SAl Viro fdput(f); 2128db4abb4aSKuniyuki Iwashima 21291da177e4SLinus Torvalds return error; 21301da177e4SLinus Torvalds } 21311da177e4SLinus Torvalds 21323ee17abdSJ. Bruce Fields /** 21333ee17abdSJ. Bruce Fields * vfs_test_lock - test file byte range lock 21343ee17abdSJ. Bruce Fields * @filp: The file to test lock for 21356924c554SJ. Bruce Fields * @fl: The lock to test; also used to hold result 21363ee17abdSJ. Bruce Fields * 21373ee17abdSJ. Bruce Fields * Returns -ERRNO on failure. Indicates presence of conflicting lock by 21383ee17abdSJ. Bruce Fields * setting conf->fl_type to something other than F_UNLCK. 21393ee17abdSJ. Bruce Fields */ 21403ee17abdSJ. Bruce Fields int vfs_test_lock(struct file *filp, struct file_lock *fl) 21413ee17abdSJ. Bruce Fields { 21424ca52f53SJeff Layton WARN_ON_ONCE(filp != fl->c.flc_file); 2143de2a4a50SMiklos Szeredi if (filp->f_op->lock) 21443ee17abdSJ. Bruce Fields return filp->f_op->lock(filp, F_GETLK, fl); 21453ee17abdSJ. Bruce Fields posix_test_lock(filp, fl); 21463ee17abdSJ. Bruce Fields return 0; 21473ee17abdSJ. Bruce Fields } 21483ee17abdSJ. Bruce Fields EXPORT_SYMBOL_GPL(vfs_test_lock); 21493ee17abdSJ. Bruce Fields 21509d5b86acSBenjamin Coddington /** 21519d5b86acSBenjamin Coddington * locks_translate_pid - translate a file_lock's fl_pid number into a namespace 21529d5b86acSBenjamin Coddington * @fl: The file_lock who's fl_pid should be translated 21539d5b86acSBenjamin Coddington * @ns: The namespace into which the pid should be translated 21549d5b86acSBenjamin Coddington * 2155bd4c4680SJakub Wilk * Used to translate a fl_pid into a namespace virtual pid number 21569d5b86acSBenjamin Coddington */ 21579d5b86acSBenjamin Coddington static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns) 21589d5b86acSBenjamin Coddington { 21599d5b86acSBenjamin Coddington pid_t vnr; 21609d5b86acSBenjamin Coddington struct pid *pid; 21619d5b86acSBenjamin Coddington 21624ca52f53SJeff Layton if (fl->c.flc_flags & FL_OFDLCK) 21639d5b86acSBenjamin Coddington return -1; 21643d40f781SJeff Layton 21653d40f781SJeff Layton /* Remote locks report a negative pid value */ 21664ca52f53SJeff Layton if (fl->c.flc_pid <= 0) 21674ca52f53SJeff Layton return fl->c.flc_pid; 21683d40f781SJeff Layton 2169826d7bc9SKonstantin Khorenko /* 2170826d7bc9SKonstantin Khorenko * If the flock owner process is dead and its pid has been already 2171826d7bc9SKonstantin Khorenko * freed, the translation below won't work, but we still want to show 2172826d7bc9SKonstantin Khorenko * flock owner pid number in init pidns. 2173826d7bc9SKonstantin Khorenko */ 2174826d7bc9SKonstantin Khorenko if (ns == &init_pid_ns) 21754ca52f53SJeff Layton return (pid_t) fl->c.flc_pid; 21769d5b86acSBenjamin Coddington 21779d5b86acSBenjamin Coddington rcu_read_lock(); 21784ca52f53SJeff Layton pid = find_pid_ns(fl->c.flc_pid, &init_pid_ns); 21799d5b86acSBenjamin Coddington vnr = pid_nr_ns(pid, ns); 21809d5b86acSBenjamin Coddington rcu_read_unlock(); 21819d5b86acSBenjamin Coddington return vnr; 21829d5b86acSBenjamin Coddington } 21839d5b86acSBenjamin Coddington 2184c2fa1b8aSJ. Bruce Fields static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) 2185c2fa1b8aSJ. Bruce Fields { 21869d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 2187c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2188c2fa1b8aSJ. Bruce Fields /* 2189c2fa1b8aSJ. Bruce Fields * Make sure we can represent the posix lock via 2190c2fa1b8aSJ. Bruce Fields * legacy 32bit flock. 2191c2fa1b8aSJ. Bruce Fields */ 2192c2fa1b8aSJ. Bruce Fields if (fl->fl_start > OFFT_OFFSET_MAX) 2193c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2194c2fa1b8aSJ. Bruce Fields if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX) 2195c2fa1b8aSJ. Bruce Fields return -EOVERFLOW; 2196c2fa1b8aSJ. Bruce Fields #endif 2197c2fa1b8aSJ. Bruce Fields flock->l_start = fl->fl_start; 2198c2fa1b8aSJ. Bruce Fields flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2199c2fa1b8aSJ. Bruce Fields fl->fl_end - fl->fl_start + 1; 2200c2fa1b8aSJ. Bruce Fields flock->l_whence = 0; 22014ca52f53SJeff Layton flock->l_type = fl->c.flc_type; 2202c2fa1b8aSJ. Bruce Fields return 0; 2203c2fa1b8aSJ. Bruce Fields } 2204c2fa1b8aSJ. Bruce Fields 2205c2fa1b8aSJ. Bruce Fields #if BITS_PER_LONG == 32 2206c2fa1b8aSJ. Bruce Fields static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) 2207c2fa1b8aSJ. Bruce Fields { 22089d5b86acSBenjamin Coddington flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current)); 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 } 2215c2fa1b8aSJ. Bruce Fields #endif 2216c2fa1b8aSJ. Bruce Fields 22171da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 22181da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 22191da177e4SLinus Torvalds */ 2220a75d30c7SChristoph Hellwig int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) 22211da177e4SLinus Torvalds { 222252306e88SBenjamin Coddington struct file_lock *fl; 22231da177e4SLinus Torvalds int error; 22241da177e4SLinus Torvalds 222552306e88SBenjamin Coddington fl = locks_alloc_lock(); 222652306e88SBenjamin Coddington if (fl == NULL) 222752306e88SBenjamin Coddington return -ENOMEM; 22281da177e4SLinus Torvalds error = -EINVAL; 22296c9007f6SStas Sergeev if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK 22306c9007f6SStas Sergeev && flock->l_type != F_WRLCK) 22311da177e4SLinus Torvalds goto out; 22321da177e4SLinus Torvalds 223352306e88SBenjamin Coddington error = flock_to_posix_lock(filp, fl, flock); 22341da177e4SLinus Torvalds if (error) 22351da177e4SLinus Torvalds goto out; 22361da177e4SLinus Torvalds 22370d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 223890478939SJeff Layton error = -EINVAL; 2239a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 224090478939SJeff Layton goto out; 224190478939SJeff Layton 22424ca52f53SJeff Layton fl->c.flc_flags |= FL_OFDLCK; 22434ca52f53SJeff Layton fl->c.flc_owner = filp; 22445d50ffd7SJeff Layton } 22455d50ffd7SJeff Layton 224652306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 22473ee17abdSJ. Bruce Fields if (error) 22481da177e4SLinus Torvalds goto out; 22491da177e4SLinus Torvalds 22504ca52f53SJeff Layton flock->l_type = fl->c.flc_type; 22514ca52f53SJeff Layton if (fl->c.flc_type != F_UNLCK) { 225252306e88SBenjamin Coddington error = posix_lock_to_flock(flock, fl); 2253c2fa1b8aSJ. Bruce Fields if (error) 225452306e88SBenjamin Coddington goto out; 22551da177e4SLinus Torvalds } 22561da177e4SLinus Torvalds out: 225752306e88SBenjamin Coddington locks_free_lock(fl); 22581da177e4SLinus Torvalds return error; 22591da177e4SLinus Torvalds } 22601da177e4SLinus Torvalds 22617723ec97SMarc Eshel /** 22627723ec97SMarc Eshel * vfs_lock_file - file byte range lock 22637723ec97SMarc Eshel * @filp: The file to apply the lock to 22647723ec97SMarc Eshel * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.) 22657723ec97SMarc Eshel * @fl: The lock to be applied 2266150b3934SMarc Eshel * @conf: Place to return a copy of the conflicting lock, if found. 2267150b3934SMarc Eshel * 2268150b3934SMarc Eshel * A caller that doesn't care about the conflicting lock may pass NULL 2269150b3934SMarc Eshel * as the final argument. 2270150b3934SMarc Eshel * 2271150b3934SMarc Eshel * If the filesystem defines a private ->lock() method, then @conf will 2272150b3934SMarc Eshel * be left unchanged; so a caller that cares should initialize it to 2273150b3934SMarc Eshel * some acceptable default. 22742beb6614SMarc Eshel * 22752beb6614SMarc Eshel * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX 22762beb6614SMarc Eshel * locks, the ->lock() interface may return asynchronously, before the lock has 22772beb6614SMarc Eshel * been granted or denied by the underlying filesystem, if (and only if) 2278e70da176SAlexander Aring * lm_grant is set. Additionally EXPORT_OP_ASYNC_LOCK in export_operations 2279e70da176SAlexander Aring * flags need to be set. 2280e70da176SAlexander Aring * 2281e70da176SAlexander Aring * Callers expecting ->lock() to return asynchronously will only use F_SETLK, 2282e70da176SAlexander Aring * not F_SETLKW; they will set FL_SLEEP if (and only if) the request is for a 2283e70da176SAlexander Aring * blocking lock. When ->lock() does return asynchronously, it must return 2284e70da176SAlexander Aring * FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock request completes. 22852beb6614SMarc Eshel * If the request is for non-blocking lock the file system should return 2286bde74e4bSMiklos Szeredi * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine 2287bde74e4bSMiklos Szeredi * with the result. If the request timed out the callback routine will return a 22882beb6614SMarc Eshel * nonzero return code and the file system should release the lock. The file 22892beb6614SMarc Eshel * system is also responsible to keep a corresponding posix lock when it 22902beb6614SMarc Eshel * grants a lock so the VFS can find out which locks are locally held and do 22912beb6614SMarc Eshel * the correct lock cleanup when required. 22922beb6614SMarc Eshel * The underlying filesystem must not drop the kernel lock or call 22938fb47a4fSJ. Bruce Fields * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED 22942beb6614SMarc Eshel * return code. 22957723ec97SMarc Eshel */ 2296150b3934SMarc Eshel int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) 22977723ec97SMarc Eshel { 22984ca52f53SJeff Layton WARN_ON_ONCE(filp != fl->c.flc_file); 2299de2a4a50SMiklos Szeredi if (filp->f_op->lock) 23007723ec97SMarc Eshel return filp->f_op->lock(filp, cmd, fl); 23017723ec97SMarc Eshel else 2302150b3934SMarc Eshel return posix_lock_file(filp, fl, conf); 23037723ec97SMarc Eshel } 23047723ec97SMarc Eshel EXPORT_SYMBOL_GPL(vfs_lock_file); 23057723ec97SMarc Eshel 2306b648a6deSMiklos Szeredi static int do_lock_file_wait(struct file *filp, unsigned int cmd, 2307b648a6deSMiklos Szeredi struct file_lock *fl) 2308b648a6deSMiklos Szeredi { 2309b648a6deSMiklos Szeredi int error; 2310b648a6deSMiklos Szeredi 23114ca52f53SJeff Layton error = security_file_lock(filp, fl->c.flc_type); 2312b648a6deSMiklos Szeredi if (error) 2313b648a6deSMiklos Szeredi return error; 2314b648a6deSMiklos Szeredi 2315b648a6deSMiklos Szeredi for (;;) { 2316764c76b3SMiklos Szeredi error = vfs_lock_file(filp, cmd, fl, NULL); 2317b648a6deSMiklos Szeredi if (error != FILE_LOCK_DEFERRED) 2318b648a6deSMiklos Szeredi break; 23194ca52f53SJeff Layton error = wait_event_interruptible(fl->c.flc_wait, 23204ca52f53SJeff Layton list_empty(&fl->c.flc_blocked_member)); 232116306a61SNeilBrown if (error) 2322b648a6deSMiklos Szeredi break; 2323b648a6deSMiklos Szeredi } 232416306a61SNeilBrown locks_delete_block(fl); 2325b648a6deSMiklos Szeredi 2326b648a6deSMiklos Szeredi return error; 2327b648a6deSMiklos Szeredi } 2328b648a6deSMiklos Szeredi 23296ca7d910SBenjamin Coddington /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */ 2330cf01f4eeSJeff Layton static int 2331cf01f4eeSJeff Layton check_fmode_for_setlk(struct file_lock *fl) 2332cf01f4eeSJeff Layton { 23334ca52f53SJeff Layton switch (fl->c.flc_type) { 2334cf01f4eeSJeff Layton case F_RDLCK: 23354ca52f53SJeff Layton if (!(fl->c.flc_file->f_mode & FMODE_READ)) 2336cf01f4eeSJeff Layton return -EBADF; 2337cf01f4eeSJeff Layton break; 2338cf01f4eeSJeff Layton case F_WRLCK: 23394ca52f53SJeff Layton if (!(fl->c.flc_file->f_mode & FMODE_WRITE)) 2340cf01f4eeSJeff Layton return -EBADF; 2341cf01f4eeSJeff Layton } 2342cf01f4eeSJeff Layton return 0; 2343cf01f4eeSJeff Layton } 2344cf01f4eeSJeff Layton 23451da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 23461da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 23471da177e4SLinus Torvalds */ 2348c293621bSPeter Staubach int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, 2349a75d30c7SChristoph Hellwig struct flock *flock) 23501da177e4SLinus Torvalds { 23511da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 2352c65454a9SJeff Layton struct inode *inode = file_inode(filp); 23530b2bac2fSAl Viro struct file *f; 23541da177e4SLinus Torvalds int error; 23551da177e4SLinus Torvalds 23561da177e4SLinus Torvalds if (file_lock == NULL) 23571da177e4SLinus Torvalds return -ENOLCK; 23581da177e4SLinus Torvalds 2359a75d30c7SChristoph Hellwig error = flock_to_posix_lock(filp, file_lock, flock); 23601da177e4SLinus Torvalds if (error) 23611da177e4SLinus Torvalds goto out; 23625d50ffd7SJeff Layton 2363cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2364cf01f4eeSJeff Layton if (error) 2365cf01f4eeSJeff Layton goto out; 2366cf01f4eeSJeff Layton 23675d50ffd7SJeff Layton /* 23685d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2369cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 23705d50ffd7SJeff Layton */ 23715d50ffd7SJeff Layton switch (cmd) { 23720d3f7a2dSJeff Layton case F_OFD_SETLK: 237390478939SJeff Layton error = -EINVAL; 2374a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 237590478939SJeff Layton goto out; 237690478939SJeff Layton 23775d50ffd7SJeff Layton cmd = F_SETLK; 23784ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 23794ca52f53SJeff Layton file_lock->c.flc_owner = filp; 23805d50ffd7SJeff Layton break; 23810d3f7a2dSJeff Layton case F_OFD_SETLKW: 238290478939SJeff Layton error = -EINVAL; 2383a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 238490478939SJeff Layton goto out; 238590478939SJeff Layton 23865d50ffd7SJeff Layton cmd = F_SETLKW; 23874ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 23884ca52f53SJeff Layton file_lock->c.flc_owner = filp; 2389df561f66SGustavo A. R. Silva fallthrough; 23905d50ffd7SJeff Layton case F_SETLKW: 23914ca52f53SJeff Layton file_lock->c.flc_flags |= FL_SLEEP; 23921da177e4SLinus Torvalds } 23931da177e4SLinus Torvalds 2394b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2395c293621bSPeter Staubach 2396c293621bSPeter Staubach /* 23970752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 23980752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 23990752ba80SJeff Layton * unlocking though, or for OFD locks. 2400c293621bSPeter Staubach */ 24014ca52f53SJeff Layton if (!error && file_lock->c.flc_type != F_UNLCK && 24024ca52f53SJeff Layton !(file_lock->c.flc_flags & FL_OFDLCK)) { 2403120ce2b0SEric W. Biederman struct files_struct *files = current->files; 24040b2bac2fSAl Viro /* 24057f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 24067f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 24077f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 24080b2bac2fSAl Viro */ 2409120ce2b0SEric W. Biederman spin_lock(&files->file_lock); 2410120ce2b0SEric W. Biederman f = files_lookup_fd_locked(files, fd); 2411120ce2b0SEric W. Biederman spin_unlock(&files->file_lock); 24127f3697e2SJeff Layton if (f != filp) { 24134ca52f53SJeff Layton file_lock->c.flc_type = F_UNLCK; 24147f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 24157f3697e2SJeff Layton WARN_ON_ONCE(error); 24167f3697e2SJeff Layton error = -EBADF; 2417c293621bSPeter Staubach } 24187f3697e2SJeff Layton } 24191da177e4SLinus Torvalds out: 24201890910fSJeff Layton trace_fcntl_setlk(inode, file_lock, error); 24211da177e4SLinus Torvalds locks_free_lock(file_lock); 24221da177e4SLinus Torvalds return error; 24231da177e4SLinus Torvalds } 24241da177e4SLinus Torvalds 24251da177e4SLinus Torvalds #if BITS_PER_LONG == 32 24261da177e4SLinus Torvalds /* Report the first existing lock that would conflict with l. 24271da177e4SLinus Torvalds * This implements the F_GETLK command of fcntl(). 24281da177e4SLinus Torvalds */ 2429a75d30c7SChristoph Hellwig int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) 24301da177e4SLinus Torvalds { 243152306e88SBenjamin Coddington struct file_lock *fl; 24321da177e4SLinus Torvalds int error; 24331da177e4SLinus Torvalds 243452306e88SBenjamin Coddington fl = locks_alloc_lock(); 243552306e88SBenjamin Coddington if (fl == NULL) 243652306e88SBenjamin Coddington return -ENOMEM; 243752306e88SBenjamin Coddington 24381da177e4SLinus Torvalds error = -EINVAL; 24396c9007f6SStas Sergeev if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK 24406c9007f6SStas Sergeev && flock->l_type != F_WRLCK) 24411da177e4SLinus Torvalds goto out; 24421da177e4SLinus Torvalds 244352306e88SBenjamin Coddington error = flock64_to_posix_lock(filp, fl, flock); 24441da177e4SLinus Torvalds if (error) 24451da177e4SLinus Torvalds goto out; 24461da177e4SLinus Torvalds 24470d3f7a2dSJeff Layton if (cmd == F_OFD_GETLK) { 244890478939SJeff Layton error = -EINVAL; 2449a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 245090478939SJeff Layton goto out; 245190478939SJeff Layton 24524ca52f53SJeff Layton fl->c.flc_flags |= FL_OFDLCK; 24534ca52f53SJeff Layton fl->c.flc_owner = filp; 24545d50ffd7SJeff Layton } 24555d50ffd7SJeff Layton 245652306e88SBenjamin Coddington error = vfs_test_lock(filp, fl); 24573ee17abdSJ. Bruce Fields if (error) 24581da177e4SLinus Torvalds goto out; 24591da177e4SLinus Torvalds 24604ca52f53SJeff Layton flock->l_type = fl->c.flc_type; 24614ca52f53SJeff Layton if (fl->c.flc_type != F_UNLCK) 246252306e88SBenjamin Coddington posix_lock_to_flock64(flock, fl); 24631da177e4SLinus Torvalds 24641da177e4SLinus Torvalds out: 246552306e88SBenjamin Coddington locks_free_lock(fl); 24661da177e4SLinus Torvalds return error; 24671da177e4SLinus Torvalds } 24681da177e4SLinus Torvalds 24691da177e4SLinus Torvalds /* Apply the lock described by l to an open file descriptor. 24701da177e4SLinus Torvalds * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 24711da177e4SLinus Torvalds */ 2472c293621bSPeter Staubach int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, 2473a75d30c7SChristoph Hellwig struct flock64 *flock) 24741da177e4SLinus Torvalds { 24751da177e4SLinus Torvalds struct file_lock *file_lock = locks_alloc_lock(); 24760b2bac2fSAl Viro struct file *f; 24771da177e4SLinus Torvalds int error; 24781da177e4SLinus Torvalds 24791da177e4SLinus Torvalds if (file_lock == NULL) 24801da177e4SLinus Torvalds return -ENOLCK; 24811da177e4SLinus Torvalds 2482a75d30c7SChristoph Hellwig error = flock64_to_posix_lock(filp, file_lock, flock); 24831da177e4SLinus Torvalds if (error) 24841da177e4SLinus Torvalds goto out; 24855d50ffd7SJeff Layton 2486cf01f4eeSJeff Layton error = check_fmode_for_setlk(file_lock); 2487cf01f4eeSJeff Layton if (error) 2488cf01f4eeSJeff Layton goto out; 2489cf01f4eeSJeff Layton 24905d50ffd7SJeff Layton /* 24915d50ffd7SJeff Layton * If the cmd is requesting file-private locks, then set the 2492cff2fce5SJeff Layton * FL_OFDLCK flag and override the owner. 24935d50ffd7SJeff Layton */ 24945d50ffd7SJeff Layton switch (cmd) { 24950d3f7a2dSJeff Layton case F_OFD_SETLK: 249690478939SJeff Layton error = -EINVAL; 2497a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 249890478939SJeff Layton goto out; 249990478939SJeff Layton 25005d50ffd7SJeff Layton cmd = F_SETLK64; 25014ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 25024ca52f53SJeff Layton file_lock->c.flc_owner = filp; 25035d50ffd7SJeff Layton break; 25040d3f7a2dSJeff Layton case F_OFD_SETLKW: 250590478939SJeff Layton error = -EINVAL; 2506a75d30c7SChristoph Hellwig if (flock->l_pid != 0) 250790478939SJeff Layton goto out; 250890478939SJeff Layton 25095d50ffd7SJeff Layton cmd = F_SETLKW64; 25104ca52f53SJeff Layton file_lock->c.flc_flags |= FL_OFDLCK; 25114ca52f53SJeff Layton file_lock->c.flc_owner = filp; 2512df561f66SGustavo A. R. Silva fallthrough; 25135d50ffd7SJeff Layton case F_SETLKW64: 25144ca52f53SJeff Layton file_lock->c.flc_flags |= FL_SLEEP; 25151da177e4SLinus Torvalds } 25161da177e4SLinus Torvalds 2517b648a6deSMiklos Szeredi error = do_lock_file_wait(filp, cmd, file_lock); 2518c293621bSPeter Staubach 2519c293621bSPeter Staubach /* 25200752ba80SJeff Layton * Attempt to detect a close/fcntl race and recover by releasing the 25210752ba80SJeff Layton * lock that was just acquired. There is no need to do that when we're 25220752ba80SJeff Layton * unlocking though, or for OFD locks. 2523c293621bSPeter Staubach */ 25244ca52f53SJeff Layton if (!error && file_lock->c.flc_type != F_UNLCK && 25254ca52f53SJeff Layton !(file_lock->c.flc_flags & FL_OFDLCK)) { 2526120ce2b0SEric W. Biederman struct files_struct *files = current->files; 25277f3697e2SJeff Layton /* 25287f3697e2SJeff Layton * We need that spin_lock here - it prevents reordering between 25297f3697e2SJeff Layton * update of i_flctx->flc_posix and check for it done in 25307f3697e2SJeff Layton * close(). rcu_read_lock() wouldn't do. 25317f3697e2SJeff Layton */ 2532120ce2b0SEric W. Biederman spin_lock(&files->file_lock); 2533120ce2b0SEric W. Biederman f = files_lookup_fd_locked(files, fd); 2534120ce2b0SEric W. Biederman spin_unlock(&files->file_lock); 25357f3697e2SJeff Layton if (f != filp) { 25364ca52f53SJeff Layton file_lock->c.flc_type = F_UNLCK; 25377f3697e2SJeff Layton error = do_lock_file_wait(filp, cmd, file_lock); 25387f3697e2SJeff Layton WARN_ON_ONCE(error); 25397f3697e2SJeff Layton error = -EBADF; 2540c293621bSPeter Staubach } 25417f3697e2SJeff Layton } 25421da177e4SLinus Torvalds out: 25431da177e4SLinus Torvalds locks_free_lock(file_lock); 25441da177e4SLinus Torvalds return error; 25451da177e4SLinus Torvalds } 25461da177e4SLinus Torvalds #endif /* BITS_PER_LONG == 32 */ 25471da177e4SLinus Torvalds 25481da177e4SLinus Torvalds /* 25491da177e4SLinus Torvalds * This function is called when the file is being removed 25501da177e4SLinus Torvalds * from the task's fd array. POSIX locks belonging to this task 25511da177e4SLinus Torvalds * are deleted at this time. 25521da177e4SLinus Torvalds */ 25531da177e4SLinus Torvalds void locks_remove_posix(struct file *filp, fl_owner_t owner) 25541da177e4SLinus Torvalds { 25551890910fSJeff Layton int error; 2556c65454a9SJeff Layton struct inode *inode = file_inode(filp); 2557ff7b86b8SMiklos Szeredi struct file_lock lock; 2558128a3785SDmitry Vyukov struct file_lock_context *ctx; 25591da177e4SLinus Torvalds 25601da177e4SLinus Torvalds /* 25611da177e4SLinus Torvalds * If there are no locks held on this file, we don't need to call 25621da177e4SLinus Torvalds * posix_lock_file(). Another process could be setting a lock on this 25631da177e4SLinus Torvalds * file at the same time, but we wouldn't remove that lock anyway. 25641da177e4SLinus Torvalds */ 2565401a8b8fSJeff Layton ctx = locks_inode_context(inode); 2566bd61e0a9SJeff Layton if (!ctx || list_empty(&ctx->flc_posix)) 25671da177e4SLinus Torvalds return; 25681da177e4SLinus Torvalds 2569d6367d62SNeilBrown locks_init_lock(&lock); 25704ca52f53SJeff Layton lock.c.flc_type = F_UNLCK; 25714ca52f53SJeff Layton lock.c.flc_flags = FL_POSIX | FL_CLOSE; 25721da177e4SLinus Torvalds lock.fl_start = 0; 25731da177e4SLinus Torvalds lock.fl_end = OFFSET_MAX; 25744ca52f53SJeff Layton lock.c.flc_owner = owner; 25754ca52f53SJeff Layton lock.c.flc_pid = current->tgid; 25764ca52f53SJeff Layton lock.c.flc_file = filp; 25771da177e4SLinus Torvalds lock.fl_ops = NULL; 25781da177e4SLinus Torvalds lock.fl_lmops = NULL; 25791da177e4SLinus Torvalds 25801890910fSJeff Layton error = vfs_lock_file(filp, F_SETLK, &lock, NULL); 25811da177e4SLinus Torvalds 25821da177e4SLinus Torvalds if (lock.fl_ops && lock.fl_ops->fl_release_private) 25831da177e4SLinus Torvalds lock.fl_ops->fl_release_private(&lock); 2584c568d683SMiklos Szeredi trace_locks_remove_posix(inode, &lock, error); 25851da177e4SLinus Torvalds } 25861da177e4SLinus Torvalds EXPORT_SYMBOL(locks_remove_posix); 25871da177e4SLinus Torvalds 25883d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 2589dd459bb1SJeff Layton static void 2590128a3785SDmitry Vyukov locks_remove_flock(struct file *filp, struct file_lock_context *flctx) 2591dd459bb1SJeff Layton { 2592d6367d62SNeilBrown struct file_lock fl; 2593c65454a9SJeff Layton struct inode *inode = file_inode(filp); 2594dd459bb1SJeff Layton 25953d8e560dSJeff Layton if (list_empty(&flctx->flc_flock)) 2596dd459bb1SJeff Layton return; 2597dd459bb1SJeff Layton 25984149be7bSKuniyuki Iwashima flock_make_lock(filp, &fl, F_UNLCK); 25994ca52f53SJeff Layton fl.c.flc_flags |= FL_CLOSE; 2600d6367d62SNeilBrown 2601de2a4a50SMiklos Szeredi if (filp->f_op->flock) 2602dd459bb1SJeff Layton filp->f_op->flock(filp, F_SETLKW, &fl); 2603dd459bb1SJeff Layton else 2604bcd7f78dSJeff Layton flock_lock_inode(inode, &fl); 2605dd459bb1SJeff Layton 2606dd459bb1SJeff Layton if (fl.fl_ops && fl.fl_ops->fl_release_private) 2607dd459bb1SJeff Layton fl.fl_ops->fl_release_private(&fl); 2608dd459bb1SJeff Layton } 2609dd459bb1SJeff Layton 26103d8e560dSJeff Layton /* The i_flctx must be valid when calling into here */ 26118634b51fSJeff Layton static void 2612128a3785SDmitry Vyukov locks_remove_lease(struct file *filp, struct file_lock_context *ctx) 26138634b51fSJeff Layton { 26148634b51fSJeff Layton struct file_lock *fl, *tmp; 26158634b51fSJeff Layton LIST_HEAD(dispose); 26168634b51fSJeff Layton 26173d8e560dSJeff Layton if (list_empty(&ctx->flc_lease)) 26188634b51fSJeff Layton return; 26198634b51fSJeff Layton 262002e525b2SPeter Zijlstra percpu_down_read(&file_rwsem); 26216109c850SJeff Layton spin_lock(&ctx->flc_lock); 26224ca52f53SJeff Layton list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) 26234ca52f53SJeff Layton if (filp == fl->c.flc_file) 26247448cc37SJeff Layton lease_modify(fl, F_UNLCK, &dispose); 26256109c850SJeff Layton spin_unlock(&ctx->flc_lock); 262602e525b2SPeter Zijlstra percpu_up_read(&file_rwsem); 26275f43086bSPeter Zijlstra 26288634b51fSJeff Layton locks_dispose_list(&dispose); 26298634b51fSJeff Layton } 26308634b51fSJeff Layton 26311da177e4SLinus Torvalds /* 26321da177e4SLinus Torvalds * This function is called on the last close of an open file. 26331da177e4SLinus Torvalds */ 263478ed8a13SJeff Layton void locks_remove_file(struct file *filp) 26351da177e4SLinus Torvalds { 2636128a3785SDmitry Vyukov struct file_lock_context *ctx; 2637128a3785SDmitry Vyukov 2638c65454a9SJeff Layton ctx = locks_inode_context(file_inode(filp)); 2639128a3785SDmitry Vyukov if (!ctx) 26403d8e560dSJeff Layton return; 26413d8e560dSJeff Layton 2642dd459bb1SJeff Layton /* remove any OFD locks */ 264373a8f5f7SChristoph Hellwig locks_remove_posix(filp, filp); 26445d50ffd7SJeff Layton 2645dd459bb1SJeff Layton /* remove flock locks */ 2646128a3785SDmitry Vyukov locks_remove_flock(filp, ctx); 2647dd459bb1SJeff Layton 26488634b51fSJeff Layton /* remove any leases */ 2649128a3785SDmitry Vyukov locks_remove_lease(filp, ctx); 26503953704fSBenjamin Coddington 26513953704fSBenjamin Coddington spin_lock(&ctx->flc_lock); 26523953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX"); 26533953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK"); 26543953704fSBenjamin Coddington locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE"); 26553953704fSBenjamin Coddington spin_unlock(&ctx->flc_lock); 26561da177e4SLinus Torvalds } 26571da177e4SLinus Torvalds 26581da177e4SLinus Torvalds /** 26599b9d2ab4SMarc Eshel * vfs_cancel_lock - file byte range unblock lock 26609b9d2ab4SMarc Eshel * @filp: The file to apply the unblock to 26619b9d2ab4SMarc Eshel * @fl: The lock to be unblocked 26629b9d2ab4SMarc Eshel * 26639b9d2ab4SMarc Eshel * Used by lock managers to cancel blocked requests 26649b9d2ab4SMarc Eshel */ 26659b9d2ab4SMarc Eshel int vfs_cancel_lock(struct file *filp, struct file_lock *fl) 26669b9d2ab4SMarc Eshel { 26674ca52f53SJeff Layton WARN_ON_ONCE(filp != fl->c.flc_file); 2668de2a4a50SMiklos Szeredi if (filp->f_op->lock) 26699b9d2ab4SMarc Eshel return filp->f_op->lock(filp, F_CANCELLK, fl); 26709b9d2ab4SMarc Eshel return 0; 26719b9d2ab4SMarc Eshel } 26729b9d2ab4SMarc Eshel EXPORT_SYMBOL_GPL(vfs_cancel_lock); 26739b9d2ab4SMarc Eshel 2674ab1ddef9SJeff Layton /** 2675ab1ddef9SJeff Layton * vfs_inode_has_locks - are any file locks held on @inode? 2676ab1ddef9SJeff Layton * @inode: inode to check for locks 2677ab1ddef9SJeff Layton * 2678ab1ddef9SJeff Layton * Return true if there are any FL_POSIX or FL_FLOCK locks currently 2679ab1ddef9SJeff Layton * set on @inode. 2680ab1ddef9SJeff Layton */ 2681ab1ddef9SJeff Layton bool vfs_inode_has_locks(struct inode *inode) 2682ab1ddef9SJeff Layton { 2683ab1ddef9SJeff Layton struct file_lock_context *ctx; 2684ab1ddef9SJeff Layton bool ret; 2685ab1ddef9SJeff Layton 2686401a8b8fSJeff Layton ctx = locks_inode_context(inode); 2687ab1ddef9SJeff Layton if (!ctx) 2688ab1ddef9SJeff Layton return false; 2689ab1ddef9SJeff Layton 2690ab1ddef9SJeff Layton spin_lock(&ctx->flc_lock); 2691ab1ddef9SJeff Layton ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock); 2692ab1ddef9SJeff Layton spin_unlock(&ctx->flc_lock); 2693ab1ddef9SJeff Layton return ret; 2694ab1ddef9SJeff Layton } 2695ab1ddef9SJeff Layton EXPORT_SYMBOL_GPL(vfs_inode_has_locks); 2696ab1ddef9SJeff Layton 26977f8ada98SPavel Emelyanov #ifdef CONFIG_PROC_FS 2698d8ba7a36SAlexey Dobriyan #include <linux/proc_fs.h> 26997f8ada98SPavel Emelyanov #include <linux/seq_file.h> 27007f8ada98SPavel Emelyanov 27017012b02aSJeff Layton struct locks_iterator { 27027012b02aSJeff Layton int li_cpu; 27037012b02aSJeff Layton loff_t li_pos; 27047012b02aSJeff Layton }; 27057012b02aSJeff Layton 27067f8ada98SPavel Emelyanov static void lock_get_status(struct seq_file *f, struct file_lock *fl, 2707b8da9b10SLuo Longjun loff_t id, char *pfx, int repeat) 27081da177e4SLinus Torvalds { 27091da177e4SLinus Torvalds struct inode *inode = NULL; 27106021d62cSJeff Layton unsigned int pid; 27119d78edeaSAlexey Gladkov struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb); 27124ca52f53SJeff Layton int type = fl->c.flc_type; 2713d67fd44fSNikolay Borisov 27146021d62cSJeff Layton pid = locks_translate_pid(fl, proc_pidns); 2715d67fd44fSNikolay Borisov /* 27161cf8e5deSKonstantin Khorenko * If lock owner is dead (and pid is freed) or not visible in current 27171cf8e5deSKonstantin Khorenko * pidns, zero is shown as a pid value. Check lock info from 27181cf8e5deSKonstantin Khorenko * init_pid_ns to get saved lock pid value. 2719d67fd44fSNikolay Borisov */ 27201da177e4SLinus Torvalds 27214ca52f53SJeff Layton if (fl->c.flc_file != NULL) 27224ca52f53SJeff Layton inode = file_inode(fl->c.flc_file); 27231da177e4SLinus Torvalds 2724b8da9b10SLuo Longjun seq_printf(f, "%lld: ", id); 2725b8da9b10SLuo Longjun 2726b8da9b10SLuo Longjun if (repeat) 2727b8da9b10SLuo Longjun seq_printf(f, "%*s", repeat - 1 + (int)strlen(pfx), pfx); 2728b8da9b10SLuo Longjun 27294ca52f53SJeff Layton if (fl->c.flc_flags & FL_POSIX) { 27304ca52f53SJeff Layton if (fl->c.flc_flags & FL_ACCESS) 27315315c26aSFabian Frederick seq_puts(f, "ACCESS"); 27324ca52f53SJeff Layton else if (fl->c.flc_flags & FL_OFDLCK) 27335315c26aSFabian Frederick seq_puts(f, "OFDLCK"); 2734c918d42aSJeff Layton else 27355315c26aSFabian Frederick seq_puts(f, "POSIX "); 2736c918d42aSJeff Layton 2737c918d42aSJeff Layton seq_printf(f, " %s ", 2738f7e33bdbSJeff Layton (inode == NULL) ? "*NOINODE*" : "ADVISORY "); 27394ca52f53SJeff Layton } else if (fl->c.flc_flags & FL_FLOCK) { 27405315c26aSFabian Frederick seq_puts(f, "FLOCK ADVISORY "); 27414ca52f53SJeff Layton } else if (fl->c.flc_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) { 27423d40f781SJeff Layton type = target_leasetype(fl); 27433d40f781SJeff Layton 27444ca52f53SJeff Layton if (fl->c.flc_flags & FL_DELEG) 27458144f1f6SJeff Layton seq_puts(f, "DELEG "); 27468144f1f6SJeff Layton else 27475315c26aSFabian Frederick seq_puts(f, "LEASE "); 27488144f1f6SJeff Layton 2749ab83fa4bSJ. Bruce Fields if (lease_breaking(fl)) 27505315c26aSFabian Frederick seq_puts(f, "BREAKING "); 27514ca52f53SJeff Layton else if (fl->c.flc_file) 27525315c26aSFabian Frederick seq_puts(f, "ACTIVE "); 27531da177e4SLinus Torvalds else 27545315c26aSFabian Frederick seq_puts(f, "BREAKER "); 27551da177e4SLinus Torvalds } else { 27565315c26aSFabian Frederick seq_puts(f, "UNKNOWN UNKNOWN "); 27571da177e4SLinus Torvalds } 275843e4cb94SPavel Begunkov 275943e4cb94SPavel Begunkov seq_printf(f, "%s ", (type == F_WRLCK) ? "WRITE" : 276043e4cb94SPavel Begunkov (type == F_RDLCK) ? "READ" : "UNLCK"); 27611da177e4SLinus Torvalds if (inode) { 27623648888eSJeff Layton /* userspace relies on this representation of dev_t */ 27636021d62cSJeff Layton seq_printf(f, "%d %02x:%02x:%lu ", pid, 27641da177e4SLinus Torvalds MAJOR(inode->i_sb->s_dev), 27651da177e4SLinus Torvalds MINOR(inode->i_sb->s_dev), inode->i_ino); 27661da177e4SLinus Torvalds } else { 27676021d62cSJeff Layton seq_printf(f, "%d <none>:0 ", pid); 27681da177e4SLinus Torvalds } 27694ca52f53SJeff Layton if (fl->c.flc_flags & FL_POSIX) { 27701da177e4SLinus Torvalds if (fl->fl_end == OFFSET_MAX) 27717f8ada98SPavel Emelyanov seq_printf(f, "%Ld EOF\n", fl->fl_start); 27721da177e4SLinus Torvalds else 27737f8ada98SPavel Emelyanov seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end); 27741da177e4SLinus Torvalds } else { 27755315c26aSFabian Frederick seq_puts(f, "0 EOF\n"); 27761da177e4SLinus Torvalds } 27771da177e4SLinus Torvalds } 27781da177e4SLinus Torvalds 2779b8da9b10SLuo Longjun static struct file_lock *get_next_blocked_member(struct file_lock *node) 2780b8da9b10SLuo Longjun { 2781b8da9b10SLuo Longjun struct file_lock *tmp; 2782b8da9b10SLuo Longjun 2783b8da9b10SLuo Longjun /* NULL node or root node */ 27844ca52f53SJeff Layton if (node == NULL || node->c.flc_blocker == NULL) 2785b8da9b10SLuo Longjun return NULL; 2786b8da9b10SLuo Longjun 2787b8da9b10SLuo Longjun /* Next member in the linked list could be itself */ 27884ca52f53SJeff Layton tmp = list_next_entry(node, c.flc_blocked_member); 27894ca52f53SJeff Layton if (list_entry_is_head(tmp, &node->c.flc_blocker->c.flc_blocked_requests, 27904ca52f53SJeff Layton c.flc_blocked_member) 2791b8da9b10SLuo Longjun || tmp == node) { 2792b8da9b10SLuo Longjun return NULL; 2793b8da9b10SLuo Longjun } 2794b8da9b10SLuo Longjun 2795b8da9b10SLuo Longjun return tmp; 2796b8da9b10SLuo Longjun } 2797b8da9b10SLuo Longjun 27987f8ada98SPavel Emelyanov static int locks_show(struct seq_file *f, void *v) 27991da177e4SLinus Torvalds { 28007012b02aSJeff Layton struct locks_iterator *iter = f->private; 2801b8da9b10SLuo Longjun struct file_lock *cur, *tmp; 28029d78edeaSAlexey Gladkov struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb); 2803b8da9b10SLuo Longjun int level = 0; 28047f8ada98SPavel Emelyanov 28054ca52f53SJeff Layton cur = hlist_entry(v, struct file_lock, c.flc_link); 28067f8ada98SPavel Emelyanov 2807b8da9b10SLuo Longjun if (locks_translate_pid(cur, proc_pidns) == 0) 2808d67fd44fSNikolay Borisov return 0; 2809d67fd44fSNikolay Borisov 2810b8da9b10SLuo Longjun /* View this crossed linked list as a binary tree, the first member of fl_blocked_requests 28114ca52f53SJeff Layton * is the left child of current node, the next silibing in flc_blocked_member is the 2812b8da9b10SLuo Longjun * right child, we can alse get the parent of current node from fl_blocker, so this 2813b8da9b10SLuo Longjun * question becomes traversal of a binary tree 2814b8da9b10SLuo Longjun */ 2815b8da9b10SLuo Longjun while (cur != NULL) { 2816b8da9b10SLuo Longjun if (level) 2817b8da9b10SLuo Longjun lock_get_status(f, cur, iter->li_pos, "-> ", level); 2818b8da9b10SLuo Longjun else 2819b8da9b10SLuo Longjun lock_get_status(f, cur, iter->li_pos, "", level); 28207f8ada98SPavel Emelyanov 28214ca52f53SJeff Layton if (!list_empty(&cur->c.flc_blocked_requests)) { 2822b8da9b10SLuo Longjun /* Turn left */ 28234ca52f53SJeff Layton cur = list_first_entry_or_null(&cur->c.flc_blocked_requests, 28244ca52f53SJeff Layton struct file_lock, 28254ca52f53SJeff Layton c.flc_blocked_member); 2826b8da9b10SLuo Longjun level++; 2827b8da9b10SLuo Longjun } else { 2828b8da9b10SLuo Longjun /* Turn right */ 2829b8da9b10SLuo Longjun tmp = get_next_blocked_member(cur); 2830b8da9b10SLuo Longjun /* Fall back to parent node */ 28314ca52f53SJeff Layton while (tmp == NULL && cur->c.flc_blocker != NULL) { 28324ca52f53SJeff Layton cur = cur->c.flc_blocker; 2833b8da9b10SLuo Longjun level--; 2834b8da9b10SLuo Longjun tmp = get_next_blocked_member(cur); 2835b8da9b10SLuo Longjun } 2836b8da9b10SLuo Longjun cur = tmp; 2837b8da9b10SLuo Longjun } 2838b8da9b10SLuo Longjun } 28397f8ada98SPavel Emelyanov 28407f8ada98SPavel Emelyanov return 0; 28411da177e4SLinus Torvalds } 28421da177e4SLinus Torvalds 28436c8c9031SAndrey Vagin static void __show_fd_locks(struct seq_file *f, 28446c8c9031SAndrey Vagin struct list_head *head, int *id, 28456c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 28466c8c9031SAndrey Vagin { 28476c8c9031SAndrey Vagin struct file_lock *fl; 28486c8c9031SAndrey Vagin 28494ca52f53SJeff Layton list_for_each_entry(fl, head, c.flc_list) { 28506c8c9031SAndrey Vagin 28514ca52f53SJeff Layton if (filp != fl->c.flc_file) 28526c8c9031SAndrey Vagin continue; 28534ca52f53SJeff Layton if (fl->c.flc_owner != files && 28544ca52f53SJeff Layton fl->c.flc_owner != filp) 28556c8c9031SAndrey Vagin continue; 28566c8c9031SAndrey Vagin 28576c8c9031SAndrey Vagin (*id)++; 28586c8c9031SAndrey Vagin seq_puts(f, "lock:\t"); 2859b8da9b10SLuo Longjun lock_get_status(f, fl, *id, "", 0); 28606c8c9031SAndrey Vagin } 28616c8c9031SAndrey Vagin } 28626c8c9031SAndrey Vagin 28636c8c9031SAndrey Vagin void show_fd_locks(struct seq_file *f, 28646c8c9031SAndrey Vagin struct file *filp, struct files_struct *files) 28656c8c9031SAndrey Vagin { 2866c65454a9SJeff Layton struct inode *inode = file_inode(filp); 28676c8c9031SAndrey Vagin struct file_lock_context *ctx; 28686c8c9031SAndrey Vagin int id = 0; 28696c8c9031SAndrey Vagin 2870401a8b8fSJeff Layton ctx = locks_inode_context(inode); 28716c8c9031SAndrey Vagin if (!ctx) 28726c8c9031SAndrey Vagin return; 28736c8c9031SAndrey Vagin 28746c8c9031SAndrey Vagin spin_lock(&ctx->flc_lock); 28756c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_flock, &id, filp, files); 28766c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_posix, &id, filp, files); 28776c8c9031SAndrey Vagin __show_fd_locks(f, &ctx->flc_lease, &id, filp, files); 28786c8c9031SAndrey Vagin spin_unlock(&ctx->flc_lock); 28796c8c9031SAndrey Vagin } 28806c8c9031SAndrey Vagin 28817f8ada98SPavel Emelyanov static void *locks_start(struct seq_file *f, loff_t *pos) 2882b03dfdecSJeff Layton __acquires(&blocked_lock_lock) 28831da177e4SLinus Torvalds { 28847012b02aSJeff Layton struct locks_iterator *iter = f->private; 288599dc8292SJerome Marchand 28867012b02aSJeff Layton iter->li_pos = *pos + 1; 2887aba37660SPeter Zijlstra percpu_down_write(&file_rwsem); 28887b2296afSJeff Layton spin_lock(&blocked_lock_lock); 28897c3f654dSPeter Zijlstra return seq_hlist_start_percpu(&file_lock_list.hlist, &iter->li_cpu, *pos); 28901da177e4SLinus Torvalds } 28917f8ada98SPavel Emelyanov 28927f8ada98SPavel Emelyanov static void *locks_next(struct seq_file *f, void *v, loff_t *pos) 28937f8ada98SPavel Emelyanov { 28947012b02aSJeff Layton struct locks_iterator *iter = f->private; 28957012b02aSJeff Layton 28967012b02aSJeff Layton ++iter->li_pos; 28977c3f654dSPeter Zijlstra return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos); 28981da177e4SLinus Torvalds } 28997f8ada98SPavel Emelyanov 29007f8ada98SPavel Emelyanov static void locks_stop(struct seq_file *f, void *v) 2901b03dfdecSJeff Layton __releases(&blocked_lock_lock) 29027f8ada98SPavel Emelyanov { 29037b2296afSJeff Layton spin_unlock(&blocked_lock_lock); 2904aba37660SPeter Zijlstra percpu_up_write(&file_rwsem); 29051da177e4SLinus Torvalds } 29061da177e4SLinus Torvalds 2907d8ba7a36SAlexey Dobriyan static const struct seq_operations locks_seq_operations = { 29087f8ada98SPavel Emelyanov .start = locks_start, 29097f8ada98SPavel Emelyanov .next = locks_next, 29107f8ada98SPavel Emelyanov .stop = locks_stop, 29117f8ada98SPavel Emelyanov .show = locks_show, 29127f8ada98SPavel Emelyanov }; 2913d8ba7a36SAlexey Dobriyan 2914d8ba7a36SAlexey Dobriyan static int __init proc_locks_init(void) 2915d8ba7a36SAlexey Dobriyan { 291644414d82SChristoph Hellwig proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, 291744414d82SChristoph Hellwig sizeof(struct locks_iterator), NULL); 2918d8ba7a36SAlexey Dobriyan return 0; 2919d8ba7a36SAlexey Dobriyan } 292091899226SPaul Gortmaker fs_initcall(proc_locks_init); 29217f8ada98SPavel Emelyanov #endif 29227f8ada98SPavel Emelyanov 29231da177e4SLinus Torvalds static int __init filelock_init(void) 29241da177e4SLinus Torvalds { 29257012b02aSJeff Layton int i; 29267012b02aSJeff Layton 29274a075e39SJeff Layton flctx_cache = kmem_cache_create("file_lock_ctx", 29283754707bSLinus Torvalds sizeof(struct file_lock_context), 0, SLAB_PANIC, NULL); 29294a075e39SJeff Layton 29301da177e4SLinus Torvalds filelock_cache = kmem_cache_create("file_lock_cache", 29313754707bSLinus Torvalds sizeof(struct file_lock), 0, SLAB_PANIC, NULL); 2932ee19cc40SMiklos Szeredi 29337c3f654dSPeter Zijlstra for_each_possible_cpu(i) { 29347c3f654dSPeter Zijlstra struct file_lock_list_struct *fll = per_cpu_ptr(&file_lock_list, i); 29357c3f654dSPeter Zijlstra 29367c3f654dSPeter Zijlstra spin_lock_init(&fll->lock); 29377c3f654dSPeter Zijlstra INIT_HLIST_HEAD(&fll->hlist); 29387c3f654dSPeter Zijlstra } 29397012b02aSJeff Layton 294018f6622eSJeff Layton lease_notifier_chain_init(); 29411da177e4SLinus Torvalds return 0; 29421da177e4SLinus Torvalds } 29431da177e4SLinus Torvalds core_initcall(filelock_init); 2944