diff options
author | Christoph Hellwig <hch@lst.de> | 2010-06-04 05:29:56 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-09 16:47:31 -0400 |
commit | f4e420dc423148fba637af1ab618fa8896dfb2d6 (patch) | |
tree | df0e81f5f4b8448dd6b3929e5537dcc46e7d7dde /fs | |
parent | 282dc178849882289d30e58b54be6b2799b351aa (diff) |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext2/dir.c | 24 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 3 | ||||
-rw-r--r-- | fs/ext2/inode.c | 11 | ||||
-rw-r--r-- | fs/minix/dir.c | 21 | ||||
-rw-r--r-- | fs/minix/inode.c | 11 | ||||
-rw-r--r-- | fs/minix/minix.h | 4 | ||||
-rw-r--r-- | fs/nilfs2/dir.c | 26 | ||||
-rw-r--r-- | fs/sysv/dir.c | 21 | ||||
-rw-r--r-- | fs/sysv/itree.c | 11 | ||||
-rw-r--r-- | fs/sysv/sysv.h | 4 | ||||
-rw-r--r-- | fs/ufs/dir.c | 13 | ||||
-rw-r--r-- | fs/ufs/inode.c | 11 | ||||
-rw-r--r-- | fs/ufs/util.h | 4 |
13 files changed, 57 insertions, 107 deletions
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 7516957273ed..6b946bae11cf 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -448,6 +448,12 @@ ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child) | |||
448 | return res; | 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 | /* Releases the page */ | 457 | /* Releases the page */ |
452 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | 458 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, |
453 | struct page *page, struct inode *inode, int update_times) | 459 | struct page *page, struct inode *inode, int update_times) |
@@ -458,8 +464,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | |||
458 | int err; | 464 | int err; |
459 | 465 | ||
460 | lock_page(page); | 466 | lock_page(page); |
461 | err = __ext2_write_begin(NULL, page->mapping, pos, len, | 467 | err = ext2_prepare_chunk(page, pos, len); |
462 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
463 | BUG_ON(err); | 468 | BUG_ON(err); |
464 | de->inode = cpu_to_le32(inode->i_ino); | 469 | de->inode = cpu_to_le32(inode->i_ino); |
465 | ext2_set_de_type(de, inode); | 470 | ext2_set_de_type(de, inode); |
@@ -542,8 +547,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) | |||
542 | got_it: | 547 | got_it: |
543 | pos = page_offset(page) + | 548 | pos = page_offset(page) + |
544 | (char*)de - (char*)page_address(page); | 549 | (char*)de - (char*)page_address(page); |
545 | err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0, | 550 | err = ext2_prepare_chunk(page, pos, rec_len); |
546 | &page, NULL); | ||
547 | if (err) | 551 | if (err) |
548 | goto out_unlock; | 552 | goto out_unlock; |
549 | if (de->inode) { | 553 | if (de->inode) { |
@@ -576,8 +580,7 @@ out_unlock: | |||
576 | */ | 580 | */ |
577 | int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) | 581 | int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) |
578 | { | 582 | { |
579 | struct address_space *mapping = page->mapping; | 583 | struct inode *inode = page->mapping->host; |
580 | struct inode *inode = mapping->host; | ||
581 | char *kaddr = page_address(page); | 584 | char *kaddr = page_address(page); |
582 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); | 585 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); |
583 | unsigned to = ((char *)dir - kaddr) + | 586 | unsigned to = ((char *)dir - kaddr) + |
@@ -601,8 +604,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) | |||
601 | from = (char*)pde - (char*)page_address(page); | 604 | from = (char*)pde - (char*)page_address(page); |
602 | pos = page_offset(page) + from; | 605 | pos = page_offset(page) + from; |
603 | lock_page(page); | 606 | lock_page(page); |
604 | err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0, | 607 | err = ext2_prepare_chunk(page, pos, to - from); |
605 | &page, NULL); | ||
606 | BUG_ON(err); | 608 | BUG_ON(err); |
607 | if (pde) | 609 | if (pde) |
608 | pde->rec_len = ext2_rec_len_to_disk(to - from); | 610 | pde->rec_len = ext2_rec_len_to_disk(to - from); |
@@ -621,8 +623,7 @@ out: | |||
621 | */ | 623 | */ |
622 | int ext2_make_empty(struct inode *inode, struct inode *parent) | 624 | int ext2_make_empty(struct inode *inode, struct inode *parent) |
623 | { | 625 | { |
624 | struct address_space *mapping = inode->i_mapping; | 626 | struct page *page = grab_cache_page(inode->i_mapping, 0); |
625 | struct page *page = grab_cache_page(mapping, 0); | ||
626 | unsigned chunk_size = ext2_chunk_size(inode); | 627 | unsigned chunk_size = ext2_chunk_size(inode); |
627 | struct ext2_dir_entry_2 * de; | 628 | struct ext2_dir_entry_2 * de; |
628 | int err; | 629 | int err; |
@@ -631,8 +632,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent) | |||
631 | if (!page) | 632 | if (!page) |
632 | return -ENOMEM; | 633 | return -ENOMEM; |
633 | 634 | ||
634 | err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0, | 635 | err = ext2_prepare_chunk(page, 0, chunk_size); |
635 | &page, NULL); | ||
636 | if (err) { | 636 | if (err) { |
637 | unlock_page(page); | 637 | unlock_page(page); |
638 | goto fail; | 638 | goto fail; |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 52b34f1d2738..8f53d11bf957 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -127,9 +127,6 @@ extern void ext2_set_inode_flags(struct inode *inode); | |||
127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); | 127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); |
128 | extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 128 | extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
129 | u64 start, u64 len); | 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 | /* ioctl.c */ | 131 | /* ioctl.c */ |
135 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); | 132 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 348805cd4109..2f4dfbcd7696 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -765,14 +765,6 @@ ext2_readpages(struct file *file, struct address_space *mapping, | |||
765 | return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); | 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 | static int | 768 | static int |
777 | ext2_write_begin(struct file *file, struct address_space *mapping, | 769 | ext2_write_begin(struct file *file, struct address_space *mapping, |
778 | loff_t pos, unsigned len, unsigned flags, | 770 | loff_t pos, unsigned len, unsigned flags, |
@@ -781,7 +773,8 @@ ext2_write_begin(struct file *file, struct address_space *mapping, | |||
781 | int ret; | 773 | int ret; |
782 | 774 | ||
783 | *pagep = NULL; | 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 | if (ret < 0) | 778 | if (ret < 0) |
786 | ext2_write_failed(mapping, pos + len); | 779 | ext2_write_failed(mapping, pos + len); |
787 | return ret; | 780 | return ret; |
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index 1dbf921ca44b..085a9262c692 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -271,8 +271,7 @@ int minix_add_link(struct dentry *dentry, struct inode *inode) | |||
271 | 271 | ||
272 | got_it: | 272 | got_it: |
273 | pos = page_offset(page) + p - (char *)page_address(page); | 273 | pos = page_offset(page) + p - (char *)page_address(page); |
274 | err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize, | 274 | err = minix_prepare_chunk(page, pos, sbi->s_dirsize); |
275 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
276 | if (err) | 275 | if (err) |
277 | goto out_unlock; | 276 | goto out_unlock; |
278 | memcpy (namx, name, namelen); | 277 | memcpy (namx, name, namelen); |
@@ -297,8 +296,7 @@ out_unlock: | |||
297 | 296 | ||
298 | int minix_delete_entry(struct minix_dir_entry *de, struct page *page) | 297 | int minix_delete_entry(struct minix_dir_entry *de, struct page *page) |
299 | { | 298 | { |
300 | struct address_space *mapping = page->mapping; | 299 | struct inode *inode = page->mapping->host; |
301 | struct inode *inode = (struct inode*)mapping->host; | ||
302 | char *kaddr = page_address(page); | 300 | char *kaddr = page_address(page); |
303 | loff_t pos = page_offset(page) + (char*)de - kaddr; | 301 | loff_t pos = page_offset(page) + (char*)de - kaddr; |
304 | struct minix_sb_info *sbi = minix_sb(inode->i_sb); | 302 | struct minix_sb_info *sbi = minix_sb(inode->i_sb); |
@@ -306,8 +304,7 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page) | |||
306 | int err; | 304 | int err; |
307 | 305 | ||
308 | lock_page(page); | 306 | lock_page(page); |
309 | err = __minix_write_begin(NULL, mapping, pos, len, | 307 | err = minix_prepare_chunk(page, pos, len); |
310 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
311 | if (err == 0) { | 308 | if (err == 0) { |
312 | if (sbi->s_version == MINIX_V3) | 309 | if (sbi->s_version == MINIX_V3) |
313 | ((minix3_dirent *) de)->inode = 0; | 310 | ((minix3_dirent *) de)->inode = 0; |
@@ -325,16 +322,14 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page) | |||
325 | 322 | ||
326 | int minix_make_empty(struct inode *inode, struct inode *dir) | 323 | int minix_make_empty(struct inode *inode, struct inode *dir) |
327 | { | 324 | { |
328 | struct address_space *mapping = inode->i_mapping; | 325 | struct page *page = grab_cache_page(inode->i_mapping, 0); |
329 | struct page *page = grab_cache_page(mapping, 0); | ||
330 | struct minix_sb_info *sbi = minix_sb(inode->i_sb); | 326 | struct minix_sb_info *sbi = minix_sb(inode->i_sb); |
331 | char *kaddr; | 327 | char *kaddr; |
332 | int err; | 328 | int err; |
333 | 329 | ||
334 | if (!page) | 330 | if (!page) |
335 | return -ENOMEM; | 331 | return -ENOMEM; |
336 | err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize, | 332 | err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize); |
337 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
338 | if (err) { | 333 | if (err) { |
339 | unlock_page(page); | 334 | unlock_page(page); |
340 | goto fail; | 335 | goto fail; |
@@ -425,8 +420,7 @@ not_empty: | |||
425 | void minix_set_link(struct minix_dir_entry *de, struct page *page, | 420 | void minix_set_link(struct minix_dir_entry *de, struct page *page, |
426 | struct inode *inode) | 421 | struct inode *inode) |
427 | { | 422 | { |
428 | struct address_space *mapping = page->mapping; | 423 | struct inode *dir = page->mapping->host; |
429 | struct inode *dir = mapping->host; | ||
430 | struct minix_sb_info *sbi = minix_sb(dir->i_sb); | 424 | struct minix_sb_info *sbi = minix_sb(dir->i_sb); |
431 | loff_t pos = page_offset(page) + | 425 | loff_t pos = page_offset(page) + |
432 | (char *)de-(char*)page_address(page); | 426 | (char *)de-(char*)page_address(page); |
@@ -434,8 +428,7 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page, | |||
434 | 428 | ||
435 | lock_page(page); | 429 | lock_page(page); |
436 | 430 | ||
437 | err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize, | 431 | err = minix_prepare_chunk(page, pos, sbi->s_dirsize); |
438 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
439 | if (err == 0) { | 432 | if (err == 0) { |
440 | if (sbi->s_version == MINIX_V3) | 433 | if (sbi->s_version == MINIX_V3) |
441 | ((minix3_dirent *) de)->inode = inode->i_ino; | 434 | ((minix3_dirent *) de)->inode = inode->i_ino; |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 756f8c93780c..f4abe45229bb 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -357,12 +357,10 @@ static int minix_readpage(struct file *file, struct page *page) | |||
357 | return block_read_full_page(page,minix_get_block); | 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, | 360 | int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len) |
361 | loff_t pos, unsigned len, unsigned flags, | ||
362 | struct page **pagep, void **fsdata) | ||
363 | { | 361 | { |
364 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 362 | return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, |
365 | minix_get_block); | 363 | &page, NULL, minix_get_block); |
366 | } | 364 | } |
367 | 365 | ||
368 | static int minix_write_begin(struct file *file, struct address_space *mapping, | 366 | static int minix_write_begin(struct file *file, struct address_space *mapping, |
@@ -370,7 +368,8 @@ static int minix_write_begin(struct file *file, struct address_space *mapping, | |||
370 | struct page **pagep, void **fsdata) | 368 | struct page **pagep, void **fsdata) |
371 | { | 369 | { |
372 | *pagep = NULL; | 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 | static sector_t minix_bmap(struct address_space *mapping, sector_t block) | 375 | static sector_t minix_bmap(struct address_space *mapping, sector_t block) |
diff --git a/fs/minix/minix.h b/fs/minix/minix.h index 111f34ee9e3b..407b1c84911e 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h | |||
@@ -53,9 +53,7 @@ extern int minix_new_block(struct inode * inode); | |||
53 | extern void minix_free_block(struct inode *inode, unsigned long block); | 53 | extern void minix_free_block(struct inode *inode, unsigned long block); |
54 | extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); | 54 | extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); |
55 | extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 55 | extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
56 | extern int __minix_write_begin(struct file *file, struct address_space *mapping, | 56 | extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len); |
57 | loff_t pos, unsigned len, unsigned flags, | ||
58 | struct page **pagep, void **fsdata); | ||
59 | 57 | ||
60 | extern void V1_minix_truncate(struct inode *); | 58 | extern void V1_minix_truncate(struct inode *); |
61 | extern void V2_minix_truncate(struct inode *); | 59 | extern void V2_minix_truncate(struct inode *); |
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c index 85c89dfc71f0..fc2bcfa599a3 100644 --- a/fs/nilfs2/dir.c +++ b/fs/nilfs2/dir.c | |||
@@ -80,23 +80,11 @@ static unsigned nilfs_last_byte(struct inode *inode, unsigned long page_nr) | |||
80 | return last_byte; | 80 | return last_byte; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int nilfs_prepare_chunk_uninterruptible(struct page *page, | 83 | static int nilfs_prepare_chunk(struct page *page, unsigned from, unsigned to) |
84 | struct address_space *mapping, | ||
85 | unsigned from, unsigned to) | ||
86 | { | 84 | { |
87 | loff_t pos = page_offset(page) + from; | 85 | loff_t pos = page_offset(page) + from; |
88 | return block_write_begin(NULL, mapping, pos, to - from, | 86 | return block_write_begin_newtrunc(NULL, page->mapping, pos, to - from, |
89 | AOP_FLAG_UNINTERRUPTIBLE, &page, | 87 | 0, &page, NULL, nilfs_get_block); |
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); | ||
100 | } | 88 | } |
101 | 89 | ||
102 | static void nilfs_commit_chunk(struct page *page, | 90 | static void nilfs_commit_chunk(struct page *page, |
@@ -449,7 +437,7 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, | |||
449 | int err; | 437 | int err; |
450 | 438 | ||
451 | lock_page(page); | 439 | lock_page(page); |
452 | err = nilfs_prepare_chunk_uninterruptible(page, mapping, from, to); | 440 | err = nilfs_prepare_chunk(page, from, to); |
453 | BUG_ON(err); | 441 | BUG_ON(err); |
454 | de->inode = cpu_to_le64(inode->i_ino); | 442 | de->inode = cpu_to_le64(inode->i_ino); |
455 | nilfs_set_de_type(de, inode); | 443 | nilfs_set_de_type(de, inode); |
@@ -530,7 +518,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) | |||
530 | got_it: | 518 | got_it: |
531 | from = (char *)de - (char *)page_address(page); | 519 | from = (char *)de - (char *)page_address(page); |
532 | to = from + rec_len; | 520 | to = from + rec_len; |
533 | err = nilfs_prepare_chunk(page, page->mapping, from, to); | 521 | err = nilfs_prepare_chunk(page, from, to); |
534 | if (err) | 522 | if (err) |
535 | goto out_unlock; | 523 | goto out_unlock; |
536 | if (de->inode) { | 524 | if (de->inode) { |
@@ -587,7 +575,7 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page) | |||
587 | if (pde) | 575 | if (pde) |
588 | from = (char *)pde - (char *)page_address(page); | 576 | from = (char *)pde - (char *)page_address(page); |
589 | lock_page(page); | 577 | lock_page(page); |
590 | err = nilfs_prepare_chunk(page, mapping, from, to); | 578 | err = nilfs_prepare_chunk(page, from, to); |
591 | BUG_ON(err); | 579 | BUG_ON(err); |
592 | if (pde) | 580 | if (pde) |
593 | pde->rec_len = cpu_to_le16(to - from); | 581 | pde->rec_len = cpu_to_le16(to - from); |
@@ -615,7 +603,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent) | |||
615 | if (!page) | 603 | if (!page) |
616 | return -ENOMEM; | 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 | if (unlikely(err)) { | 607 | if (unlikely(err)) { |
620 | unlock_page(page); | 608 | unlock_page(page); |
621 | goto fail; | 609 | goto fail; |
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 79941e4964a4..a77c42157620 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c | |||
@@ -218,8 +218,7 @@ got_it: | |||
218 | pos = page_offset(page) + | 218 | pos = page_offset(page) + |
219 | (char*)de - (char*)page_address(page); | 219 | (char*)de - (char*)page_address(page); |
220 | lock_page(page); | 220 | lock_page(page); |
221 | err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE, | 221 | err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); |
222 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
223 | if (err) | 222 | if (err) |
224 | goto out_unlock; | 223 | goto out_unlock; |
225 | memcpy (de->name, name, namelen); | 224 | memcpy (de->name, name, namelen); |
@@ -239,15 +238,13 @@ out_unlock: | |||
239 | 238 | ||
240 | int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) | 239 | int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) |
241 | { | 240 | { |
242 | struct address_space *mapping = page->mapping; | 241 | struct inode *inode = page->mapping->host; |
243 | struct inode *inode = (struct inode*)mapping->host; | ||
244 | char *kaddr = (char*)page_address(page); | 242 | char *kaddr = (char*)page_address(page); |
245 | loff_t pos = page_offset(page) + (char *)de - kaddr; | 243 | loff_t pos = page_offset(page) + (char *)de - kaddr; |
246 | int err; | 244 | int err; |
247 | 245 | ||
248 | lock_page(page); | 246 | lock_page(page); |
249 | err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, | 247 | err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); |
250 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
251 | BUG_ON(err); | 248 | BUG_ON(err); |
252 | de->inode = 0; | 249 | de->inode = 0; |
253 | err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); | 250 | err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); |
@@ -259,16 +256,14 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) | |||
259 | 256 | ||
260 | int sysv_make_empty(struct inode *inode, struct inode *dir) | 257 | int sysv_make_empty(struct inode *inode, struct inode *dir) |
261 | { | 258 | { |
262 | struct address_space *mapping = inode->i_mapping; | 259 | struct page *page = grab_cache_page(inode->i_mapping, 0); |
263 | struct page *page = grab_cache_page(mapping, 0); | ||
264 | struct sysv_dir_entry * de; | 260 | struct sysv_dir_entry * de; |
265 | char *base; | 261 | char *base; |
266 | int err; | 262 | int err; |
267 | 263 | ||
268 | if (!page) | 264 | if (!page) |
269 | return -ENOMEM; | 265 | return -ENOMEM; |
270 | err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE, | 266 | err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE); |
271 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
272 | if (err) { | 267 | if (err) { |
273 | unlock_page(page); | 268 | unlock_page(page); |
274 | goto fail; | 269 | goto fail; |
@@ -341,15 +336,13 @@ not_empty: | |||
341 | void sysv_set_link(struct sysv_dir_entry *de, struct page *page, | 336 | void sysv_set_link(struct sysv_dir_entry *de, struct page *page, |
342 | struct inode *inode) | 337 | struct inode *inode) |
343 | { | 338 | { |
344 | struct address_space *mapping = page->mapping; | 339 | struct inode *dir = page->mapping->host; |
345 | struct inode *dir = mapping->host; | ||
346 | loff_t pos = page_offset(page) + | 340 | loff_t pos = page_offset(page) + |
347 | (char *)de-(char*)page_address(page); | 341 | (char *)de-(char*)page_address(page); |
348 | int err; | 342 | int err; |
349 | 343 | ||
350 | lock_page(page); | 344 | lock_page(page); |
351 | err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, | 345 | err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); |
352 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
353 | BUG_ON(err); | 346 | BUG_ON(err); |
354 | de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); | 347 | de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); |
355 | err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); | 348 | err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); |
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c index f042eec464c2..4068f485cfd6 100644 --- a/fs/sysv/itree.c +++ b/fs/sysv/itree.c | |||
@@ -459,12 +459,10 @@ static int sysv_readpage(struct file *file, struct page *page) | |||
459 | return block_read_full_page(page,get_block); | 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, | 462 | int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len) |
463 | loff_t pos, unsigned len, unsigned flags, | ||
464 | struct page **pagep, void **fsdata) | ||
465 | { | 463 | { |
466 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 464 | return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, |
467 | get_block); | 465 | &page, NULL, get_block); |
468 | } | 466 | } |
469 | 467 | ||
470 | static int sysv_write_begin(struct file *file, struct address_space *mapping, | 468 | static int sysv_write_begin(struct file *file, struct address_space *mapping, |
@@ -472,7 +470,8 @@ static int sysv_write_begin(struct file *file, struct address_space *mapping, | |||
472 | struct page **pagep, void **fsdata) | 470 | struct page **pagep, void **fsdata) |
473 | { | 471 | { |
474 | *pagep = NULL; | 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 | static sector_t sysv_bmap(struct address_space *mapping, sector_t block) | 477 | static sector_t sysv_bmap(struct address_space *mapping, sector_t block) |
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index 94cb9b4d76c2..bb55cdb394bf 100644 --- a/fs/sysv/sysv.h +++ b/fs/sysv/sysv.h | |||
@@ -136,9 +136,7 @@ extern unsigned long sysv_count_free_blocks(struct super_block *); | |||
136 | 136 | ||
137 | /* itree.c */ | 137 | /* itree.c */ |
138 | extern void sysv_truncate(struct inode *); | 138 | extern void sysv_truncate(struct inode *); |
139 | extern int __sysv_write_begin(struct file *file, struct address_space *mapping, | 139 | extern int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len); |
140 | loff_t pos, unsigned len, unsigned flags, | ||
141 | struct page **pagep, void **fsdata); | ||
142 | 140 | ||
143 | /* inode.c */ | 141 | /* inode.c */ |
144 | extern struct inode *sysv_iget(struct super_block *, unsigned int); | 142 | extern struct inode *sysv_iget(struct super_block *, unsigned int); |
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index ec784756dc65..dbc90994715a 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -95,8 +95,7 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, | |||
95 | int err; | 95 | int err; |
96 | 96 | ||
97 | lock_page(page); | 97 | lock_page(page); |
98 | err = __ufs_write_begin(NULL, page->mapping, pos, len, | 98 | err = ufs_prepare_chunk(page, pos, len); |
99 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
100 | BUG_ON(err); | 99 | BUG_ON(err); |
101 | 100 | ||
102 | de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); | 101 | de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); |
@@ -381,8 +380,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) | |||
381 | got_it: | 380 | got_it: |
382 | pos = page_offset(page) + | 381 | pos = page_offset(page) + |
383 | (char*)de - (char*)page_address(page); | 382 | (char*)de - (char*)page_address(page); |
384 | err = __ufs_write_begin(NULL, page->mapping, pos, rec_len, | 383 | err = ufs_prepare_chunk(page, pos, rec_len); |
385 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
386 | if (err) | 384 | if (err) |
387 | goto out_unlock; | 385 | goto out_unlock; |
388 | if (de->d_ino) { | 386 | if (de->d_ino) { |
@@ -518,7 +516,6 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, | |||
518 | struct page * page) | 516 | struct page * page) |
519 | { | 517 | { |
520 | struct super_block *sb = inode->i_sb; | 518 | struct super_block *sb = inode->i_sb; |
521 | struct address_space *mapping = page->mapping; | ||
522 | char *kaddr = page_address(page); | 519 | char *kaddr = page_address(page); |
523 | unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); | 520 | unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); |
524 | unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); | 521 | unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); |
@@ -549,8 +546,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, | |||
549 | 546 | ||
550 | pos = page_offset(page) + from; | 547 | pos = page_offset(page) + from; |
551 | lock_page(page); | 548 | lock_page(page); |
552 | err = __ufs_write_begin(NULL, mapping, pos, to - from, | 549 | err = ufs_prepare_chunk(page, pos, to - from); |
553 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
554 | BUG_ON(err); | 550 | BUG_ON(err); |
555 | if (pde) | 551 | if (pde) |
556 | pde->d_reclen = cpu_to_fs16(sb, to - from); | 552 | pde->d_reclen = cpu_to_fs16(sb, to - from); |
@@ -577,8 +573,7 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) | |||
577 | if (!page) | 573 | if (!page) |
578 | return -ENOMEM; | 574 | return -ENOMEM; |
579 | 575 | ||
580 | err = __ufs_write_begin(NULL, mapping, 0, chunk_size, | 576 | err = ufs_prepare_chunk(page, 0, chunk_size); |
581 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
582 | if (err) { | 577 | if (err) { |
583 | unlock_page(page); | 578 | unlock_page(page); |
584 | goto fail; | 579 | goto fail; |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 73fe773aa034..a9555b1ffd28 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -558,12 +558,10 @@ static int ufs_readpage(struct file *file, struct page *page) | |||
558 | return block_read_full_page(page,ufs_getfrag_block); | 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, | 561 | int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len) |
562 | loff_t pos, unsigned len, unsigned flags, | ||
563 | struct page **pagep, void **fsdata) | ||
564 | { | 562 | { |
565 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 563 | return block_write_begin_newtrunc(NULL, page->mapping, pos, len, 0, |
566 | ufs_getfrag_block); | 564 | &page, NULL, ufs_getfrag_block); |
567 | } | 565 | } |
568 | 566 | ||
569 | static int ufs_write_begin(struct file *file, struct address_space *mapping, | 567 | static int ufs_write_begin(struct file *file, struct address_space *mapping, |
@@ -571,7 +569,8 @@ static int ufs_write_begin(struct file *file, struct address_space *mapping, | |||
571 | struct page **pagep, void **fsdata) | 569 | struct page **pagep, void **fsdata) |
572 | { | 570 | { |
573 | *pagep = NULL; | 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 | static sector_t ufs_bmap(struct address_space *mapping, sector_t block) | 576 | static sector_t ufs_bmap(struct address_space *mapping, sector_t block) |
diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 23ceed8c8fb9..0466036912f1 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h | |||
@@ -257,9 +257,7 @@ ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value) | |||
257 | 257 | ||
258 | extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); | 258 | extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); |
259 | extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t); | 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, | 260 | extern int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len); |
261 | loff_t pos, unsigned len, unsigned flags, | ||
262 | struct page **pagep, void **fsdata); | ||
263 | 261 | ||
264 | /* | 262 | /* |
265 | * These functions manipulate ufs buffers | 263 | * These functions manipulate ufs buffers |