aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c70
1 files changed, 53 insertions, 17 deletions
diff --git a/fs/locks.c b/fs/locks.c
index b27a3005d78d..92a0f0a52b06 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -134,7 +134,7 @@
134 134
135#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX) 135#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
136#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK) 136#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
137#define IS_LEASE(fl) (fl->fl_flags & FL_LEASE) 137#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG))
138 138
139static bool lease_breaking(struct file_lock *fl) 139static bool lease_breaking(struct file_lock *fl)
140{ 140{
@@ -1292,28 +1292,40 @@ static void time_out_leases(struct inode *inode)
1292 } 1292 }
1293} 1293}
1294 1294
1295static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker)
1296{
1297 if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE))
1298 return false;
1299 return locks_conflict(breaker, lease);
1300}
1301
1295/** 1302/**
1296 * __break_lease - revoke all outstanding leases on file 1303 * __break_lease - revoke all outstanding leases on file
1297 * @inode: the inode of the file to return 1304 * @inode: the inode of the file to return
1298 * @mode: the open mode (read or write) 1305 * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR:
1306 * break all leases
1307 * @type: FL_LEASE: break leases and delegations; FL_DELEG: break
1308 * only delegations
1299 * 1309 *
1300 * break_lease (inlined for speed) has checked there already is at least 1310 * break_lease (inlined for speed) has checked there already is at least
1301 * some kind of lock (maybe a lease) on this file. Leases are broken on 1311 * some kind of lock (maybe a lease) on this file. Leases are broken on
1302 * a call to open() or truncate(). This function can sleep unless you 1312 * a call to open() or truncate(). This function can sleep unless you
1303 * specified %O_NONBLOCK to your open(). 1313 * specified %O_NONBLOCK to your open().
1304 */ 1314 */
1305int __break_lease(struct inode *inode, unsigned int mode) 1315int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
1306{ 1316{
1307 int error = 0; 1317 int error = 0;
1308 struct file_lock *new_fl, *flock; 1318 struct file_lock *new_fl, *flock;
1309 struct file_lock *fl; 1319 struct file_lock *fl;
1310 unsigned long break_time; 1320 unsigned long break_time;
1311 int i_have_this_lease = 0; 1321 int i_have_this_lease = 0;
1322 bool lease_conflict = false;
1312 int want_write = (mode & O_ACCMODE) != O_RDONLY; 1323 int want_write = (mode & O_ACCMODE) != O_RDONLY;
1313 1324
1314 new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); 1325 new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
1315 if (IS_ERR(new_fl)) 1326 if (IS_ERR(new_fl))
1316 return PTR_ERR(new_fl); 1327 return PTR_ERR(new_fl);
1328 new_fl->fl_flags = type;
1317 1329
1318 spin_lock(&inode->i_lock); 1330 spin_lock(&inode->i_lock);
1319 1331
@@ -1323,13 +1335,16 @@ int __break_lease(struct inode *inode, unsigned int mode)
1323 if ((flock == NULL) || !IS_LEASE(flock)) 1335 if ((flock == NULL) || !IS_LEASE(flock))
1324 goto out; 1336 goto out;
1325 1337
1326 if (!locks_conflict(flock, new_fl)) 1338 for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next) {
1339 if (leases_conflict(fl, new_fl)) {
1340 lease_conflict = true;
1341 if (fl->fl_owner == current->files)
1342 i_have_this_lease = 1;
1343 }
1344 }
1345 if (!lease_conflict)
1327 goto out; 1346 goto out;
1328 1347
1329 for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next)
1330 if (fl->fl_owner == current->files)
1331 i_have_this_lease = 1;
1332
1333 break_time = 0; 1348 break_time = 0;
1334 if (lease_break_time > 0) { 1349 if (lease_break_time > 0) {
1335 break_time = jiffies + lease_break_time * HZ; 1350 break_time = jiffies + lease_break_time * HZ;
@@ -1338,6 +1353,8 @@ int __break_lease(struct inode *inode, unsigned int mode)
1338 } 1353 }
1339 1354
1340 for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next) { 1355 for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next) {
1356 if (!leases_conflict(fl, new_fl))
1357 continue;
1341 if (want_write) { 1358 if (want_write) {
1342 if (fl->fl_flags & FL_UNLOCK_PENDING) 1359 if (fl->fl_flags & FL_UNLOCK_PENDING)
1343 continue; 1360 continue;
@@ -1379,7 +1396,7 @@ restart:
1379 */ 1396 */
1380 for (flock = inode->i_flock; flock && IS_LEASE(flock); 1397 for (flock = inode->i_flock; flock && IS_LEASE(flock);
1381 flock = flock->fl_next) { 1398 flock = flock->fl_next) {
1382 if (locks_conflict(new_fl, flock)) 1399 if (leases_conflict(new_fl, flock))
1383 goto restart; 1400 goto restart;
1384 } 1401 }
1385 error = 0; 1402 error = 0;
@@ -1460,9 +1477,27 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
1460 struct file_lock *fl, **before, **my_before = NULL, *lease; 1477 struct file_lock *fl, **before, **my_before = NULL, *lease;
1461 struct dentry *dentry = filp->f_path.dentry; 1478 struct dentry *dentry = filp->f_path.dentry;
1462 struct inode *inode = dentry->d_inode; 1479 struct inode *inode = dentry->d_inode;
1480 bool is_deleg = (*flp)->fl_flags & FL_DELEG;
1463 int error; 1481 int error;
1464 1482
1465 lease = *flp; 1483 lease = *flp;
1484 /*
1485 * In the delegation case we need mutual exclusion with
1486 * a number of operations that take the i_mutex. We trylock
1487 * because delegations are an optional optimization, and if
1488 * there's some chance of a conflict--we'd rather not
1489 * bother, maybe that's a sign this just isn't a good file to
1490 * hand out a delegation on.
1491 */
1492 if (is_deleg && !mutex_trylock(&inode->i_mutex))
1493 return -EAGAIN;
1494
1495 if (is_deleg && arg == F_WRLCK) {
1496 /* Write delegations are not currently supported: */
1497 mutex_unlock(&inode->i_mutex);
1498 WARN_ON_ONCE(1);
1499 return -EINVAL;
1500 }
1466 1501
1467 error = -EAGAIN; 1502 error = -EAGAIN;
1468 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) 1503 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
@@ -1514,9 +1549,10 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
1514 goto out; 1549 goto out;
1515 1550
1516 locks_insert_lock(before, lease); 1551 locks_insert_lock(before, lease);
1517 return 0; 1552 error = 0;
1518
1519out: 1553out:
1554 if (is_deleg)
1555 mutex_unlock(&inode->i_mutex);
1520 return error; 1556 return error;
1521} 1557}
1522 1558
@@ -1579,7 +1615,7 @@ EXPORT_SYMBOL(generic_setlease);
1579 1615
1580static int __vfs_setlease(struct file *filp, long arg, struct file_lock **lease) 1616static int __vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
1581{ 1617{
1582 if (filp->f_op && filp->f_op->setlease) 1618 if (filp->f_op->setlease)
1583 return filp->f_op->setlease(filp, arg, lease); 1619 return filp->f_op->setlease(filp, arg, lease);
1584 else 1620 else
1585 return generic_setlease(filp, arg, lease); 1621 return generic_setlease(filp, arg, lease);
@@ -1771,7 +1807,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
1771 if (error) 1807 if (error)
1772 goto out_free; 1808 goto out_free;
1773 1809
1774 if (f.file->f_op && f.file->f_op->flock) 1810 if (f.file->f_op->flock)
1775 error = f.file->f_op->flock(f.file, 1811 error = f.file->f_op->flock(f.file,
1776 (can_sleep) ? F_SETLKW : F_SETLK, 1812 (can_sleep) ? F_SETLKW : F_SETLK,
1777 lock); 1813 lock);
@@ -1797,7 +1833,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
1797 */ 1833 */
1798int vfs_test_lock(struct file *filp, struct file_lock *fl) 1834int vfs_test_lock(struct file *filp, struct file_lock *fl)
1799{ 1835{
1800 if (filp->f_op && filp->f_op->lock) 1836 if (filp->f_op->lock)
1801 return filp->f_op->lock(filp, F_GETLK, fl); 1837 return filp->f_op->lock(filp, F_GETLK, fl);
1802 posix_test_lock(filp, fl); 1838 posix_test_lock(filp, fl);
1803 return 0; 1839 return 0;
@@ -1909,7 +1945,7 @@ out:
1909 */ 1945 */
1910int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) 1946int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
1911{ 1947{
1912 if (filp->f_op && filp->f_op->lock) 1948 if (filp->f_op->lock)
1913 return filp->f_op->lock(filp, cmd, fl); 1949 return filp->f_op->lock(filp, cmd, fl);
1914 else 1950 else
1915 return posix_lock_file(filp, fl, conf); 1951 return posix_lock_file(filp, fl, conf);
@@ -2182,7 +2218,7 @@ void locks_remove_flock(struct file *filp)
2182 if (!inode->i_flock) 2218 if (!inode->i_flock)
2183 return; 2219 return;
2184 2220
2185 if (filp->f_op && filp->f_op->flock) { 2221 if (filp->f_op->flock) {
2186 struct file_lock fl = { 2222 struct file_lock fl = {
2187 .fl_pid = current->tgid, 2223 .fl_pid = current->tgid,
2188 .fl_file = filp, 2224 .fl_file = filp,
@@ -2246,7 +2282,7 @@ EXPORT_SYMBOL(posix_unblock_lock);
2246 */ 2282 */
2247int vfs_cancel_lock(struct file *filp, struct file_lock *fl) 2283int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
2248{ 2284{
2249 if (filp->f_op && filp->f_op->lock) 2285 if (filp->f_op->lock)
2250 return filp->f_op->lock(filp, F_CANCELLK, fl); 2286 return filp->f_op->lock(filp, F_CANCELLK, fl);
2251 return 0; 2287 return 0;
2252} 2288}