aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-06-04 05:29:56 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-09 16:47:31 -0400
commitf4e420dc423148fba637af1ab618fa8896dfb2d6 (patch)
treedf0e81f5f4b8448dd6b3929e5537dcc46e7d7dde
parent282dc178849882289d30e58b54be6b2799b351aa (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>
-rw-r--r--fs/ext2/dir.c24
-rw-r--r--fs/ext2/ext2.h3
-rw-r--r--fs/ext2/inode.c11
-rw-r--r--fs/minix/dir.c21
-rw-r--r--fs/minix/inode.c11
-rw-r--r--fs/minix/minix.h4
-rw-r--r--fs/nilfs2/dir.c26
-rw-r--r--fs/sysv/dir.c21
-rw-r--r--fs/sysv/itree.c11
-rw-r--r--fs/sysv/sysv.h4
-rw-r--r--fs/ufs/dir.c13
-rw-r--r--fs/ufs/inode.c11
-rw-r--r--fs/ufs/util.h4
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
451static 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 */
452void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, 458void 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)
542got_it: 547got_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 */
577int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) 581int 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 */
622int ext2_make_empty(struct inode *inode, struct inode *parent) 624int 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);
127extern void ext2_get_inode_flags(struct ext2_inode_info *); 127extern void ext2_get_inode_flags(struct ext2_inode_info *);
128extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 128extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
129 u64 start, u64 len); 129 u64 start, u64 len);
130int __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 */
135extern long ext2_ioctl(struct file *, unsigned int, unsigned long); 132extern 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
768int __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
776static int 768static int
777ext2_write_begin(struct file *file, struct address_space *mapping, 769ext2_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
272got_it: 272got_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
298int minix_delete_entry(struct minix_dir_entry *de, struct page *page) 297int 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
326int minix_make_empty(struct inode *inode, struct inode *dir) 323int 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:
425void minix_set_link(struct minix_dir_entry *de, struct page *page, 420void 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
360int __minix_write_begin(struct file *file, struct address_space *mapping, 360int 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
368static int minix_write_begin(struct file *file, struct address_space *mapping, 366static 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
376static sector_t minix_bmap(struct address_space *mapping, sector_t block) 375static 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);
53extern void minix_free_block(struct inode *inode, unsigned long block); 53extern void minix_free_block(struct inode *inode, unsigned long block);
54extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); 54extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi);
55extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); 55extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *);
56extern int __minix_write_begin(struct file *file, struct address_space *mapping, 56extern 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
60extern void V1_minix_truncate(struct inode *); 58extern void V1_minix_truncate(struct inode *);
61extern void V2_minix_truncate(struct inode *); 59extern 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
83static int nilfs_prepare_chunk_uninterruptible(struct page *page, 83static 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
93static 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
102static void nilfs_commit_chunk(struct page *page, 90static 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)
530got_it: 518got_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
240int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) 239int 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
260int sysv_make_empty(struct inode *inode, struct inode *dir) 257int 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:
341void sysv_set_link(struct sysv_dir_entry *de, struct page *page, 336void 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
462int __sysv_write_begin(struct file *file, struct address_space *mapping, 462int 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
470static int sysv_write_begin(struct file *file, struct address_space *mapping, 468static 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
478static sector_t sysv_bmap(struct address_space *mapping, sector_t block) 477static 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 */
138extern void sysv_truncate(struct inode *); 138extern void sysv_truncate(struct inode *);
139extern int __sysv_write_begin(struct file *file, struct address_space *mapping, 139extern 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 */
144extern struct inode *sysv_iget(struct super_block *, unsigned int); 142extern 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)
381got_it: 380got_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
561int __ufs_write_begin(struct file *file, struct address_space *mapping, 561int 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
569static int ufs_write_begin(struct file *file, struct address_space *mapping, 567static 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
577static sector_t ufs_bmap(struct address_space *mapping, sector_t block) 576static 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
258extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); 258extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *);
259extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t); 259extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t);
260extern int __ufs_write_begin(struct file *file, struct address_space *mapping, 260extern 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