diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-09-11 20:21:56 -0400 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-10-12 14:54:38 -0400 |
commit | 38760e243249f03b4c6d78ca624dd846a2681b67 (patch) | |
tree | adf4cc72ac30455f9d4a646f64f1628e38b14a89 | |
parent | be94d11704ef79030fd2e6a0c41b4a7f65f9e860 (diff) |
ocfs2: Rename cleanups
ocfs2_rename() does direct manipulation of the dirent it's gotten back from
a directory search. Wrap this manipulation inside of a function so that we
can transparently change directory update behavior in the future. As an
added bonus, this gets rid of an ugly macro.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Reviewed-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r-- | fs/ocfs2/dir.c | 22 | ||||
-rw-r--r-- | fs/ocfs2/dir.h | 3 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 53 |
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 | ||
274 | int 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 | |||
292 | out: | ||
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 | } |
53 | int 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 | ||
54 | int ocfs2_check_dir_for_entry(struct inode *dir, | 57 | int 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 | |||
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--; |