aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r--fs/ocfs2/namei.c53
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
941static int ocfs2_rename(struct inode *old_dir, 936static 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--;