locks: prevent ENOMEM on lease unlock

Removing a lock shouldn't require any allocations; a failure due to
ENOMEM leaves the caller with a choice between retrying or giving up and
leaking an unused lease.

Next we should split the other lease calls into add and delete cases.
I wanted to start with just the bugfix.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by J. Bruce Fields and committed by Linus Torvalds 0ceaf6c7 0d07025e

+30 -13
+30 -13
fs/locks.c
··· 1441 return 0; 1442 1443 out: 1444 - locks_free_lock(lease); 1445 return error; 1446 } 1447 EXPORT_SYMBOL(generic_setlease); ··· 1494 } 1495 EXPORT_SYMBOL_GPL(vfs_setlease); 1496 1497 - /** 1498 - * fcntl_setlease - sets a lease on an open file 1499 - * @fd: open file descriptor 1500 - * @filp: file pointer 1501 - * @arg: type of lease to obtain 1502 - * 1503 - * Call this fcntl to establish a lease on the file. 1504 - * Note that you also need to call %F_SETSIG to 1505 - * receive a signal when the lease is broken. 1506 - */ 1507 - int fcntl_setlease(unsigned int fd, struct file *filp, long arg) 1508 { 1509 struct file_lock *fl; 1510 struct fasync_struct *new; ··· 1521 } 1522 lock_flocks(); 1523 error = __vfs_setlease(filp, arg, &fl); 1524 - if (error || arg == F_UNLCK) 1525 goto out_unlock; 1526 1527 /* ··· 1547 if (new) 1548 fasync_free(new); 1549 return error; 1550 } 1551 1552 /**
··· 1441 return 0; 1442 1443 out: 1444 + if (arg != F_UNLCK) 1445 + locks_free_lock(lease); 1446 return error; 1447 } 1448 EXPORT_SYMBOL(generic_setlease); ··· 1493 } 1494 EXPORT_SYMBOL_GPL(vfs_setlease); 1495 1496 + static int do_fcntl_delete_lease(struct file *filp) 1497 + { 1498 + struct file_lock fl, *flp = &fl; 1499 + 1500 + lease_init(filp, F_UNLCK, flp); 1501 + 1502 + return vfs_setlease(filp, F_UNLCK, &flp); 1503 + } 1504 + 1505 + static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) 1506 { 1507 struct file_lock *fl; 1508 struct fasync_struct *new; ··· 1521 } 1522 lock_flocks(); 1523 error = __vfs_setlease(filp, arg, &fl); 1524 + if (error) 1525 goto out_unlock; 1526 1527 /* ··· 1547 if (new) 1548 fasync_free(new); 1549 return error; 1550 + } 1551 + 1552 + /** 1553 + * fcntl_setlease - sets a lease on an open file 1554 + * @fd: open file descriptor 1555 + * @filp: file pointer 1556 + * @arg: type of lease to obtain 1557 + * 1558 + * Call this fcntl to establish a lease on the file. 1559 + * Note that you also need to call %F_SETSIG to 1560 + * receive a signal when the lease is broken. 1561 + */ 1562 + int fcntl_setlease(unsigned int fd, struct file *filp, long arg) 1563 + { 1564 + if (arg == F_UNLCK) 1565 + return do_fcntl_delete_lease(filp); 1566 + return do_fcntl_add_lease(fd, filp, arg); 1567 } 1568 1569 /**