Skip to content

Commit 9e22031

Browse files
Christoph HellwigAl Viro
authored andcommitted
ufs: don't flush page immediately for DIRSYNC directories
We do not need to writeout modified directory blocks immediately when modifying them while the page is locked. It is enough to do the flush somewhat later which has the added benefit that inode times can be flushed as well. It also allows us to stop depending on write_one_page() function. Ported from an ext2 patch by Jan Kara. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent eeac8ed commit 9e22031

1 file changed

Lines changed: 19 additions & 10 deletions

File tree

fs/ufs/dir.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,27 @@ static inline int ufs_match(struct super_block *sb, int len,
4242
return !memcmp(name, de->d_name, len);
4343
}
4444

45-
static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
45+
static void ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
4646
{
4747
struct address_space *mapping = page->mapping;
4848
struct inode *dir = mapping->host;
49-
int err = 0;
5049

5150
inode_inc_iversion(dir);
5251
block_write_end(NULL, mapping, pos, len, len, page, NULL);
5352
if (pos+len > dir->i_size) {
5453
i_size_write(dir, pos+len);
5554
mark_inode_dirty(dir);
5655
}
57-
if (IS_DIRSYNC(dir))
58-
err = write_one_page(page);
59-
else
60-
unlock_page(page);
56+
unlock_page(page);
57+
}
58+
59+
static int ufs_handle_dirsync(struct inode *dir)
60+
{
61+
int err;
62+
63+
err = filemap_write_and_wait(dir->i_mapping);
64+
if (!err)
65+
err = sync_inode_metadata(dir, 1);
6166
return err;
6267
}
6368

@@ -99,11 +104,12 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
99104
de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
100105
ufs_set_de_type(dir->i_sb, de, inode->i_mode);
101106

102-
err = ufs_commit_chunk(page, pos, len);
107+
ufs_commit_chunk(page, pos, len);
103108
ufs_put_page(page);
104109
if (update_times)
105110
dir->i_mtime = dir->i_ctime = current_time(dir);
106111
mark_inode_dirty(dir);
112+
ufs_handle_dirsync(dir);
107113
}
108114

109115

@@ -390,10 +396,11 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
390396
de->d_ino = cpu_to_fs32(sb, inode->i_ino);
391397
ufs_set_de_type(sb, de, inode->i_mode);
392398

393-
err = ufs_commit_chunk(page, pos, rec_len);
399+
ufs_commit_chunk(page, pos, rec_len);
394400
dir->i_mtime = dir->i_ctime = current_time(dir);
395401

396402
mark_inode_dirty(dir);
403+
err = ufs_handle_dirsync(dir);
397404
/* OFFSET_CACHE */
398405
out_put:
399406
ufs_put_page(page);
@@ -531,9 +538,10 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
531538
if (pde)
532539
pde->d_reclen = cpu_to_fs16(sb, to - from);
533540
dir->d_ino = 0;
534-
err = ufs_commit_chunk(page, pos, to - from);
541+
ufs_commit_chunk(page, pos, to - from);
535542
inode->i_ctime = inode->i_mtime = current_time(inode);
536543
mark_inode_dirty(inode);
544+
err = ufs_handle_dirsync(inode);
537545
out:
538546
ufs_put_page(page);
539547
UFSD("EXIT\n");
@@ -579,7 +587,8 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
579587
strcpy (de->d_name, "..");
580588
kunmap(page);
581589

582-
err = ufs_commit_chunk(page, 0, chunk_size);
590+
ufs_commit_chunk(page, 0, chunk_size);
591+
err = ufs_handle_dirsync(inode);
583592
fail:
584593
put_page(page);
585594
return err;

0 commit comments

Comments
 (0)