diff options
Diffstat (limited to 'fs/locks.c')
-rw-r--r-- | fs/locks.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/locks.c b/fs/locks.c index 592faadbcec1..e1ea2fe03681 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -224,7 +224,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) | |||
224 | /* | 224 | /* |
225 | * Initialize a new lock from an existing file_lock structure. | 225 | * Initialize a new lock from an existing file_lock structure. |
226 | */ | 226 | */ |
227 | static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) | 227 | void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) |
228 | { | 228 | { |
229 | new->fl_owner = fl->fl_owner; | 229 | new->fl_owner = fl->fl_owner; |
230 | new->fl_pid = fl->fl_pid; | 230 | new->fl_pid = fl->fl_pid; |
@@ -833,7 +833,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
833 | if (!posix_locks_conflict(request, fl)) | 833 | if (!posix_locks_conflict(request, fl)) |
834 | continue; | 834 | continue; |
835 | if (conflock) | 835 | if (conflock) |
836 | locks_copy_lock(conflock, fl); | 836 | __locks_copy_lock(conflock, fl); |
837 | error = -EAGAIN; | 837 | error = -EAGAIN; |
838 | if (!(request->fl_flags & FL_SLEEP)) | 838 | if (!(request->fl_flags & FL_SLEEP)) |
839 | goto out; | 839 | goto out; |
@@ -1367,18 +1367,20 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | |||
1367 | 1367 | ||
1368 | lease = *flp; | 1368 | lease = *flp; |
1369 | 1369 | ||
1370 | error = -EAGAIN; | 1370 | if (arg != F_UNLCK) { |
1371 | if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) | 1371 | error = -ENOMEM; |
1372 | goto out; | 1372 | new_fl = locks_alloc_lock(); |
1373 | if ((arg == F_WRLCK) | 1373 | if (new_fl == NULL) |
1374 | && ((atomic_read(&dentry->d_count) > 1) | 1374 | goto out; |
1375 | || (atomic_read(&inode->i_count) > 1))) | ||
1376 | goto out; | ||
1377 | 1375 | ||
1378 | error = -ENOMEM; | 1376 | error = -EAGAIN; |
1379 | new_fl = locks_alloc_lock(); | 1377 | if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) |
1380 | if (new_fl == NULL) | 1378 | goto out; |
1381 | goto out; | 1379 | if ((arg == F_WRLCK) |
1380 | && ((atomic_read(&dentry->d_count) > 1) | ||
1381 | || (atomic_read(&inode->i_count) > 1))) | ||
1382 | goto out; | ||
1383 | } | ||
1382 | 1384 | ||
1383 | /* | 1385 | /* |
1384 | * At this point, we know that if there is an exclusive | 1386 | * At this point, we know that if there is an exclusive |
@@ -1404,6 +1406,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | |||
1404 | rdlease_count++; | 1406 | rdlease_count++; |
1405 | } | 1407 | } |
1406 | 1408 | ||
1409 | error = -EAGAIN; | ||
1407 | if ((arg == F_RDLCK && (wrlease_count > 0)) || | 1410 | if ((arg == F_RDLCK && (wrlease_count > 0)) || |
1408 | (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0))) | 1411 | (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0))) |
1409 | goto out; | 1412 | goto out; |
@@ -1490,8 +1493,7 @@ EXPORT_SYMBOL_GPL(vfs_setlease); | |||
1490 | int fcntl_setlease(unsigned int fd, struct file *filp, long arg) | 1493 | int fcntl_setlease(unsigned int fd, struct file *filp, long arg) |
1491 | { | 1494 | { |
1492 | struct file_lock fl, *flp = &fl; | 1495 | struct file_lock fl, *flp = &fl; |
1493 | struct dentry *dentry = filp->f_path.dentry; | 1496 | struct inode *inode = filp->f_path.dentry->d_inode; |
1494 | struct inode *inode = dentry->d_inode; | ||
1495 | int error; | 1497 | int error; |
1496 | 1498 | ||
1497 | locks_init_lock(&fl); | 1499 | locks_init_lock(&fl); |