Commit 1b1dcc1b authored by Jes Sorensen's avatar Jes Sorensen Committed by Ingo Molnar

[PATCH] mutex subsystem, semaphore to mutex: VFS, ->i_sem

This patch converts the inode semaphore to a mutex. I have tested it on
XFS and compiled as much as one can consider on an ia64. Anyway your
luck with it might be different.
Modified-by: 's avatarIngo Molnar <mingo@elte.hu>

(finished the conversion)
Signed-off-by: 's avatarJes Sorensen <jes@sgi.com>
Signed-off-by: 's avatarIngo Molnar <mingo@elte.hu>
parent 794ee1ba
......@@ -137,7 +137,7 @@ spufs_delete_inode(struct inode *inode)
static void spufs_prune_dir(struct dentry *dir)
{
struct dentry *dentry, *tmp;
down(&dir->d_inode->i_sem);
mutex_lock(&dir->d_inode->i_mutex);
list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
......@@ -154,7 +154,7 @@ static void spufs_prune_dir(struct dentry *dir)
}
}
shrink_dcache_parent(dir);
up(&dir->d_inode->i_sem);
mutex_unlock(&dir->d_inode->i_mutex);
}
static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
......@@ -162,15 +162,15 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
struct spu_context *ctx;
/* remove all entries */
down(&root->i_sem);
mutex_lock(&root->i_mutex);
spufs_prune_dir(dir_dentry);
up(&root->i_sem);
mutex_unlock(&root->i_mutex);
/* We have to give up the mm_struct */
ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;
spu_forget(ctx);
/* XXX Do we need to hold i_sem here ? */
/* XXX Do we need to hold i_mutex here ? */
return simple_rmdir(root, dir_dentry);
}
......@@ -330,7 +330,7 @@ long spufs_create_thread(struct nameidata *nd,
out_dput:
dput(dentry);
out_dir:
up(&nd->dentry->d_inode->i_sem);
mutex_unlock(&nd->dentry->d_inode->i_mutex);
out:
return ret;
}
......
......@@ -215,7 +215,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
unsigned offset, bv_offs;
int len, ret;
down(&mapping->host->i_sem);
mutex_lock(&mapping->host->i_mutex);
index = pos >> PAGE_CACHE_SHIFT;
offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1);
bv_offs = bvec->bv_offset;
......@@ -278,7 +278,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
}
ret = 0;
out:
up(&mapping->host->i_sem);
mutex_unlock(&mapping->host->i_mutex);
return ret;
unlock:
unlock_page(page);
......
......@@ -741,7 +741,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
{
loff_t ret;
down(&file->f_dentry->d_inode->i_sem);
mutex_lock(&file->f_dentry->d_inode->i_mutex);
switch (orig) {
case 0:
file->f_pos = offset;
......@@ -756,7 +756,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
default:
ret = -EINVAL;
}
up(&file->f_dentry->d_inode->i_sem);
mutex_unlock(&file->f_dentry->d_inode->i_mutex);
return ret;
}
......
......@@ -138,7 +138,7 @@ static struct dentry *get_node(int num)
{
char s[10];
struct dentry *root = capifs_root;
down(&root->d_inode->i_sem);
mutex_lock(&root->d_inode->i_mutex);
return lookup_one_len(s, root, sprintf(s, "%d", num));
}
......@@ -159,7 +159,7 @@ void capifs_new_ncci(unsigned int number, dev_t device)
dentry = get_node(number);
if (!IS_ERR(dentry) && !dentry->d_inode)
d_instantiate(dentry, inode);
up(&capifs_root->d_inode->i_sem);
mutex_unlock(&capifs_root->d_inode->i_mutex);
}
void capifs_free_ncci(unsigned int number)
......@@ -175,7 +175,7 @@ void capifs_free_ncci(unsigned int number)
}
dput(dentry);
}
up(&capifs_root->d_inode->i_sem);
mutex_unlock(&capifs_root->d_inode->i_mutex);
}
static int __init capifs_init(void)
......
......@@ -837,9 +837,9 @@ static void __set_size(struct mapped_device *md, sector_t size)
{
set_capacity(md->disk, size);
down(&md->suspended_bdev->bd_inode->i_sem);
mutex_lock(&md->suspended_bdev->bd_inode->i_mutex);
i_size_write(md->suspended_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
up(&md->suspended_bdev->bd_inode->i_sem);
mutex_unlock(&md->suspended_bdev->bd_inode->i_mutex);
}
static int __bind(struct mapped_device *md, struct dm_table *t)
......
......@@ -3460,9 +3460,9 @@ static int update_size(mddev_t *mddev, unsigned long size)
bdev = bdget_disk(mddev->gendisk, 0);
if (bdev) {
down(&bdev->bd_inode->i_sem);
mutex_lock(&bdev->bd_inode->i_mutex);
i_size_write(bdev->bd_inode, mddev->array_size << 10);
up(&bdev->bd_inode->i_sem);
mutex_unlock(&bdev->bd_inode->i_mutex);
bdput(bdev);
}
}
......@@ -3486,9 +3486,9 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks)
bdev = bdget_disk(mddev->gendisk, 0);
if (bdev) {
down(&bdev->bd_inode->i_sem);
mutex_lock(&bdev->bd_inode->i_mutex);
i_size_write(bdev->bd_inode, mddev->array_size << 10);
up(&bdev->bd_inode->i_sem);
mutex_unlock(&bdev->bd_inode->i_mutex);
bdput(bdev);
}
}
......
......@@ -25,7 +25,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
loff_t new = -1;
struct inode *inode = file->f_dentry->d_inode;
down(&inode->i_sem);
mutex_lock(&inode->i_mutex);
switch (whence) {
case 0:
new = off;
......@@ -41,7 +41,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
new = -EINVAL;
else
file->f_pos = new;
up(&inode->i_sem);
mutex_unlock(&inode->i_mutex);
return new;
}
......
......@@ -184,13 +184,13 @@ static void update_bus(struct dentry *bus)
bus->d_inode->i_gid = busgid;
bus->d_inode->i_mode = S_IFDIR | busmode;
down(&bus->d_inode->i_sem);
mutex_lock(&bus->d_inode->i_mutex);
list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
if (dev->d_inode)
update_dev(dev);
up(&bus->d_inode->i_sem);
mutex_unlock(&bus->d_inode->i_mutex);
}
static void update_sb(struct super_block *sb)
......@@ -201,7 +201,7 @@ static void update_sb(struct super_block *sb)
if (!root)
return;
down(&root->d_inode->i_sem);
mutex_lock(&root->d_inode->i_mutex);
list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
if (bus->d_inode) {
......@@ -219,7 +219,7 @@ static void update_sb(struct super_block *sb)
}
}
up(&root->d_inode->i_sem);
mutex_unlock(&root->d_inode->i_mutex);
}
static int remount(struct super_block *sb, int *flags, char *data)
......@@ -333,10 +333,10 @@ static int usbfs_empty (struct dentry *dentry)
static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
down(&inode->i_sem);
mutex_lock(&inode->i_mutex);
dentry->d_inode->i_nlink--;
dput(dentry);
up(&inode->i_sem);
mutex_unlock(&inode->i_mutex);
d_delete(dentry);
return 0;
}
......@@ -346,7 +346,7 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
int error = -ENOTEMPTY;
struct inode * inode = dentry->d_inode;
down(&inode->i_sem);
mutex_lock(&inode->i_mutex);
dentry_unhash(dentry);
if (usbfs_empty(dentry)) {
dentry->d_inode->i_nlink -= 2;
......@@ -355,7 +355,7 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
dir->i_nlink--;
error = 0;
}
up(&inode->i_sem);
mutex_unlock(&inode->i_mutex);
if (!error)
d_delete(dentry);
dput(dentry);
......@@ -380,7 +380,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
{
loff_t retval = -EINVAL;
down(&file->f_dentry->d_inode->i_sem);
mutex_lock(&file->f_dentry->d_inode->i_mutex);
switch(orig) {
case 0:
if (offset > 0) {
......@@ -397,7 +397,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
default:
break;
}
up(&file->f_dentry->d_inode->i_sem);
mutex_unlock(&file->f_dentry->d_inode->i_mutex);
return retval;
}
......@@ -480,7 +480,7 @@ static int fs_create_by_name (const char *name, mode_t mode,
}
*dentry = NULL;
down(&parent->d_inode->i_sem);
mutex_lock(&parent->d_inode->i_mutex);
*dentry = lookup_one_len(name, parent, strlen(name));
if (!IS_ERR(dentry)) {
if ((mode & S_IFMT) == S_IFDIR)
......@@ -489,7 +489,7 @@ static int fs_create_by_name (const char *name, mode_t mode,
error = usbfs_create (parent->d_inode, *dentry, mode);
} else
error = PTR_ERR(dentry);
up(&parent->d_inode->i_sem);
mutex_unlock(&parent->d_inode->i_mutex);
return error;
}
......@@ -528,7 +528,7 @@ static void fs_remove_file (struct dentry *dentry)
if (!parent || !parent->d_inode)
return;
down(&parent->d_inode->i_sem);
mutex_lock(&parent->d_inode->i_mutex);
if (usbfs_positive(dentry)) {
if (dentry->d_inode) {
if (S_ISDIR(dentry->d_inode->i_mode))
......@@ -538,7 +538,7 @@ static void fs_remove_file (struct dentry *dentry)
dput(dentry);
}
}
up(&parent->d_inode->i_sem);
mutex_unlock(&parent->d_inode->i_mutex);
}
/* --------------------------------------------------------------------- */
......
......@@ -1891,7 +1891,7 @@ static int fsync_sub(struct lun *curlun)
return -EINVAL;
inode = filp->f_dentry->d_inode;
down(&inode->i_sem);
mutex_lock(&inode->i_mutex);
current->flags |= PF_SYNCWRITE;
rc = filemap_fdatawrite(inode->i_mapping);
err = filp->f_op->fsync(filp, filp->f_dentry, 1);
......@@ -1901,7 +1901,7 @@ static int fsync_sub(struct lun *curlun)
if (!rc)
rc = err;
current->flags &= ~PF_SYNCWRITE;
up(&inode->i_sem);
mutex_unlock(&inode->i_mutex);
VLDBG(curlun, "fdatasync -> %d\n", rc);
return rc;
}
......
......@@ -1562,10 +1562,10 @@ static void destroy_ep_files (struct dev_data *dev)
spin_unlock_irq (&dev->lock);
/* break link to dcache */
down (&parent->i_sem);
mutex_lock (&parent->i_mutex);
d_delete (dentry);
dput (dentry);
up (&parent->i_sem);
mutex_unlock (&parent->i_mutex);
/* fds may still be open */
goto restart;
......
......@@ -244,10 +244,10 @@ affs_put_inode(struct inode *inode)
pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
affs_free_prealloc(inode);
if (atomic_read(&inode->i_count) == 1) {
down(&inode->i_sem);
mutex_lock(&inode->i_mutex);
if (inode->i_size != AFFS_I(inode)->mmu_private)
affs_truncate(inode);
up(&inode->i_sem);
mutex_unlock(&inode->i_mutex);
}
}
......
......@@ -229,9 +229,9 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
dentry->d_flags |= DCACHE_AUTOFS_PENDING;
d_add(dentry, NULL);
up(&dir->i_sem);
mutex_unlock(&dir->i_mutex);
autofs_revalidate(dentry, nd);
down(&dir->i_sem);
mutex_lock(&dir->i_mutex);
/*
* If we are still pending, check if we had to handle
......
......@@ -489,9 +489,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
d_add(dentry, NULL);
if (dentry->d_op && dentry->d_op->d_revalidate) {
up(&dir->i_sem);
mutex_unlock(&dir->i_mutex);
(dentry->d_op->d_revalidate)(dentry, nd);
down(&dir->i_sem);
mutex_lock(&dir->i_mutex);
}
/*
......
......@@ -588,11 +588,11 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
case 2: set_bit(Enabled, &e->flags);
break;
case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
down(&root->d_inode->i_sem);
mutex_lock(&root->d_inode->i_mutex);
kill_node(e);
up(&root->d_inode->i_sem);
mutex_unlock(&root->d_inode->i_mutex);
dput(root);
break;
default: return res;
......@@ -622,7 +622,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
return PTR_ERR(e);
root = dget(sb->s_root);
down(&root->d_inode->i_sem);
mutex_lock(&root->d_inode->i_mutex);
dentry = lookup_one_len(e->name, root, strlen(e->name));
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
......@@ -658,7 +658,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
out2:
dput(dentry);
out:
up(&root->d_inode->i_sem);
mutex_unlock(&root->d_inode->i_mutex);
dput(root);
if (err) {
......@@ -703,12 +703,12 @@ static ssize_t bm_status_write(struct file * file, const char __user * buffer,
case 1: enabled = 0; break;
case 2: enabled = 1; break;
case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
down(&root->d_inode->i_sem);
mutex_lock(&root->d_inode->i_mutex);
while (!list_empty(&entries))
kill_node(list_entry(entries.next, Node, list));
up(&root->d_inode->i_sem);
mutex_unlock(&root->d_inode->i_mutex);
dput(root);
default: return res;
}
......
......@@ -202,7 +202,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
loff_t size;
loff_t retval;
down(&bd_inode->i_sem);
mutex_lock(&bd_inode->i_mutex);
size = i_size_read(bd_inode);
switch (origin) {
......@@ -219,7 +219,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
}
retval = offset;
}
up(&bd_inode->i_sem);
mutex_unlock(&bd_inode->i_mutex);
return retval;
}
......
......@@ -352,11 +352,11 @@ static long do_fsync(unsigned int fd, int datasync)
* We need to protect against concurrent writers,
* which could cause livelocks in fsync_buffers_list
*/
down(&mapping->host->i_sem);
mutex_lock(&mapping->host->i_mutex);
err = file->f_op->fsync(file, file->f_dentry, datasync);
if (!ret)
ret = err;
up(&mapping->host->i_sem);
mutex_unlock(&mapping->host->i_mutex);
err = filemap_fdatawait(mapping);
if (!ret)
ret = err;
......@@ -2338,7 +2338,7 @@ int generic_commit_write(struct file *file, struct page *page,
__block_commit_write(inode,page,from,to);
/*
* No need to use i_size_read() here, the i_size
* cannot change under us because we hold i_sem.
* cannot change under us because we hold i_mutex.
*/
if (pos > inode->i_size) {
i_size_write(inode, pos);
......
......@@ -860,9 +860,9 @@ static int cifs_oplock_thread(void * dummyarg)
DeleteOplockQEntry(oplock_item);
/* can not grab inode sem here since it would
deadlock when oplock received on delete
since vfs_unlink holds the i_sem across
since vfs_unlink holds the i_mutex across
the call */
/* down(&inode->i_sem);*/
/* mutex_lock(&inode->i_mutex);*/
if (S_ISREG(inode->i_mode)) {
rc = filemap_fdatawrite(inode->i_mapping);
if(CIFS_I(inode)->clientCanCacheRead == 0) {
......@@ -871,7 +871,7 @@ static int cifs_oplock_thread(void * dummyarg)
}
} else
rc = 0;
/* up(&inode->i_sem);*/
/* mutex_unlock(&inode->i_mutex);*/
if (rc)
CIFS_I(inode)->write_behind_rc = rc;
cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
......
......@@ -1040,9 +1040,9 @@ int cifs_revalidate(struct dentry *direntry)
}
/* can not grab this sem since kernel filesys locking documentation
indicates i_sem may be taken by the kernel on lookup and rename
which could deadlock if we grab the i_sem here as well */
/* down(&direntry->d_inode->i_sem);*/
indicates i_mutex may be taken by the kernel on lookup and rename
which could deadlock if we grab the i_mutex here as well */
/* mutex_lock(&direntry->d_inode->i_mutex);*/
/* need to write out dirty pages here */
if (direntry->d_inode->i_mapping) {
/* do we need to lock inode until after invalidate completes
......@@ -1066,7 +1066,7 @@ int cifs_revalidate(struct dentry *direntry)
}
}
}
/* up(&direntry->d_inode->i_sem); */
/* mutex_unlock(&direntry->d_inode->i_mutex); */
kfree(full_path);
FreeXid(xid);
......
......@@ -453,7 +453,7 @@ int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir)
coda_vfs_stat.readdir++;
host_inode = host_file->f_dentry->d_inode;
down(&host_inode->i_sem);
mutex_lock(&host_inode->i_mutex);
host_file->f_pos = coda_file->f_pos;
if (!host_file->f_op->readdir) {
......@@ -475,7 +475,7 @@ int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir)
}
out:
coda_file->f_pos = host_file->f_pos;
up(&host_inode->i_sem);
mutex_unlock(&host_inode->i_mutex);
return ret;
}
......
......@@ -77,14 +77,14 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo
return -EINVAL;
host_inode = host_file->f_dentry->d_inode;
down(&coda_inode->i_sem);
mutex_lock(&coda_inode->i_mutex);
ret = host_file->f_op->write(host_file, buf, count, ppos);
coda_inode->i_size = host_inode->i_size;
coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
up(&coda_inode->i_sem);
mutex_unlock(&coda_inode->i_mutex);
return ret;
}
......@@ -272,9 +272,9 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync)
if (host_file->f_op && host_file->f_op->fsync) {
host_dentry = host_file->f_dentry;
host_inode = host_dentry->d_inode;
down(&host_inode->i_sem);
mutex_lock(&host_inode->i_mutex);
err = host_file->f_op->fsync(host_file, host_dentry, datasync);
up(&host_inode->i_sem);
mutex_unlock(&host_inode->i_mutex);
}
if ( !err && !datasync ) {
......
......@@ -288,10 +288,10 @@ static struct dentry * configfs_lookup(struct inode *dir,
/*
* Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are
* attributes and are removed by rmdir(). We recurse, taking i_sem
* attributes and are removed by rmdir(). We recurse, taking i_mutex
* on all children that are candidates for default detach. If the
* result is clean, then configfs_detach_group() will handle dropping
* i_sem. If there is an error, the caller will clean up the i_sem
* i_mutex. If there is an error, the caller will clean up the i_mutex
* holders via configfs_detach_rollback().
*/
static int configfs_detach_prep(struct dentry *dentry)
......@@ -309,8 +309,8 @@ static int configfs_detach_prep(struct dentry *dentry)
if (sd->s_type & CONFIGFS_NOT_PINNED)
continue;
if (sd->s_type & CONFIGFS_USET_DEFAULT) {
down(&sd->s_dentry->d_inode->i_sem);
/* Mark that we've taken i_sem */
mutex_lock(&sd->s_dentry->d_inode->i_mutex);
/* Mark that we've taken i_mutex */
sd->s_type |= CONFIGFS_USET_DROPPING;
ret = configfs_detach_prep(sd->s_dentry);
......@@ -327,7 +327,7 @@ static int configfs_detach_prep(struct dentry *dentry)
}
/*
* Walk the tree, dropping i_sem wherever CONFIGFS_USET_DROPPING is
* Walk the tree, dropping i_mutex wherever CONFIGFS_USET_DROPPING is
* set.
*/
static void configfs_detach_rollback(struct dentry *dentry)
......@@ -341,7 +341,7 @@ static void configfs_detach_rollback(struct dentry *dentry)
if (sd->s_type & CONFIGFS_USET_DROPPING) {
sd->s_type &= ~CONFIGFS_USET_DROPPING;
up(&sd->s_dentry->d_inode->i_sem);
mutex_unlock(&sd->s_dentry->d_inode->i_mutex);
}
}
}
......@@ -424,11 +424,11 @@ static void detach_groups(struct config_group *group)
/*
* From rmdir/unregister, a configfs_detach_prep() pass
* has taken our i_sem for us. Drop it.
* has taken our i_mutex for us. Drop it.
* From mkdir/register cleanup, there is no sem held.
*/
if (sd->s_type & CONFIGFS_USET_DROPPING)
up(&child->d_inode->i_sem);
mutex_unlock(&child->d_inode->i_mutex);
d_delete(child);
dput(child);
......@@ -493,11 +493,11 @@ static int populate_groups(struct config_group *group)
/* FYI, we're faking mkdir here
* I'm not sure we need this semaphore, as we're called
* from our parent's mkdir. That holds our parent's
* i_sem, so afaik lookup cannot continue through our
* i_mutex, so afaik lookup cannot continue through our
* parent to find us, let alone mess with our tree.
* That said, taking our i_sem is closer to mkdir
* That said, taking our i_mutex is closer to mkdir
* emulation, and shouldn't hurt. */
down(&dentry->d_inode->i_sem);
mutex_lock(&dentry->d_inode->i_mutex);
for (i = 0; group->default_groups[i]; i++) {
new_group = group->default_groups[i];
......@@ -507,7 +507,7 @@ static int populate_groups(struct config_group *group)
break;
}
up(&dentry->d_inode->i_sem);
mutex_unlock(&dentry->d_inode->i_mutex);
}
if (ret)
......@@ -856,7 +856,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name)
down_write(&configfs_rename_sem);
parent = item->parent->dentry;
down(&parent->d_inode->i_sem);
mutex_lock(&parent->d_inode->i_mutex);
new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
if (!IS_ERR(new_dentry)) {
......@@ -872,7 +872,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name)
error = -EEXIST;
dput(new_dentry);
}
up(&parent->d_inode->i_sem);
mutex_unlock(&parent->d_inode->i_mutex);
up_write(&configfs_rename_sem);
return error;
......@@ -884,9 +884,9 @@ static int configfs_dir_open(struct inode *inode, struct file *file)
struct dentry * dentry = file->f_dentry;
struct configfs_dirent * parent_sd = dentry->d_fsdata;
down(&dentry->d_inode->i_sem);
mutex_lock(&dentry->d_inode->i_mutex);
file->private_data = configfs_new_dirent(parent_sd, NULL);
up(&dentry->d_inode->i_sem);
mutex_unlock(&dentry->d_inode->i_mutex);
return file->private_data ? 0 : -ENOMEM;
......@@ -897,9 +897,9 @@ static int configfs_dir_close(struct inode *inode, struct file *file)
struct dentry * dentry = file->f_dentry;
struct configfs_dirent * cursor = file->private_data;
down(&dentry->d_inode->i_sem);
mutex_lock(&dentry->d_inode->i_mutex);
list_del_init(&cursor->s_sibling);
up(&dentry->d_inode->i_sem);
mutex_unlock(&dentry->d_inode->i_mutex);
release_configfs_dirent(cursor);
......@@ -975,7 +975,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin)
{
struct dentry * dentry = file->f_dentry;
down(&dentry->d_inode->i_sem);
mutex_lock(&dentry->d_inode->i_mutex);
switch (origin) {
case 1:
offset += file->f_pos;
......@@ -983,7 +983,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin)
if (offset >= 0)
break;
default:
up(&file->f_dentry->d_inode->i_sem);
mutex_unlock(&file->f_dentry->d_inode->i_mutex);
return -EINVAL;
}
if (offset != file->f_pos) {
......@@ -1007,7 +1007,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin)
list_add_tail(&cursor->s_sibling, p);
}
}
up(&dentry->d_inode->i_sem);
mutex_unlock(&dentry->d_inode->i_mutex);
return offset;
}
......@@ -1037,7 +1037,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
sd = configfs_sb->s_root->d_fsdata;
link_group(to_config_group(sd->s_element), group);
down(&configfs_sb->s_root->d_inode->i_sem);
mutex_lock(&configfs_sb->s_root->d_inode->i_mutex);
name.name = group->cg_item.ci_name;