Lines Matching +full:input +full:- +full:justification

1 // SPDX-License-Identifier: GPL-2.0-only
19 * - the root of a tree may be an applied or waiting lock.
20 * - every other node in the tree is a waiting lock that
84 return fl->c.flc_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING); in lease_breaking()
89 if (fl->c.flc_flags & FL_UNLOCK_PENDING) in target_leasetype()
91 if (fl->c.flc_flags & FL_DOWNGRADE_PENDING) in target_leasetype()
93 return fl->c.flc_type; in target_leasetype()
102 .procname = "leases-enable",
110 .procname = "lease-break-time",
161 * In addition, it also protects the fl->fl_blocked_requests list, and the
162 * fl->fl_blocker pointer for file_lock structures that are acting as lock
190 spin_lock_init(&ctx->flc_lock); in locks_get_lock_context()
191 INIT_LIST_HEAD(&ctx->flc_flock); in locks_get_lock_context()
192 INIT_LIST_HEAD(&ctx->flc_posix); in locks_get_lock_context()
193 INIT_LIST_HEAD(&ctx->flc_lease); in locks_get_lock_context()
199 if (cmpxchg(&inode->i_flctx, NULL, ctx)) { in locks_get_lock_context()
215 list_type, flc->flc_owner, flc->flc_flags, in locks_dump_ctx_list()
216 flc->flc_type, flc->flc_pid); in locks_dump_ctx_list()
222 struct file_lock_context *ctx = inode->i_flctx; in locks_check_ctx_lists()
224 if (unlikely(!list_empty(&ctx->flc_flock) || in locks_check_ctx_lists()
225 !list_empty(&ctx->flc_posix) || in locks_check_ctx_lists()
226 !list_empty(&ctx->flc_lease))) { in locks_check_ctx_lists()
228 MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev), in locks_check_ctx_lists()
229 inode->i_ino); in locks_check_ctx_lists()
230 locks_dump_ctx_list(&ctx->flc_flock, "FLOCK"); in locks_check_ctx_lists()
231 locks_dump_ctx_list(&ctx->flc_posix, "POSIX"); in locks_check_ctx_lists()
232 locks_dump_ctx_list(&ctx->flc_lease, "LEASE"); in locks_check_ctx_lists()
243 if (flc->flc_file == filp) in locks_check_ctx_file_list()
246 list_type, MAJOR(inode->i_sb->s_dev), in locks_check_ctx_file_list()
247 MINOR(inode->i_sb->s_dev), inode->i_ino, in locks_check_ctx_file_list()
248 flc->flc_owner, flc->flc_flags, in locks_check_ctx_file_list()
249 flc->flc_type, flc->flc_pid); in locks_check_ctx_file_list()
265 INIT_HLIST_NODE(&flc->flc_link); in locks_init_lock_heads()
266 INIT_LIST_HEAD(&flc->flc_list); in locks_init_lock_heads()
267 INIT_LIST_HEAD(&flc->flc_blocked_requests); in locks_init_lock_heads()
268 INIT_LIST_HEAD(&flc->flc_blocked_member); in locks_init_lock_heads()
269 init_waitqueue_head(&flc->flc_wait); in locks_init_lock_heads()
278 locks_init_lock_heads(&fl->c); in locks_alloc_lock()
290 locks_init_lock_heads(&fl->c); in locks_alloc_lease()
298 struct file_lock_core *flc = &fl->c; in locks_release_private()
300 BUG_ON(waitqueue_active(&flc->flc_wait)); in locks_release_private()
301 BUG_ON(!list_empty(&flc->flc_list)); in locks_release_private()
302 BUG_ON(!list_empty(&flc->flc_blocked_requests)); in locks_release_private()
303 BUG_ON(!list_empty(&flc->flc_blocked_member)); in locks_release_private()
304 BUG_ON(!hlist_unhashed(&flc->flc_link)); in locks_release_private()
306 if (fl->fl_ops) { in locks_release_private()
307 if (fl->fl_ops->fl_release_private) in locks_release_private()
308 fl->fl_ops->fl_release_private(fl); in locks_release_private()
309 fl->fl_ops = NULL; in locks_release_private()
312 if (fl->fl_lmops) { in locks_release_private()
313 if (fl->fl_lmops->lm_put_owner) { in locks_release_private()
314 fl->fl_lmops->lm_put_owner(flc->flc_owner); in locks_release_private()
315 flc->flc_owner = NULL; in locks_release_private()
317 fl->fl_lmops = NULL; in locks_release_private()
323 * locks_owner_has_blockers - Check for blocking lock requests
335 spin_lock(&flctx->flc_lock); in locks_owner_has_blockers()
336 list_for_each_entry(flc, &flctx->flc_posix, flc_list) { in locks_owner_has_blockers()
337 if (flc->flc_owner != owner) in locks_owner_has_blockers()
339 if (!list_empty(&flc->flc_blocked_requests)) { in locks_owner_has_blockers()
340 spin_unlock(&flctx->flc_lock); in locks_owner_has_blockers()
344 spin_unlock(&flctx->flc_lock); in locks_owner_has_blockers()
371 list_del_init(&flc->flc_list); in locks_dispose_list()
372 if (flc->flc_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) in locks_dispose_list()
382 locks_init_lock_heads(&fl->c); in locks_init_lock()
389 locks_init_lock_heads(&fl->c); in locks_init_lease()
398 new->c.flc_owner = fl->c.flc_owner; in locks_copy_conflock()
399 new->c.flc_pid = fl->c.flc_pid; in locks_copy_conflock()
400 new->c.flc_file = NULL; in locks_copy_conflock()
401 new->c.flc_flags = fl->c.flc_flags; in locks_copy_conflock()
402 new->c.flc_type = fl->c.flc_type; in locks_copy_conflock()
403 new->fl_start = fl->fl_start; in locks_copy_conflock()
404 new->fl_end = fl->fl_end; in locks_copy_conflock()
405 new->fl_lmops = fl->fl_lmops; in locks_copy_conflock()
406 new->fl_ops = NULL; in locks_copy_conflock()
408 if (fl->fl_lmops) { in locks_copy_conflock()
409 if (fl->fl_lmops->lm_get_owner) in locks_copy_conflock()
410 fl->fl_lmops->lm_get_owner(fl->c.flc_owner); in locks_copy_conflock()
417 /* "new" must be a freshly-initialized lock */ in locks_copy_lock()
418 WARN_ON_ONCE(new->fl_ops); in locks_copy_lock()
422 new->c.flc_file = fl->c.flc_file; in locks_copy_lock()
423 new->fl_ops = fl->fl_ops; in locks_copy_lock()
425 if (fl->fl_ops) { in locks_copy_lock()
426 if (fl->fl_ops->fl_copy_lock) in locks_copy_lock()
427 fl->fl_ops->fl_copy_lock(new, fl); in locks_copy_lock()
437 * As ctx->flc_lock is held, new requests cannot be added to in locks_move_blocks()
438 * ->flc_blocked_requests, so we don't need a lock to check if it in locks_move_blocks()
441 if (list_empty(&fl->c.flc_blocked_requests)) in locks_move_blocks()
444 list_splice_init(&fl->c.flc_blocked_requests, in locks_move_blocks()
445 &new->c.flc_blocked_requests); in locks_move_blocks()
446 list_for_each_entry(f, &new->c.flc_blocked_requests, in locks_move_blocks()
448 f->c.flc_blocker = &new->c; in locks_move_blocks()
461 return -EINVAL; in flock_translate_cmd()
469 fl->c.flc_file = filp; in flock_make_lock()
470 fl->c.flc_owner = filp; in flock_make_lock()
471 fl->c.flc_pid = current->tgid; in flock_make_lock()
472 fl->c.flc_flags = FL_FLOCK; in flock_make_lock()
473 fl->c.flc_type = type; in flock_make_lock()
474 fl->fl_end = OFFSET_MAX; in flock_make_lock()
483 flc->flc_type = type; in assign_type()
486 return -EINVAL; in assign_type()
494 switch (l->l_whence) { in flock64_to_posix_lock()
496 fl->fl_start = 0; in flock64_to_posix_lock()
499 fl->fl_start = filp->f_pos; in flock64_to_posix_lock()
502 fl->fl_start = i_size_read(file_inode(filp)); in flock64_to_posix_lock()
505 return -EINVAL; in flock64_to_posix_lock()
507 if (l->l_start > OFFSET_MAX - fl->fl_start) in flock64_to_posix_lock()
508 return -EOVERFLOW; in flock64_to_posix_lock()
509 fl->fl_start += l->l_start; in flock64_to_posix_lock()
510 if (fl->fl_start < 0) in flock64_to_posix_lock()
511 return -EINVAL; in flock64_to_posix_lock()
513 /* POSIX-1996 leaves the case l->l_len < 0 undefined; in flock64_to_posix_lock()
514 POSIX-2001 defines it. */ in flock64_to_posix_lock()
515 if (l->l_len > 0) { in flock64_to_posix_lock()
516 if (l->l_len - 1 > OFFSET_MAX - fl->fl_start) in flock64_to_posix_lock()
517 return -EOVERFLOW; in flock64_to_posix_lock()
518 fl->fl_end = fl->fl_start + (l->l_len - 1); in flock64_to_posix_lock()
520 } else if (l->l_len < 0) { in flock64_to_posix_lock()
521 if (fl->fl_start + l->l_len < 0) in flock64_to_posix_lock()
522 return -EINVAL; in flock64_to_posix_lock()
523 fl->fl_end = fl->fl_start - 1; in flock64_to_posix_lock()
524 fl->fl_start += l->l_len; in flock64_to_posix_lock()
526 fl->fl_end = OFFSET_MAX; in flock64_to_posix_lock()
528 fl->c.flc_owner = current->files; in flock64_to_posix_lock()
529 fl->c.flc_pid = current->tgid; in flock64_to_posix_lock()
530 fl->c.flc_file = filp; in flock64_to_posix_lock()
531 fl->c.flc_flags = FL_POSIX; in flock64_to_posix_lock()
532 fl->fl_ops = NULL; in flock64_to_posix_lock()
533 fl->fl_lmops = NULL; in flock64_to_posix_lock()
535 return assign_type(&fl->c, l->l_type); in flock64_to_posix_lock()
545 .l_type = l->l_type, in flock_to_posix_lock()
546 .l_whence = l->l_whence, in flock_to_posix_lock()
547 .l_start = l->l_start, in flock_to_posix_lock()
548 .l_len = l->l_len, in flock_to_posix_lock()
558 kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG); in lease_break_callback()
565 struct file *filp = fl->c.flc_file; in lease_setup()
573 if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa)) in lease_setup()
590 if (assign_type(&fl->c, type) != 0) in lease_init()
591 return -EINVAL; in lease_init()
593 fl->c.flc_owner = filp; in lease_init()
594 fl->c.flc_pid = current->tgid; in lease_init()
596 fl->c.flc_file = filp; in lease_init()
597 fl->c.flc_flags = FL_LEASE; in lease_init()
598 fl->fl_lmops = &lease_manager_ops; in lease_init()
606 int error = -ENOMEM; in lease_alloc()
623 return ((fl1->fl_end >= fl2->fl_start) && in locks_overlap()
624 (fl2->fl_end >= fl1->fl_start)); in locks_overlap()
632 return fl1->flc_owner == fl2->flc_owner; in posix_same_owner()
642 spin_lock(&fll->lock); in locks_insert_global_locks()
643 flc->flc_link_cpu = smp_processor_id(); in locks_insert_global_locks()
644 hlist_add_head(&flc->flc_link, &fll->hlist); in locks_insert_global_locks()
645 spin_unlock(&fll->lock); in locks_insert_global_locks()
660 if (hlist_unhashed(&flc->flc_link)) in locks_delete_global_locks()
663 fll = per_cpu_ptr(&file_lock_list, flc->flc_link_cpu); in locks_delete_global_locks()
664 spin_lock(&fll->lock); in locks_delete_global_locks()
665 hlist_del_init(&flc->flc_link); in locks_delete_global_locks()
666 spin_unlock(&fll->lock); in locks_delete_global_locks()
672 return (unsigned long) flc->flc_owner; in posix_owner_key()
679 hash_add(blocked_hash, &waiter->flc_link, posix_owner_key(waiter)); in locks_insert_global_blocked()
686 hash_del(&waiter->flc_link); in locks_delete_global_blocked()
697 list_del_init(&waiter->flc_blocked_member); in __locks_unlink_block()
702 while (!list_empty(&blocker->flc_blocked_requests)) { in __locks_wake_up_blocks()
706 waiter = list_first_entry(&blocker->flc_blocked_requests, in __locks_wake_up_blocks()
711 if ((waiter->flc_flags & (FL_POSIX | FL_FLOCK)) && in __locks_wake_up_blocks()
712 fl->fl_lmops && fl->fl_lmops->lm_notify) in __locks_wake_up_blocks()
713 fl->fl_lmops->lm_notify(fl); in __locks_wake_up_blocks()
722 smp_store_release(&waiter->flc_blocker, NULL); in __locks_wake_up_blocks()
728 int status = -ENOENT; in __locks_delete_block()
751 if (!smp_load_acquire(&waiter->flc_blocker) && in __locks_delete_block()
752 list_empty(&waiter->flc_blocked_requests)) in __locks_delete_block()
756 if (waiter->flc_blocker) in __locks_delete_block()
765 smp_store_release(&waiter->flc_blocker, NULL); in __locks_delete_block()
771 * locks_delete_block - stop waiting for a file lock
778 return __locks_delete_block(&waiter->c); in locks_delete_block()
804 BUG_ON(!list_empty(&waiter->flc_blocked_member)); in __locks_insert_block()
806 list_for_each_entry(flc, &blocker->flc_blocked_requests, flc_blocked_member) in __locks_insert_block()
811 waiter->flc_blocker = blocker; in __locks_insert_block()
812 list_add_tail(&waiter->flc_blocked_member, in __locks_insert_block()
813 &blocker->flc_blocked_requests); in __locks_insert_block()
815 if ((blocker->flc_flags & (FL_POSIX|FL_OFDLCK)) == FL_POSIX) in __locks_insert_block()
818 /* The requests in waiter->flc_blocked are known to conflict with in __locks_insert_block()
839 * Must be called with the inode->flc_lock held!
850 if (list_empty(&blocker->flc_blocked_requests)) in locks_wake_up_blocks()
861 list_add_tail(&fl->flc_list, before); in locks_insert_lock_ctx()
869 list_del_init(&fl->flc_list); in locks_unlink_lock_ctx()
878 list_add(&fl->flc_list, dispose); in locks_delete_lock_ctx()
889 if (sys_flc->flc_type == F_WRLCK) in locks_conflict()
891 if (caller_flc->flc_type == F_WRLCK) in locks_conflict()
919 * path so checks for additional GETLK-specific things like F_UNLCK.
924 struct file_lock_core *caller = &caller_fl->c; in posix_test_locks_conflict()
925 struct file_lock_core *sys = &sys_fl->c; in posix_test_locks_conflict()
945 if (caller_flc->flc_file == sys_flc->flc_file) in flock_locks_conflict()
961 if (!ctx || list_empty_careful(&ctx->flc_posix)) { in posix_test_lock()
962 fl->c.flc_type = F_UNLCK; in posix_test_lock()
967 spin_lock(&ctx->flc_lock); in posix_test_lock()
968 list_for_each_entry(cfl, &ctx->flc_posix, c.flc_list) { in posix_test_lock()
971 if (cfl->fl_lmops && cfl->fl_lmops->lm_lock_expirable in posix_test_lock()
972 && (*cfl->fl_lmops->lm_lock_expirable)(cfl)) { in posix_test_lock()
973 owner = cfl->fl_lmops->lm_mod_owner; in posix_test_lock()
974 func = cfl->fl_lmops->lm_expire_lock; in posix_test_lock()
976 spin_unlock(&ctx->flc_lock); in posix_test_lock()
984 fl->c.flc_type = F_UNLCK; in posix_test_lock()
986 spin_unlock(&ctx->flc_lock); in posix_test_lock()
1033 while (flc->flc_blocker) in what_owner_is_waiting_for()
1034 flc = flc->flc_blocker; in what_owner_is_waiting_for()
1045 struct file_lock_core *caller = &caller_fl->c; in posix_locks_deadlock()
1046 struct file_lock_core *blocker = &block_fl->c; in posix_locks_deadlock()
1053 * FL_OFDLCK locks, since they aren't owned by a process, per-se. in posix_locks_deadlock()
1055 if (caller->flc_flags & FL_OFDLCK) in posix_locks_deadlock()
1072 * value for -ENOENT.
1083 ctx = locks_get_lock_context(inode, request->c.flc_type); in flock_lock_inode()
1085 if (request->c.flc_type != F_UNLCK) in flock_lock_inode()
1086 return -ENOMEM; in flock_lock_inode()
1087 return (request->c.flc_flags & FL_EXISTS) ? -ENOENT : 0; in flock_lock_inode()
1090 if (!(request->c.flc_flags & FL_ACCESS) && (request->c.flc_type != F_UNLCK)) { in flock_lock_inode()
1093 return -ENOMEM; in flock_lock_inode()
1097 spin_lock(&ctx->flc_lock); in flock_lock_inode()
1098 if (request->c.flc_flags & FL_ACCESS) in flock_lock_inode()
1101 list_for_each_entry(fl, &ctx->flc_flock, c.flc_list) { in flock_lock_inode()
1102 if (request->c.flc_file != fl->c.flc_file) in flock_lock_inode()
1104 if (request->c.flc_type == fl->c.flc_type) in flock_lock_inode()
1107 locks_delete_lock_ctx(&fl->c, &dispose); in flock_lock_inode()
1112 if ((request->c.flc_flags & FL_EXISTS) && !found) in flock_lock_inode()
1113 error = -ENOENT; in flock_lock_inode()
1118 list_for_each_entry(fl, &ctx->flc_flock, c.flc_list) { in flock_lock_inode()
1119 if (!flock_locks_conflict(&request->c, &fl->c)) in flock_lock_inode()
1121 error = -EAGAIN; in flock_lock_inode()
1122 if (!(request->c.flc_flags & FL_SLEEP)) in flock_lock_inode()
1125 locks_insert_block(&fl->c, &request->c, flock_locks_conflict); in flock_lock_inode()
1128 if (request->c.flc_flags & FL_ACCESS) in flock_lock_inode()
1132 locks_insert_lock_ctx(&new_fl->c, &ctx->flc_flock); in flock_lock_inode()
1137 spin_unlock(&ctx->flc_lock); in flock_lock_inode()
1161 ctx = locks_get_lock_context(inode, request->c.flc_type); in posix_lock_inode()
1163 return lock_is_unlock(request) ? 0 : -ENOMEM; in posix_lock_inode()
1171 if (!(request->c.flc_flags & FL_ACCESS) && in posix_lock_inode()
1172 (request->c.flc_type != F_UNLCK || in posix_lock_inode()
1173 request->fl_start != 0 || request->fl_end != OFFSET_MAX)) { in posix_lock_inode()
1180 spin_lock(&ctx->flc_lock); in posix_lock_inode()
1186 if (request->c.flc_type != F_UNLCK) { in posix_lock_inode()
1187 list_for_each_entry(fl, &ctx->flc_posix, c.flc_list) { in posix_lock_inode()
1188 if (!posix_locks_conflict(&request->c, &fl->c)) in posix_lock_inode()
1190 if (fl->fl_lmops && fl->fl_lmops->lm_lock_expirable in posix_lock_inode()
1191 && (*fl->fl_lmops->lm_lock_expirable)(fl)) { in posix_lock_inode()
1192 owner = fl->fl_lmops->lm_mod_owner; in posix_lock_inode()
1193 func = fl->fl_lmops->lm_expire_lock; in posix_lock_inode()
1195 spin_unlock(&ctx->flc_lock); in posix_lock_inode()
1203 error = -EAGAIN; in posix_lock_inode()
1204 if (!(request->c.flc_flags & FL_SLEEP)) in posix_lock_inode()
1210 error = -EDEADLK; in posix_lock_inode()
1216 __locks_wake_up_blocks(&request->c); in posix_lock_inode()
1219 __locks_insert_block(&fl->c, &request->c, in posix_lock_inode()
1229 if (request->c.flc_flags & FL_ACCESS) in posix_lock_inode()
1233 list_for_each_entry(fl, &ctx->flc_posix, c.flc_list) { in posix_lock_inode()
1234 if (posix_same_owner(&request->c, &fl->c)) in posix_lock_inode()
1239 list_for_each_entry_safe_from(fl, tmp, &ctx->flc_posix, c.flc_list) { in posix_lock_inode()
1240 if (!posix_same_owner(&request->c, &fl->c)) in posix_lock_inode()
1244 if (request->c.flc_type == fl->c.flc_type) { in posix_lock_inode()
1246 * "start - 1" rather than "end + 1". If end in posix_lock_inode()
1249 if (fl->fl_end < request->fl_start - 1) in posix_lock_inode()
1254 if (fl->fl_start - 1 > request->fl_end) in posix_lock_inode()
1262 if (fl->fl_start > request->fl_start) in posix_lock_inode()
1263 fl->fl_start = request->fl_start; in posix_lock_inode()
1265 request->fl_start = fl->fl_start; in posix_lock_inode()
1266 if (fl->fl_end < request->fl_end) in posix_lock_inode()
1267 fl->fl_end = request->fl_end; in posix_lock_inode()
1269 request->fl_end = fl->fl_end; in posix_lock_inode()
1271 locks_delete_lock_ctx(&fl->c, &dispose); in posix_lock_inode()
1280 if (fl->fl_end < request->fl_start) in posix_lock_inode()
1282 if (fl->fl_start > request->fl_end) in posix_lock_inode()
1286 if (fl->fl_start < request->fl_start) in posix_lock_inode()
1291 if (fl->fl_end > request->fl_end) { in posix_lock_inode()
1295 if (fl->fl_start >= request->fl_start) { in posix_lock_inode()
1300 locks_delete_lock_ctx(&fl->c, &dispose); in posix_lock_inode()
1310 error = -ENOLCK; in posix_lock_inode()
1317 locks_insert_lock_ctx(&request->c, in posix_lock_inode()
1318 &fl->c.flc_list); in posix_lock_inode()
1319 locks_delete_lock_ctx(&fl->c, &dispose); in posix_lock_inode()
1330 error = -ENOLCK; /* "no luck" */ in posix_lock_inode()
1337 if (request->c.flc_flags & FL_EXISTS) in posix_lock_inode()
1338 error = -ENOENT; in posix_lock_inode()
1343 error = -ENOLCK; in posix_lock_inode()
1348 locks_insert_lock_ctx(&new_fl->c, &fl->c.flc_list); in posix_lock_inode()
1360 locks_insert_lock_ctx(&left->c, &fl->c.flc_list); in posix_lock_inode()
1362 right->fl_start = request->fl_end + 1; in posix_lock_inode()
1363 locks_wake_up_blocks(&right->c); in posix_lock_inode()
1366 left->fl_end = request->fl_start - 1; in posix_lock_inode()
1367 locks_wake_up_blocks(&left->c); in posix_lock_inode()
1371 spin_unlock(&ctx->flc_lock); in posix_lock_inode()
1386 * posix_lock_file - Apply a POSIX-style lock to a file
1397 * value for -ENOENT.
1407 * posix_lock_inode_wait - Apply a POSIX-style lock to a file
1421 error = wait_event_interruptible(fl->c.flc_wait, in posix_lock_inode_wait()
1422 list_empty(&fl->c.flc_blocked_member)); in posix_lock_inode_wait()
1434 fl->c.flc_flags &= ~FL_UNLOCK_PENDING; in lease_clear_pending()
1437 fl->c.flc_flags &= ~FL_DOWNGRADE_PENDING; in lease_clear_pending()
1444 int error = assign_type(&fl->c, arg); in lease_modify()
1449 locks_wake_up_blocks(&fl->c); in lease_modify()
1451 struct file *filp = fl->c.flc_file; in lease_modify()
1454 file_f_owner(filp)->signum = 0; in lease_modify()
1455 fasync_helper(0, fl->c.flc_file, 0, &fl->fl_fasync); in lease_modify()
1456 if (fl->fl_fasync != NULL) { in lease_modify()
1457 printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync); in lease_modify()
1458 fl->fl_fasync = NULL; in lease_modify()
1460 locks_delete_lock_ctx(&fl->c, dispose); in lease_modify()
1476 struct file_lock_context *ctx = inode->i_flctx; in time_out_leases()
1479 lockdep_assert_held(&ctx->flc_lock); in time_out_leases()
1481 list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { in time_out_leases()
1483 if (past_time(fl->fl_downgrade_time)) in time_out_leases()
1485 if (past_time(fl->fl_break_time)) in time_out_leases()
1496 if (lease->fl_lmops->lm_breaker_owns_lease in leases_conflict()
1497 && lease->fl_lmops->lm_breaker_owns_lease(lease)) in leases_conflict()
1499 if ((bc->flc_flags & FL_LAYOUT) != (lc->flc_flags & FL_LAYOUT)) { in leases_conflict()
1503 if ((bc->flc_flags & FL_DELEG) && (lc->flc_flags & FL_LEASE)) { in leases_conflict()
1517 struct file_lock_context *ctx = inode->i_flctx; in any_leases_conflict()
1520 lockdep_assert_held(&ctx->flc_lock); in any_leases_conflict()
1522 list_for_each_entry(flc, &ctx->flc_lease, flc_list) { in any_leases_conflict()
1523 if (leases_conflict(flc, &breaker->c)) in any_leases_conflict()
1530 * __break_lease - revoke all outstanding leases on file
1554 new_fl->c.flc_flags = type; in __break_lease()
1556 /* typically we will check that ctx is non-NULL before calling */ in __break_lease()
1564 spin_lock(&ctx->flc_lock); in __break_lease()
1578 list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { in __break_lease()
1579 if (!leases_conflict(&fl->c, &new_fl->c)) in __break_lease()
1582 if (fl->c.flc_flags & FL_UNLOCK_PENDING) in __break_lease()
1584 fl->c.flc_flags |= FL_UNLOCK_PENDING; in __break_lease()
1585 fl->fl_break_time = break_time; in __break_lease()
1589 fl->c.flc_flags |= FL_DOWNGRADE_PENDING; in __break_lease()
1590 fl->fl_downgrade_time = break_time; in __break_lease()
1592 if (fl->fl_lmops->lm_break(fl)) in __break_lease()
1593 locks_delete_lock_ctx(&fl->c, &dispose); in __break_lease()
1596 if (list_empty(&ctx->flc_lease)) in __break_lease()
1601 error = -EWOULDBLOCK; in __break_lease()
1606 fl = list_first_entry(&ctx->flc_lease, struct file_lease, c.flc_list); in __break_lease()
1607 break_time = fl->fl_break_time; in __break_lease()
1609 break_time -= jiffies; in __break_lease()
1612 locks_insert_block(&fl->c, &new_fl->c, leases_conflict); in __break_lease()
1614 spin_unlock(&ctx->flc_lock); in __break_lease()
1618 error = wait_event_interruptible_timeout(new_fl->c.flc_wait, in __break_lease()
1619 list_empty(&new_fl->c.flc_blocked_member), in __break_lease()
1623 spin_lock(&ctx->flc_lock); in __break_lease()
1625 __locks_delete_block(&new_fl->c); in __break_lease()
1638 spin_unlock(&ctx->flc_lock); in __break_lease()
1648 * lease_get_mtime - update modified time of an inode with exclusive lease
1653 * exclusive leases. The justification is that if someone has an
1663 if (ctx && !list_empty_careful(&ctx->flc_lease)) { in lease_get_mtime()
1664 spin_lock(&ctx->flc_lock); in lease_get_mtime()
1665 flc = list_first_entry_or_null(&ctx->flc_lease, in lease_get_mtime()
1667 if (flc && flc->flc_type == F_WRLCK) in lease_get_mtime()
1669 spin_unlock(&ctx->flc_lock); in lease_get_mtime()
1678 * fcntl_getlease - Enquire what lease is currently active
1709 if (ctx && !list_empty_careful(&ctx->flc_lease)) { in fcntl_getlease()
1711 spin_lock(&ctx->flc_lock); in fcntl_getlease()
1713 list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { in fcntl_getlease()
1714 if (fl->c.flc_file != filp) in fcntl_getlease()
1719 spin_unlock(&ctx->flc_lock); in fcntl_getlease()
1728 * check_conflicting_open - see if the given file points to an inode that has
1751 return inode_is_open_for_write(inode) ? -EAGAIN : 0; in check_conflicting_open()
1761 if (filp->f_mode & FMODE_WRITE) in check_conflicting_open()
1763 else if (filp->f_mode & FMODE_READ) in check_conflicting_open()
1766 if (atomic_read(&inode->i_writecount) != self_wcount || in check_conflicting_open()
1767 atomic_read(&inode->i_readcount) != self_rcount) in check_conflicting_open()
1768 return -EAGAIN; in check_conflicting_open()
1779 bool is_deleg = (*flp)->c.flc_flags & FL_DELEG; in generic_add_lease()
1793 return -ENOMEM; in generic_add_lease()
1799 * there's some chance of a conflict--we'd rather not in generic_add_lease()
1804 return -EAGAIN; in generic_add_lease()
1807 spin_lock(&ctx->flc_lock); in generic_add_lease()
1809 error = check_conflicting_open(filp, arg, lease->c.flc_flags); in generic_add_lease()
1821 error = -EAGAIN; in generic_add_lease()
1822 list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { in generic_add_lease()
1823 if (fl->c.flc_file == filp && in generic_add_lease()
1824 fl->c.flc_owner == lease->c.flc_owner) { in generic_add_lease()
1839 if (fl->c.flc_flags & FL_UNLOCK_PENDING) in generic_add_lease()
1845 error = lease->fl_lmops->lm_change(lease, arg, &dispose); in generic_add_lease()
1851 error = -EINVAL; in generic_add_lease()
1855 locks_insert_lock_ctx(&lease->c, &ctx->flc_lease); in generic_add_lease()
1866 error = check_conflicting_open(filp, arg, lease->c.flc_flags); in generic_add_lease()
1868 locks_unlink_lock_ctx(&lease->c); in generic_add_lease()
1873 if (lease->fl_lmops->lm_setup) in generic_add_lease()
1874 lease->fl_lmops->lm_setup(lease, priv); in generic_add_lease()
1876 spin_unlock(&ctx->flc_lock); in generic_add_lease()
1888 int error = -EAGAIN; in generic_delete_lease()
1901 spin_lock(&ctx->flc_lock); in generic_delete_lease()
1902 list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { in generic_delete_lease()
1903 if (fl->c.flc_file == filp && in generic_delete_lease()
1904 fl->c.flc_owner == owner) { in generic_delete_lease()
1911 error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose); in generic_delete_lease()
1912 spin_unlock(&ctx->flc_lock); in generic_delete_lease()
1919 * generic_setlease - sets a lease on an open file
1922 * @flp: input - file_lock to use, output - file_lock inserted
1926 * The (input) flp->fl_lmops->lm_break function is required
1937 if (!(*flp)->fl_lmops->lm_break) { in generic_setlease()
1939 return -ENOLCK; in generic_setlease()
1944 return -EINVAL; in generic_setlease()
1988 if (filp->f_op->setlease) in kernel_setlease()
1989 return filp->f_op->setlease(filp, arg, lease, priv); in kernel_setlease()
1996 * vfs_setlease - sets a lease on an open file
2005 * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be
2006 * set; if not, this function will return -ENOLCK (and generate a scary-looking
2009 * The "priv" pointer is passed directly to the lm_setup function as-is. It
2020 return -EACCES; in vfs_setlease()
2021 if (!S_ISREG(inode->i_mode)) in vfs_setlease()
2022 return -EINVAL; in vfs_setlease()
2043 return -ENOMEM; in do_fcntl_add_lease()
2045 new->fa_fd = fd; in do_fcntl_add_lease()
2056 * fcntl_setlease - sets a lease on an open file
2073 * flock_lock_inode_wait - Apply a FLOCK-style lock to a file
2087 error = wait_event_interruptible(fl->c.flc_wait, in flock_lock_inode_wait()
2088 list_empty(&fl->c.flc_blocked_member)); in flock_lock_inode_wait()
2097 * locks_lock_inode_wait - Apply a lock to an inode
2106 switch (fl->c.flc_flags & (FL_POSIX|FL_FLOCK)) { in locks_lock_inode_wait()
2121 * sys_flock: - flock() system call.
2128 * - %LOCK_SH -- a shared lock.
2129 * - %LOCK_EX -- an exclusive lock.
2130 * - %LOCK_UN -- remove an existing lock.
2131 * - %LOCK_MAND -- a 'mandatory' flock. (DEPRECATED)
2149 … flock(2). This support has been removed and the request ignored.\n", current->comm, current->pid); in SYSCALL_DEFINE2()
2159 return -EBADF; in SYSCALL_DEFINE2()
2161 if (type != F_UNLCK && !(fd_file(f)->f_mode & (FMODE_READ | FMODE_WRITE))) in SYSCALL_DEFINE2()
2162 return -EBADF; in SYSCALL_DEFINE2()
2174 if (fd_file(f)->f_op->flock) in SYSCALL_DEFINE2()
2175 error = fd_file(f)->f_op->flock(fd_file(f), in SYSCALL_DEFINE2()
2186 * vfs_test_lock - test file byte range lock
2190 * Returns -ERRNO on failure. Indicates presence of conflicting lock by
2191 * setting conf->fl_type to something other than F_UNLCK.
2195 WARN_ON_ONCE(filp != fl->c.flc_file); in vfs_test_lock()
2196 if (filp->f_op->lock) in vfs_test_lock()
2197 return filp->f_op->lock(filp, F_GETLK, fl); in vfs_test_lock()
2204 * locks_translate_pid - translate a file_lock's fl_pid number into a namespace
2215 if (fl->flc_flags & FL_OFDLCK) in locks_translate_pid()
2216 return -1; in locks_translate_pid()
2219 if (fl->flc_pid <= 0) in locks_translate_pid()
2220 return fl->flc_pid; in locks_translate_pid()
2228 return (pid_t) fl->flc_pid; in locks_translate_pid()
2231 pid = find_pid_ns(fl->flc_pid, &init_pid_ns); in locks_translate_pid()
2239 flock->l_pid = locks_translate_pid(&fl->c, task_active_pid_ns(current)); in posix_lock_to_flock()
2245 if (fl->fl_start > OFFT_OFFSET_MAX) in posix_lock_to_flock()
2246 return -EOVERFLOW; in posix_lock_to_flock()
2247 if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX) in posix_lock_to_flock()
2248 return -EOVERFLOW; in posix_lock_to_flock()
2250 flock->l_start = fl->fl_start; in posix_lock_to_flock()
2251 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : in posix_lock_to_flock()
2252 fl->fl_end - fl->fl_start + 1; in posix_lock_to_flock()
2253 flock->l_whence = 0; in posix_lock_to_flock()
2254 flock->l_type = fl->c.flc_type; in posix_lock_to_flock()
2261 flock->l_pid = locks_translate_pid(&fl->c, task_active_pid_ns(current)); in posix_lock_to_flock64()
2262 flock->l_start = fl->fl_start; in posix_lock_to_flock64()
2263 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : in posix_lock_to_flock64()
2264 fl->fl_end - fl->fl_start + 1; in posix_lock_to_flock64()
2265 flock->l_whence = 0; in posix_lock_to_flock64()
2266 flock->l_type = fl->c.flc_type; in posix_lock_to_flock64()
2280 return -ENOMEM; in fcntl_getlk()
2281 error = -EINVAL; in fcntl_getlk()
2282 if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK in fcntl_getlk()
2283 && flock->l_type != F_WRLCK) in fcntl_getlk()
2291 error = -EINVAL; in fcntl_getlk()
2292 if (flock->l_pid != 0) in fcntl_getlk()
2295 fl->c.flc_flags |= FL_OFDLCK; in fcntl_getlk()
2296 fl->c.flc_owner = filp; in fcntl_getlk()
2303 flock->l_type = fl->c.flc_type; in fcntl_getlk()
2304 if (fl->c.flc_type != F_UNLCK) { in fcntl_getlk()
2315 * vfs_lock_file - file byte range lock
2324 * If the filesystem defines a private ->lock() method, then @conf will
2329 * locks, the ->lock() interface may return asynchronously, before the lock has
2334 * Callers expecting ->lock() to return asynchronously will only use F_SETLK,
2336 * blocking lock. When ->lock() does return asynchronously, it must return
2337 * FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock request completes.
2338 * If the request is for non-blocking lock the file system should return
2346 * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED
2351 WARN_ON_ONCE(filp != fl->c.flc_file); in vfs_lock_file()
2352 if (filp->f_op->lock) in vfs_lock_file()
2353 return filp->f_op->lock(filp, cmd, fl); in vfs_lock_file()
2364 error = security_file_lock(filp, fl->c.flc_type); in do_lock_file_wait()
2372 error = wait_event_interruptible(fl->c.flc_wait, in do_lock_file_wait()
2373 list_empty(&fl->c.flc_blocked_member)); in do_lock_file_wait()
2382 /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */
2386 switch (fl->c.flc_type) { in check_fmode_for_setlk()
2388 if (!(fl->c.flc_file->f_mode & FMODE_READ)) in check_fmode_for_setlk()
2389 return -EBADF; in check_fmode_for_setlk()
2392 if (!(fl->c.flc_file->f_mode & FMODE_WRITE)) in check_fmode_for_setlk()
2393 return -EBADF; in check_fmode_for_setlk()
2410 return -ENOLCK; in fcntl_setlk()
2421 * If the cmd is requesting file-private locks, then set the in fcntl_setlk()
2426 error = -EINVAL; in fcntl_setlk()
2427 if (flock->l_pid != 0) in fcntl_setlk()
2431 file_lock->c.flc_flags |= FL_OFDLCK; in fcntl_setlk()
2432 file_lock->c.flc_owner = filp; in fcntl_setlk()
2435 error = -EINVAL; in fcntl_setlk()
2436 if (flock->l_pid != 0) in fcntl_setlk()
2440 file_lock->c.flc_flags |= FL_OFDLCK; in fcntl_setlk()
2441 file_lock->c.flc_owner = filp; in fcntl_setlk()
2444 file_lock->c.flc_flags |= FL_SLEEP; in fcntl_setlk()
2455 if (!error && file_lock->c.flc_type != F_UNLCK && in fcntl_setlk()
2456 !(file_lock->c.flc_flags & FL_OFDLCK)) { in fcntl_setlk()
2457 struct files_struct *files = current->files; in fcntl_setlk()
2459 * We need that spin_lock here - it prevents reordering between in fcntl_setlk()
2460 * update of i_flctx->flc_posix and check for it done in in fcntl_setlk()
2463 spin_lock(&files->file_lock); in fcntl_setlk()
2465 spin_unlock(&files->file_lock); in fcntl_setlk()
2468 error = -EBADF; in fcntl_setlk()
2488 return -ENOMEM; in fcntl_getlk64()
2490 error = -EINVAL; in fcntl_getlk64()
2491 if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK in fcntl_getlk64()
2492 && flock->l_type != F_WRLCK) in fcntl_getlk64()
2500 error = -EINVAL; in fcntl_getlk64()
2501 if (flock->l_pid != 0) in fcntl_getlk64()
2504 fl->c.flc_flags |= FL_OFDLCK; in fcntl_getlk64()
2505 fl->c.flc_owner = filp; in fcntl_getlk64()
2512 flock->l_type = fl->c.flc_type; in fcntl_getlk64()
2513 if (fl->c.flc_type != F_UNLCK) in fcntl_getlk64()
2532 return -ENOLCK; in fcntl_setlk64()
2543 * If the cmd is requesting file-private locks, then set the in fcntl_setlk64()
2548 error = -EINVAL; in fcntl_setlk64()
2549 if (flock->l_pid != 0) in fcntl_setlk64()
2553 file_lock->c.flc_flags |= FL_OFDLCK; in fcntl_setlk64()
2554 file_lock->c.flc_owner = filp; in fcntl_setlk64()
2557 error = -EINVAL; in fcntl_setlk64()
2558 if (flock->l_pid != 0) in fcntl_setlk64()
2562 file_lock->c.flc_flags |= FL_OFDLCK; in fcntl_setlk64()
2563 file_lock->c.flc_owner = filp; in fcntl_setlk64()
2566 file_lock->c.flc_flags |= FL_SLEEP; in fcntl_setlk64()
2577 if (!error && file_lock->c.flc_type != F_UNLCK && in fcntl_setlk64()
2578 !(file_lock->c.flc_flags & FL_OFDLCK)) { in fcntl_setlk64()
2579 struct files_struct *files = current->files; in fcntl_setlk64()
2581 * We need that spin_lock here - it prevents reordering between in fcntl_setlk64()
2582 * update of i_flctx->flc_posix and check for it done in in fcntl_setlk64()
2585 spin_lock(&files->file_lock); in fcntl_setlk64()
2587 spin_unlock(&files->file_lock); in fcntl_setlk64()
2590 error = -EBADF; in fcntl_setlk64()
2617 if (!ctx || list_empty(&ctx->flc_posix)) in locks_remove_posix()
2626 lock.c.flc_pid = current->tgid; in locks_remove_posix()
2633 if (lock.fl_ops && lock.fl_ops->fl_release_private) in locks_remove_posix()
2634 lock.fl_ops->fl_release_private(&lock); in locks_remove_posix()
2646 if (list_empty(&flctx->flc_flock)) in locks_remove_flock()
2652 if (filp->f_op->flock) in locks_remove_flock()
2653 filp->f_op->flock(filp, F_SETLKW, &fl); in locks_remove_flock()
2657 if (fl.fl_ops && fl.fl_ops->fl_release_private) in locks_remove_flock()
2658 fl.fl_ops->fl_release_private(&fl); in locks_remove_flock()
2668 if (list_empty(&ctx->flc_lease)) in locks_remove_lease()
2672 spin_lock(&ctx->flc_lock); in locks_remove_lease()
2673 list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) in locks_remove_lease()
2674 if (filp == fl->c.flc_file) in locks_remove_lease()
2676 spin_unlock(&ctx->flc_lock); in locks_remove_lease()
2702 spin_lock(&ctx->flc_lock); in locks_remove_file()
2703 locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX"); in locks_remove_file()
2704 locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK"); in locks_remove_file()
2705 locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE"); in locks_remove_file()
2706 spin_unlock(&ctx->flc_lock); in locks_remove_file()
2710 * vfs_cancel_lock - file byte range unblock lock
2718 WARN_ON_ONCE(filp != fl->c.flc_file); in vfs_cancel_lock()
2719 if (filp->f_op->lock) in vfs_cancel_lock()
2720 return filp->f_op->lock(filp, F_CANCELLK, fl); in vfs_cancel_lock()
2726 * vfs_inode_has_locks - are any file locks held on @inode?
2741 spin_lock(&ctx->flc_lock); in vfs_inode_has_locks()
2742 ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock); in vfs_inode_has_locks()
2743 spin_unlock(&ctx->flc_lock); in vfs_inode_has_locks()
2762 struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb); in lock_get_status()
2763 int type = flc->flc_type; in lock_get_status()
2773 if (flc->flc_file != NULL) in lock_get_status()
2774 inode = file_inode(flc->flc_file); in lock_get_status()
2779 seq_printf(f, "%*s", repeat - 1 + (int)strlen(pfx), pfx); in lock_get_status()
2781 if (flc->flc_flags & FL_POSIX) { in lock_get_status()
2782 if (flc->flc_flags & FL_ACCESS) in lock_get_status()
2784 else if (flc->flc_flags & FL_OFDLCK) in lock_get_status()
2791 } else if (flc->flc_flags & FL_FLOCK) { in lock_get_status()
2793 } else if (flc->flc_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) { in lock_get_status()
2798 if (flc->flc_flags & FL_DELEG) in lock_get_status()
2805 else if (flc->flc_file) in lock_get_status()
2818 MAJOR(inode->i_sb->s_dev), in lock_get_status()
2819 MINOR(inode->i_sb->s_dev), inode->i_ino); in lock_get_status()
2823 if (flc->flc_flags & FL_POSIX) { in lock_get_status()
2824 if (fl->fl_end == OFFSET_MAX) in lock_get_status()
2825 seq_printf(f, "%Ld EOF\n", fl->fl_start); in lock_get_status()
2827 seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end); in lock_get_status()
2838 if (node == NULL || node->flc_blocker == NULL) in get_next_blocked_member()
2843 if (list_entry_is_head(tmp, &node->flc_blocker->flc_blocked_requests, in get_next_blocked_member()
2854 struct locks_iterator *iter = f->private; in locks_show()
2856 struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb); in locks_show()
2871 lock_get_status(f, cur, iter->li_pos, "-> ", level); in locks_show()
2873 lock_get_status(f, cur, iter->li_pos, "", level); in locks_show()
2875 if (!list_empty(&cur->flc_blocked_requests)) { in locks_show()
2877 cur = list_first_entry_or_null(&cur->flc_blocked_requests, in locks_show()
2885 while (tmp == NULL && cur->flc_blocker != NULL) { in locks_show()
2886 cur = cur->flc_blocker; in locks_show()
2887 level--; in locks_show()
2905 if (filp != fl->flc_file) in __show_fd_locks()
2907 if (fl->flc_owner != files && fl->flc_owner != filp) in __show_fd_locks()
2927 spin_lock(&ctx->flc_lock); in show_fd_locks()
2928 __show_fd_locks(f, &ctx->flc_flock, &id, filp, files); in show_fd_locks()
2929 __show_fd_locks(f, &ctx->flc_posix, &id, filp, files); in show_fd_locks()
2930 __show_fd_locks(f, &ctx->flc_lease, &id, filp, files); in show_fd_locks()
2931 spin_unlock(&ctx->flc_lock); in show_fd_locks()
2937 struct locks_iterator *iter = f->private; in locks_start()
2939 iter->li_pos = *pos + 1; in locks_start()
2942 return seq_hlist_start_percpu(&file_lock_list.hlist, &iter->li_cpu, *pos); in locks_start()
2947 struct locks_iterator *iter = f->private; in locks_next()
2949 ++iter->li_pos; in locks_next()
2950 return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos); in locks_next()
2992 spin_lock_init(&fll->lock); in filelock_init()
2993 INIT_HLIST_HEAD(&fll->hlist); in filelock_init()