summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-10-31 08:35:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-31 06:35:15 -0700
commit51ee4b84f5c86935b438d6636f34b523edb415a8 (patch)
treec60e0da8f8b6393477d79ef6d6ce321ee3b8ecaa
parent96f935934591b72f5b05fd6923bc8cdcae92f2e5 (diff)
downloadop-kernel-dev-51ee4b84f5c86935b438d6636f34b523edb415a8.zip
op-kernel-dev-51ee4b84f5c86935b438d6636f34b523edb415a8.tar.gz
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>
-rw-r--r--fs/cifs/cifsfs.c5
-rw-r--r--fs/gfs2/file.c2
-rw-r--r--fs/locks.c20
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/nfsd/nfs4state.c1
5 files changed, 13 insertions, 17 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 54745b6..75c4eaa 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -625,11 +625,8 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
knows that the file won't be changed on the server
by anyone else */
return generic_setlease(file, arg, lease);
- else {
- if (arg != F_UNLCK)
- locks_free_lock(*lease);
+ else
return -EAGAIN;
- }
}
struct file_system_type cifs_fs_type = {
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index ac943c1..aa99647 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -629,8 +629,6 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl)
{
- if (arg != F_UNLCK)
- locks_free_lock(*fl);
return -EINVAL;
}
diff --git a/fs/locks.c b/fs/locks.c
index 5b526a9..a2ab790 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1428,8 +1428,9 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
goto out;
if (my_before != NULL) {
- *flp = *my_before;
error = lease->fl_lmops->fl_change(my_before, arg);
+ if (!error)
+ *flp = *my_before;
goto out;
}
@@ -1444,8 +1445,6 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
return 0;
out:
- if (arg != F_UNLCK)
- locks_free_lock(lease);
return error;
}
EXPORT_SYMBOL(generic_setlease);
@@ -1524,8 +1523,11 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
}
lock_flocks();
error = __vfs_setlease(filp, arg, &fl);
- if (error)
- goto out_unlock;
+ if (error) {
+ unlock_flocks();
+ locks_free_lock(fl);
+ goto out_free_fasync;
+ }
/*
* fasync_insert_entry() returns the old entry if any.
@@ -1541,12 +1543,12 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
fl->fl_type = F_UNLCK | F_INPROGRESS;
fl->fl_break_time = jiffies - 10;
time_out_leases(inode);
- goto out_unlock;
+ } else {
+ error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
}
-
- error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
-out_unlock:
unlock_flocks();
+
+out_free_fasync:
if (new)
fasync_free(new);
return error;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 1e524fb..60677f9 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -884,7 +884,5 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
file->f_path.dentry->d_parent->d_name.name,
file->f_path.dentry->d_name.name, arg);
- if (arg != F_UNLCK)
- locks_free_lock(*fl);
return -EINVAL;
}
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b7f818b..f1e5ec6 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2652,6 +2652,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
dprintk("NFSD: setlease failed [%d], no delegation\n", status);
dp->dl_flock = NULL;
+ locks_free_lock(fl);
unhash_delegation(dp);
flag = NFS4_OPEN_DELEGATE_NONE;
goto out;
OpenPOWER on IntegriCloud