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>

+37 -32
+37 -32
fs/ocfs2/namei.c
··· 932 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 937 drop_nlink(dir); 937 - status = ocfs2_mark_inode_dirty(handle, dir, 938 - parent_node_bh); 939 - if (status < 0) { 940 - mlog_errno(status); 938 + 939 + status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh); 940 + if (status < 0) { 941 + mlog_errno(status); 942 + if (S_ISDIR(inode->i_mode)) 941 943 inc_nlink(dir); 942 - } 943 944 } 944 945 945 946 leave: ··· 1069 1068 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; 1070 1069 struct buffer_head *orphan_entry_bh = NULL; 1071 1070 struct buffer_head *newfe_bh = NULL; 1071 + struct buffer_head *old_inode_bh = NULL; 1072 1072 struct buffer_head *insert_entry_bh = NULL; 1073 1073 struct ocfs2_super *osb = NULL; 1074 1074 u64 newfe_blkno; ··· 1081 1079 struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above 1082 1080 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, 1083 1081 // this is the 1st dirent bh 1084 - nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink; 1082 + nlink_t old_dir_nlink = old_dir->i_nlink; 1085 1083 1086 1084 /* At some point it might be nice to break this function up a 1087 1085 * bit. */ ··· 1141 1139 } 1142 1140 1143 1141 /* 1144 - * Though we don't require an inode meta data update if 1145 - * old_inode is not a directory, we lock anyway here to ensure 1146 - * the vote thread on other nodes won't have to concurrently 1147 - * downconvert the inode and the dentry locks. 1142 + * Aside from allowing a meta data update, the locking here 1143 + * also ensures that the vote thread on other nodes won't have 1144 + * to concurrently downconvert the inode and the dentry locks. 1148 1145 */ 1149 - status = ocfs2_meta_lock(old_inode, NULL, 1); 1146 + status = ocfs2_meta_lock(old_inode, &old_inode_bh, 1); 1150 1147 if (status < 0) { 1151 1148 if (status != -ENOENT) 1152 1149 mlog_errno(status); ··· 1356 1355 1357 1356 old_inode->i_ctime = CURRENT_TIME; 1358 1357 mark_inode_dirty(old_inode); 1358 + ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh); 1359 1359 1360 1360 /* now that the name has been added to new_dir, remove the old name */ 1361 1361 status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh); ··· 1386 1384 } 1387 1385 } 1388 1386 mark_inode_dirty(old_dir); 1389 - if (new_inode) 1387 + ocfs2_mark_inode_dirty(handle, old_dir, old_dir_bh); 1388 + if (new_inode) { 1390 1389 mark_inode_dirty(new_inode); 1390 + ocfs2_mark_inode_dirty(handle, new_inode, newfe_bh); 1391 + } 1391 1392 1392 - if (old_dir != new_dir) 1393 - if (new_dir_nlink != new_dir->i_nlink) { 1394 - if (!new_dir_bh) { 1395 - mlog(ML_ERROR, "need to change nlink for new " 1396 - "dir %llu from %d to %d but bh is NULL\n", 1397 - (unsigned long long)OCFS2_I(new_dir)->ip_blkno, 1398 - (int)new_dir_nlink, new_dir->i_nlink); 1399 - } else { 1400 - struct ocfs2_dinode *fe; 1401 - status = ocfs2_journal_access(handle, 1402 - new_dir, 1403 - new_dir_bh, 1404 - OCFS2_JOURNAL_ACCESS_WRITE); 1405 - fe = (struct ocfs2_dinode *) new_dir_bh->b_data; 1406 - fe->i_links_count = cpu_to_le16(new_dir->i_nlink); 1407 - status = ocfs2_journal_dirty(handle, new_dir_bh); 1408 - } 1409 - } 1393 + if (old_dir != new_dir) { 1394 + /* Keep the same times on both directories.*/ 1395 + new_dir->i_ctime = new_dir->i_mtime = old_dir->i_ctime; 1396 + 1397 + /* 1398 + * This will also pick up the i_nlink change from the 1399 + * block above. 1400 + */ 1401 + ocfs2_mark_inode_dirty(handle, new_dir, new_dir_bh); 1402 + } 1410 1403 1411 1404 if (old_dir_nlink != old_dir->i_nlink) { 1412 1405 if (!old_dir_bh) { ··· 1452 1455 iput(new_inode); 1453 1456 if (newfe_bh) 1454 1457 brelse(newfe_bh); 1458 + if (old_inode_bh) 1459 + brelse(old_inode_bh); 1455 1460 if (old_dir_bh) 1456 1461 brelse(old_dir_bh); 1457 1462 if (new_dir_bh) ··· 1825 1826 (le16_to_cpu(de->rec_len) >= rec_len)) || 1826 1827 (le16_to_cpu(de->rec_len) >= 1827 1828 (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) { 1829 + dir->i_mtime = dir->i_ctime = CURRENT_TIME; 1830 + retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh); 1831 + if (retval < 0) { 1832 + mlog_errno(retval); 1833 + goto bail; 1834 + } 1835 + 1828 1836 status = ocfs2_journal_access(handle, dir, insert_bh, 1829 1837 OCFS2_JOURNAL_ACCESS_WRITE); 1830 1838 /* By now the buffer is marked for journaling */ ··· 1854 1848 de->name_len = namelen; 1855 1849 memcpy(de->name, name, namelen); 1856 1850 1857 - dir->i_mtime = dir->i_ctime = CURRENT_TIME; 1858 1851 dir->i_version++; 1859 1852 status = ocfs2_journal_dirty(handle, insert_bh); 1860 1853 retval = 0;