aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/debugfs/inode.c5
-rw-r--r--fs/gfs2/ops_file.c24
-rw-r--r--fs/locks.c112
-rw-r--r--fs/nfs/file.c16
-rw-r--r--fs/nfsd/nfs4state.c10
-rw-r--r--fs/sysfs/dir.c25
-rw-r--r--fs/sysfs/file.c9
-rw-r--r--fs/sysfs/inode.c2
-rw-r--r--fs/sysfs/mount.c10
-rw-r--r--fs/sysfs/symlink.c12
-rw-r--r--fs/sysfs/sysfs.h1
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
500static 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
643const struct file_operations gfs2_dir_fops = { 667const 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 */
461static int lease_alloc(struct file *filp, int type, struct file_lock **flp) 461static 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 }
474out: 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
664int 662void
665posix_test_lock(struct file *filp, struct file_lock *fl) 663posix_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
686EXPORT_SYMBOL(posix_test_lock); 682EXPORT_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 */
1177int __break_lease(struct inode *inode, unsigned int mode) 1173int __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
1261out: 1256out:
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 */
1342static int __setlease(struct file *filp, long arg, struct file_lock **flp) 1337int 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)
1418out: 1419out:
1419 return error; 1420 return error;
1420} 1421}
1422EXPORT_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
1432int setlease(struct file *filp, long arg, struct file_lock **lease) 1451int 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 1464EXPORT_SYMBOL_GPL(vfs_setlease);
1453EXPORT_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);
53static int nfs_check_flags(int flags); 53static int nfs_check_flags(int flags);
54static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); 54static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
55static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 55static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
56static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
56 57
57const struct file_operations nfs_file_operations = { 58const 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
74const struct inode_operations nfs_file_inode_operations = { 76const 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
566static 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 */
1407static 1407static
1408void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl) 1408void 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 */
1421static 1421static
1422int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) 1422int 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 = {
361struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) 361struct 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
714int sysfs_create_subdir(struct kobject *kobj, const char *name, 717int 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 */
134static struct lock_class_key sysfs_inode_imutex_key; 134static struct lock_class_key sysfs_inode_imutex_key;
135 135
136void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 136static 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,
71extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); 71extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
72 72
73extern void sysfs_delete_inode(struct inode *inode); 73extern void sysfs_delete_inode(struct inode *inode);
74extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode);
75extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd); 74extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
76extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode); 75extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
77 76