.. | .. |
---|
79 | 79 | size_t n = min_t(size_t, count, |
---|
80 | 80 | PAGE_SIZE - offset_in_page(pos)); |
---|
81 | 81 | struct page *page; |
---|
82 | | - void *fsdata; |
---|
83 | | - void *addr; |
---|
| 82 | + void *fsdata = NULL; |
---|
84 | 83 | int res; |
---|
85 | 84 | |
---|
86 | 85 | res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0, |
---|
.. | .. |
---|
88 | 87 | if (res) |
---|
89 | 88 | return res; |
---|
90 | 89 | |
---|
91 | | - addr = kmap_atomic(page); |
---|
92 | | - memcpy(addr + offset_in_page(pos), buf, n); |
---|
93 | | - kunmap_atomic(addr); |
---|
| 90 | + memcpy_to_page(page, offset_in_page(pos), buf, n); |
---|
94 | 91 | |
---|
95 | 92 | res = pagecache_write_end(NULL, inode->i_mapping, pos, n, n, |
---|
96 | 93 | page, fsdata); |
---|
.. | .. |
---|
112 | 109 | const int credits = 2; /* superblock and inode for ext4_orphan_add() */ |
---|
113 | 110 | handle_t *handle; |
---|
114 | 111 | int err; |
---|
| 112 | + |
---|
| 113 | + if (IS_DAX(inode) || ext4_test_inode_flag(inode, EXT4_INODE_DAX)) |
---|
| 114 | + return -EINVAL; |
---|
115 | 115 | |
---|
116 | 116 | if (ext4_verity_in_progress(inode)) |
---|
117 | 117 | return -EBUSY; |
---|
.. | .. |
---|
198 | 198 | struct inode *inode = file_inode(filp); |
---|
199 | 199 | const int credits = 2; /* superblock and inode for ext4_orphan_del() */ |
---|
200 | 200 | handle_t *handle; |
---|
| 201 | + struct ext4_iloc iloc; |
---|
201 | 202 | int err = 0; |
---|
202 | | - int err2; |
---|
203 | | - |
---|
204 | | - if (desc != NULL) { |
---|
205 | | - /* Succeeded; write the verity descriptor. */ |
---|
206 | | - err = ext4_write_verity_descriptor(inode, desc, desc_size, |
---|
207 | | - merkle_tree_size); |
---|
208 | | - |
---|
209 | | - /* Write all pages before clearing VERITY_IN_PROGRESS. */ |
---|
210 | | - if (!err) |
---|
211 | | - err = filemap_write_and_wait(inode->i_mapping); |
---|
212 | | - } |
---|
213 | | - |
---|
214 | | - /* If we failed, truncate anything we wrote past i_size. */ |
---|
215 | | - if (desc == NULL || err) |
---|
216 | | - ext4_truncate(inode); |
---|
217 | 203 | |
---|
218 | 204 | /* |
---|
219 | | - * We must always clean up by clearing EXT4_STATE_VERITY_IN_PROGRESS and |
---|
220 | | - * deleting the inode from the orphan list, even if something failed. |
---|
221 | | - * If everything succeeded, we'll also set the verity bit in the same |
---|
222 | | - * transaction. |
---|
| 205 | + * If an error already occurred (which fs/verity/ signals by passing |
---|
| 206 | + * desc == NULL), then only clean-up is needed. |
---|
223 | 207 | */ |
---|
| 208 | + if (desc == NULL) |
---|
| 209 | + goto cleanup; |
---|
224 | 210 | |
---|
225 | | - ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); |
---|
| 211 | + /* Append the verity descriptor. */ |
---|
| 212 | + err = ext4_write_verity_descriptor(inode, desc, desc_size, |
---|
| 213 | + merkle_tree_size); |
---|
| 214 | + if (err) |
---|
| 215 | + goto cleanup; |
---|
| 216 | + |
---|
| 217 | + /* |
---|
| 218 | + * Write all pages (both data and verity metadata). Note that this must |
---|
| 219 | + * happen before clearing EXT4_STATE_VERITY_IN_PROGRESS; otherwise pages |
---|
| 220 | + * beyond i_size won't be written properly. For crash consistency, this |
---|
| 221 | + * also must happen before the verity inode flag gets persisted. |
---|
| 222 | + */ |
---|
| 223 | + err = filemap_write_and_wait(inode->i_mapping); |
---|
| 224 | + if (err) |
---|
| 225 | + goto cleanup; |
---|
| 226 | + |
---|
| 227 | + /* |
---|
| 228 | + * Finally, set the verity inode flag and remove the inode from the |
---|
| 229 | + * orphan list (in a single transaction). |
---|
| 230 | + */ |
---|
226 | 231 | |
---|
227 | 232 | handle = ext4_journal_start(inode, EXT4_HT_INODE, credits); |
---|
228 | 233 | if (IS_ERR(handle)) { |
---|
229 | | - ext4_orphan_del(NULL, inode); |
---|
230 | | - return PTR_ERR(handle); |
---|
| 234 | + err = PTR_ERR(handle); |
---|
| 235 | + goto cleanup; |
---|
231 | 236 | } |
---|
232 | 237 | |
---|
233 | | - err2 = ext4_orphan_del(handle, inode); |
---|
234 | | - if (err2) |
---|
235 | | - goto out_stop; |
---|
| 238 | + err = ext4_orphan_del(handle, inode); |
---|
| 239 | + if (err) |
---|
| 240 | + goto stop_and_cleanup; |
---|
236 | 241 | |
---|
237 | | - if (desc != NULL && !err) { |
---|
238 | | - struct ext4_iloc iloc; |
---|
| 242 | + err = ext4_reserve_inode_write(handle, inode, &iloc); |
---|
| 243 | + if (err) |
---|
| 244 | + goto stop_and_cleanup; |
---|
239 | 245 | |
---|
240 | | - err = ext4_reserve_inode_write(handle, inode, &iloc); |
---|
241 | | - if (err) |
---|
242 | | - goto out_stop; |
---|
243 | | - ext4_set_inode_flag(inode, EXT4_INODE_VERITY); |
---|
244 | | - ext4_set_inode_flags(inode); |
---|
245 | | - err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
---|
246 | | - } |
---|
247 | | -out_stop: |
---|
| 246 | + ext4_set_inode_flag(inode, EXT4_INODE_VERITY); |
---|
| 247 | + ext4_set_inode_flags(inode, false); |
---|
| 248 | + err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
---|
| 249 | + if (err) |
---|
| 250 | + goto stop_and_cleanup; |
---|
| 251 | + |
---|
248 | 252 | ext4_journal_stop(handle); |
---|
249 | | - return err ?: err2; |
---|
| 253 | + |
---|
| 254 | + ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); |
---|
| 255 | + return 0; |
---|
| 256 | + |
---|
| 257 | +stop_and_cleanup: |
---|
| 258 | + ext4_journal_stop(handle); |
---|
| 259 | +cleanup: |
---|
| 260 | + /* |
---|
| 261 | + * Verity failed to be enabled, so clean up by truncating any verity |
---|
| 262 | + * metadata that was written beyond i_size (both from cache and from |
---|
| 263 | + * disk), removing the inode from the orphan list (if it wasn't done |
---|
| 264 | + * already), and clearing EXT4_STATE_VERITY_IN_PROGRESS. |
---|
| 265 | + */ |
---|
| 266 | + truncate_inode_pages(inode->i_mapping, inode->i_size); |
---|
| 267 | + ext4_truncate(inode); |
---|
| 268 | + ext4_orphan_del(NULL, inode); |
---|
| 269 | + ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS); |
---|
| 270 | + return err; |
---|
250 | 271 | } |
---|
251 | 272 | |
---|
252 | 273 | static int ext4_get_verity_descriptor_location(struct inode *inode, |
---|
.. | .. |
---|
342 | 363 | return desc_size; |
---|
343 | 364 | } |
---|
344 | 365 | |
---|
345 | | -/* |
---|
346 | | - * Prefetch some pages from the file's Merkle tree. |
---|
347 | | - * |
---|
348 | | - * This is basically a stripped-down version of __do_page_cache_readahead() |
---|
349 | | - * which works on pages past i_size. |
---|
350 | | - */ |
---|
351 | | -static void ext4_merkle_tree_readahead(struct address_space *mapping, |
---|
352 | | - pgoff_t start_index, unsigned long count) |
---|
353 | | -{ |
---|
354 | | - LIST_HEAD(pages); |
---|
355 | | - unsigned int nr_pages = 0; |
---|
356 | | - struct page *page; |
---|
357 | | - pgoff_t index; |
---|
358 | | - struct blk_plug plug; |
---|
359 | | - |
---|
360 | | - for (index = start_index; index < start_index + count; index++) { |
---|
361 | | - rcu_read_lock(); |
---|
362 | | - page = radix_tree_lookup(&mapping->i_pages, index); |
---|
363 | | - rcu_read_unlock(); |
---|
364 | | - if (!page || radix_tree_exceptional_entry(page)) { |
---|
365 | | - page = __page_cache_alloc(readahead_gfp_mask(mapping)); |
---|
366 | | - if (!page) |
---|
367 | | - break; |
---|
368 | | - page->index = index; |
---|
369 | | - list_add(&page->lru, &pages); |
---|
370 | | - nr_pages++; |
---|
371 | | - } |
---|
372 | | - } |
---|
373 | | - blk_start_plug(&plug); |
---|
374 | | - ext4_mpage_readpages(mapping, &pages, NULL, nr_pages, true); |
---|
375 | | - blk_finish_plug(&plug); |
---|
376 | | -} |
---|
377 | | - |
---|
378 | 366 | static struct page *ext4_read_merkle_tree_page(struct inode *inode, |
---|
379 | 367 | pgoff_t index, |
---|
380 | 368 | unsigned long num_ra_pages) |
---|
.. | .. |
---|
385 | 373 | |
---|
386 | 374 | page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED); |
---|
387 | 375 | if (!page || !PageUptodate(page)) { |
---|
| 376 | + DEFINE_READAHEAD(ractl, NULL, inode->i_mapping, index); |
---|
| 377 | + |
---|
388 | 378 | if (page) |
---|
389 | 379 | put_page(page); |
---|
390 | 380 | else if (num_ra_pages > 1) |
---|
391 | | - ext4_merkle_tree_readahead(inode->i_mapping, index, |
---|
392 | | - num_ra_pages); |
---|
| 381 | + page_cache_ra_unbounded(&ractl, num_ra_pages, 0); |
---|
393 | 382 | page = read_mapping_page(inode->i_mapping, index, NULL); |
---|
394 | 383 | } |
---|
395 | 384 | return page; |
---|