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

clean up write_begin usage for directories in pagecache

For filesystem that implement directories in pagecache we call
block_write_begin with an already allocated page for this code, while the
normal regular file write path uses the default block_write_begin behaviour.

Get rid of the __foofs_write_begin helper and opencode the normal write_begin
call in foofs_write_begin, while adding a new foofs_prepare_chunk helper for
the directory code. The added benefit is that foofs_prepare_chunk has
a much saner calling convention.

Note that the interruptible flag passed into block_write_begin is always
ignored if we already pass in a page (see next patch for details), and
we never were doing truncations of exessive blocks for this case either so we
can switch directly to block_write_begin_newtrunc.

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
f4e420dc 282dc178

+57 -107
+12 -12
fs/ext2/dir.c
··· 448 448 return res; 449 449 } 450 450 451 + static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len) 452 + { 453 + return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 454 + &page, NULL, ext2_get_block); 455 + } 456 + 451 457 /* Releases the page */ 452 458 void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, 453 459 struct page *page, struct inode *inode, int update_times) ··· 464 458 int err; 465 459 466 460 lock_page(page); 467 - err = __ext2_write_begin(NULL, page->mapping, pos, len, 468 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 461 + err = ext2_prepare_chunk(page, pos, len); 469 462 BUG_ON(err); 470 463 de->inode = cpu_to_le32(inode->i_ino); 471 464 ext2_set_de_type(de, inode); ··· 547 542 got_it: 548 543 pos = page_offset(page) + 549 544 (char*)de - (char*)page_address(page); 550 - err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0, 551 - &page, NULL); 545 + err = ext2_prepare_chunk(page, pos, rec_len); 552 546 if (err) 553 547 goto out_unlock; 554 548 if (de->inode) { ··· 580 576 */ 581 577 int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) 582 578 { 583 - struct address_space *mapping = page->mapping; 584 - struct inode *inode = mapping->host; 579 + struct inode *inode = page->mapping->host; 585 580 char *kaddr = page_address(page); 586 581 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); 587 582 unsigned to = ((char *)dir - kaddr) + ··· 604 601 from = (char*)pde - (char*)page_address(page); 605 602 pos = page_offset(page) + from; 606 603 lock_page(page); 607 - err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0, 608 - &page, NULL); 604 + err = ext2_prepare_chunk(page, pos, to - from); 609 605 BUG_ON(err); 610 606 if (pde) 611 607 pde->rec_len = ext2_rec_len_to_disk(to - from); ··· 623 621 */ 624 622 int ext2_make_empty(struct inode *inode, struct inode *parent) 625 623 { 626 - struct address_space *mapping = inode->i_mapping; 627 - struct page *page = grab_cache_page(mapping, 0); 624 + struct page *page = grab_cache_page(inode->i_mapping, 0); 628 625 unsigned chunk_size = ext2_chunk_size(inode); 629 626 struct ext2_dir_entry_2 * de; 630 627 int err; ··· 632 631 if (!page) 633 632 return -ENOMEM; 634 633 635 - err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0, 636 - &page, NULL); 634 + err = ext2_prepare_chunk(page, 0, chunk_size); 637 635 if (err) { 638 636 unlock_page(page); 639 637 goto fail;
-3
fs/ext2/ext2.h
··· 127 127 extern void ext2_get_inode_flags(struct ext2_inode_info *); 128 128 extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 129 129 u64 start, u64 len); 130 - int __ext2_write_begin(struct file *file, struct address_space *mapping, 131 - loff_t pos, unsigned len, unsigned flags, 132 - struct page **pagep, void **fsdata); 133 130 134 131 /* ioctl.c */ 135 132 extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
+2 -9
fs/ext2/inode.c
··· 765 765 return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); 766 766 } 767 767 768 - int __ext2_write_begin(struct file *file, struct address_space *mapping, 769 - loff_t pos, unsigned len, unsigned flags, 770 - struct page **pagep, void **fsdata) 771 - { 772 - return block_write_begin_newtrunc(file, mapping, pos, len, flags, 773 - pagep, fsdata, ext2_get_block); 774 - } 775 - 776 768 static int 777 769 ext2_write_begin(struct file *file, struct address_space *mapping, 778 770 loff_t pos, unsigned len, unsigned flags, ··· 773 781 int ret; 774 782 775 783 *pagep = NULL; 776 - ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata); 784 + ret = block_write_begin_newtrunc(file, mapping, pos, len, flags, 785 + pagep, fsdata, ext2_get_block); 777 786 if (ret < 0) 778 787 ext2_write_failed(mapping, pos + len); 779 788 return ret;
+7 -14
fs/minix/dir.c
··· 271 271 272 272 got_it: 273 273 pos = page_offset(page) + p - (char *)page_address(page); 274 - err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize, 275 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 274 + err = minix_prepare_chunk(page, pos, sbi->s_dirsize); 276 275 if (err) 277 276 goto out_unlock; 278 277 memcpy (namx, name, namelen); ··· 296 297 297 298 int minix_delete_entry(struct minix_dir_entry *de, struct page *page) 298 299 { 299 - struct address_space *mapping = page->mapping; 300 - struct inode *inode = (struct inode*)mapping->host; 300 + struct inode *inode = page->mapping->host; 301 301 char *kaddr = page_address(page); 302 302 loff_t pos = page_offset(page) + (char*)de - kaddr; 303 303 struct minix_sb_info *sbi = minix_sb(inode->i_sb); ··· 304 306 int err; 305 307 306 308 lock_page(page); 307 - err = __minix_write_begin(NULL, mapping, pos, len, 308 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 309 + err = minix_prepare_chunk(page, pos, len); 309 310 if (err == 0) { 310 311 if (sbi->s_version == MINIX_V3) 311 312 ((minix3_dirent *) de)->inode = 0; ··· 322 325 323 326 int minix_make_empty(struct inode *inode, struct inode *dir) 324 327 { 325 - struct address_space *mapping = inode->i_mapping; 326 - struct page *page = grab_cache_page(mapping, 0); 328 + struct page *page = grab_cache_page(inode->i_mapping, 0); 327 329 struct minix_sb_info *sbi = minix_sb(inode->i_sb); 328 330 char *kaddr; 329 331 int err; 330 332 331 333 if (!page) 332 334 return -ENOMEM; 333 - err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize, 334 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 335 + err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize); 335 336 if (err) { 336 337 unlock_page(page); 337 338 goto fail; ··· 420 425 void minix_set_link(struct minix_dir_entry *de, struct page *page, 421 426 struct inode *inode) 422 427 { 423 - struct address_space *mapping = page->mapping; 424 - struct inode *dir = mapping->host; 428 + struct inode *dir = page->mapping->host; 425 429 struct minix_sb_info *sbi = minix_sb(dir->i_sb); 426 430 loff_t pos = page_offset(page) + 427 431 (char *)de-(char*)page_address(page); ··· 428 434 429 435 lock_page(page); 430 436 431 - err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize, 432 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 437 + err = minix_prepare_chunk(page, pos, sbi->s_dirsize); 433 438 if (err == 0) { 434 439 if (sbi->s_version == MINIX_V3) 435 440 ((minix3_dirent *) de)->inode = inode->i_ino;
+5 -6
fs/minix/inode.c
··· 357 357 return block_read_full_page(page,minix_get_block); 358 358 } 359 359 360 - int __minix_write_begin(struct file *file, struct address_space *mapping, 361 - loff_t pos, unsigned len, unsigned flags, 362 - struct page **pagep, void **fsdata) 360 + int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len) 363 361 { 364 - return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 365 - minix_get_block); 362 + return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 363 + &page, NULL, minix_get_block); 366 364 } 367 365 368 366 static int minix_write_begin(struct file *file, struct address_space *mapping, ··· 368 370 struct page **pagep, void **fsdata) 369 371 { 370 372 *pagep = NULL; 371 - return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata); 373 + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 374 + minix_get_block); 372 375 } 373 376 374 377 static sector_t minix_bmap(struct address_space *mapping, sector_t block)
+1 -3
fs/minix/minix.h
··· 53 53 extern void minix_free_block(struct inode *inode, unsigned long block); 54 54 extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); 55 55 extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); 56 - extern int __minix_write_begin(struct file *file, struct address_space *mapping, 57 - loff_t pos, unsigned len, unsigned flags, 58 - struct page **pagep, void **fsdata); 56 + extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len); 59 57 60 58 extern void V1_minix_truncate(struct inode *); 61 59 extern void V2_minix_truncate(struct inode *);
+7 -19
fs/nilfs2/dir.c
··· 80 80 return last_byte; 81 81 } 82 82 83 - static int nilfs_prepare_chunk_uninterruptible(struct page *page, 84 - struct address_space *mapping, 85 - unsigned from, unsigned to) 83 + static int nilfs_prepare_chunk(struct page *page, unsigned from, unsigned to) 86 84 { 87 85 loff_t pos = page_offset(page) + from; 88 - return block_write_begin(NULL, mapping, pos, to - from, 89 - AOP_FLAG_UNINTERRUPTIBLE, &page, 90 - NULL, nilfs_get_block); 91 - } 92 - 93 - static int nilfs_prepare_chunk(struct page *page, 94 - struct address_space *mapping, 95 - unsigned from, unsigned to) 96 - { 97 - loff_t pos = page_offset(page) + from; 98 - return block_write_begin(NULL, mapping, pos, to - from, 0, &page, 99 - NULL, nilfs_get_block); 86 + return block_write_begin_newtrunc(NULL, page->mapping, pos, to - from, 87 + 0, &page, NULL, nilfs_get_block); 100 88 } 101 89 102 90 static void nilfs_commit_chunk(struct page *page, ··· 437 449 int err; 438 450 439 451 lock_page(page); 440 - err = nilfs_prepare_chunk_uninterruptible(page, mapping, from, to); 452 + err = nilfs_prepare_chunk(page, from, to); 441 453 BUG_ON(err); 442 454 de->inode = cpu_to_le64(inode->i_ino); 443 455 nilfs_set_de_type(de, inode); ··· 518 530 got_it: 519 531 from = (char *)de - (char *)page_address(page); 520 532 to = from + rec_len; 521 - err = nilfs_prepare_chunk(page, page->mapping, from, to); 533 + err = nilfs_prepare_chunk(page, from, to); 522 534 if (err) 523 535 goto out_unlock; 524 536 if (de->inode) { ··· 575 587 if (pde) 576 588 from = (char *)pde - (char *)page_address(page); 577 589 lock_page(page); 578 - err = nilfs_prepare_chunk(page, mapping, from, to); 590 + err = nilfs_prepare_chunk(page, from, to); 579 591 BUG_ON(err); 580 592 if (pde) 581 593 pde->rec_len = cpu_to_le16(to - from); ··· 603 615 if (!page) 604 616 return -ENOMEM; 605 617 606 - err = nilfs_prepare_chunk(page, mapping, 0, chunk_size); 618 + err = nilfs_prepare_chunk(page, 0, chunk_size); 607 619 if (unlikely(err)) { 608 620 unlock_page(page); 609 621 goto fail;
+7 -14
fs/sysv/dir.c
··· 218 218 pos = page_offset(page) + 219 219 (char*)de - (char*)page_address(page); 220 220 lock_page(page); 221 - err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE, 222 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 221 + err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); 223 222 if (err) 224 223 goto out_unlock; 225 224 memcpy (de->name, name, namelen); ··· 238 239 239 240 int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) 240 241 { 241 - struct address_space *mapping = page->mapping; 242 - struct inode *inode = (struct inode*)mapping->host; 242 + struct inode *inode = page->mapping->host; 243 243 char *kaddr = (char*)page_address(page); 244 244 loff_t pos = page_offset(page) + (char *)de - kaddr; 245 245 int err; 246 246 247 247 lock_page(page); 248 - err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, 249 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 248 + err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); 250 249 BUG_ON(err); 251 250 de->inode = 0; 252 251 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); ··· 256 259 257 260 int sysv_make_empty(struct inode *inode, struct inode *dir) 258 261 { 259 - struct address_space *mapping = inode->i_mapping; 260 - struct page *page = grab_cache_page(mapping, 0); 262 + struct page *page = grab_cache_page(inode->i_mapping, 0); 261 263 struct sysv_dir_entry * de; 262 264 char *base; 263 265 int err; 264 266 265 267 if (!page) 266 268 return -ENOMEM; 267 - err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE, 268 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 269 + err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE); 269 270 if (err) { 270 271 unlock_page(page); 271 272 goto fail; ··· 336 341 void sysv_set_link(struct sysv_dir_entry *de, struct page *page, 337 342 struct inode *inode) 338 343 { 339 - struct address_space *mapping = page->mapping; 340 - struct inode *dir = mapping->host; 344 + struct inode *dir = page->mapping->host; 341 345 loff_t pos = page_offset(page) + 342 346 (char *)de-(char*)page_address(page); 343 347 int err; 344 348 345 349 lock_page(page); 346 - err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, 347 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 350 + err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); 348 351 BUG_ON(err); 349 352 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 350 353 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
+5 -6
fs/sysv/itree.c
··· 459 459 return block_read_full_page(page,get_block); 460 460 } 461 461 462 - int __sysv_write_begin(struct file *file, struct address_space *mapping, 463 - loff_t pos, unsigned len, unsigned flags, 464 - struct page **pagep, void **fsdata) 462 + int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len) 465 463 { 466 - return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 467 - get_block); 464 + return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 465 + &page, NULL, get_block); 468 466 } 469 467 470 468 static int sysv_write_begin(struct file *file, struct address_space *mapping, ··· 470 472 struct page **pagep, void **fsdata) 471 473 { 472 474 *pagep = NULL; 473 - return __sysv_write_begin(file, mapping, pos, len, flags, pagep, fsdata); 475 + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 476 + get_block); 474 477 } 475 478 476 479 static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
+1 -3
fs/sysv/sysv.h
··· 136 136 137 137 /* itree.c */ 138 138 extern void sysv_truncate(struct inode *); 139 - extern int __sysv_write_begin(struct file *file, struct address_space *mapping, 140 - loff_t pos, unsigned len, unsigned flags, 141 - struct page **pagep, void **fsdata); 139 + extern int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len); 142 140 143 141 /* inode.c */ 144 142 extern struct inode *sysv_iget(struct super_block *, unsigned int);
+4 -9
fs/ufs/dir.c
··· 95 95 int err; 96 96 97 97 lock_page(page); 98 - err = __ufs_write_begin(NULL, page->mapping, pos, len, 99 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 98 + err = ufs_prepare_chunk(page, pos, len); 100 99 BUG_ON(err); 101 100 102 101 de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); ··· 380 381 got_it: 381 382 pos = page_offset(page) + 382 383 (char*)de - (char*)page_address(page); 383 - err = __ufs_write_begin(NULL, page->mapping, pos, rec_len, 384 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 384 + err = ufs_prepare_chunk(page, pos, rec_len); 385 385 if (err) 386 386 goto out_unlock; 387 387 if (de->d_ino) { ··· 516 518 struct page * page) 517 519 { 518 520 struct super_block *sb = inode->i_sb; 519 - struct address_space *mapping = page->mapping; 520 521 char *kaddr = page_address(page); 521 522 unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); 522 523 unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); ··· 546 549 547 550 pos = page_offset(page) + from; 548 551 lock_page(page); 549 - err = __ufs_write_begin(NULL, mapping, pos, to - from, 550 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 552 + err = ufs_prepare_chunk(page, pos, to - from); 551 553 BUG_ON(err); 552 554 if (pde) 553 555 pde->d_reclen = cpu_to_fs16(sb, to - from); ··· 573 577 if (!page) 574 578 return -ENOMEM; 575 579 576 - err = __ufs_write_begin(NULL, mapping, 0, chunk_size, 577 - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); 580 + err = ufs_prepare_chunk(page, 0, chunk_size); 578 581 if (err) { 579 582 unlock_page(page); 580 583 goto fail;
+5 -6
fs/ufs/inode.c
··· 558 558 return block_read_full_page(page,ufs_getfrag_block); 559 559 } 560 560 561 - int __ufs_write_begin(struct file *file, struct address_space *mapping, 562 - loff_t pos, unsigned len, unsigned flags, 563 - struct page **pagep, void **fsdata) 561 + int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len) 564 562 { 565 - return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 566 - ufs_getfrag_block); 563 + return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, 564 + &page, NULL, ufs_getfrag_block); 567 565 } 568 566 569 567 static int ufs_write_begin(struct file *file, struct address_space *mapping, ··· 569 571 struct page **pagep, void **fsdata) 570 572 { 571 573 *pagep = NULL; 572 - return __ufs_write_begin(file, mapping, pos, len, flags, pagep, fsdata); 574 + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 575 + ufs_getfrag_block); 573 576 } 574 577 575 578 static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
+1 -3
fs/ufs/util.h
··· 257 257 258 258 extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); 259 259 extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t); 260 - extern int __ufs_write_begin(struct file *file, struct address_space *mapping, 261 - loff_t pos, unsigned len, unsigned flags, 262 - struct page **pagep, void **fsdata); 260 + extern int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len); 263 261 264 262 /* 265 263 * These functions manipulate ufs buffers