aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorSunil Mushran <sunil.musran@oracle.com>2007-08-06 18:11:56 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2007-08-09 20:27:10 -0400
commit480214d71f1972756473415d31953647952400fb (patch)
tree558ca94278953cc2c01e60a206954d059fda75b1 /fs/ocfs2
parent6a18380e7ddd7d1a0493efe3be6475dd92323364 (diff)
ocfs2: Fix rename/extend race
If one process is extending a file while another is renaming it, there exists a window when rename could flush the old inode's stale i_size to disk. This patch recognizes the fact that rename is only updating the old inode's ctime, so it ensures only that value is flushed to disk. Signed-off-by: Sunil Mushran <sunil.musran@oracle.com> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/namei.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index d430fdab16e9..701e6d04ed5d 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1080,6 +1080,7 @@ static int ocfs2_rename(struct inode *old_dir,
1080 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, 1080 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
1081 // this is the 1st dirent bh 1081 // this is the 1st dirent bh
1082 nlink_t old_dir_nlink = old_dir->i_nlink; 1082 nlink_t old_dir_nlink = old_dir->i_nlink;
1083 struct ocfs2_dinode *old_di;
1083 1084
1084 /* At some point it might be nice to break this function up a 1085 /* At some point it might be nice to break this function up a
1085 * bit. */ 1086 * bit. */
@@ -1354,7 +1355,20 @@ static int ocfs2_rename(struct inode *old_dir,
1354 1355
1355 old_inode->i_ctime = CURRENT_TIME; 1356 old_inode->i_ctime = CURRENT_TIME;
1356 mark_inode_dirty(old_inode); 1357 mark_inode_dirty(old_inode);
1357 ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh); 1358
1359 status = ocfs2_journal_access(handle, old_inode, old_inode_bh,
1360 OCFS2_JOURNAL_ACCESS_WRITE);
1361 if (status >= 0) {
1362 old_di = (struct ocfs2_dinode *) old_inode_bh->b_data;
1363
1364 old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec);
1365 old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec);
1366
1367 status = ocfs2_journal_dirty(handle, old_inode_bh);
1368 if (status < 0)
1369 mlog_errno(status);
1370 } else
1371 mlog_errno(status);
1358 1372
1359 /* now that the name has been added to new_dir, remove the old name */ 1373 /* now that the name has been added to new_dir, remove the old name */
1360 status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh); 1374 status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);