diff options
Diffstat (limited to 'fs/ufs/dir.c')
-rw-r--r-- | fs/ufs/dir.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 154452172f43..2410ec6002db 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/time.h> | 19 | #include <linux/time.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/ufs_fs.h> | 21 | #include <linux/ufs_fs.h> |
22 | #include <linux/swap.h> | ||
22 | 23 | ||
23 | #include "swab.h" | 24 | #include "swab.h" |
24 | #include "util.h" | 25 | #include "util.h" |
@@ -38,12 +39,18 @@ static inline int ufs_match(struct super_block *sb, int len, | |||
38 | return !memcmp(name, de->d_name, len); | 39 | return !memcmp(name, de->d_name, len); |
39 | } | 40 | } |
40 | 41 | ||
41 | static int ufs_commit_chunk(struct page *page, unsigned from, unsigned to) | 42 | static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len) |
42 | { | 43 | { |
43 | struct inode *dir = page->mapping->host; | 44 | struct address_space *mapping = page->mapping; |
45 | struct inode *dir = mapping->host; | ||
44 | int err = 0; | 46 | int err = 0; |
47 | |||
45 | dir->i_version++; | 48 | dir->i_version++; |
46 | page->mapping->a_ops->commit_write(NULL, page, from, to); | 49 | block_write_end(NULL, mapping, pos, len, len, page, NULL); |
50 | if (pos+len > dir->i_size) { | ||
51 | i_size_write(dir, pos+len); | ||
52 | mark_inode_dirty(dir); | ||
53 | } | ||
47 | if (IS_DIRSYNC(dir)) | 54 | if (IS_DIRSYNC(dir)) |
48 | err = write_one_page(page, 1); | 55 | err = write_one_page(page, 1); |
49 | else | 56 | else |
@@ -81,16 +88,20 @@ ino_t ufs_inode_by_name(struct inode *dir, struct dentry *dentry) | |||
81 | void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, | 88 | void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, |
82 | struct page *page, struct inode *inode) | 89 | struct page *page, struct inode *inode) |
83 | { | 90 | { |
84 | unsigned from = (char *) de - (char *) page_address(page); | 91 | loff_t pos = page_offset(page) + |
85 | unsigned to = from + fs16_to_cpu(dir->i_sb, de->d_reclen); | 92 | (char *) de - (char *) page_address(page); |
93 | unsigned len = fs16_to_cpu(dir->i_sb, de->d_reclen); | ||
86 | int err; | 94 | int err; |
87 | 95 | ||
88 | lock_page(page); | 96 | lock_page(page); |
89 | err = page->mapping->a_ops->prepare_write(NULL, page, from, to); | 97 | err = __ufs_write_begin(NULL, page->mapping, pos, len, |
98 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
90 | BUG_ON(err); | 99 | BUG_ON(err); |
100 | |||
91 | 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); |
92 | ufs_set_de_type(dir->i_sb, de, inode->i_mode); | 102 | ufs_set_de_type(dir->i_sb, de, inode->i_mode); |
93 | err = ufs_commit_chunk(page, from, to); | 103 | |
104 | err = ufs_commit_chunk(page, pos, len); | ||
94 | ufs_put_page(page); | 105 | ufs_put_page(page); |
95 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 106 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; |
96 | mark_inode_dirty(dir); | 107 | mark_inode_dirty(dir); |
@@ -312,7 +323,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) | |||
312 | unsigned long npages = ufs_dir_pages(dir); | 323 | unsigned long npages = ufs_dir_pages(dir); |
313 | unsigned long n; | 324 | unsigned long n; |
314 | char *kaddr; | 325 | char *kaddr; |
315 | unsigned from, to; | 326 | loff_t pos; |
316 | int err; | 327 | int err; |
317 | 328 | ||
318 | UFSD("ENTER, name %s, namelen %u\n", name, namelen); | 329 | UFSD("ENTER, name %s, namelen %u\n", name, namelen); |
@@ -367,9 +378,10 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) | |||
367 | return -EINVAL; | 378 | return -EINVAL; |
368 | 379 | ||
369 | got_it: | 380 | got_it: |
370 | from = (char*)de - (char*)page_address(page); | 381 | pos = page_offset(page) + |
371 | to = from + rec_len; | 382 | (char*)de - (char*)page_address(page); |
372 | err = page->mapping->a_ops->prepare_write(NULL, page, from, to); | 383 | err = __ufs_write_begin(NULL, page->mapping, pos, rec_len, |
384 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
373 | if (err) | 385 | if (err) |
374 | goto out_unlock; | 386 | goto out_unlock; |
375 | if (de->d_ino) { | 387 | if (de->d_ino) { |
@@ -386,7 +398,7 @@ got_it: | |||
386 | de->d_ino = cpu_to_fs32(sb, inode->i_ino); | 398 | de->d_ino = cpu_to_fs32(sb, inode->i_ino); |
387 | ufs_set_de_type(sb, de, inode->i_mode); | 399 | ufs_set_de_type(sb, de, inode->i_mode); |
388 | 400 | ||
389 | err = ufs_commit_chunk(page, from, to); | 401 | err = ufs_commit_chunk(page, pos, rec_len); |
390 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 402 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; |
391 | 403 | ||
392 | mark_inode_dirty(dir); | 404 | mark_inode_dirty(dir); |
@@ -509,6 +521,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, | |||
509 | char *kaddr = page_address(page); | 521 | char *kaddr = page_address(page); |
510 | unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); | 522 | unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); |
511 | unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); | 523 | unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); |
524 | loff_t pos; | ||
512 | struct ufs_dir_entry *pde = NULL; | 525 | struct ufs_dir_entry *pde = NULL; |
513 | struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from); | 526 | struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from); |
514 | int err; | 527 | int err; |
@@ -532,13 +545,16 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, | |||
532 | } | 545 | } |
533 | if (pde) | 546 | if (pde) |
534 | from = (char*)pde - (char*)page_address(page); | 547 | from = (char*)pde - (char*)page_address(page); |
548 | |||
549 | pos = page_offset(page) + from; | ||
535 | lock_page(page); | 550 | lock_page(page); |
536 | err = mapping->a_ops->prepare_write(NULL, page, from, to); | 551 | err = __ufs_write_begin(NULL, mapping, pos, to - from, |
552 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
537 | BUG_ON(err); | 553 | BUG_ON(err); |
538 | if (pde) | 554 | if (pde) |
539 | pde->d_reclen = cpu_to_fs16(sb, to-from); | 555 | pde->d_reclen = cpu_to_fs16(sb, to - from); |
540 | dir->d_ino = 0; | 556 | dir->d_ino = 0; |
541 | err = ufs_commit_chunk(page, from, to); | 557 | err = ufs_commit_chunk(page, pos, to - from); |
542 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | 558 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; |
543 | mark_inode_dirty(inode); | 559 | mark_inode_dirty(inode); |
544 | out: | 560 | out: |
@@ -559,14 +575,15 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) | |||
559 | 575 | ||
560 | if (!page) | 576 | if (!page) |
561 | return -ENOMEM; | 577 | return -ENOMEM; |
562 | kmap(page); | 578 | |
563 | err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); | 579 | err = __ufs_write_begin(NULL, mapping, 0, chunk_size, |
580 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
564 | if (err) { | 581 | if (err) { |
565 | unlock_page(page); | 582 | unlock_page(page); |
566 | goto fail; | 583 | goto fail; |
567 | } | 584 | } |
568 | 585 | ||
569 | 586 | kmap(page); | |
570 | base = (char*)page_address(page); | 587 | base = (char*)page_address(page); |
571 | memset(base, 0, PAGE_CACHE_SIZE); | 588 | memset(base, 0, PAGE_CACHE_SIZE); |
572 | 589 | ||
@@ -584,10 +601,10 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) | |||
584 | de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1)); | 601 | de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1)); |
585 | ufs_set_de_namlen(sb, de, 2); | 602 | ufs_set_de_namlen(sb, de, 2); |
586 | strcpy (de->d_name, ".."); | 603 | strcpy (de->d_name, ".."); |
604 | kunmap(page); | ||
587 | 605 | ||
588 | err = ufs_commit_chunk(page, 0, chunk_size); | 606 | err = ufs_commit_chunk(page, 0, chunk_size); |
589 | fail: | 607 | fail: |
590 | kunmap(page); | ||
591 | page_cache_release(page); | 608 | page_cache_release(page); |
592 | return err; | 609 | return err; |
593 | } | 610 | } |