Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

minix: 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>

authored by

Christoph Hellwig and committed by
Al Viro
f556e776 2d1a9d59

+20 -16
+20 -16
fs/minix/dir.c
··· 46 46 return last_byte; 47 47 } 48 48 49 - static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) 49 + static void dir_commit_chunk(struct page *page, loff_t pos, unsigned len) 50 50 { 51 51 struct address_space *mapping = page->mapping; 52 52 struct inode *dir = mapping->host; 53 - int err = 0; 53 + 54 54 block_write_end(NULL, mapping, pos, len, len, page, NULL); 55 55 56 56 if (pos+len > dir->i_size) { 57 57 i_size_write(dir, pos+len); 58 58 mark_inode_dirty(dir); 59 59 } 60 - if (IS_DIRSYNC(dir)) 61 - err = write_one_page(page); 62 - else 63 - unlock_page(page); 60 + unlock_page(page); 61 + } 62 + 63 + static int minix_handle_dirsync(struct inode *dir) 64 + { 65 + int err; 66 + 67 + err = filemap_write_and_wait(dir->i_mapping); 68 + if (!err) 69 + err = sync_inode_metadata(dir, 1); 64 70 return err; 65 71 } 66 72 ··· 280 274 memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2); 281 275 de->inode = inode->i_ino; 282 276 } 283 - err = dir_commit_chunk(page, pos, sbi->s_dirsize); 277 + dir_commit_chunk(page, pos, sbi->s_dirsize); 284 278 dir->i_mtime = dir->i_ctime = current_time(dir); 285 279 mark_inode_dirty(dir); 280 + err = minix_handle_dirsync(dir); 286 281 out_put: 287 282 dir_put_page(page); 288 283 out: ··· 312 305 ((minix3_dirent *)de)->inode = 0; 313 306 else 314 307 de->inode = 0; 315 - err = dir_commit_chunk(page, pos, len); 316 - if (err) 317 - return err; 308 + dir_commit_chunk(page, pos, len); 318 309 inode->i_ctime = inode->i_mtime = current_time(inode); 319 310 mark_inode_dirty(inode); 320 - return 0; 311 + return minix_handle_dirsync(inode); 321 312 } 322 313 323 314 int minix_make_empty(struct inode *inode, struct inode *dir) ··· 355 350 } 356 351 kunmap_atomic(kaddr); 357 352 358 - err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize); 353 + dir_commit_chunk(page, 0, 2 * sbi->s_dirsize); 354 + err = minix_handle_dirsync(inode); 359 355 fail: 360 356 put_page(page); 361 357 return err; ··· 435 429 ((minix3_dirent *)de)->inode = inode->i_ino; 436 430 else 437 431 de->inode = inode->i_ino; 438 - err = dir_commit_chunk(page, pos, sbi->s_dirsize); 439 - if (err) 440 - return err; 432 + dir_commit_chunk(page, pos, sbi->s_dirsize); 441 433 dir->i_mtime = dir->i_ctime = current_time(dir); 442 434 mark_inode_dirty(dir); 443 - return 0; 435 + return minix_handle_dirsync(dir); 444 436 } 445 437 446 438 struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)