aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
authorFrank Mayhar <fmayhar@google.com>2009-01-07 00:06:22 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-01-07 00:06:22 -0500
commit0390131ba84fd3f726f9e24fc4553828125700bb (patch)
tree4c90afad4e8690e25aec0ce069fd450e92ab5f96 /fs/ext4/namei.c
parentff7ef329b268b603ea4a2303241ef1c3829fd574 (diff)
ext4: Allow ext4 to run without a journal
A few weeks ago I posted a patch for discussion that allowed ext4 to run without a journal. Since that time I've integrated the excellent comments from Andreas and fixed several serious bugs. We're currently running with this patch and generating some performance numbers against both ext2 (with backported reservations code) and ext4 with and without a journal. It just so happens that running without a journal is slightly faster for most everything. We did iozone -T -t 4 s 2g -r 256k -T -I -i0 -i1 -i2 which creates 4 threads, each of which create and do reads and writes on a 2G file, with a buffer size of 256K, using O_DIRECT for all file opens to bypass the page cache. Results: ext2 ext4, default ext4, no journal initial writes 13.0 MB/s 15.4 MB/s 15.7 MB/s rewrites 13.1 MB/s 15.6 MB/s 15.9 MB/s reads 15.2 MB/s 16.9 MB/s 17.2 MB/s re-reads 15.3 MB/s 16.9 MB/s 17.2 MB/s random readers 5.6 MB/s 5.6 MB/s 5.7 MB/s random writers 5.1 MB/s 5.3 MB/s 5.4 MB/s So it seems that, so far, this was a useful exercise. Signed-off-by: Frank Mayhar <fmayhar@google.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r--fs/ext4/namei.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 84a68ae623c1..08873e938ab2 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1233,10 +1233,10 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
1233 de = de2; 1233 de = de2;
1234 } 1234 }
1235 dx_insert_block(frame, hash2 + continued, newblock); 1235 dx_insert_block(frame, hash2 + continued, newblock);
1236 err = ext4_journal_dirty_metadata(handle, bh2); 1236 err = ext4_handle_dirty_metadata(handle, dir, bh2);
1237 if (err) 1237 if (err)
1238 goto journal_error; 1238 goto journal_error;
1239 err = ext4_journal_dirty_metadata(handle, frame->bh); 1239 err = ext4_handle_dirty_metadata(handle, dir, frame->bh);
1240 if (err) 1240 if (err)
1241 goto journal_error; 1241 goto journal_error;
1242 brelse(bh2); 1242 brelse(bh2);
@@ -1340,8 +1340,8 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1340 ext4_update_dx_flag(dir); 1340 ext4_update_dx_flag(dir);
1341 dir->i_version++; 1341 dir->i_version++;
1342 ext4_mark_inode_dirty(handle, dir); 1342 ext4_mark_inode_dirty(handle, dir);
1343 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 1343 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
1344 err = ext4_journal_dirty_metadata(handle, bh); 1344 err = ext4_handle_dirty_metadata(handle, dir, bh);
1345 if (err) 1345 if (err)
1346 ext4_std_error(dir->i_sb, err); 1346 ext4_std_error(dir->i_sb, err);
1347 brelse(bh); 1347 brelse(bh);
@@ -1581,7 +1581,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1581 dxtrace(dx_show_index("node", frames[1].entries)); 1581 dxtrace(dx_show_index("node", frames[1].entries));
1582 dxtrace(dx_show_index("node", 1582 dxtrace(dx_show_index("node",
1583 ((struct dx_node *) bh2->b_data)->entries)); 1583 ((struct dx_node *) bh2->b_data)->entries));
1584 err = ext4_journal_dirty_metadata(handle, bh2); 1584 err = ext4_handle_dirty_metadata(handle, inode, bh2);
1585 if (err) 1585 if (err)
1586 goto journal_error; 1586 goto journal_error;
1587 brelse (bh2); 1587 brelse (bh2);
@@ -1607,7 +1607,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1607 if (err) 1607 if (err)
1608 goto journal_error; 1608 goto journal_error;
1609 } 1609 }
1610 ext4_journal_dirty_metadata(handle, frames[0].bh); 1610 ext4_handle_dirty_metadata(handle, inode, frames[0].bh);
1611 } 1611 }
1612 de = do_split(handle, dir, &bh, frame, &hinfo, &err); 1612 de = do_split(handle, dir, &bh, frame, &hinfo, &err);
1613 if (!de) 1613 if (!de)
@@ -1653,8 +1653,8 @@ static int ext4_delete_entry(handle_t *handle,
1653 else 1653 else
1654 de->inode = 0; 1654 de->inode = 0;
1655 dir->i_version++; 1655 dir->i_version++;
1656 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 1656 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
1657 ext4_journal_dirty_metadata(handle, bh); 1657 ext4_handle_dirty_metadata(handle, dir, bh);
1658 return 0; 1658 return 0;
1659 } 1659 }
1660 i += ext4_rec_len_from_disk(de->rec_len); 1660 i += ext4_rec_len_from_disk(de->rec_len);
@@ -1732,7 +1732,7 @@ retry:
1732 return PTR_ERR(handle); 1732 return PTR_ERR(handle);
1733 1733
1734 if (IS_DIRSYNC(dir)) 1734 if (IS_DIRSYNC(dir))
1735 handle->h_sync = 1; 1735 ext4_handle_sync(handle);
1736 1736
1737 inode = ext4_new_inode (handle, dir, mode); 1737 inode = ext4_new_inode (handle, dir, mode);
1738 err = PTR_ERR(inode); 1738 err = PTR_ERR(inode);
@@ -1766,7 +1766,7 @@ retry:
1766 return PTR_ERR(handle); 1766 return PTR_ERR(handle);
1767 1767
1768 if (IS_DIRSYNC(dir)) 1768 if (IS_DIRSYNC(dir))
1769 handle->h_sync = 1; 1769 ext4_handle_sync(handle);
1770 1770
1771 inode = ext4_new_inode(handle, dir, mode); 1771 inode = ext4_new_inode(handle, dir, mode);
1772 err = PTR_ERR(inode); 1772 err = PTR_ERR(inode);
@@ -1802,7 +1802,7 @@ retry:
1802 return PTR_ERR(handle); 1802 return PTR_ERR(handle);
1803 1803
1804 if (IS_DIRSYNC(dir)) 1804 if (IS_DIRSYNC(dir))
1805 handle->h_sync = 1; 1805 ext4_handle_sync(handle);
1806 1806
1807 inode = ext4_new_inode(handle, dir, S_IFDIR | mode); 1807 inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
1808 err = PTR_ERR(inode); 1808 err = PTR_ERR(inode);
@@ -1831,8 +1831,8 @@ retry:
1831 strcpy(de->name, ".."); 1831 strcpy(de->name, "..");
1832 ext4_set_de_type(dir->i_sb, de, S_IFDIR); 1832 ext4_set_de_type(dir->i_sb, de, S_IFDIR);
1833 inode->i_nlink = 2; 1833 inode->i_nlink = 2;
1834 BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata"); 1834 BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
1835 ext4_journal_dirty_metadata(handle, dir_block); 1835 ext4_handle_dirty_metadata(handle, dir, dir_block);
1836 brelse(dir_block); 1836 brelse(dir_block);
1837 ext4_mark_inode_dirty(handle, inode); 1837 ext4_mark_inode_dirty(handle, inode);
1838 err = ext4_add_entry(handle, dentry, inode); 1838 err = ext4_add_entry(handle, dentry, inode);
@@ -1944,6 +1944,9 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
1944 struct ext4_iloc iloc; 1944 struct ext4_iloc iloc;
1945 int err = 0, rc; 1945 int err = 0, rc;
1946 1946
1947 if (!ext4_handle_valid(handle))
1948 return 0;
1949
1947 lock_super(sb); 1950 lock_super(sb);
1948 if (!list_empty(&EXT4_I(inode)->i_orphan)) 1951 if (!list_empty(&EXT4_I(inode)->i_orphan))
1949 goto out_unlock; 1952 goto out_unlock;
@@ -1972,7 +1975,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
1972 /* Insert this inode at the head of the on-disk orphan list... */ 1975 /* Insert this inode at the head of the on-disk orphan list... */
1973 NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan); 1976 NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
1974 EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); 1977 EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
1975 err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); 1978 err = ext4_handle_dirty_metadata(handle, inode, EXT4_SB(sb)->s_sbh);
1976 rc = ext4_mark_iloc_dirty(handle, inode, &iloc); 1979 rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
1977 if (!err) 1980 if (!err)
1978 err = rc; 1981 err = rc;
@@ -2010,6 +2013,9 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2010 struct ext4_iloc iloc; 2013 struct ext4_iloc iloc;
2011 int err = 0; 2014 int err = 0;
2012 2015
2016 if (!ext4_handle_valid(handle))
2017 return 0;
2018
2013 lock_super(inode->i_sb); 2019 lock_super(inode->i_sb);
2014 if (list_empty(&ei->i_orphan)) { 2020 if (list_empty(&ei->i_orphan)) {
2015 unlock_super(inode->i_sb); 2021 unlock_super(inode->i_sb);
@@ -2028,7 +2034,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2028 * transaction handle with which to update the orphan list on 2034 * transaction handle with which to update the orphan list on
2029 * disk, but we still need to remove the inode from the linked 2035 * disk, but we still need to remove the inode from the linked
2030 * list in memory. */ 2036 * list in memory. */
2031 if (!handle) 2037 if (sbi->s_journal && !handle)
2032 goto out; 2038 goto out;
2033 2039
2034 err = ext4_reserve_inode_write(handle, inode, &iloc); 2040 err = ext4_reserve_inode_write(handle, inode, &iloc);
@@ -2042,7 +2048,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2042 if (err) 2048 if (err)
2043 goto out_brelse; 2049 goto out_brelse;
2044 sbi->s_es->s_last_orphan = cpu_to_le32(ino_next); 2050 sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
2045 err = ext4_journal_dirty_metadata(handle, sbi->s_sbh); 2051 err = ext4_handle_dirty_metadata(handle, inode, sbi->s_sbh);
2046 } else { 2052 } else {
2047 struct ext4_iloc iloc2; 2053 struct ext4_iloc iloc2;
2048 struct inode *i_prev = 2054 struct inode *i_prev =
@@ -2093,7 +2099,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
2093 goto end_rmdir; 2099 goto end_rmdir;
2094 2100
2095 if (IS_DIRSYNC(dir)) 2101 if (IS_DIRSYNC(dir))
2096 handle->h_sync = 1; 2102 ext4_handle_sync(handle);
2097 2103
2098 inode = dentry->d_inode; 2104 inode = dentry->d_inode;
2099 2105
@@ -2147,7 +2153,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
2147 return PTR_ERR(handle); 2153 return PTR_ERR(handle);
2148 2154
2149 if (IS_DIRSYNC(dir)) 2155 if (IS_DIRSYNC(dir))
2150 handle->h_sync = 1; 2156 ext4_handle_sync(handle);
2151 2157
2152 retval = -ENOENT; 2158 retval = -ENOENT;
2153 bh = ext4_find_entry(dir, &dentry->d_name, &de); 2159 bh = ext4_find_entry(dir, &dentry->d_name, &de);
@@ -2204,7 +2210,7 @@ retry:
2204 return PTR_ERR(handle); 2210 return PTR_ERR(handle);
2205 2211
2206 if (IS_DIRSYNC(dir)) 2212 if (IS_DIRSYNC(dir))
2207 handle->h_sync = 1; 2213 ext4_handle_sync(handle);
2208 2214
2209 inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO); 2215 inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
2210 err = PTR_ERR(inode); 2216 err = PTR_ERR(inode);
@@ -2267,7 +2273,7 @@ retry:
2267 return PTR_ERR(handle); 2273 return PTR_ERR(handle);
2268 2274
2269 if (IS_DIRSYNC(dir)) 2275 if (IS_DIRSYNC(dir))
2270 handle->h_sync = 1; 2276 ext4_handle_sync(handle);
2271 2277
2272 inode->i_ctime = ext4_current_time(inode); 2278 inode->i_ctime = ext4_current_time(inode);
2273 ext4_inc_count(handle, inode); 2279 ext4_inc_count(handle, inode);
@@ -2316,7 +2322,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2316 return PTR_ERR(handle); 2322 return PTR_ERR(handle);
2317 2323
2318 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) 2324 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
2319 handle->h_sync = 1; 2325 ext4_handle_sync(handle);
2320 2326
2321 old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de); 2327 old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de);
2322 /* 2328 /*
@@ -2370,8 +2376,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2370 new_dir->i_ctime = new_dir->i_mtime = 2376 new_dir->i_ctime = new_dir->i_mtime =
2371 ext4_current_time(new_dir); 2377 ext4_current_time(new_dir);
2372 ext4_mark_inode_dirty(handle, new_dir); 2378 ext4_mark_inode_dirty(handle, new_dir);
2373 BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata"); 2379 BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata");
2374 ext4_journal_dirty_metadata(handle, new_bh); 2380 ext4_handle_dirty_metadata(handle, new_dir, new_bh);
2375 brelse(new_bh); 2381 brelse(new_bh);
2376 new_bh = NULL; 2382 new_bh = NULL;
2377 } 2383 }
@@ -2421,8 +2427,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2421 BUFFER_TRACE(dir_bh, "get_write_access"); 2427 BUFFER_TRACE(dir_bh, "get_write_access");
2422 ext4_journal_get_write_access(handle, dir_bh); 2428 ext4_journal_get_write_access(handle, dir_bh);
2423 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); 2429 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
2424 BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata"); 2430 BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
2425 ext4_journal_dirty_metadata(handle, dir_bh); 2431 ext4_handle_dirty_metadata(handle, old_dir, dir_bh);
2426 ext4_dec_count(handle, old_dir); 2432 ext4_dec_count(handle, old_dir);
2427 if (new_inode) { 2433 if (new_inode) {
2428 /* checked empty_dir above, can't have another parent, 2434 /* checked empty_dir above, can't have another parent,