aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-01-02 20:59:40 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2007-01-21 19:18:49 -0500
commit592282cf2eaa33409c6511ddd3f3ecaa57daeaaa (patch)
treefea7fe8403d6b2a96848372a69976b0123a4cf1d /fs
parent72bce5078d124a8b13fb167aea028b6e8d91873e (diff)
ocfs2: Directory c/mtime update fixes
ocfs2 wasn't updating c/mtime on directories during dirent creation/deletion. Fix ocfs2_unlink(), ocfs2_rename() and __ocfs2_add_entry() by adding the proper code to update the struct inode and push the change out to disk. This helps rename/unlink on nfs exported file systems in particular as those clients compare directory time values to avoid a full re-reading a directory which hasn't changed. ocfs2_rename() loses some superfluous error handling as a result of this patch. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/namei.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 9637039c2633..f3d7803b4b46 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -932,14 +932,15 @@ static int ocfs2_unlink(struct inode *dir,
932 goto leave; 932 goto leave;
933 } 933 }
934 934
935 if (S_ISDIR(inode->i_mode)) { 935 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
936 if (S_ISDIR(inode->i_mode))
936 drop_nlink(dir); 937 drop_nlink(dir);
937 status = ocfs2_mark_inode_dirty(handle, dir, 938
938 parent_node_bh); 939 status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh);
939 if (status < 0) { 940 if (status < 0) {
940 mlog_errno(status); 941 mlog_errno(status);
942 if (S_ISDIR(inode->i_mode))
941 inc_nlink(dir); 943 inc_nlink(dir);
942 }
943 } 944 }
944 945
945leave: 946leave:
@@ -1068,6 +1069,7 @@ static int ocfs2_rename(struct inode *old_dir,
1068 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; 1069 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
1069 struct buffer_head *orphan_entry_bh = NULL; 1070 struct buffer_head *orphan_entry_bh = NULL;
1070 struct buffer_head *newfe_bh = NULL; 1071 struct buffer_head *newfe_bh = NULL;
1072 struct buffer_head *old_inode_bh = NULL;
1071 struct buffer_head *insert_entry_bh = NULL; 1073 struct buffer_head *insert_entry_bh = NULL;
1072 struct ocfs2_super *osb = NULL; 1074 struct ocfs2_super *osb = NULL;
1073 u64 newfe_blkno; 1075 u64 newfe_blkno;
@@ -1079,7 +1081,7 @@ static int ocfs2_rename(struct inode *old_dir,
1079 struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above 1081 struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
1080 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, 1082 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
1081 // this is the 1st dirent bh 1083 // this is the 1st dirent bh
1082 nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink; 1084 nlink_t old_dir_nlink = old_dir->i_nlink;
1083 1085
1084 /* At some point it might be nice to break this function up a 1086 /* At some point it might be nice to break this function up a
1085 * bit. */ 1087 * bit. */
@@ -1139,12 +1141,11 @@ static int ocfs2_rename(struct inode *old_dir,
1139 } 1141 }
1140 1142
1141 /* 1143 /*
1142 * Though we don't require an inode meta data update if 1144 * Aside from allowing a meta data update, the locking here
1143 * old_inode is not a directory, we lock anyway here to ensure 1145 * also ensures that the vote thread on other nodes won't have
1144 * the vote thread on other nodes won't have to concurrently 1146 * to concurrently downconvert the inode and the dentry locks.
1145 * downconvert the inode and the dentry locks.
1146 */ 1147 */
1147 status = ocfs2_meta_lock(old_inode, NULL, 1); 1148 status = ocfs2_meta_lock(old_inode, &old_inode_bh, 1);
1148 if (status < 0) { 1149 if (status < 0) {
1149 if (status != -ENOENT) 1150 if (status != -ENOENT)
1150 mlog_errno(status); 1151 mlog_errno(status);
@@ -1355,6 +1356,7 @@ static int ocfs2_rename(struct inode *old_dir,
1355 1356
1356 old_inode->i_ctime = CURRENT_TIME; 1357 old_inode->i_ctime = CURRENT_TIME;
1357 mark_inode_dirty(old_inode); 1358 mark_inode_dirty(old_inode);
1359 ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
1358 1360
1359 /* now that the name has been added to new_dir, remove the old name */ 1361 /* 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); 1362 status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
@@ -1384,27 +1386,22 @@ static int ocfs2_rename(struct inode *old_dir,
1384 } 1386 }
1385 } 1387 }
1386 mark_inode_dirty(old_dir); 1388 mark_inode_dirty(old_dir);
1387 if (new_inode) 1389 ocfs2_mark_inode_dirty(handle, old_dir, old_dir_bh);
1390 if (new_inode) {
1388 mark_inode_dirty(new_inode); 1391 mark_inode_dirty(new_inode);
1392 ocfs2_mark_inode_dirty(handle, new_inode, newfe_bh);
1393 }
1389 1394
1390 if (old_dir != new_dir) 1395 if (old_dir != new_dir) {
1391 if (new_dir_nlink != new_dir->i_nlink) { 1396 /* Keep the same times on both directories.*/
1392 if (!new_dir_bh) { 1397 new_dir->i_ctime = new_dir->i_mtime = old_dir->i_ctime;
1393 mlog(ML_ERROR, "need to change nlink for new " 1398
1394 "dir %llu from %d to %d but bh is NULL\n", 1399 /*
1395 (unsigned long long)OCFS2_I(new_dir)->ip_blkno, 1400 * This will also pick up the i_nlink change from the
1396 (int)new_dir_nlink, new_dir->i_nlink); 1401 * block above.
1397 } else { 1402 */
1398 struct ocfs2_dinode *fe; 1403 ocfs2_mark_inode_dirty(handle, new_dir, new_dir_bh);
1399 status = ocfs2_journal_access(handle, 1404 }
1400 new_dir,
1401 new_dir_bh,
1402 OCFS2_JOURNAL_ACCESS_WRITE);
1403 fe = (struct ocfs2_dinode *) new_dir_bh->b_data;
1404 fe->i_links_count = cpu_to_le16(new_dir->i_nlink);
1405 status = ocfs2_journal_dirty(handle, new_dir_bh);
1406 }
1407 }
1408 1405
1409 if (old_dir_nlink != old_dir->i_nlink) { 1406 if (old_dir_nlink != old_dir->i_nlink) {
1410 if (!old_dir_bh) { 1407 if (!old_dir_bh) {
@@ -1455,6 +1452,8 @@ bail:
1455 iput(new_inode); 1452 iput(new_inode);
1456 if (newfe_bh) 1453 if (newfe_bh)
1457 brelse(newfe_bh); 1454 brelse(newfe_bh);
1455 if (old_inode_bh)
1456 brelse(old_inode_bh);
1458 if (old_dir_bh) 1457 if (old_dir_bh)
1459 brelse(old_dir_bh); 1458 brelse(old_dir_bh);
1460 if (new_dir_bh) 1459 if (new_dir_bh)
@@ -1826,6 +1825,13 @@ static int __ocfs2_add_entry(handle_t *handle,
1826 (le16_to_cpu(de->rec_len) >= rec_len)) || 1825 (le16_to_cpu(de->rec_len) >= rec_len)) ||
1827 (le16_to_cpu(de->rec_len) >= 1826 (le16_to_cpu(de->rec_len) >=
1828 (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) { 1827 (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
1828 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
1829 retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
1830 if (retval < 0) {
1831 mlog_errno(retval);
1832 goto bail;
1833 }
1834
1829 status = ocfs2_journal_access(handle, dir, insert_bh, 1835 status = ocfs2_journal_access(handle, dir, insert_bh,
1830 OCFS2_JOURNAL_ACCESS_WRITE); 1836 OCFS2_JOURNAL_ACCESS_WRITE);
1831 /* By now the buffer is marked for journaling */ 1837 /* By now the buffer is marked for journaling */
@@ -1848,7 +1854,6 @@ static int __ocfs2_add_entry(handle_t *handle,
1848 de->name_len = namelen; 1854 de->name_len = namelen;
1849 memcpy(de->name, name, namelen); 1855 memcpy(de->name, name, namelen);
1850 1856
1851 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
1852 dir->i_version++; 1857 dir->i_version++;
1853 status = ocfs2_journal_dirty(handle, insert_bh); 1858 status = ocfs2_journal_dirty(handle, insert_bh);
1854 retval = 0; 1859 retval = 0;