Commit f4e420dc423148fba637af1ab618fa8896dfb2d6

Authored by Christoph Hellwig
Committed by Al Viro
1 parent 282dc17884

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>

Showing 13 changed files with 57 additions and 107 deletions Side-by-side Diff

... ... @@ -448,6 +448,12 @@
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)
... ... @@ -458,8 +464,7 @@
458 464 int err;
459 465  
460 466 lock_page(page);
461   - err = __ext2_write_begin(NULL, page->mapping, pos, len,
462   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  467 + err = ext2_prepare_chunk(page, pos, len);
463 468 BUG_ON(err);
464 469 de->inode = cpu_to_le32(inode->i_ino);
465 470 ext2_set_de_type(de, inode);
... ... @@ -542,8 +547,7 @@
542 547 got_it:
543 548 pos = page_offset(page) +
544 549 (char*)de - (char*)page_address(page);
545   - err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
546   - &page, NULL);
  550 + err = ext2_prepare_chunk(page, pos, rec_len);
547 551 if (err)
548 552 goto out_unlock;
549 553 if (de->inode) {
... ... @@ -576,8 +580,7 @@
576 580 */
577 581 int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
578 582 {
579   - struct address_space *mapping = page->mapping;
580   - struct inode *inode = mapping->host;
  583 + struct inode *inode = page->mapping->host;
581 584 char *kaddr = page_address(page);
582 585 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
583 586 unsigned to = ((char *)dir - kaddr) +
... ... @@ -601,8 +604,7 @@
601 604 from = (char*)pde - (char*)page_address(page);
602 605 pos = page_offset(page) + from;
603 606 lock_page(page);
604   - err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0,
605   - &page, NULL);
  607 + err = ext2_prepare_chunk(page, pos, to - from);
606 608 BUG_ON(err);
607 609 if (pde)
608 610 pde->rec_len = ext2_rec_len_to_disk(to - from);
... ... @@ -621,8 +623,7 @@
621 623 */
622 624 int ext2_make_empty(struct inode *inode, struct inode *parent)
623 625 {
624   - struct address_space *mapping = inode->i_mapping;
625   - struct page *page = grab_cache_page(mapping, 0);
  626 + struct page *page = grab_cache_page(inode->i_mapping, 0);
626 627 unsigned chunk_size = ext2_chunk_size(inode);
627 628 struct ext2_dir_entry_2 * de;
628 629 int err;
... ... @@ -631,8 +632,7 @@
631 632 if (!page)
632 633 return -ENOMEM;
633 634  
634   - err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0,
635   - &page, NULL);
  635 + err = ext2_prepare_chunk(page, 0, chunk_size);
636 636 if (err) {
637 637 unlock_page(page);
638 638 goto fail;
... ... @@ -127,9 +127,6 @@
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);
... ... @@ -765,14 +765,6 @@
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,
... ... @@ -781,7 +773,8 @@
781 773 int ret;
782 774  
783 775 *pagep = NULL;
784   - ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
  776 + ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
  777 + pagep, fsdata, ext2_get_block);
785 778 if (ret < 0)
786 779 ext2_write_failed(mapping, pos + len);
787 780 return ret;
... ... @@ -271,8 +271,7 @@
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);
... ... @@ -297,8 +296,7 @@
297 296  
298 297 int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
299 298 {
300   - struct address_space *mapping = page->mapping;
301   - struct inode *inode = (struct inode*)mapping->host;
  299 + struct inode *inode = page->mapping->host;
302 300 char *kaddr = page_address(page);
303 301 loff_t pos = page_offset(page) + (char*)de - kaddr;
304 302 struct minix_sb_info *sbi = minix_sb(inode->i_sb);
... ... @@ -306,8 +304,7 @@
306 304 int err;
307 305  
308 306 lock_page(page);
309   - err = __minix_write_begin(NULL, mapping, pos, len,
310   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  307 + err = minix_prepare_chunk(page, pos, len);
311 308 if (err == 0) {
312 309 if (sbi->s_version == MINIX_V3)
313 310 ((minix3_dirent *) de)->inode = 0;
314 311  
... ... @@ -325,16 +322,14 @@
325 322  
326 323 int minix_make_empty(struct inode *inode, struct inode *dir)
327 324 {
328   - struct address_space *mapping = inode->i_mapping;
329   - struct page *page = grab_cache_page(mapping, 0);
  325 + struct page *page = grab_cache_page(inode->i_mapping, 0);
330 326 struct minix_sb_info *sbi = minix_sb(inode->i_sb);
331 327 char *kaddr;
332 328 int err;
333 329  
334 330 if (!page)
335 331 return -ENOMEM;
336   - err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize,
337   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  332 + err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize);
338 333 if (err) {
339 334 unlock_page(page);
340 335 goto fail;
... ... @@ -425,8 +420,7 @@
425 420 void minix_set_link(struct minix_dir_entry *de, struct page *page,
426 421 struct inode *inode)
427 422 {
428   - struct address_space *mapping = page->mapping;
429   - struct inode *dir = mapping->host;
  423 + struct inode *dir = page->mapping->host;
430 424 struct minix_sb_info *sbi = minix_sb(dir->i_sb);
431 425 loff_t pos = page_offset(page) +
432 426 (char *)de-(char*)page_address(page);
... ... @@ -434,8 +428,7 @@
434 428  
435 429 lock_page(page);
436 430  
437   - err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
438   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  431 + err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
439 432 if (err == 0) {
440 433 if (sbi->s_version == MINIX_V3)
441 434 ((minix3_dirent *) de)->inode = inode->i_ino;
... ... @@ -357,12 +357,10 @@
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,
... ... @@ -370,7 +368,8 @@
370 368 struct page **pagep, void **fsdata)
371 369 {
372 370 *pagep = NULL;
373   - return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
  371 + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
  372 + minix_get_block);
374 373 }
375 374  
376 375 static sector_t minix_bmap(struct address_space *mapping, sector_t block)
... ... @@ -53,9 +53,7 @@
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 *);
... ... @@ -80,25 +80,13 @@
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);
  86 + return block_write_begin_newtrunc(NULL, page->mapping, pos, to - from,
  87 + 0, &page, NULL, nilfs_get_block);
91 88 }
92 89  
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);
100   -}
101   -
102 90 static void nilfs_commit_chunk(struct page *page,
103 91 struct address_space *mapping,
104 92 unsigned from, unsigned to)
... ... @@ -449,7 +437,7 @@
449 437 int err;
450 438  
451 439 lock_page(page);
452   - err = nilfs_prepare_chunk_uninterruptible(page, mapping, from, to);
  440 + err = nilfs_prepare_chunk(page, from, to);
453 441 BUG_ON(err);
454 442 de->inode = cpu_to_le64(inode->i_ino);
455 443 nilfs_set_de_type(de, inode);
... ... @@ -530,7 +518,7 @@
530 518 got_it:
531 519 from = (char *)de - (char *)page_address(page);
532 520 to = from + rec_len;
533   - err = nilfs_prepare_chunk(page, page->mapping, from, to);
  521 + err = nilfs_prepare_chunk(page, from, to);
534 522 if (err)
535 523 goto out_unlock;
536 524 if (de->inode) {
... ... @@ -587,7 +575,7 @@
587 575 if (pde)
588 576 from = (char *)pde - (char *)page_address(page);
589 577 lock_page(page);
590   - err = nilfs_prepare_chunk(page, mapping, from, to);
  578 + err = nilfs_prepare_chunk(page, from, to);
591 579 BUG_ON(err);
592 580 if (pde)
593 581 pde->rec_len = cpu_to_le16(to - from);
... ... @@ -615,7 +603,7 @@
615 603 if (!page)
616 604 return -ENOMEM;
617 605  
618   - err = nilfs_prepare_chunk(page, mapping, 0, chunk_size);
  606 + err = nilfs_prepare_chunk(page, 0, chunk_size);
619 607 if (unlikely(err)) {
620 608 unlock_page(page);
621 609 goto fail;
... ... @@ -218,8 +218,7 @@
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);
226 225  
... ... @@ -239,15 +238,13 @@
239 238  
240 239 int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
241 240 {
242   - struct address_space *mapping = page->mapping;
243   - struct inode *inode = (struct inode*)mapping->host;
  241 + struct inode *inode = page->mapping->host;
244 242 char *kaddr = (char*)page_address(page);
245 243 loff_t pos = page_offset(page) + (char *)de - kaddr;
246 244 int err;
247 245  
248 246 lock_page(page);
249   - err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
250   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  247 + err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
251 248 BUG_ON(err);
252 249 de->inode = 0;
253 250 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
254 251  
... ... @@ -259,16 +256,14 @@
259 256  
260 257 int sysv_make_empty(struct inode *inode, struct inode *dir)
261 258 {
262   - struct address_space *mapping = inode->i_mapping;
263   - struct page *page = grab_cache_page(mapping, 0);
  259 + struct page *page = grab_cache_page(inode->i_mapping, 0);
264 260 struct sysv_dir_entry * de;
265 261 char *base;
266 262 int err;
267 263  
268 264 if (!page)
269 265 return -ENOMEM;
270   - err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE,
271   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  266 + err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE);
272 267 if (err) {
273 268 unlock_page(page);
274 269 goto fail;
275 270  
... ... @@ -341,15 +336,13 @@
341 336 void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
342 337 struct inode *inode)
343 338 {
344   - struct address_space *mapping = page->mapping;
345   - struct inode *dir = mapping->host;
  339 + struct inode *dir = page->mapping->host;
346 340 loff_t pos = page_offset(page) +
347 341 (char *)de-(char*)page_address(page);
348 342 int err;
349 343  
350 344 lock_page(page);
351   - err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
352   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  345 + err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
353 346 BUG_ON(err);
354 347 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
355 348 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
... ... @@ -459,12 +459,10 @@
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,
... ... @@ -472,7 +470,8 @@
472 470 struct page **pagep, void **fsdata)
473 471 {
474 472 *pagep = NULL;
475   - return __sysv_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
  473 + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
  474 + get_block);
476 475 }
477 476  
478 477 static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
... ... @@ -136,9 +136,7 @@
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);
... ... @@ -95,8 +95,7 @@
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);
... ... @@ -381,8 +380,7 @@
381 380 got_it:
382 381 pos = page_offset(page) +
383 382 (char*)de - (char*)page_address(page);
384   - err = __ufs_write_begin(NULL, page->mapping, pos, rec_len,
385   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  383 + err = ufs_prepare_chunk(page, pos, rec_len);
386 384 if (err)
387 385 goto out_unlock;
388 386 if (de->d_ino) {
... ... @@ -518,7 +516,6 @@
518 516 struct page * page)
519 517 {
520 518 struct super_block *sb = inode->i_sb;
521   - struct address_space *mapping = page->mapping;
522 519 char *kaddr = page_address(page);
523 520 unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
524 521 unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
... ... @@ -549,8 +546,7 @@
549 546  
550 547 pos = page_offset(page) + from;
551 548 lock_page(page);
552   - err = __ufs_write_begin(NULL, mapping, pos, to - from,
553   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  549 + err = ufs_prepare_chunk(page, pos, to - from);
554 550 BUG_ON(err);
555 551 if (pde)
556 552 pde->d_reclen = cpu_to_fs16(sb, to - from);
... ... @@ -577,8 +573,7 @@
577 573 if (!page)
578 574 return -ENOMEM;
579 575  
580   - err = __ufs_write_begin(NULL, mapping, 0, chunk_size,
581   - AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  576 + err = ufs_prepare_chunk(page, 0, chunk_size);
582 577 if (err) {
583 578 unlock_page(page);
584 579 goto fail;
... ... @@ -558,12 +558,10 @@
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,
... ... @@ -571,7 +569,8 @@
571 569 struct page **pagep, void **fsdata)
572 570 {
573 571 *pagep = NULL;
574   - return __ufs_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
  572 + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
  573 + ufs_getfrag_block);
575 574 }
576 575  
577 576 static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
... ... @@ -257,9 +257,7 @@
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