diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/debugfs/inode.c | 5 | ||||
-rw-r--r-- | fs/gfs2/ops_file.c | 24 | ||||
-rw-r--r-- | fs/locks.c | 112 | ||||
-rw-r--r-- | fs/nfs/file.c | 16 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 10 | ||||
-rw-r--r-- | fs/sysfs/dir.c | 25 | ||||
-rw-r--r-- | fs/sysfs/file.c | 9 | ||||
-rw-r--r-- | fs/sysfs/inode.c | 2 | ||||
-rw-r--r-- | fs/sysfs/mount.c | 10 | ||||
-rw-r--r-- | fs/sysfs/symlink.c | 12 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 1 |
11 files changed, 134 insertions, 92 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 1d533a2ec3a6..11be8a325e26 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -345,11 +345,6 @@ void debugfs_remove(struct dentry *dentry) | |||
345 | switch (dentry->d_inode->i_mode & S_IFMT) { | 345 | switch (dentry->d_inode->i_mode & S_IFMT) { |
346 | case S_IFDIR: | 346 | case S_IFDIR: |
347 | ret = simple_rmdir(parent->d_inode, dentry); | 347 | ret = simple_rmdir(parent->d_inode, dentry); |
348 | if (ret) | ||
349 | printk(KERN_ERR | ||
350 | "DebugFS rmdir on %s failed : " | ||
351 | "directory not empty.\n", | ||
352 | dentry->d_name.name); | ||
353 | break; | 348 | break; |
354 | case S_IFLNK: | 349 | case S_IFLNK: |
355 | kfree(dentry->d_inode->i_private); | 350 | kfree(dentry->d_inode->i_private); |
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 196d83266e34..1a5e8e893d75 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -489,6 +489,29 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
489 | } | 489 | } |
490 | 490 | ||
491 | /** | 491 | /** |
492 | * gfs2_setlease - acquire/release a file lease | ||
493 | * @file: the file pointer | ||
494 | * @arg: lease type | ||
495 | * @fl: file lock | ||
496 | * | ||
497 | * Returns: errno | ||
498 | */ | ||
499 | |||
500 | static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl) | ||
501 | { | ||
502 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); | ||
503 | |||
504 | /* | ||
505 | * We don't currently have a way to enforce a lease across the whole | ||
506 | * cluster; until we do, disable leases (by just returning -EINVAL), | ||
507 | * unless the administrator has requested purely local locking. | ||
508 | */ | ||
509 | if (!sdp->sd_args.ar_localflocks) | ||
510 | return -EINVAL; | ||
511 | return setlease(file, arg, fl); | ||
512 | } | ||
513 | |||
514 | /** | ||
492 | * gfs2_lock - acquire/release a posix lock on a file | 515 | * gfs2_lock - acquire/release a posix lock on a file |
493 | * @file: the file pointer | 516 | * @file: the file pointer |
494 | * @cmd: either modify or retrieve lock state, possibly wait | 517 | * @cmd: either modify or retrieve lock state, possibly wait |
@@ -638,6 +661,7 @@ const struct file_operations gfs2_file_fops = { | |||
638 | .flock = gfs2_flock, | 661 | .flock = gfs2_flock, |
639 | .splice_read = generic_file_splice_read, | 662 | .splice_read = generic_file_splice_read, |
640 | .splice_write = generic_file_splice_write, | 663 | .splice_write = generic_file_splice_write, |
664 | .setlease = gfs2_setlease, | ||
641 | }; | 665 | }; |
642 | 666 | ||
643 | const struct file_operations gfs2_dir_fops = { | 667 | const struct file_operations gfs2_dir_fops = { |
diff --git a/fs/locks.c b/fs/locks.c index 431a8b871fce..4f2d749ac624 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -458,22 +458,20 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl) | |||
458 | } | 458 | } |
459 | 459 | ||
460 | /* Allocate a file_lock initialised to this type of lease */ | 460 | /* Allocate a file_lock initialised to this type of lease */ |
461 | static int lease_alloc(struct file *filp, int type, struct file_lock **flp) | 461 | static struct file_lock *lease_alloc(struct file *filp, int type) |
462 | { | 462 | { |
463 | struct file_lock *fl = locks_alloc_lock(); | 463 | struct file_lock *fl = locks_alloc_lock(); |
464 | int error = -ENOMEM; | 464 | int error = -ENOMEM; |
465 | 465 | ||
466 | if (fl == NULL) | 466 | if (fl == NULL) |
467 | goto out; | 467 | return ERR_PTR(error); |
468 | 468 | ||
469 | error = lease_init(filp, type, fl); | 469 | error = lease_init(filp, type, fl); |
470 | if (error) { | 470 | if (error) { |
471 | locks_free_lock(fl); | 471 | locks_free_lock(fl); |
472 | fl = NULL; | 472 | return ERR_PTR(error); |
473 | } | 473 | } |
474 | out: | 474 | return fl; |
475 | *flp = fl; | ||
476 | return error; | ||
477 | } | 475 | } |
478 | 476 | ||
479 | /* Check if two locks overlap each other. | 477 | /* Check if two locks overlap each other. |
@@ -661,7 +659,7 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w | |||
661 | return result; | 659 | return result; |
662 | } | 660 | } |
663 | 661 | ||
664 | int | 662 | void |
665 | posix_test_lock(struct file *filp, struct file_lock *fl) | 663 | posix_test_lock(struct file *filp, struct file_lock *fl) |
666 | { | 664 | { |
667 | struct file_lock *cfl; | 665 | struct file_lock *cfl; |
@@ -673,14 +671,12 @@ posix_test_lock(struct file *filp, struct file_lock *fl) | |||
673 | if (posix_locks_conflict(cfl, fl)) | 671 | if (posix_locks_conflict(cfl, fl)) |
674 | break; | 672 | break; |
675 | } | 673 | } |
676 | if (cfl) { | 674 | if (cfl) |
677 | __locks_copy_lock(fl, cfl); | 675 | __locks_copy_lock(fl, cfl); |
678 | unlock_kernel(); | 676 | else |
679 | return 1; | ||
680 | } else | ||
681 | fl->fl_type = F_UNLCK; | 677 | fl->fl_type = F_UNLCK; |
682 | unlock_kernel(); | 678 | unlock_kernel(); |
683 | return 0; | 679 | return; |
684 | } | 680 | } |
685 | 681 | ||
686 | EXPORT_SYMBOL(posix_test_lock); | 682 | EXPORT_SYMBOL(posix_test_lock); |
@@ -1169,9 +1165,9 @@ static void time_out_leases(struct inode *inode) | |||
1169 | * @inode: the inode of the file to return | 1165 | * @inode: the inode of the file to return |
1170 | * @mode: the open mode (read or write) | 1166 | * @mode: the open mode (read or write) |
1171 | * | 1167 | * |
1172 | * break_lease (inlined for speed) has checked there already | 1168 | * break_lease (inlined for speed) has checked there already is at least |
1173 | * is a lease on this file. Leases are broken on a call to open() | 1169 | * some kind of lock (maybe a lease) on this file. Leases are broken on |
1174 | * or truncate(). This function can sleep unless you | 1170 | * a call to open() or truncate(). This function can sleep unless you |
1175 | * specified %O_NONBLOCK to your open(). | 1171 | * specified %O_NONBLOCK to your open(). |
1176 | */ | 1172 | */ |
1177 | int __break_lease(struct inode *inode, unsigned int mode) | 1173 | int __break_lease(struct inode *inode, unsigned int mode) |
@@ -1179,12 +1175,10 @@ int __break_lease(struct inode *inode, unsigned int mode) | |||
1179 | int error = 0, future; | 1175 | int error = 0, future; |
1180 | struct file_lock *new_fl, *flock; | 1176 | struct file_lock *new_fl, *flock; |
1181 | struct file_lock *fl; | 1177 | struct file_lock *fl; |
1182 | int alloc_err; | ||
1183 | unsigned long break_time; | 1178 | unsigned long break_time; |
1184 | int i_have_this_lease = 0; | 1179 | int i_have_this_lease = 0; |
1185 | 1180 | ||
1186 | alloc_err = lease_alloc(NULL, mode & FMODE_WRITE ? F_WRLCK : F_RDLCK, | 1181 | new_fl = lease_alloc(NULL, mode & FMODE_WRITE ? F_WRLCK : F_RDLCK); |
1187 | &new_fl); | ||
1188 | 1182 | ||
1189 | lock_kernel(); | 1183 | lock_kernel(); |
1190 | 1184 | ||
@@ -1212,8 +1206,9 @@ int __break_lease(struct inode *inode, unsigned int mode) | |||
1212 | goto out; | 1206 | goto out; |
1213 | } | 1207 | } |
1214 | 1208 | ||
1215 | if (alloc_err && !i_have_this_lease && ((mode & O_NONBLOCK) == 0)) { | 1209 | if (IS_ERR(new_fl) && !i_have_this_lease |
1216 | error = alloc_err; | 1210 | && ((mode & O_NONBLOCK) == 0)) { |
1211 | error = PTR_ERR(new_fl); | ||
1217 | goto out; | 1212 | goto out; |
1218 | } | 1213 | } |
1219 | 1214 | ||
@@ -1260,7 +1255,7 @@ restart: | |||
1260 | 1255 | ||
1261 | out: | 1256 | out: |
1262 | unlock_kernel(); | 1257 | unlock_kernel(); |
1263 | if (!alloc_err) | 1258 | if (!IS_ERR(new_fl)) |
1264 | locks_free_lock(new_fl); | 1259 | locks_free_lock(new_fl); |
1265 | return error; | 1260 | return error; |
1266 | } | 1261 | } |
@@ -1329,7 +1324,7 @@ int fcntl_getlease(struct file *filp) | |||
1329 | } | 1324 | } |
1330 | 1325 | ||
1331 | /** | 1326 | /** |
1332 | * __setlease - sets a lease on an open file | 1327 | * setlease - sets a lease on an open file |
1333 | * @filp: file pointer | 1328 | * @filp: file pointer |
1334 | * @arg: type of lease to obtain | 1329 | * @arg: type of lease to obtain |
1335 | * @flp: input - file_lock to use, output - file_lock inserted | 1330 | * @flp: input - file_lock to use, output - file_lock inserted |
@@ -1339,18 +1334,24 @@ int fcntl_getlease(struct file *filp) | |||
1339 | * | 1334 | * |
1340 | * Called with kernel lock held. | 1335 | * Called with kernel lock held. |
1341 | */ | 1336 | */ |
1342 | static int __setlease(struct file *filp, long arg, struct file_lock **flp) | 1337 | int setlease(struct file *filp, long arg, struct file_lock **flp) |
1343 | { | 1338 | { |
1344 | struct file_lock *fl, **before, **my_before = NULL, *lease; | 1339 | struct file_lock *fl, **before, **my_before = NULL, *lease; |
1345 | struct dentry *dentry = filp->f_path.dentry; | 1340 | struct dentry *dentry = filp->f_path.dentry; |
1346 | struct inode *inode = dentry->d_inode; | 1341 | struct inode *inode = dentry->d_inode; |
1347 | int error, rdlease_count = 0, wrlease_count = 0; | 1342 | int error, rdlease_count = 0, wrlease_count = 0; |
1348 | 1343 | ||
1344 | if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE)) | ||
1345 | return -EACCES; | ||
1346 | if (!S_ISREG(inode->i_mode)) | ||
1347 | return -EINVAL; | ||
1348 | error = security_file_lock(filp, arg); | ||
1349 | if (error) | ||
1350 | return error; | ||
1351 | |||
1349 | time_out_leases(inode); | 1352 | time_out_leases(inode); |
1350 | 1353 | ||
1351 | error = -EINVAL; | 1354 | BUG_ON(!(*flp)->fl_lmops->fl_break); |
1352 | if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break) | ||
1353 | goto out; | ||
1354 | 1355 | ||
1355 | lease = *flp; | 1356 | lease = *flp; |
1356 | 1357 | ||
@@ -1418,39 +1419,49 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) | |||
1418 | out: | 1419 | out: |
1419 | return error; | 1420 | return error; |
1420 | } | 1421 | } |
1422 | EXPORT_SYMBOL(setlease); | ||
1421 | 1423 | ||
1422 | /** | 1424 | /** |
1423 | * setlease - sets a lease on an open file | 1425 | * vfs_setlease - sets a lease on an open file |
1424 | * @filp: file pointer | 1426 | * @filp: file pointer |
1425 | * @arg: type of lease to obtain | 1427 | * @arg: type of lease to obtain |
1426 | * @lease: file_lock to use | 1428 | * @lease: file_lock to use |
1427 | * | 1429 | * |
1428 | * Call this to establish a lease on the file. | 1430 | * Call this to establish a lease on the file. |
1429 | * The fl_lmops fl_break function is required by break_lease | 1431 | * The (*lease)->fl_lmops->fl_break operation must be set; if not, |
1432 | * break_lease will oops! | ||
1433 | * | ||
1434 | * This will call the filesystem's setlease file method, if | ||
1435 | * defined. Note that there is no getlease method; instead, the | ||
1436 | * filesystem setlease method should call back to setlease() to | ||
1437 | * add a lease to the inode's lease list, where fcntl_getlease() can | ||
1438 | * find it. Since fcntl_getlease() only reports whether the current | ||
1439 | * task holds a lease, a cluster filesystem need only do this for | ||
1440 | * leases held by processes on this node. | ||
1441 | * | ||
1442 | * There is also no break_lease method; filesystems that | ||
1443 | * handle their own leases shoud break leases themselves from the | ||
1444 | * filesystem's open, create, and (on truncate) setattr methods. | ||
1445 | * | ||
1446 | * Warning: the only current setlease methods exist only to disable | ||
1447 | * leases in certain cases. More vfs changes may be required to | ||
1448 | * allow a full filesystem lease implementation. | ||
1430 | */ | 1449 | */ |
1431 | 1450 | ||
1432 | int setlease(struct file *filp, long arg, struct file_lock **lease) | 1451 | int vfs_setlease(struct file *filp, long arg, struct file_lock **lease) |
1433 | { | 1452 | { |
1434 | struct dentry *dentry = filp->f_path.dentry; | ||
1435 | struct inode *inode = dentry->d_inode; | ||
1436 | int error; | 1453 | int error; |
1437 | 1454 | ||
1438 | if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE)) | ||
1439 | return -EACCES; | ||
1440 | if (!S_ISREG(inode->i_mode)) | ||
1441 | return -EINVAL; | ||
1442 | error = security_file_lock(filp, arg); | ||
1443 | if (error) | ||
1444 | return error; | ||
1445 | |||
1446 | lock_kernel(); | 1455 | lock_kernel(); |
1447 | error = __setlease(filp, arg, lease); | 1456 | if (filp->f_op && filp->f_op->setlease) |
1457 | error = filp->f_op->setlease(filp, arg, lease); | ||
1458 | else | ||
1459 | error = setlease(filp, arg, lease); | ||
1448 | unlock_kernel(); | 1460 | unlock_kernel(); |
1449 | 1461 | ||
1450 | return error; | 1462 | return error; |
1451 | } | 1463 | } |
1452 | 1464 | EXPORT_SYMBOL_GPL(vfs_setlease); | |
1453 | EXPORT_SYMBOL(setlease); | ||
1454 | 1465 | ||
1455 | /** | 1466 | /** |
1456 | * fcntl_setlease - sets a lease on an open file | 1467 | * fcntl_setlease - sets a lease on an open file |
@@ -1469,14 +1480,6 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg) | |||
1469 | struct inode *inode = dentry->d_inode; | 1480 | struct inode *inode = dentry->d_inode; |
1470 | int error; | 1481 | int error; |
1471 | 1482 | ||
1472 | if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE)) | ||
1473 | return -EACCES; | ||
1474 | if (!S_ISREG(inode->i_mode)) | ||
1475 | return -EINVAL; | ||
1476 | error = security_file_lock(filp, arg); | ||
1477 | if (error) | ||
1478 | return error; | ||
1479 | |||
1480 | locks_init_lock(&fl); | 1483 | locks_init_lock(&fl); |
1481 | error = lease_init(filp, arg, &fl); | 1484 | error = lease_init(filp, arg, &fl); |
1482 | if (error) | 1485 | if (error) |
@@ -1484,15 +1487,15 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg) | |||
1484 | 1487 | ||
1485 | lock_kernel(); | 1488 | lock_kernel(); |
1486 | 1489 | ||
1487 | error = __setlease(filp, arg, &flp); | 1490 | error = vfs_setlease(filp, arg, &flp); |
1488 | if (error || arg == F_UNLCK) | 1491 | if (error || arg == F_UNLCK) |
1489 | goto out_unlock; | 1492 | goto out_unlock; |
1490 | 1493 | ||
1491 | error = fasync_helper(fd, filp, 1, &flp->fl_fasync); | 1494 | error = fasync_helper(fd, filp, 1, &flp->fl_fasync); |
1492 | if (error < 0) { | 1495 | if (error < 0) { |
1493 | /* remove lease just inserted by __setlease */ | 1496 | /* remove lease just inserted by setlease */ |
1494 | flp->fl_type = F_UNLCK | F_INPROGRESS; | 1497 | flp->fl_type = F_UNLCK | F_INPROGRESS; |
1495 | flp->fl_break_time = jiffies- 10; | 1498 | flp->fl_break_time = jiffies - 10; |
1496 | time_out_leases(inode); | 1499 | time_out_leases(inode); |
1497 | goto out_unlock; | 1500 | goto out_unlock; |
1498 | } | 1501 | } |
@@ -1597,8 +1600,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) | |||
1597 | /** | 1600 | /** |
1598 | * vfs_test_lock - test file byte range lock | 1601 | * vfs_test_lock - test file byte range lock |
1599 | * @filp: The file to test lock for | 1602 | * @filp: The file to test lock for |
1600 | * @fl: The lock to test | 1603 | * @fl: The lock to test; also used to hold result |
1601 | * @conf: Place to return a copy of the conflicting lock, if found | ||
1602 | * | 1604 | * |
1603 | * Returns -ERRNO on failure. Indicates presence of conflicting lock by | 1605 | * Returns -ERRNO on failure. Indicates presence of conflicting lock by |
1604 | * setting conf->fl_type to something other than F_UNLCK. | 1606 | * setting conf->fl_type to something other than F_UNLCK. |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 8689b736fdd9..c87dc713b5d7 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -53,6 +53,7 @@ static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); | |||
53 | static int nfs_check_flags(int flags); | 53 | static int nfs_check_flags(int flags); |
54 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | 54 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); |
55 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); | 55 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); |
56 | static int nfs_setlease(struct file *file, long arg, struct file_lock **fl); | ||
56 | 57 | ||
57 | const struct file_operations nfs_file_operations = { | 58 | const struct file_operations nfs_file_operations = { |
58 | .llseek = nfs_file_llseek, | 59 | .llseek = nfs_file_llseek, |
@@ -69,6 +70,7 @@ const struct file_operations nfs_file_operations = { | |||
69 | .flock = nfs_flock, | 70 | .flock = nfs_flock, |
70 | .splice_read = nfs_file_splice_read, | 71 | .splice_read = nfs_file_splice_read, |
71 | .check_flags = nfs_check_flags, | 72 | .check_flags = nfs_check_flags, |
73 | .setlease = nfs_setlease, | ||
72 | }; | 74 | }; |
73 | 75 | ||
74 | const struct inode_operations nfs_file_inode_operations = { | 76 | const struct inode_operations nfs_file_inode_operations = { |
@@ -400,7 +402,9 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) | |||
400 | 402 | ||
401 | lock_kernel(); | 403 | lock_kernel(); |
402 | /* Try local locking first */ | 404 | /* Try local locking first */ |
403 | if (posix_test_lock(filp, fl)) { | 405 | posix_test_lock(filp, fl); |
406 | if (fl->fl_type != F_UNLCK) { | ||
407 | /* found a conflict */ | ||
404 | goto out; | 408 | goto out; |
405 | } | 409 | } |
406 | 410 | ||
@@ -558,3 +562,13 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | |||
558 | return do_unlk(filp, cmd, fl); | 562 | return do_unlk(filp, cmd, fl); |
559 | return do_setlk(filp, cmd, fl); | 563 | return do_setlk(filp, cmd, fl); |
560 | } | 564 | } |
565 | |||
566 | static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) | ||
567 | { | ||
568 | /* | ||
569 | * There is no protocol support for leases, so we have no way | ||
570 | * to implement them correctly in the face of opens by other | ||
571 | * clients. | ||
572 | */ | ||
573 | return -EINVAL; | ||
574 | } | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index e4a4c87ec8c6..6284807bd37e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -256,7 +256,7 @@ nfs4_close_delegation(struct nfs4_delegation *dp) | |||
256 | /* The following nfsd_close may not actually close the file, | 256 | /* The following nfsd_close may not actually close the file, |
257 | * but we want to remove the lease in any case. */ | 257 | * but we want to remove the lease in any case. */ |
258 | if (dp->dl_flock) | 258 | if (dp->dl_flock) |
259 | setlease(filp, F_UNLCK, &dp->dl_flock); | 259 | vfs_setlease(filp, F_UNLCK, &dp->dl_flock); |
260 | nfsd_close(filp); | 260 | nfsd_close(filp); |
261 | } | 261 | } |
262 | 262 | ||
@@ -1402,7 +1402,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl) | |||
1402 | /* | 1402 | /* |
1403 | * Set the delegation file_lock back pointer. | 1403 | * Set the delegation file_lock back pointer. |
1404 | * | 1404 | * |
1405 | * Called from __setlease() with lock_kernel() held. | 1405 | * Called from setlease() with lock_kernel() held. |
1406 | */ | 1406 | */ |
1407 | static | 1407 | static |
1408 | void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl) | 1408 | void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl) |
@@ -1416,7 +1416,7 @@ void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl) | |||
1416 | } | 1416 | } |
1417 | 1417 | ||
1418 | /* | 1418 | /* |
1419 | * Called from __setlease() with lock_kernel() held | 1419 | * Called from setlease() with lock_kernel() held |
1420 | */ | 1420 | */ |
1421 | static | 1421 | static |
1422 | int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) | 1422 | int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) |
@@ -1716,10 +1716,10 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
1716 | fl.fl_file = stp->st_vfs_file; | 1716 | fl.fl_file = stp->st_vfs_file; |
1717 | fl.fl_pid = current->tgid; | 1717 | fl.fl_pid = current->tgid; |
1718 | 1718 | ||
1719 | /* setlease checks to see if delegation should be handed out. | 1719 | /* vfs_setlease checks to see if delegation should be handed out. |
1720 | * the lock_manager callbacks fl_mylease and fl_change are used | 1720 | * the lock_manager callbacks fl_mylease and fl_change are used |
1721 | */ | 1721 | */ |
1722 | if ((status = setlease(stp->st_vfs_file, | 1722 | if ((status = vfs_setlease(stp->st_vfs_file, |
1723 | flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) { | 1723 | flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) { |
1724 | dprintk("NFSD: setlease failed [%d], no delegation\n", status); | 1724 | dprintk("NFSD: setlease failed [%d], no delegation\n", status); |
1725 | unhash_delegation(dp); | 1725 | unhash_delegation(dp); |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index aee966c44aac..048e6054c2fd 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -361,20 +361,20 @@ static struct dentry_operations sysfs_dentry_ops = { | |||
361 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) | 361 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) |
362 | { | 362 | { |
363 | char *dup_name = NULL; | 363 | char *dup_name = NULL; |
364 | struct sysfs_dirent *sd = NULL; | 364 | struct sysfs_dirent *sd; |
365 | 365 | ||
366 | if (type & SYSFS_COPY_NAME) { | 366 | if (type & SYSFS_COPY_NAME) { |
367 | name = dup_name = kstrdup(name, GFP_KERNEL); | 367 | name = dup_name = kstrdup(name, GFP_KERNEL); |
368 | if (!name) | 368 | if (!name) |
369 | goto err_out; | 369 | return NULL; |
370 | } | 370 | } |
371 | 371 | ||
372 | sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL); | 372 | sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL); |
373 | if (!sd) | 373 | if (!sd) |
374 | goto err_out; | 374 | goto err_out1; |
375 | 375 | ||
376 | if (sysfs_alloc_ino(&sd->s_ino)) | 376 | if (sysfs_alloc_ino(&sd->s_ino)) |
377 | goto err_out; | 377 | goto err_out2; |
378 | 378 | ||
379 | atomic_set(&sd->s_count, 1); | 379 | atomic_set(&sd->s_count, 1); |
380 | atomic_set(&sd->s_active, 0); | 380 | atomic_set(&sd->s_active, 0); |
@@ -386,9 +386,10 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) | |||
386 | 386 | ||
387 | return sd; | 387 | return sd; |
388 | 388 | ||
389 | err_out: | 389 | err_out2: |
390 | kfree(dup_name); | ||
391 | kmem_cache_free(sysfs_dir_cachep, sd); | 390 | kmem_cache_free(sysfs_dir_cachep, sd); |
391 | err_out1: | ||
392 | kfree(dup_name); | ||
392 | return NULL; | 393 | return NULL; |
393 | } | 394 | } |
394 | 395 | ||
@@ -698,17 +699,19 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, | |||
698 | 699 | ||
699 | /* link in */ | 700 | /* link in */ |
700 | sysfs_addrm_start(&acxt, parent_sd); | 701 | sysfs_addrm_start(&acxt, parent_sd); |
702 | |||
701 | if (!sysfs_find_dirent(parent_sd, name)) { | 703 | if (!sysfs_find_dirent(parent_sd, name)) { |
702 | sysfs_add_one(&acxt, sd); | 704 | sysfs_add_one(&acxt, sd); |
703 | sysfs_link_sibling(sd); | 705 | sysfs_link_sibling(sd); |
704 | } | 706 | } |
705 | if (sysfs_addrm_finish(&acxt)) { | 707 | |
706 | *p_sd = sd; | 708 | if (!sysfs_addrm_finish(&acxt)) { |
707 | return 0; | 709 | sysfs_put(sd); |
710 | return -EEXIST; | ||
708 | } | 711 | } |
709 | 712 | ||
710 | sysfs_put(sd); | 713 | *p_sd = sd; |
711 | return -EEXIST; | 714 | return 0; |
712 | } | 715 | } |
713 | 716 | ||
714 | int sysfs_create_subdir(struct kobject *kobj, const char *name, | 717 | int sysfs_create_subdir(struct kobject *kobj, const char *name, |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index cc497994b2a8..3e1cc062a740 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -410,11 +410,12 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, | |||
410 | sysfs_link_sibling(sd); | 410 | sysfs_link_sibling(sd); |
411 | } | 411 | } |
412 | 412 | ||
413 | if (sysfs_addrm_finish(&acxt)) | 413 | if (!sysfs_addrm_finish(&acxt)) { |
414 | return 0; | 414 | sysfs_put(sd); |
415 | return -EEXIST; | ||
416 | } | ||
415 | 417 | ||
416 | sysfs_put(sd); | 418 | return 0; |
417 | return -EEXIST; | ||
418 | } | 419 | } |
419 | 420 | ||
420 | 421 | ||
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 3756e152285a..10d1b52899f1 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -133,7 +133,7 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) | |||
133 | */ | 133 | */ |
134 | static struct lock_class_key sysfs_inode_imutex_key; | 134 | static struct lock_class_key sysfs_inode_imutex_key; |
135 | 135 | ||
136 | void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) | 136 | static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) |
137 | { | 137 | { |
138 | inode->i_blocks = 0; | 138 | inode->i_blocks = 0; |
139 | inode->i_mapping->a_ops = &sysfs_aops; | 139 | inode->i_mapping->a_ops = &sysfs_aops; |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 402cc356203c..60714d075c2f 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -43,19 +43,19 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent) | |||
43 | sb->s_time_gran = 1; | 43 | sb->s_time_gran = 1; |
44 | sysfs_sb = sb; | 44 | sysfs_sb = sb; |
45 | 45 | ||
46 | inode = new_inode(sysfs_sb); | 46 | /* get root inode, initialize and unlock it */ |
47 | inode = sysfs_get_inode(&sysfs_root); | ||
47 | if (!inode) { | 48 | if (!inode) { |
48 | pr_debug("sysfs: could not get root inode\n"); | 49 | pr_debug("sysfs: could not get root inode\n"); |
49 | return -ENOMEM; | 50 | return -ENOMEM; |
50 | } | 51 | } |
51 | 52 | ||
52 | sysfs_init_inode(&sysfs_root, inode); | ||
53 | |||
54 | inode->i_op = &sysfs_dir_inode_operations; | 53 | inode->i_op = &sysfs_dir_inode_operations; |
55 | inode->i_fop = &sysfs_dir_operations; | 54 | inode->i_fop = &sysfs_dir_operations; |
56 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | 55 | inc_nlink(inode); /* directory, account for "." */ |
57 | inc_nlink(inode); | 56 | unlock_new_inode(inode); |
58 | 57 | ||
58 | /* instantiate and link root dentry */ | ||
59 | root = d_alloc_root(inode); | 59 | root = d_alloc_root(inode); |
60 | if (!root) { | 60 | if (!root) { |
61 | pr_debug("%s: could not get root dentry!\n",__FUNCTION__); | 61 | pr_debug("%s: could not get root dentry!\n",__FUNCTION__); |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 2f86e0422290..4ce687f0b5d0 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -86,7 +86,9 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
86 | sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); | 86 | sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); |
87 | if (!sd) | 87 | if (!sd) |
88 | goto out_put; | 88 | goto out_put; |
89 | |||
89 | sd->s_elem.symlink.target_sd = target_sd; | 90 | sd->s_elem.symlink.target_sd = target_sd; |
91 | target_sd = NULL; /* reference is now owned by the symlink */ | ||
90 | 92 | ||
91 | sysfs_addrm_start(&acxt, parent_sd); | 93 | sysfs_addrm_start(&acxt, parent_sd); |
92 | 94 | ||
@@ -95,11 +97,13 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
95 | sysfs_link_sibling(sd); | 97 | sysfs_link_sibling(sd); |
96 | } | 98 | } |
97 | 99 | ||
98 | if (sysfs_addrm_finish(&acxt)) | 100 | if (!sysfs_addrm_finish(&acxt)) { |
99 | return 0; | 101 | error = -EEXIST; |
102 | goto out_put; | ||
103 | } | ||
104 | |||
105 | return 0; | ||
100 | 106 | ||
101 | error = -EEXIST; | ||
102 | /* fall through */ | ||
103 | out_put: | 107 | out_put: |
104 | sysfs_put(target_sd); | 108 | sysfs_put(target_sd); |
105 | sysfs_put(sd); | 109 | sysfs_put(sd); |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 6a37f2386a8d..6b8c8d76d308 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -71,7 +71,6 @@ extern void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, | |||
71 | extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); | 71 | extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); |
72 | 72 | ||
73 | extern void sysfs_delete_inode(struct inode *inode); | 73 | extern void sysfs_delete_inode(struct inode *inode); |
74 | extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode); | ||
75 | extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd); | 74 | extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd); |
76 | extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode); | 75 | extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode); |
77 | 76 | ||