Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 130853
b: refs/heads/master
c: 82c1593
h: refs/heads/master
i:
  130851: ef01b0d
v: v3
  • Loading branch information
Artem Bityutskiy authored and Artem Bityutskiy committed Jan 26, 2009
1 parent 13186d6 commit ed944c3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 57 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7078202e55b565582fcbd831a8dd3069bdc72610
refs/heads/master: 82c1593cad3dfc97661764c8bc62aa1a416e9ea8
92 changes: 36 additions & 56 deletions trunk/fs/ubifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,30 +482,29 @@ static int ubifs_dir_release(struct inode *dir, struct file *file)
}

/**
* lock_2_inodes - lock two UBIFS inodes.
* lock_2_inodes - a wrapper for locking two UBIFS inodes.
* @inode1: first inode
* @inode2: second inode
*
* We do not implement any tricks to guarantee strict lock ordering, because
* VFS has already done it for us on the @i_mutex. So this is just a simple
* wrapper function.
*/
static void lock_2_inodes(struct inode *inode1, struct inode *inode2)
{
if (inode1->i_ino < inode2->i_ino) {
mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_2);
mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_3);
} else {
mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_3);
}
mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
}

/**
* unlock_2_inodes - unlock two UBIFS inodes inodes.
* unlock_2_inodes - a wrapper for unlocking two UBIFS inodes.
* @inode1: first inode
* @inode2: second inode
*/
static void unlock_2_inodes(struct inode *inode1, struct inode *inode2)
{
mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
}

static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
Expand All @@ -527,6 +526,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
dbg_gen("dent '%.*s' to ino %lu (nlink %d) in dir ino %lu",
dentry->d_name.len, dentry->d_name.name, inode->i_ino,
inode->i_nlink, dir->i_ino);
ubifs_assert(mutex_is_locked(&dir->i_mutex));
ubifs_assert(mutex_is_locked(&inode->i_mutex));
err = dbg_check_synced_i_size(inode);
if (err)
return err;
Expand Down Expand Up @@ -580,6 +581,8 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
dbg_gen("dent '%.*s' from ino %lu (nlink %d) in dir ino %lu",
dentry->d_name.len, dentry->d_name.name, inode->i_ino,
inode->i_nlink, dir->i_ino);
ubifs_assert(mutex_is_locked(&dir->i_mutex));
ubifs_assert(mutex_is_locked(&inode->i_mutex));
err = dbg_check_synced_i_size(inode);
if (err)
return err;
Expand Down Expand Up @@ -667,7 +670,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)

dbg_gen("directory '%.*s', ino %lu in dir ino %lu", dentry->d_name.len,
dentry->d_name.name, inode->i_ino, dir->i_ino);

ubifs_assert(mutex_is_locked(&dir->i_mutex));
ubifs_assert(mutex_is_locked(&inode->i_mutex));
err = check_dir_empty(c, dentry->d_inode);
if (err)
return err;
Expand Down Expand Up @@ -922,71 +926,42 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
}

/**
* lock_3_inodes - lock three UBIFS inodes for rename.
* lock_3_inodes - a wrapper for locking three UBIFS inodes.
* @inode1: first inode
* @inode2: second inode
* @inode3: third inode
*
* For 'ubifs_rename()', @inode1 may be the same as @inode2 whereas @inode3 may
* be null.
* This function is used for 'ubifs_rename()' and @inode1 may be the same as
* @inode2 whereas @inode3 may be %NULL.
*
* We do not implement any tricks to guarantee strict lock ordering, because
* VFS has already done it for us on the @i_mutex. So this is just a simple
* wrapper function.
*/
static void lock_3_inodes(struct inode *inode1, struct inode *inode2,
struct inode *inode3)
{
struct inode *i1, *i2, *i3;

if (!inode3) {
if (inode1 != inode2) {
lock_2_inodes(inode1, inode2);
return;
}
mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
return;
}

if (inode1 == inode2) {
lock_2_inodes(inode1, inode3);
return;
}

/* 3 different inodes */
if (inode1 < inode2) {
i3 = inode2;
if (inode1 < inode3) {
i1 = inode1;
i2 = inode3;
} else {
i1 = inode3;
i2 = inode1;
}
} else {
i3 = inode1;
if (inode2 < inode3) {
i1 = inode2;
i2 = inode3;
} else {
i1 = inode3;
i2 = inode2;
}
}
mutex_lock_nested(&ubifs_inode(i1)->ui_mutex, WB_MUTEX_1);
lock_2_inodes(i2, i3);
mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
if (inode2 != inode1)
mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
if (inode3)
mutex_lock_nested(&ubifs_inode(inode3)->ui_mutex, WB_MUTEX_3);
}

/**
* unlock_3_inodes - unlock three UBIFS inodes for rename.
* unlock_3_inodes - a wrapper for unlocking three UBIFS inodes for rename.
* @inode1: first inode
* @inode2: second inode
* @inode3: third inode
*/
static void unlock_3_inodes(struct inode *inode1, struct inode *inode2,
struct inode *inode3)
{
mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
if (inode1 != inode2)
mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
if (inode3)
mutex_unlock(&ubifs_inode(inode3)->ui_mutex);
if (inode1 != inode2)
mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
}

static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
Expand Down Expand Up @@ -1020,6 +995,11 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
"dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name,
old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len,
new_dentry->d_name.name, new_dir->i_ino);
ubifs_assert(mutex_is_locked(&old_dir->i_mutex));
ubifs_assert(mutex_is_locked(&new_dir->i_mutex));
if (unlink)
ubifs_assert(mutex_is_locked(&new_inode->i_mutex));


if (unlink && is_dir) {
err = check_dir_empty(c, new_inode);
Expand Down

0 comments on commit ed944c3

Please sign in to comment.