Skip to content

Commit 4309093

Browse files
Christoph HellwigAl Viro
authored andcommitted
sysv: 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 <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent b7bfaa7 commit 4309093

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

fs/sysv/dir.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,26 @@ static inline void dir_put_page(struct page *page)
3434
put_page(page);
3535
}
3636

37-
static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
37+
static void dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
3838
{
3939
struct address_space *mapping = page->mapping;
4040
struct inode *dir = mapping->host;
41-
int err = 0;
4241

4342
block_write_end(NULL, mapping, pos, len, len, page, NULL);
4443
if (pos+len > dir->i_size) {
4544
i_size_write(dir, pos+len);
4645
mark_inode_dirty(dir);
4746
}
48-
if (IS_DIRSYNC(dir))
49-
err = write_one_page(page);
50-
else
51-
unlock_page(page);
47+
unlock_page(page);
48+
}
49+
50+
static int sysv_handle_dirsync(struct inode *dir)
51+
{
52+
int err;
53+
54+
err = filemap_write_and_wait(dir->i_mapping);
55+
if (!err)
56+
err = sync_inode_metadata(dir, 1);
5257
return err;
5358
}
5459

@@ -215,9 +220,10 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
215220
memcpy (de->name, name, namelen);
216221
memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
217222
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
218-
err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
223+
dir_commit_chunk(page, pos, SYSV_DIRSIZE);
219224
dir->i_mtime = dir->i_ctime = current_time(dir);
220225
mark_inode_dirty(dir);
226+
err = sysv_handle_dirsync(dir);
221227
out_page:
222228
dir_put_page(page);
223229
out:
@@ -238,11 +244,11 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
238244
err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
239245
BUG_ON(err);
240246
de->inode = 0;
241-
err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
247+
dir_commit_chunk(page, pos, SYSV_DIRSIZE);
242248
dir_put_page(page);
243249
inode->i_ctime = inode->i_mtime = current_time(inode);
244250
mark_inode_dirty(inode);
245-
return err;
251+
return sysv_handle_dirsync(inode);
246252
}
247253

248254
int sysv_make_empty(struct inode *inode, struct inode *dir)
@@ -272,7 +278,8 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
272278
strcpy(de->name,"..");
273279

274280
kunmap(page);
275-
err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
281+
dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
282+
err = sysv_handle_dirsync(inode);
276283
fail:
277284
put_page(page);
278285
return err;
@@ -336,10 +343,11 @@ void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
336343
err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
337344
BUG_ON(err);
338345
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
339-
err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
346+
dir_commit_chunk(page, pos, SYSV_DIRSIZE);
340347
dir_put_page(page);
341348
dir->i_mtime = dir->i_ctime = current_time(dir);
342349
mark_inode_dirty(dir);
350+
sysv_handle_dirsync(inode);
343351
}
344352

345353
struct sysv_dir_entry * sysv_dotdot (struct inode *dir, struct page **p)

0 commit comments

Comments
 (0)