aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/dir.c22
-rw-r--r--fs/ocfs2/dir.h3
-rw-r--r--fs/ocfs2/namei.c53
3 files changed, 47 insertions, 31 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 4791683a119c..31db7e3881b1 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -271,6 +271,28 @@ cleanup_and_exit:
271 return ret; 271 return ret;
272} 272}
273 273
274int ocfs2_update_entry(struct inode *dir, handle_t *handle,
275 struct buffer_head *de_bh, struct ocfs2_dir_entry *de,
276 struct inode *new_entry_inode)
277{
278 int ret;
279
280 ret = ocfs2_journal_access(handle, dir, de_bh,
281 OCFS2_JOURNAL_ACCESS_WRITE);
282 if (ret) {
283 mlog_errno(ret);
284 goto out;
285 }
286
287 de->inode = cpu_to_le64(OCFS2_I(new_entry_inode)->ip_blkno);
288 ocfs2_set_de_type(de, new_entry_inode->i_mode);
289
290 ocfs2_journal_dirty(handle, de_bh);
291
292out:
293 return ret;
294}
295
274/* 296/*
275 * ocfs2_delete_entry deletes a directory entry by merging it with the 297 * ocfs2_delete_entry deletes a directory entry by merging it with the
276 * previous entry 298 * previous entry
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
index d03eaaa5cfd4..ce48b9080d87 100644
--- a/fs/ocfs2/dir.h
+++ b/fs/ocfs2/dir.h
@@ -50,6 +50,9 @@ static inline int ocfs2_add_entry(handle_t *handle,
50 dentry->d_name.name, dentry->d_name.len, 50 dentry->d_name.name, dentry->d_name.len,
51 inode, blkno, parent_fe_bh, insert_bh); 51 inode, blkno, parent_fe_bh, insert_bh);
52} 52}
53int ocfs2_update_entry(struct inode *dir, handle_t *handle,
54 struct buffer_head *de_bh, struct ocfs2_dir_entry *de,
55 struct inode *new_entry_inode);
53 56
54int ocfs2_check_dir_for_entry(struct inode *dir, 57int ocfs2_check_dir_for_entry(struct inode *dir,
55 const char *name, 58 const char *name,
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--;