diff options
Diffstat (limited to 'fs/logfs/readwrite.c')
| -rw-r--r-- | fs/logfs/readwrite.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 3159db6958e5..0718d112a1a5 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
| @@ -892,6 +892,8 @@ u64 logfs_seek_hole(struct inode *inode, u64 bix) | |||
| 892 | return bix; | 892 | return bix; |
| 893 | else if (li->li_data[INDIRECT_INDEX] & LOGFS_FULLY_POPULATED) | 893 | else if (li->li_data[INDIRECT_INDEX] & LOGFS_FULLY_POPULATED) |
| 894 | bix = maxbix(li->li_height); | 894 | bix = maxbix(li->li_height); |
| 895 | else if (bix >= maxbix(li->li_height)) | ||
| 896 | return bix; | ||
| 895 | else { | 897 | else { |
| 896 | bix = seek_holedata_loop(inode, bix, 0); | 898 | bix = seek_holedata_loop(inode, bix, 0); |
| 897 | if (bix < maxbix(li->li_height)) | 899 | if (bix < maxbix(li->li_height)) |
| @@ -1093,17 +1095,25 @@ static int logfs_reserve_bytes(struct inode *inode, int bytes) | |||
| 1093 | int get_page_reserve(struct inode *inode, struct page *page) | 1095 | int get_page_reserve(struct inode *inode, struct page *page) |
| 1094 | { | 1096 | { |
| 1095 | struct logfs_super *super = logfs_super(inode->i_sb); | 1097 | struct logfs_super *super = logfs_super(inode->i_sb); |
| 1098 | struct logfs_block *block = logfs_block(page); | ||
| 1096 | int ret; | 1099 | int ret; |
| 1097 | 1100 | ||
| 1098 | if (logfs_block(page) && logfs_block(page)->reserved_bytes) | 1101 | if (block && block->reserved_bytes) |
| 1099 | return 0; | 1102 | return 0; |
| 1100 | 1103 | ||
| 1101 | logfs_get_wblocks(inode->i_sb, page, WF_LOCK); | 1104 | logfs_get_wblocks(inode->i_sb, page, WF_LOCK); |
| 1102 | ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE); | 1105 | while ((ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE)) && |
| 1106 | !list_empty(&super->s_writeback_list)) { | ||
| 1107 | block = list_entry(super->s_writeback_list.next, | ||
| 1108 | struct logfs_block, alias_list); | ||
| 1109 | block->ops->write_block(block); | ||
| 1110 | } | ||
| 1103 | if (!ret) { | 1111 | if (!ret) { |
| 1104 | alloc_data_block(inode, page); | 1112 | alloc_data_block(inode, page); |
| 1105 | logfs_block(page)->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE; | 1113 | block = logfs_block(page); |
| 1114 | block->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE; | ||
| 1106 | super->s_dirty_pages += 6 * LOGFS_MAX_OBJECTSIZE; | 1115 | super->s_dirty_pages += 6 * LOGFS_MAX_OBJECTSIZE; |
| 1116 | list_move_tail(&block->alias_list, &super->s_writeback_list); | ||
| 1107 | } | 1117 | } |
| 1108 | logfs_put_wblocks(inode->i_sb, page, WF_LOCK); | 1118 | logfs_put_wblocks(inode->i_sb, page, WF_LOCK); |
| 1109 | return ret; | 1119 | return ret; |
| @@ -1861,7 +1871,7 @@ int logfs_truncate(struct inode *inode, u64 target) | |||
| 1861 | size = target; | 1871 | size = target; |
| 1862 | 1872 | ||
| 1863 | logfs_get_wblocks(sb, NULL, 1); | 1873 | logfs_get_wblocks(sb, NULL, 1); |
| 1864 | err = __logfs_truncate(inode, target); | 1874 | err = __logfs_truncate(inode, size); |
| 1865 | if (!err) | 1875 | if (!err) |
| 1866 | err = __logfs_write_inode(inode, 0); | 1876 | err = __logfs_write_inode(inode, 0); |
| 1867 | logfs_put_wblocks(sb, NULL, 1); | 1877 | logfs_put_wblocks(sb, NULL, 1); |
| @@ -2249,6 +2259,7 @@ int logfs_init_rw(struct super_block *sb) | |||
| 2249 | int min_fill = 3 * super->s_no_blocks; | 2259 | int min_fill = 3 * super->s_no_blocks; |
| 2250 | 2260 | ||
| 2251 | INIT_LIST_HEAD(&super->s_object_alias); | 2261 | INIT_LIST_HEAD(&super->s_object_alias); |
| 2262 | INIT_LIST_HEAD(&super->s_writeback_list); | ||
| 2252 | mutex_init(&super->s_write_mutex); | 2263 | mutex_init(&super->s_write_mutex); |
| 2253 | super->s_block_pool = mempool_create_kmalloc_pool(min_fill, | 2264 | super->s_block_pool = mempool_create_kmalloc_pool(min_fill, |
| 2254 | sizeof(struct logfs_block)); | 2265 | sizeof(struct logfs_block)); |
