aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r--fs/sysfs/dir.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 3aa3434621ca..511edef8b321 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -372,9 +372,54 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
372 return error; 372 return error;
373} 373}
374 374
375int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
376{
377 struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry;
378 struct sysfs_dirent *new_parent_sd, *sd;
379 int error;
380
381 if (!new_parent)
382 return -EINVAL;
383
384 old_parent_dentry = kobj->parent ?
385 kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
386 new_parent_dentry = new_parent->dentry;
387
388again:
389 mutex_lock(&old_parent_dentry->d_inode->i_mutex);
390 if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) {
391 mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
392 goto again;
393 }
394
395 new_parent_sd = new_parent_dentry->d_fsdata;
396 sd = kobj->dentry->d_fsdata;
397
398 new_dentry = lookup_one_len(kobj->name, new_parent_dentry,
399 strlen(kobj->name));
400 if (IS_ERR(new_dentry)) {
401 error = PTR_ERR(new_dentry);
402 goto out;
403 } else
404 error = 0;
405 d_add(new_dentry, NULL);
406 d_move(kobj->dentry, new_dentry);
407 dput(new_dentry);
408
409 /* Remove from old parent's list and insert into new parent's list. */
410 list_del_init(&sd->s_sibling);
411 list_add(&sd->s_sibling, &new_parent_sd->s_children);
412
413out:
414 mutex_unlock(&new_parent_dentry->d_inode->i_mutex);
415 mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
416
417 return error;
418}
419
375static int sysfs_dir_open(struct inode *inode, struct file *file) 420static int sysfs_dir_open(struct inode *inode, struct file *file)
376{ 421{
377 struct dentry * dentry = file->f_dentry; 422 struct dentry * dentry = file->f_path.dentry;
378 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 423 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
379 424
380 mutex_lock(&dentry->d_inode->i_mutex); 425 mutex_lock(&dentry->d_inode->i_mutex);
@@ -387,7 +432,7 @@ static int sysfs_dir_open(struct inode *inode, struct file *file)
387 432
388static int sysfs_dir_close(struct inode *inode, struct file *file) 433static int sysfs_dir_close(struct inode *inode, struct file *file)
389{ 434{
390 struct dentry * dentry = file->f_dentry; 435 struct dentry * dentry = file->f_path.dentry;
391 struct sysfs_dirent * cursor = file->private_data; 436 struct sysfs_dirent * cursor = file->private_data;
392 437
393 mutex_lock(&dentry->d_inode->i_mutex); 438 mutex_lock(&dentry->d_inode->i_mutex);
@@ -407,7 +452,7 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd)
407 452
408static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) 453static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
409{ 454{
410 struct dentry *dentry = filp->f_dentry; 455 struct dentry *dentry = filp->f_path.dentry;
411 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 456 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
412 struct sysfs_dirent *cursor = filp->private_data; 457 struct sysfs_dirent *cursor = filp->private_data;
413 struct list_head *p, *q = &cursor->s_sibling; 458 struct list_head *p, *q = &cursor->s_sibling;
@@ -464,7 +509,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
464 509
465static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) 510static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
466{ 511{
467 struct dentry * dentry = file->f_dentry; 512 struct dentry * dentry = file->f_path.dentry;
468 513
469 mutex_lock(&dentry->d_inode->i_mutex); 514 mutex_lock(&dentry->d_inode->i_mutex);
470 switch (origin) { 515 switch (origin) {
@@ -474,7 +519,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
474 if (offset >= 0) 519 if (offset >= 0)
475 break; 520 break;
476 default: 521 default:
477 mutex_unlock(&file->f_dentry->d_inode->i_mutex); 522 mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
478 return -EINVAL; 523 return -EINVAL;
479 } 524 }
480 if (offset != file->f_pos) { 525 if (offset != file->f_pos) {