locks: let the caller free file_lock on ->setlease failure

The caller allocated it, the caller should free it.

The only issue so far is that we could change the flp pointer even on an
error return if the fl_change callback failed. But we can simply move
the flp assignment after the fl_change invocation, as the callers don't
care about the flp return value if the setlease call failed.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Christoph Hellwig and committed by Linus Torvalds 51ee4b84 96f93593

+13 -17
+1 -4
fs/cifs/cifsfs.c
··· 625 625 knows that the file won't be changed on the server 626 626 by anyone else */ 627 627 return generic_setlease(file, arg, lease); 628 - else { 629 - if (arg != F_UNLCK) 630 - locks_free_lock(*lease); 628 + else 631 629 return -EAGAIN; 632 - } 633 630 } 634 631 635 632 struct file_system_type cifs_fs_type = {
-2
fs/gfs2/file.c
··· 629 629 630 630 static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl) 631 631 { 632 - if (arg != F_UNLCK) 633 - locks_free_lock(*fl); 634 632 return -EINVAL; 635 633 } 636 634
+11 -9
fs/locks.c
··· 1428 1428 goto out; 1429 1429 1430 1430 if (my_before != NULL) { 1431 - *flp = *my_before; 1432 1431 error = lease->fl_lmops->fl_change(my_before, arg); 1432 + if (!error) 1433 + *flp = *my_before; 1433 1434 goto out; 1434 1435 } 1435 1436 ··· 1445 1444 return 0; 1446 1445 1447 1446 out: 1448 - if (arg != F_UNLCK) 1449 - locks_free_lock(lease); 1450 1447 return error; 1451 1448 } 1452 1449 EXPORT_SYMBOL(generic_setlease); ··· 1523 1524 } 1524 1525 lock_flocks(); 1525 1526 error = __vfs_setlease(filp, arg, &fl); 1526 - if (error) 1527 - goto out_unlock; 1527 + if (error) { 1528 + unlock_flocks(); 1529 + locks_free_lock(fl); 1530 + goto out_free_fasync; 1531 + } 1528 1532 1529 1533 /* 1530 1534 * fasync_insert_entry() returns the old entry if any. ··· 1543 1541 fl->fl_type = F_UNLCK | F_INPROGRESS; 1544 1542 fl->fl_break_time = jiffies - 10; 1545 1543 time_out_leases(inode); 1546 - goto out_unlock; 1544 + } else { 1545 + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); 1547 1546 } 1548 - 1549 - error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); 1550 - out_unlock: 1551 1547 unlock_flocks(); 1548 + 1549 + out_free_fasync: 1552 1550 if (new) 1553 1551 fasync_free(new); 1554 1552 return error;
-2
fs/nfs/file.c
··· 884 884 dprintk("NFS: setlease(%s/%s, arg=%ld)\n", 885 885 file->f_path.dentry->d_parent->d_name.name, 886 886 file->f_path.dentry->d_name.name, arg); 887 - if (arg != F_UNLCK) 888 - locks_free_lock(*fl); 889 887 return -EINVAL; 890 888 }
+1
fs/nfsd/nfs4state.c
··· 2652 2652 if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { 2653 2653 dprintk("NFSD: setlease failed [%d], no delegation\n", status); 2654 2654 dp->dl_flock = NULL; 2655 + locks_free_lock(fl); 2655 2656 unhash_delegation(dp); 2656 2657 flag = NFS4_OPEN_DELEGATE_NONE; 2657 2658 goto out;