locks.c (320424c7d44f54c18df9812fd7c45f6963524002) locks.c (f7e33bdbd6d1bdf9c3df8bba5abcf3399f957ac3)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * linux/fs/locks.c
4 *
5 * Provide support for fcntl()'s F_GETLK, F_SETLK, and F_SETLKW calls.
6 * Doug Evans (dje@spiff.uucp), August 07, 1992
7 *
8 * Deadlock detection added.

--- 1383 unchanged lines hidden (view full) ---

1392 list_empty(&fl->fl_blocked_member));
1393 if (error)
1394 break;
1395 }
1396 locks_delete_block(fl);
1397 return error;
1398}
1399
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * linux/fs/locks.c
4 *
5 * Provide support for fcntl()'s F_GETLK, F_SETLK, and F_SETLKW calls.
6 * Doug Evans (dje@spiff.uucp), August 07, 1992
7 *
8 * Deadlock detection added.

--- 1383 unchanged lines hidden (view full) ---

1392 list_empty(&fl->fl_blocked_member));
1393 if (error)
1394 break;
1395 }
1396 locks_delete_block(fl);
1397 return error;
1398}
1399
1400#ifdef CONFIG_MANDATORY_FILE_LOCKING
1401/**
1402 * locks_mandatory_locked - Check for an active lock
1403 * @file: the file to check
1404 *
1405 * Searches the inode's list of locks to find any POSIX locks which conflict.
1406 * This function is called from locks_verify_locked() only.
1407 */
1408int locks_mandatory_locked(struct file *file)
1409{
1410 int ret;
1411 struct inode *inode = locks_inode(file);
1412 struct file_lock_context *ctx;
1413 struct file_lock *fl;
1414
1415 ctx = smp_load_acquire(&inode->i_flctx);
1416 if (!ctx || list_empty_careful(&ctx->flc_posix))
1417 return 0;
1418
1419 /*
1420 * Search the lock list for this inode for any POSIX locks.
1421 */
1422 spin_lock(&ctx->flc_lock);
1423 ret = 0;
1424 list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
1425 if (fl->fl_owner != current->files &&
1426 fl->fl_owner != file) {
1427 ret = -EAGAIN;
1428 break;
1429 }
1430 }
1431 spin_unlock(&ctx->flc_lock);
1432 return ret;
1433}
1434
1435/**
1436 * locks_mandatory_area - Check for a conflicting lock
1437 * @inode: the file to check
1438 * @filp: how the file was opened (if it was)
1439 * @start: first byte in the file to check
1440 * @end: lastbyte in the file to check
1441 * @type: %F_WRLCK for a write lock, else %F_RDLCK
1442 *
1443 * Searches the inode's list of locks to find any POSIX locks which conflict.
1444 */
1445int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start,
1446 loff_t end, unsigned char type)
1447{
1448 struct file_lock fl;
1449 int error;
1450 bool sleep = false;
1451
1452 locks_init_lock(&fl);
1453 fl.fl_pid = current->tgid;
1454 fl.fl_file = filp;
1455 fl.fl_flags = FL_POSIX | FL_ACCESS;
1456 if (filp && !(filp->f_flags & O_NONBLOCK))
1457 sleep = true;
1458 fl.fl_type = type;
1459 fl.fl_start = start;
1460 fl.fl_end = end;
1461
1462 for (;;) {
1463 if (filp) {
1464 fl.fl_owner = filp;
1465 fl.fl_flags &= ~FL_SLEEP;
1466 error = posix_lock_inode(inode, &fl, NULL);
1467 if (!error)
1468 break;
1469 }
1470
1471 if (sleep)
1472 fl.fl_flags |= FL_SLEEP;
1473 fl.fl_owner = current->files;
1474 error = posix_lock_inode(inode, &fl, NULL);
1475 if (error != FILE_LOCK_DEFERRED)
1476 break;
1477 error = wait_event_interruptible(fl.fl_wait,
1478 list_empty(&fl.fl_blocked_member));
1479 if (!error) {
1480 /*
1481 * If we've been sleeping someone might have
1482 * changed the permissions behind our back.
1483 */
1484 if (__mandatory_lock(inode))
1485 continue;
1486 }
1487
1488 break;
1489 }
1490 locks_delete_block(&fl);
1491
1492 return error;
1493}
1494EXPORT_SYMBOL(locks_mandatory_area);
1495#endif /* CONFIG_MANDATORY_FILE_LOCKING */
1496
1497static void lease_clear_pending(struct file_lock *fl, int arg)
1498{
1499 switch (arg) {
1500 case F_UNLCK:
1501 fl->fl_flags &= ~FL_UNLOCK_PENDING;
1502 fallthrough;
1503 case F_RDLCK:
1504 fl->fl_flags &= ~FL_DOWNGRADE_PENDING;

--- 976 unchanged lines hidden (view full) ---

2481 struct file_lock *file_lock = locks_alloc_lock();
2482 struct inode *inode = locks_inode(filp);
2483 struct file *f;
2484 int error;
2485
2486 if (file_lock == NULL)
2487 return -ENOLCK;
2488
1400static void lease_clear_pending(struct file_lock *fl, int arg)
1401{
1402 switch (arg) {
1403 case F_UNLCK:
1404 fl->fl_flags &= ~FL_UNLOCK_PENDING;
1405 fallthrough;
1406 case F_RDLCK:
1407 fl->fl_flags &= ~FL_DOWNGRADE_PENDING;

--- 976 unchanged lines hidden (view full) ---

2384 struct file_lock *file_lock = locks_alloc_lock();
2385 struct inode *inode = locks_inode(filp);
2386 struct file *f;
2387 int error;
2388
2389 if (file_lock == NULL)
2390 return -ENOLCK;
2391
2489 /* Don't allow mandatory locks on files that may be memory mapped
2490 * and shared.
2491 */
2492 if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
2493 error = -EAGAIN;
2494 goto out;
2495 }
2496
2497 error = flock_to_posix_lock(filp, file_lock, flock);
2498 if (error)
2499 goto out;
2500
2501 error = check_fmode_for_setlk(file_lock);
2502 if (error)
2503 goto out;
2504

--- 101 unchanged lines hidden (view full) ---

2606
2607/* Apply the lock described by l to an open file descriptor.
2608 * This implements both the F_SETLK and F_SETLKW commands of fcntl().
2609 */
2610int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
2611 struct flock64 *flock)
2612{
2613 struct file_lock *file_lock = locks_alloc_lock();
2392 error = flock_to_posix_lock(filp, file_lock, flock);
2393 if (error)
2394 goto out;
2395
2396 error = check_fmode_for_setlk(file_lock);
2397 if (error)
2398 goto out;
2399

--- 101 unchanged lines hidden (view full) ---

2501
2502/* Apply the lock described by l to an open file descriptor.
2503 * This implements both the F_SETLK and F_SETLKW commands of fcntl().
2504 */
2505int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
2506 struct flock64 *flock)
2507{
2508 struct file_lock *file_lock = locks_alloc_lock();
2614 struct inode *inode = locks_inode(filp);
2615 struct file *f;
2616 int error;
2617
2618 if (file_lock == NULL)
2619 return -ENOLCK;
2620
2509 struct file *f;
2510 int error;
2511
2512 if (file_lock == NULL)
2513 return -ENOLCK;
2514
2621 /* Don't allow mandatory locks on files that may be memory mapped
2622 * and shared.
2623 */
2624 if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
2625 error = -EAGAIN;
2626 goto out;
2627 }
2628
2629 error = flock64_to_posix_lock(filp, file_lock, flock);
2630 if (error)
2631 goto out;
2632
2633 error = check_fmode_for_setlk(file_lock);
2634 if (error)
2635 goto out;
2636

--- 215 unchanged lines hidden (view full) ---

2852 if (fl->fl_flags & FL_ACCESS)
2853 seq_puts(f, "ACCESS");
2854 else if (IS_OFDLCK(fl))
2855 seq_puts(f, "OFDLCK");
2856 else
2857 seq_puts(f, "POSIX ");
2858
2859 seq_printf(f, " %s ",
2515 error = flock64_to_posix_lock(filp, file_lock, flock);
2516 if (error)
2517 goto out;
2518
2519 error = check_fmode_for_setlk(file_lock);
2520 if (error)
2521 goto out;
2522

--- 215 unchanged lines hidden (view full) ---

2738 if (fl->fl_flags & FL_ACCESS)
2739 seq_puts(f, "ACCESS");
2740 else if (IS_OFDLCK(fl))
2741 seq_puts(f, "OFDLCK");
2742 else
2743 seq_puts(f, "POSIX ");
2744
2745 seq_printf(f, " %s ",
2860 (inode == NULL) ? "*NOINODE*" :
2861 mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
2746 (inode == NULL) ? "*NOINODE*" : "ADVISORY ");
2862 } else if (IS_FLOCK(fl)) {
2863 if (fl->fl_type & LOCK_MAND) {
2864 seq_puts(f, "FLOCK MSNFS ");
2865 } else {
2866 seq_puts(f, "FLOCK ADVISORY ");
2867 }
2868 } else if (IS_LEASE(fl)) {
2869 if (fl->fl_flags & FL_DELEG)

--- 205 unchanged lines hidden ---
2747 } else if (IS_FLOCK(fl)) {
2748 if (fl->fl_type & LOCK_MAND) {
2749 seq_puts(f, "FLOCK MSNFS ");
2750 } else {
2751 seq_puts(f, "FLOCK ADVISORY ");
2752 }
2753 } else if (IS_LEASE(fl)) {
2754 if (fl->fl_flags & FL_DELEG)

--- 205 unchanged lines hidden ---