diff options
Diffstat (limited to 'fs/exofs/inode.c')
-rw-r--r-- | fs/exofs/inode.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index a7555238c41a..8472c098445d 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -43,6 +43,17 @@ enum { BIO_MAX_PAGES_KMALLOC = | |||
43 | PAGE_SIZE / sizeof(struct page *), | 43 | PAGE_SIZE / sizeof(struct page *), |
44 | }; | 44 | }; |
45 | 45 | ||
46 | unsigned exofs_max_io_pages(struct exofs_layout *layout, | ||
47 | unsigned expected_pages) | ||
48 | { | ||
49 | unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); | ||
50 | |||
51 | /* TODO: easily support bio chaining */ | ||
52 | pages = min_t(unsigned, pages, | ||
53 | layout->group_width * BIO_MAX_PAGES_KMALLOC); | ||
54 | return pages; | ||
55 | } | ||
56 | |||
46 | struct page_collect { | 57 | struct page_collect { |
47 | struct exofs_sb_info *sbi; | 58 | struct exofs_sb_info *sbi; |
48 | struct inode *inode; | 59 | struct inode *inode; |
@@ -97,8 +108,7 @@ static void _pcol_reset(struct page_collect *pcol) | |||
97 | 108 | ||
98 | static int pcol_try_alloc(struct page_collect *pcol) | 109 | static int pcol_try_alloc(struct page_collect *pcol) |
99 | { | 110 | { |
100 | unsigned pages = min_t(unsigned, pcol->expected_pages, | 111 | unsigned pages; |
101 | MAX_PAGES_KMALLOC); | ||
102 | 112 | ||
103 | if (!pcol->ios) { /* First time allocate io_state */ | 113 | if (!pcol->ios) { /* First time allocate io_state */ |
104 | int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); | 114 | int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); |
@@ -108,8 +118,7 @@ static int pcol_try_alloc(struct page_collect *pcol) | |||
108 | } | 118 | } |
109 | 119 | ||
110 | /* TODO: easily support bio chaining */ | 120 | /* TODO: easily support bio chaining */ |
111 | pages = min_t(unsigned, pages, | 121 | pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); |
112 | pcol->sbi->layout.group_width * BIO_MAX_PAGES_KMALLOC); | ||
113 | 122 | ||
114 | for (; pages; pages >>= 1) { | 123 | for (; pages; pages >>= 1) { |
115 | pcol->pages = kmalloc(pages * sizeof(struct page *), | 124 | pcol->pages = kmalloc(pages * sizeof(struct page *), |
@@ -350,8 +359,10 @@ static int readpage_strip(void *data, struct page *page) | |||
350 | 359 | ||
351 | if (!pcol->read_4_write) | 360 | if (!pcol->read_4_write) |
352 | unlock_page(page); | 361 | unlock_page(page); |
353 | EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," | 362 | EXOFS_DBGMSG("readpage_strip(0x%lx) empty page len=%zx " |
354 | " splitting\n", inode->i_ino, page->index); | 363 | "read_4_write=%d index=0x%lx end_index=0x%lx " |
364 | "splitting\n", inode->i_ino, len, | ||
365 | pcol->read_4_write, page->index, end_index); | ||
355 | 366 | ||
356 | return read_exec(pcol); | 367 | return read_exec(pcol); |
357 | } | 368 | } |
@@ -722,11 +733,28 @@ int exofs_write_begin(struct file *file, struct address_space *mapping, | |||
722 | 733 | ||
723 | /* read modify write */ | 734 | /* read modify write */ |
724 | if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) { | 735 | if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) { |
736 | loff_t i_size = i_size_read(mapping->host); | ||
737 | pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; | ||
738 | size_t rlen; | ||
739 | |||
740 | if (page->index < end_index) | ||
741 | rlen = PAGE_CACHE_SIZE; | ||
742 | else if (page->index == end_index) | ||
743 | rlen = i_size & ~PAGE_CACHE_MASK; | ||
744 | else | ||
745 | rlen = 0; | ||
746 | |||
747 | if (!rlen) { | ||
748 | clear_highpage(page); | ||
749 | SetPageUptodate(page); | ||
750 | goto out; | ||
751 | } | ||
752 | |||
725 | ret = _readpage(page, true); | 753 | ret = _readpage(page, true); |
726 | if (ret) { | 754 | if (ret) { |
727 | /*SetPageError was done by _readpage. Is it ok?*/ | 755 | /*SetPageError was done by _readpage. Is it ok?*/ |
728 | unlock_page(page); | 756 | unlock_page(page); |
729 | EXOFS_DBGMSG("__readpage_filler failed\n"); | 757 | EXOFS_DBGMSG("__readpage failed\n"); |
730 | } | 758 | } |
731 | } | 759 | } |
732 | out: | 760 | out: |
@@ -795,7 +823,6 @@ const struct address_space_operations exofs_aops = { | |||
795 | .direct_IO = NULL, /* TODO: Should be trivial to do */ | 823 | .direct_IO = NULL, /* TODO: Should be trivial to do */ |
796 | 824 | ||
797 | /* With these NULL has special meaning or default is not exported */ | 825 | /* With these NULL has special meaning or default is not exported */ |
798 | .sync_page = NULL, | ||
799 | .get_xip_mem = NULL, | 826 | .get_xip_mem = NULL, |
800 | .migratepage = NULL, | 827 | .migratepage = NULL, |
801 | .launder_page = NULL, | 828 | .launder_page = NULL, |
@@ -1030,6 +1057,7 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) | |||
1030 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); | 1057 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); |
1031 | } | 1058 | } |
1032 | 1059 | ||
1060 | inode->i_mapping->backing_dev_info = sb->s_bdi; | ||
1033 | if (S_ISREG(inode->i_mode)) { | 1061 | if (S_ISREG(inode->i_mode)) { |
1034 | inode->i_op = &exofs_file_inode_operations; | 1062 | inode->i_op = &exofs_file_inode_operations; |
1035 | inode->i_fop = &exofs_file_operations; | 1063 | inode->i_fop = &exofs_file_operations; |
@@ -1073,6 +1101,7 @@ int __exofs_wait_obj_created(struct exofs_i_info *oi) | |||
1073 | } | 1101 | } |
1074 | return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0; | 1102 | return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0; |
1075 | } | 1103 | } |
1104 | |||
1076 | /* | 1105 | /* |
1077 | * Callback function from exofs_new_inode(). The important thing is that we | 1106 | * Callback function from exofs_new_inode(). The important thing is that we |
1078 | * set the obj_created flag so that other methods know that the object exists on | 1107 | * set the obj_created flag so that other methods know that the object exists on |
@@ -1130,7 +1159,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1130 | 1159 | ||
1131 | sbi = sb->s_fs_info; | 1160 | sbi = sb->s_fs_info; |
1132 | 1161 | ||
1133 | sb->s_dirt = 1; | 1162 | inode->i_mapping->backing_dev_info = sb->s_bdi; |
1134 | inode_init_owner(inode, dir, mode); | 1163 | inode_init_owner(inode, dir, mode); |
1135 | inode->i_ino = sbi->s_nextid++; | 1164 | inode->i_ino = sbi->s_nextid++; |
1136 | inode->i_blkbits = EXOFS_BLKSHIFT; | 1165 | inode->i_blkbits = EXOFS_BLKSHIFT; |
@@ -1141,6 +1170,8 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1141 | spin_unlock(&sbi->s_next_gen_lock); | 1170 | spin_unlock(&sbi->s_next_gen_lock); |
1142 | insert_inode_hash(inode); | 1171 | insert_inode_hash(inode); |
1143 | 1172 | ||
1173 | exofs_sbi_write_stats(sbi); /* Make sure new sbi->s_nextid is on disk */ | ||
1174 | |||
1144 | mark_inode_dirty(inode); | 1175 | mark_inode_dirty(inode); |
1145 | 1176 | ||
1146 | ret = exofs_get_io_state(&sbi->layout, &ios); | 1177 | ret = exofs_get_io_state(&sbi->layout, &ios); |
@@ -1271,7 +1302,8 @@ out: | |||
1271 | 1302 | ||
1272 | int exofs_write_inode(struct inode *inode, struct writeback_control *wbc) | 1303 | int exofs_write_inode(struct inode *inode, struct writeback_control *wbc) |
1273 | { | 1304 | { |
1274 | return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | 1305 | /* FIXME: fix fsync and use wbc->sync_mode == WB_SYNC_ALL */ |
1306 | return exofs_update_inode(inode, 1); | ||
1275 | } | 1307 | } |
1276 | 1308 | ||
1277 | /* | 1309 | /* |