diff options
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 53 |
1 files changed, 22 insertions, 31 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 98aeebc2c9fa..d2f03355d127 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -933,11 +933,6 @@ static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2) | |||
933 | ocfs2_meta_unlock(inode2, 1); | 933 | ocfs2_meta_unlock(inode2, 1); |
934 | } | 934 | } |
935 | 935 | ||
936 | #define PARENT_INO(buffer) \ | ||
937 | ((struct ocfs2_dir_entry *) \ | ||
938 | ((char *)buffer + \ | ||
939 | le16_to_cpu(((struct ocfs2_dir_entry *)buffer)->rec_len)))->inode | ||
940 | |||
941 | static int ocfs2_rename(struct inode *old_dir, | 936 | static int ocfs2_rename(struct inode *old_dir, |
942 | struct dentry *old_dentry, | 937 | struct dentry *old_dentry, |
943 | struct inode *new_dir, | 938 | struct inode *new_dir, |
@@ -959,8 +954,8 @@ static int ocfs2_rename(struct inode *old_dir, | |||
959 | handle_t *handle = NULL; | 954 | handle_t *handle = NULL; |
960 | struct buffer_head *old_dir_bh = NULL; | 955 | struct buffer_head *old_dir_bh = NULL; |
961 | struct buffer_head *new_dir_bh = NULL; | 956 | struct buffer_head *new_dir_bh = NULL; |
962 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry | 957 | struct ocfs2_dir_entry *old_inode_dot_dot_de = NULL, *old_de = NULL, |
963 | // and new_dentry | 958 | *new_de = NULL; |
964 | struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above | 959 | struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above |
965 | struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, | 960 | struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, |
966 | // this is the 1st dirent bh | 961 | // this is the 1st dirent bh |
@@ -1044,19 +1039,26 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1044 | } | 1039 | } |
1045 | 1040 | ||
1046 | if (S_ISDIR(old_inode->i_mode)) { | 1041 | if (S_ISDIR(old_inode->i_mode)) { |
1047 | status = -EIO; | 1042 | u64 old_inode_parent; |
1048 | old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0); | 1043 | |
1049 | if (!old_inode_de_bh) | 1044 | status = ocfs2_find_files_on_disk("..", 2, &old_inode_parent, |
1045 | old_inode, &old_inode_de_bh, | ||
1046 | &old_inode_dot_dot_de); | ||
1047 | if (status) { | ||
1048 | status = -EIO; | ||
1050 | goto bail; | 1049 | goto bail; |
1050 | } | ||
1051 | 1051 | ||
1052 | status = -EIO; | 1052 | if (old_inode_parent != OCFS2_I(old_dir)->ip_blkno) { |
1053 | if (le64_to_cpu(PARENT_INO(old_inode_de_bh->b_data)) != | 1053 | status = -EIO; |
1054 | OCFS2_I(old_dir)->ip_blkno) | ||
1055 | goto bail; | 1054 | goto bail; |
1056 | status = -EMLINK; | 1055 | } |
1057 | if (!new_inode && new_dir!=old_dir && | 1056 | |
1058 | new_dir->i_nlink >= OCFS2_LINK_MAX) | 1057 | if (!new_inode && new_dir != old_dir && |
1058 | new_dir->i_nlink >= OCFS2_LINK_MAX) { | ||
1059 | status = -EMLINK; | ||
1059 | goto bail; | 1060 | goto bail; |
1061 | } | ||
1060 | } | 1062 | } |
1061 | 1063 | ||
1062 | status = -ENOENT; | 1064 | status = -ENOENT; |
@@ -1206,20 +1208,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1206 | } | 1208 | } |
1207 | 1209 | ||
1208 | /* change the dirent to point to the correct inode */ | 1210 | /* change the dirent to point to the correct inode */ |
1209 | status = ocfs2_journal_access(handle, new_dir, new_de_bh, | 1211 | status = ocfs2_update_entry(new_dir, handle, new_de_bh, |
1210 | OCFS2_JOURNAL_ACCESS_WRITE); | 1212 | new_de, old_inode); |
1211 | if (status < 0) { | 1213 | if (status < 0) { |
1212 | mlog_errno(status); | 1214 | mlog_errno(status); |
1213 | goto bail; | 1215 | goto bail; |
1214 | } | 1216 | } |
1215 | new_de->inode = cpu_to_le64(OCFS2_I(old_inode)->ip_blkno); | ||
1216 | new_de->file_type = old_de->file_type; | ||
1217 | new_dir->i_version++; | 1217 | new_dir->i_version++; |
1218 | status = ocfs2_journal_dirty(handle, new_de_bh); | ||
1219 | if (status < 0) { | ||
1220 | mlog_errno(status); | ||
1221 | goto bail; | ||
1222 | } | ||
1223 | 1218 | ||
1224 | if (S_ISDIR(new_inode->i_mode)) | 1219 | if (S_ISDIR(new_inode->i_mode)) |
1225 | newfe->i_links_count = 0; | 1220 | newfe->i_links_count = 0; |
@@ -1268,12 +1263,8 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1268 | } | 1263 | } |
1269 | old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; | 1264 | old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; |
1270 | if (old_inode_de_bh) { | 1265 | if (old_inode_de_bh) { |
1271 | status = ocfs2_journal_access(handle, old_inode, | 1266 | status = ocfs2_update_entry(old_inode, handle, old_inode_de_bh, |
1272 | old_inode_de_bh, | 1267 | old_inode_dot_dot_de, new_dir); |
1273 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
1274 | PARENT_INO(old_inode_de_bh->b_data) = | ||
1275 | cpu_to_le64(OCFS2_I(new_dir)->ip_blkno); | ||
1276 | status = ocfs2_journal_dirty(handle, old_inode_de_bh); | ||
1277 | old_dir->i_nlink--; | 1268 | old_dir->i_nlink--; |
1278 | if (new_inode) { | 1269 | if (new_inode) { |
1279 | new_inode->i_nlink--; | 1270 | new_inode->i_nlink--; |