diff options
author | Dave Kleikamp <dave.kleikamp@oracle.com> | 2015-07-15 13:52:47 -0400 |
---|---|---|
committer | Dave Kleikamp <dave.kleikamp@oracle.com> | 2015-07-15 15:11:30 -0400 |
commit | 26456955719b79cc4a011b18221aa68f599f6b6c (patch) | |
tree | 2228980d70a85410beb6b473a8fb58b31a882fbc | |
parent | f7f31adf07d1c9e66c160e9bdd77e12531cd6996 (diff) |
jfs: clean up jfs_rename and fix out of order unlock
The end of jfs_rename(), which is also used by the error paths,
included a call to IWRITE_UNLOCK(new_ip) after labels out1, out2
and out3. If we come in through these labels, IWRITE_LOCK() has not
been called yet.
In moving that call to the correct spot, I also moved some
exceptional truncate code earlier as well, since the early error
paths don't need to deal with it, and I renamed out4: to out_tx: so
a future patch by Jan Kara doesn't need to deal with renumbering or
confusing out-of-order labels.
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
-rw-r--r-- | fs/jfs/namei.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 66db7bc0ed10..f7b40370a856 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1161,7 +1161,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1161 | rc = dtModify(tid, new_dir, &new_dname, &ino, | 1161 | rc = dtModify(tid, new_dir, &new_dname, &ino, |
1162 | old_ip->i_ino, JFS_RENAME); | 1162 | old_ip->i_ino, JFS_RENAME); |
1163 | if (rc) | 1163 | if (rc) |
1164 | goto out4; | 1164 | goto out_tx; |
1165 | drop_nlink(new_ip); | 1165 | drop_nlink(new_ip); |
1166 | if (S_ISDIR(new_ip->i_mode)) { | 1166 | if (S_ISDIR(new_ip->i_mode)) { |
1167 | drop_nlink(new_ip); | 1167 | drop_nlink(new_ip); |
@@ -1186,7 +1186,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1186 | if ((new_size = commitZeroLink(tid, new_ip)) < 0) { | 1186 | if ((new_size = commitZeroLink(tid, new_ip)) < 0) { |
1187 | txAbort(tid, 1); /* Marks FS Dirty */ | 1187 | txAbort(tid, 1); /* Marks FS Dirty */ |
1188 | rc = new_size; | 1188 | rc = new_size; |
1189 | goto out4; | 1189 | goto out_tx; |
1190 | } | 1190 | } |
1191 | tblk = tid_to_tblock(tid); | 1191 | tblk = tid_to_tblock(tid); |
1192 | tblk->xflag |= COMMIT_DELETE; | 1192 | tblk->xflag |= COMMIT_DELETE; |
@@ -1204,7 +1204,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1204 | if (rc) { | 1204 | if (rc) { |
1205 | jfs_err("jfs_rename didn't expect dtSearch to fail " | 1205 | jfs_err("jfs_rename didn't expect dtSearch to fail " |
1206 | "w/rc = %d", rc); | 1206 | "w/rc = %d", rc); |
1207 | goto out4; | 1207 | goto out_tx; |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | ino = old_ip->i_ino; | 1210 | ino = old_ip->i_ino; |
@@ -1212,7 +1212,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1212 | if (rc) { | 1212 | if (rc) { |
1213 | if (rc == -EIO) | 1213 | if (rc == -EIO) |
1214 | jfs_err("jfs_rename: dtInsert returned -EIO"); | 1214 | jfs_err("jfs_rename: dtInsert returned -EIO"); |
1215 | goto out4; | 1215 | goto out_tx; |
1216 | } | 1216 | } |
1217 | if (S_ISDIR(old_ip->i_mode)) | 1217 | if (S_ISDIR(old_ip->i_mode)) |
1218 | inc_nlink(new_dir); | 1218 | inc_nlink(new_dir); |
@@ -1227,7 +1227,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1227 | jfs_err("jfs_rename did not expect dtDelete to return rc = %d", | 1227 | jfs_err("jfs_rename did not expect dtDelete to return rc = %d", |
1228 | rc); | 1228 | rc); |
1229 | txAbort(tid, 1); /* Marks Filesystem dirty */ | 1229 | txAbort(tid, 1); /* Marks Filesystem dirty */ |
1230 | goto out4; | 1230 | goto out_tx; |
1231 | } | 1231 | } |
1232 | if (S_ISDIR(old_ip->i_mode)) { | 1232 | if (S_ISDIR(old_ip->i_mode)) { |
1233 | drop_nlink(old_dir); | 1233 | drop_nlink(old_dir); |
@@ -1286,7 +1286,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1286 | 1286 | ||
1287 | rc = txCommit(tid, ipcount, iplist, commit_flag); | 1287 | rc = txCommit(tid, ipcount, iplist, commit_flag); |
1288 | 1288 | ||
1289 | out4: | 1289 | out_tx: |
1290 | txEnd(tid); | 1290 | txEnd(tid); |
1291 | if (new_ip) | 1291 | if (new_ip) |
1292 | mutex_unlock(&JFS_IP(new_ip)->commit_mutex); | 1292 | mutex_unlock(&JFS_IP(new_ip)->commit_mutex); |
@@ -1309,13 +1309,6 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1309 | } | 1309 | } |
1310 | if (new_ip && (new_ip->i_nlink == 0)) | 1310 | if (new_ip && (new_ip->i_nlink == 0)) |
1311 | set_cflag(COMMIT_Nolink, new_ip); | 1311 | set_cflag(COMMIT_Nolink, new_ip); |
1312 | out3: | ||
1313 | free_UCSname(&new_dname); | ||
1314 | out2: | ||
1315 | free_UCSname(&old_dname); | ||
1316 | out1: | ||
1317 | if (new_ip && !S_ISDIR(new_ip->i_mode)) | ||
1318 | IWRITE_UNLOCK(new_ip); | ||
1319 | /* | 1312 | /* |
1320 | * Truncating the directory index table is not guaranteed. It | 1313 | * Truncating the directory index table is not guaranteed. It |
1321 | * may need to be done iteratively | 1314 | * may need to be done iteratively |
@@ -1326,7 +1319,13 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1326 | 1319 | ||
1327 | clear_cflag(COMMIT_Stale, old_dir); | 1320 | clear_cflag(COMMIT_Stale, old_dir); |
1328 | } | 1321 | } |
1329 | 1322 | if (new_ip && !S_ISDIR(new_ip->i_mode)) | |
1323 | IWRITE_UNLOCK(new_ip); | ||
1324 | out3: | ||
1325 | free_UCSname(&new_dname); | ||
1326 | out2: | ||
1327 | free_UCSname(&old_dname); | ||
1328 | out1: | ||
1330 | jfs_info("jfs_rename: returning %d", rc); | 1329 | jfs_info("jfs_rename: returning %d", rc); |
1331 | return rc; | 1330 | return rc; |
1332 | } | 1331 | } |