diff options
Diffstat (limited to 'fs/jfs/namei.c')
-rw-r--r-- | fs/jfs/namei.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index a6a8c16c872c..41c204771262 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -104,8 +104,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
104 | 104 | ||
105 | tid = txBegin(dip->i_sb, 0); | 105 | tid = txBegin(dip->i_sb, 0); |
106 | 106 | ||
107 | mutex_lock(&JFS_IP(dip)->commit_mutex); | 107 | mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); |
108 | mutex_lock(&JFS_IP(ip)->commit_mutex); | 108 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
109 | 109 | ||
110 | rc = jfs_init_acl(tid, ip, dip); | 110 | rc = jfs_init_acl(tid, ip, dip); |
111 | if (rc) | 111 | if (rc) |
@@ -238,8 +238,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
238 | 238 | ||
239 | tid = txBegin(dip->i_sb, 0); | 239 | tid = txBegin(dip->i_sb, 0); |
240 | 240 | ||
241 | mutex_lock(&JFS_IP(dip)->commit_mutex); | 241 | mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); |
242 | mutex_lock(&JFS_IP(ip)->commit_mutex); | 242 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
243 | 243 | ||
244 | rc = jfs_init_acl(tid, ip, dip); | 244 | rc = jfs_init_acl(tid, ip, dip); |
245 | if (rc) | 245 | if (rc) |
@@ -365,8 +365,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) | |||
365 | 365 | ||
366 | tid = txBegin(dip->i_sb, 0); | 366 | tid = txBegin(dip->i_sb, 0); |
367 | 367 | ||
368 | mutex_lock(&JFS_IP(dip)->commit_mutex); | 368 | mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); |
369 | mutex_lock(&JFS_IP(ip)->commit_mutex); | 369 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
370 | 370 | ||
371 | iplist[0] = dip; | 371 | iplist[0] = dip; |
372 | iplist[1] = ip; | 372 | iplist[1] = ip; |
@@ -483,12 +483,12 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) | |||
483 | if ((rc = get_UCSname(&dname, dentry))) | 483 | if ((rc = get_UCSname(&dname, dentry))) |
484 | goto out; | 484 | goto out; |
485 | 485 | ||
486 | IWRITE_LOCK(ip); | 486 | IWRITE_LOCK(ip, RDWRLOCK_NORMAL); |
487 | 487 | ||
488 | tid = txBegin(dip->i_sb, 0); | 488 | tid = txBegin(dip->i_sb, 0); |
489 | 489 | ||
490 | mutex_lock(&JFS_IP(dip)->commit_mutex); | 490 | mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); |
491 | mutex_lock(&JFS_IP(ip)->commit_mutex); | 491 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
492 | 492 | ||
493 | iplist[0] = dip; | 493 | iplist[0] = dip; |
494 | iplist[1] = ip; | 494 | iplist[1] = ip; |
@@ -802,8 +802,8 @@ static int jfs_link(struct dentry *old_dentry, | |||
802 | 802 | ||
803 | tid = txBegin(ip->i_sb, 0); | 803 | tid = txBegin(ip->i_sb, 0); |
804 | 804 | ||
805 | mutex_lock(&JFS_IP(dir)->commit_mutex); | 805 | mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT); |
806 | mutex_lock(&JFS_IP(ip)->commit_mutex); | 806 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
807 | 807 | ||
808 | /* | 808 | /* |
809 | * scan parent directory for entry/freespace | 809 | * scan parent directory for entry/freespace |
@@ -913,8 +913,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
913 | 913 | ||
914 | tid = txBegin(dip->i_sb, 0); | 914 | tid = txBegin(dip->i_sb, 0); |
915 | 915 | ||
916 | mutex_lock(&JFS_IP(dip)->commit_mutex); | 916 | mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); |
917 | mutex_lock(&JFS_IP(ip)->commit_mutex); | 917 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
918 | 918 | ||
919 | rc = jfs_init_security(tid, ip, dip); | 919 | rc = jfs_init_security(tid, ip, dip); |
920 | if (rc) | 920 | if (rc) |
@@ -1127,7 +1127,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1127 | goto out3; | 1127 | goto out3; |
1128 | } | 1128 | } |
1129 | } else if (new_ip) { | 1129 | } else if (new_ip) { |
1130 | IWRITE_LOCK(new_ip); | 1130 | IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL); |
1131 | /* Init inode for quota operations. */ | 1131 | /* Init inode for quota operations. */ |
1132 | DQUOT_INIT(new_ip); | 1132 | DQUOT_INIT(new_ip); |
1133 | } | 1133 | } |
@@ -1137,13 +1137,21 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1137 | */ | 1137 | */ |
1138 | tid = txBegin(new_dir->i_sb, 0); | 1138 | tid = txBegin(new_dir->i_sb, 0); |
1139 | 1139 | ||
1140 | mutex_lock(&JFS_IP(new_dir)->commit_mutex); | 1140 | /* |
1141 | mutex_lock(&JFS_IP(old_ip)->commit_mutex); | 1141 | * How do we know the locking is safe from deadlocks? |
1142 | * The vfs does the hard part for us. Any time we are taking nested | ||
1143 | * commit_mutexes, the vfs already has i_mutex held on the parent. | ||
1144 | * Here, the vfs has already taken i_mutex on both old_dir and new_dir. | ||
1145 | */ | ||
1146 | mutex_lock_nested(&JFS_IP(new_dir)->commit_mutex, COMMIT_MUTEX_PARENT); | ||
1147 | mutex_lock_nested(&JFS_IP(old_ip)->commit_mutex, COMMIT_MUTEX_CHILD); | ||
1142 | if (old_dir != new_dir) | 1148 | if (old_dir != new_dir) |
1143 | mutex_lock(&JFS_IP(old_dir)->commit_mutex); | 1149 | mutex_lock_nested(&JFS_IP(old_dir)->commit_mutex, |
1150 | COMMIT_MUTEX_SECOND_PARENT); | ||
1144 | 1151 | ||
1145 | if (new_ip) { | 1152 | if (new_ip) { |
1146 | mutex_lock(&JFS_IP(new_ip)->commit_mutex); | 1153 | mutex_lock_nested(&JFS_IP(new_ip)->commit_mutex, |
1154 | COMMIT_MUTEX_VICTIM); | ||
1147 | /* | 1155 | /* |
1148 | * Change existing directory entry to new inode number | 1156 | * Change existing directory entry to new inode number |
1149 | */ | 1157 | */ |
@@ -1357,8 +1365,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1357 | 1365 | ||
1358 | tid = txBegin(dir->i_sb, 0); | 1366 | tid = txBegin(dir->i_sb, 0); |
1359 | 1367 | ||
1360 | mutex_lock(&JFS_IP(dir)->commit_mutex); | 1368 | mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT); |
1361 | mutex_lock(&JFS_IP(ip)->commit_mutex); | 1369 | mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); |
1362 | 1370 | ||
1363 | rc = jfs_init_acl(tid, ip, dir); | 1371 | rc = jfs_init_acl(tid, ip, dir); |
1364 | if (rc) | 1372 | if (rc) |
@@ -1495,7 +1503,7 @@ struct dentry *jfs_get_parent(struct dentry *dentry) | |||
1495 | return parent; | 1503 | return parent; |
1496 | } | 1504 | } |
1497 | 1505 | ||
1498 | struct inode_operations jfs_dir_inode_operations = { | 1506 | const struct inode_operations jfs_dir_inode_operations = { |
1499 | .create = jfs_create, | 1507 | .create = jfs_create, |
1500 | .lookup = jfs_lookup, | 1508 | .lookup = jfs_lookup, |
1501 | .link = jfs_link, | 1509 | .link = jfs_link, |