668 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Meta data file for NILFS4 *5 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.6 *7 * Written by Ryusuke Konishi.8 */9 10#include <linux/buffer_head.h>11#include <linux/mpage.h>12#include <linux/mm.h>13#include <linux/writeback.h>14#include <linux/backing-dev.h>15#include <linux/swap.h>16#include <linux/slab.h>17#include "nilfs.h"18#include "btnode.h"19#include "segment.h"20#include "page.h"21#include "mdt.h"22#include "alloc.h" /* nilfs_palloc_destroy_cache() */23 24#include <trace/events/nilfs2.h>25 26#define NILFS_MDT_MAX_RA_BLOCKS (16 - 1)27 28 29static int30nilfs_mdt_insert_new_block(struct inode *inode, unsigned long block,31 struct buffer_head *bh,32 void (*init_block)(struct inode *,33 struct buffer_head *, void *))34{35 struct nilfs_inode_info *ii = NILFS_I(inode);36 void *kaddr;37 int ret;38 39 /* Caller exclude read accesses using page lock */40 41 /* set_buffer_new(bh); */42 bh->b_blocknr = 0;43 44 ret = nilfs_bmap_insert(ii->i_bmap, block, (unsigned long)bh);45 if (unlikely(ret))46 return ret;47 48 set_buffer_mapped(bh);49 50 kaddr = kmap_local_page(bh->b_page);51 memset(kaddr + bh_offset(bh), 0, i_blocksize(inode));52 if (init_block)53 init_block(inode, bh, kaddr);54 flush_dcache_page(bh->b_page);55 kunmap_local(kaddr);56 57 set_buffer_uptodate(bh);58 mark_buffer_dirty(bh);59 nilfs_mdt_mark_dirty(inode);60 61 trace_nilfs2_mdt_insert_new_block(inode, inode->i_ino, block);62 63 return 0;64}65 66static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,67 struct buffer_head **out_bh,68 void (*init_block)(struct inode *,69 struct buffer_head *,70 void *))71{72 struct super_block *sb = inode->i_sb;73 struct nilfs_transaction_info ti;74 struct buffer_head *bh;75 int err;76 77 nilfs_transaction_begin(sb, &ti, 0);78 79 err = -ENOMEM;80 bh = nilfs_grab_buffer(inode, inode->i_mapping, block, 0);81 if (unlikely(!bh))82 goto failed_unlock;83 84 err = -EEXIST;85 if (buffer_uptodate(bh))86 goto failed_bh;87 88 wait_on_buffer(bh);89 if (buffer_uptodate(bh))90 goto failed_bh;91 92 err = nilfs_mdt_insert_new_block(inode, block, bh, init_block);93 if (likely(!err)) {94 get_bh(bh);95 *out_bh = bh;96 }97 98 failed_bh:99 folio_unlock(bh->b_folio);100 folio_put(bh->b_folio);101 brelse(bh);102 103 failed_unlock:104 if (likely(!err))105 err = nilfs_transaction_commit(sb);106 else107 nilfs_transaction_abort(sb);108 109 return err;110}111 112static int113nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff, blk_opf_t opf,114 struct buffer_head **out_bh)115{116 struct buffer_head *bh;117 __u64 blknum = 0;118 int ret = -ENOMEM;119 120 bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0);121 if (unlikely(!bh))122 goto failed;123 124 ret = -EEXIST; /* internal code */125 if (buffer_uptodate(bh))126 goto out;127 128 if (opf & REQ_RAHEAD) {129 if (!trylock_buffer(bh)) {130 ret = -EBUSY;131 goto failed_bh;132 }133 } else /* opf == REQ_OP_READ */134 lock_buffer(bh);135 136 if (buffer_uptodate(bh)) {137 unlock_buffer(bh);138 goto out;139 }140 141 ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, &blknum);142 if (unlikely(ret)) {143 unlock_buffer(bh);144 goto failed_bh;145 }146 map_bh(bh, inode->i_sb, (sector_t)blknum);147 148 bh->b_end_io = end_buffer_read_sync;149 get_bh(bh);150 submit_bh(opf, bh);151 ret = 0;152 153 trace_nilfs2_mdt_submit_block(inode, inode->i_ino, blkoff,154 opf & REQ_OP_MASK);155 out:156 get_bh(bh);157 *out_bh = bh;158 159 failed_bh:160 folio_unlock(bh->b_folio);161 folio_put(bh->b_folio);162 brelse(bh);163 failed:164 return ret;165}166 167static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,168 int readahead, struct buffer_head **out_bh)169{170 struct buffer_head *first_bh, *bh;171 unsigned long blkoff;172 int i, nr_ra_blocks = NILFS_MDT_MAX_RA_BLOCKS;173 int err;174 175 err = nilfs_mdt_submit_block(inode, block, REQ_OP_READ, &first_bh);176 if (err == -EEXIST) /* internal code */177 goto out;178 179 if (unlikely(err))180 goto failed;181 182 if (readahead) {183 blkoff = block + 1;184 for (i = 0; i < nr_ra_blocks; i++, blkoff++) {185 err = nilfs_mdt_submit_block(inode, blkoff,186 REQ_OP_READ | REQ_RAHEAD, &bh);187 if (likely(!err || err == -EEXIST))188 brelse(bh);189 else if (err != -EBUSY)190 break;191 /* abort readahead if bmap lookup failed */192 if (!buffer_locked(first_bh))193 goto out_no_wait;194 }195 }196 197 wait_on_buffer(first_bh);198 199 out_no_wait:200 err = -EIO;201 if (!buffer_uptodate(first_bh)) {202 nilfs_err(inode->i_sb,203 "I/O error reading meta-data file (ino=%lu, block-offset=%lu)",204 inode->i_ino, block);205 goto failed_bh;206 }207 out:208 *out_bh = first_bh;209 return 0;210 211 failed_bh:212 brelse(first_bh);213 failed:214 return err;215}216 217/**218 * nilfs_mdt_get_block - read or create a buffer on meta data file.219 * @inode: inode of the meta data file220 * @blkoff: block offset221 * @create: create flag222 * @init_block: initializer used for newly allocated block223 * @out_bh: output of a pointer to the buffer_head224 *225 * nilfs_mdt_get_block() looks up the specified buffer and tries to create226 * a new buffer if @create is not zero. On success, the returned buffer is227 * assured to be either existing or formatted using a buffer lock on success.228 * @out_bh is substituted only when zero is returned.229 *230 * Return Value: On success, it returns 0. On error, the following negative231 * error code is returned.232 *233 * %-ENOMEM - Insufficient memory available.234 *235 * %-EIO - I/O error236 *237 * %-ENOENT - the specified block does not exist (hole block)238 *239 * %-EROFS - Read only filesystem (for create mode)240 */241int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,242 void (*init_block)(struct inode *,243 struct buffer_head *, void *),244 struct buffer_head **out_bh)245{246 int ret;247 248 /* Should be rewritten with merging nilfs_mdt_read_block() */249 retry:250 ret = nilfs_mdt_read_block(inode, blkoff, !create, out_bh);251 if (!create || ret != -ENOENT)252 return ret;253 254 ret = nilfs_mdt_create_block(inode, blkoff, out_bh, init_block);255 if (unlikely(ret == -EEXIST)) {256 /* create = 0; */ /* limit read-create loop retries */257 goto retry;258 }259 return ret;260}261 262/**263 * nilfs_mdt_find_block - find and get a buffer on meta data file.264 * @inode: inode of the meta data file265 * @start: start block offset (inclusive)266 * @end: end block offset (inclusive)267 * @blkoff: block offset268 * @out_bh: place to store a pointer to buffer_head struct269 *270 * nilfs_mdt_find_block() looks up an existing block in range of271 * [@start, @end] and stores pointer to a buffer head of the block to272 * @out_bh, and block offset to @blkoff, respectively. @out_bh and273 * @blkoff are substituted only when zero is returned.274 *275 * Return Value: On success, it returns 0. On error, the following negative276 * error code is returned.277 *278 * %-ENOMEM - Insufficient memory available.279 *280 * %-EIO - I/O error281 *282 * %-ENOENT - no block was found in the range283 */284int nilfs_mdt_find_block(struct inode *inode, unsigned long start,285 unsigned long end, unsigned long *blkoff,286 struct buffer_head **out_bh)287{288 __u64 next;289 int ret;290 291 if (unlikely(start > end))292 return -ENOENT;293 294 ret = nilfs_mdt_read_block(inode, start, true, out_bh);295 if (!ret) {296 *blkoff = start;297 goto out;298 }299 if (unlikely(ret != -ENOENT || start == ULONG_MAX))300 goto out;301 302 ret = nilfs_bmap_seek_key(NILFS_I(inode)->i_bmap, start + 1, &next);303 if (!ret) {304 if (next <= end) {305 ret = nilfs_mdt_read_block(inode, next, true, out_bh);306 if (!ret)307 *blkoff = next;308 } else {309 ret = -ENOENT;310 }311 }312out:313 return ret;314}315 316/**317 * nilfs_mdt_delete_block - make a hole on the meta data file.318 * @inode: inode of the meta data file319 * @block: block offset320 *321 * Return Value: On success, zero is returned.322 * On error, one of the following negative error code is returned.323 *324 * %-ENOMEM - Insufficient memory available.325 *326 * %-EIO - I/O error327 */328int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)329{330 struct nilfs_inode_info *ii = NILFS_I(inode);331 int err;332 333 err = nilfs_bmap_delete(ii->i_bmap, block);334 if (!err || err == -ENOENT) {335 nilfs_mdt_mark_dirty(inode);336 nilfs_mdt_forget_block(inode, block);337 }338 return err;339}340 341/**342 * nilfs_mdt_forget_block - discard dirty state and try to remove the page343 * @inode: inode of the meta data file344 * @block: block offset345 *346 * nilfs_mdt_forget_block() clears a dirty flag of the specified buffer, and347 * tries to release the page including the buffer from a page cache.348 *349 * Return Value: On success, 0 is returned. On error, one of the following350 * negative error code is returned.351 *352 * %-EBUSY - page has an active buffer.353 *354 * %-ENOENT - page cache has no page addressed by the offset.355 */356int nilfs_mdt_forget_block(struct inode *inode, unsigned long block)357{358 pgoff_t index = block >> (PAGE_SHIFT - inode->i_blkbits);359 struct folio *folio;360 struct buffer_head *bh;361 int ret = 0;362 int still_dirty;363 364 folio = filemap_lock_folio(inode->i_mapping, index);365 if (IS_ERR(folio))366 return -ENOENT;367 368 folio_wait_writeback(folio);369 370 bh = folio_buffers(folio);371 if (bh) {372 unsigned long first_block = index <<373 (PAGE_SHIFT - inode->i_blkbits);374 bh = get_nth_bh(bh, block - first_block);375 nilfs_forget_buffer(bh);376 }377 still_dirty = folio_test_dirty(folio);378 folio_unlock(folio);379 folio_put(folio);380 381 if (still_dirty ||382 invalidate_inode_pages2_range(inode->i_mapping, index, index) != 0)383 ret = -EBUSY;384 return ret;385}386 387int nilfs_mdt_fetch_dirty(struct inode *inode)388{389 struct nilfs_inode_info *ii = NILFS_I(inode);390 391 if (nilfs_bmap_test_and_clear_dirty(ii->i_bmap)) {392 set_bit(NILFS_I_DIRTY, &ii->i_state);393 return 1;394 }395 return test_bit(NILFS_I_DIRTY, &ii->i_state);396}397 398static int399nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)400{401 struct folio *folio = page_folio(page);402 struct inode *inode = folio->mapping->host;403 struct super_block *sb;404 int err = 0;405 406 if (inode && sb_rdonly(inode->i_sb)) {407 /*408 * It means that filesystem was remounted in read-only409 * mode because of error or metadata corruption. But we410 * have dirty folios that try to be flushed in background.411 * So, here we simply discard this dirty folio.412 */413 nilfs_clear_folio_dirty(folio);414 folio_unlock(folio);415 return -EROFS;416 }417 418 folio_redirty_for_writepage(wbc, folio);419 folio_unlock(folio);420 421 if (!inode)422 return 0;423 424 sb = inode->i_sb;425 426 if (wbc->sync_mode == WB_SYNC_ALL)427 err = nilfs_construct_segment(sb);428 else if (wbc->for_reclaim)429 nilfs_flush_segment(sb, inode->i_ino);430 431 return err;432}433 434 435static const struct address_space_operations def_mdt_aops = {436 .dirty_folio = block_dirty_folio,437 .invalidate_folio = block_invalidate_folio,438 .writepage = nilfs_mdt_write_page,439};440 441static const struct inode_operations def_mdt_iops;442static const struct file_operations def_mdt_fops;443 444 445int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz)446{447 struct nilfs_mdt_info *mi;448 449 mi = kzalloc(max(sizeof(*mi), objsz), GFP_NOFS);450 if (!mi)451 return -ENOMEM;452 453 init_rwsem(&mi->mi_sem);454 inode->i_private = mi;455 456 inode->i_mode = S_IFREG;457 mapping_set_gfp_mask(inode->i_mapping, gfp_mask);458 459 inode->i_op = &def_mdt_iops;460 inode->i_fop = &def_mdt_fops;461 inode->i_mapping->a_ops = &def_mdt_aops;462 463 return 0;464}465 466/**467 * nilfs_mdt_clear - do cleanup for the metadata file468 * @inode: inode of the metadata file469 */470void nilfs_mdt_clear(struct inode *inode)471{472 struct nilfs_mdt_info *mdi = NILFS_MDT(inode);473 struct nilfs_shadow_map *shadow = mdi->mi_shadow;474 475 if (mdi->mi_palloc_cache)476 nilfs_palloc_destroy_cache(inode);477 478 if (shadow) {479 struct inode *s_inode = shadow->inode;480 481 shadow->inode = NULL;482 iput(s_inode);483 mdi->mi_shadow = NULL;484 }485}486 487/**488 * nilfs_mdt_destroy - release resources used by the metadata file489 * @inode: inode of the metadata file490 */491void nilfs_mdt_destroy(struct inode *inode)492{493 struct nilfs_mdt_info *mdi = NILFS_MDT(inode);494 495 kfree(mdi->mi_bgl); /* kfree(NULL) is safe */496 kfree(mdi);497}498 499void nilfs_mdt_set_entry_size(struct inode *inode, unsigned int entry_size,500 unsigned int header_size)501{502 struct nilfs_mdt_info *mi = NILFS_MDT(inode);503 504 mi->mi_entry_size = entry_size;505 mi->mi_entries_per_block = i_blocksize(inode) / entry_size;506 mi->mi_first_entry_offset = DIV_ROUND_UP(header_size, entry_size);507}508 509/**510 * nilfs_mdt_setup_shadow_map - setup shadow map and bind it to metadata file511 * @inode: inode of the metadata file512 * @shadow: shadow mapping513 */514int nilfs_mdt_setup_shadow_map(struct inode *inode,515 struct nilfs_shadow_map *shadow)516{517 struct nilfs_mdt_info *mi = NILFS_MDT(inode);518 struct inode *s_inode;519 520 INIT_LIST_HEAD(&shadow->frozen_buffers);521 522 s_inode = nilfs_iget_for_shadow(inode);523 if (IS_ERR(s_inode))524 return PTR_ERR(s_inode);525 526 shadow->inode = s_inode;527 mi->mi_shadow = shadow;528 return 0;529}530 531/**532 * nilfs_mdt_save_to_shadow_map - copy bmap and dirty pages to shadow map533 * @inode: inode of the metadata file534 */535int nilfs_mdt_save_to_shadow_map(struct inode *inode)536{537 struct nilfs_mdt_info *mi = NILFS_MDT(inode);538 struct nilfs_inode_info *ii = NILFS_I(inode);539 struct nilfs_shadow_map *shadow = mi->mi_shadow;540 struct inode *s_inode = shadow->inode;541 int ret;542 543 ret = nilfs_copy_dirty_pages(s_inode->i_mapping, inode->i_mapping);544 if (ret)545 goto out;546 547 ret = nilfs_copy_dirty_pages(NILFS_I(s_inode)->i_assoc_inode->i_mapping,548 ii->i_assoc_inode->i_mapping);549 if (ret)550 goto out;551 552 nilfs_bmap_save(ii->i_bmap, &shadow->bmap_store);553 out:554 return ret;555}556 557int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)558{559 struct nilfs_shadow_map *shadow = NILFS_MDT(inode)->mi_shadow;560 struct buffer_head *bh_frozen;561 struct folio *folio;562 int blkbits = inode->i_blkbits;563 564 folio = filemap_grab_folio(shadow->inode->i_mapping,565 bh->b_folio->index);566 if (IS_ERR(folio))567 return PTR_ERR(folio);568 569 bh_frozen = folio_buffers(folio);570 if (!bh_frozen)571 bh_frozen = create_empty_buffers(folio, 1 << blkbits, 0);572 573 bh_frozen = get_nth_bh(bh_frozen, bh_offset(bh) >> blkbits);574 575 if (!buffer_uptodate(bh_frozen))576 nilfs_copy_buffer(bh_frozen, bh);577 if (list_empty(&bh_frozen->b_assoc_buffers)) {578 list_add_tail(&bh_frozen->b_assoc_buffers,579 &shadow->frozen_buffers);580 set_buffer_nilfs_redirected(bh);581 } else {582 brelse(bh_frozen); /* already frozen */583 }584 585 folio_unlock(folio);586 folio_put(folio);587 return 0;588}589 590struct buffer_head *591nilfs_mdt_get_frozen_buffer(struct inode *inode, struct buffer_head *bh)592{593 struct nilfs_shadow_map *shadow = NILFS_MDT(inode)->mi_shadow;594 struct buffer_head *bh_frozen = NULL;595 struct folio *folio;596 int n;597 598 folio = filemap_lock_folio(shadow->inode->i_mapping,599 bh->b_folio->index);600 if (!IS_ERR(folio)) {601 bh_frozen = folio_buffers(folio);602 if (bh_frozen) {603 n = bh_offset(bh) >> inode->i_blkbits;604 bh_frozen = get_nth_bh(bh_frozen, n);605 }606 folio_unlock(folio);607 folio_put(folio);608 }609 return bh_frozen;610}611 612static void nilfs_release_frozen_buffers(struct nilfs_shadow_map *shadow)613{614 struct list_head *head = &shadow->frozen_buffers;615 struct buffer_head *bh;616 617 while (!list_empty(head)) {618 bh = list_first_entry(head, struct buffer_head,619 b_assoc_buffers);620 list_del_init(&bh->b_assoc_buffers);621 brelse(bh); /* drop ref-count to make it releasable */622 }623}624 625/**626 * nilfs_mdt_restore_from_shadow_map - restore dirty pages and bmap state627 * @inode: inode of the metadata file628 */629void nilfs_mdt_restore_from_shadow_map(struct inode *inode)630{631 struct nilfs_mdt_info *mi = NILFS_MDT(inode);632 struct nilfs_inode_info *ii = NILFS_I(inode);633 struct nilfs_shadow_map *shadow = mi->mi_shadow;634 635 down_write(&mi->mi_sem);636 637 if (mi->mi_palloc_cache)638 nilfs_palloc_clear_cache(inode);639 640 nilfs_clear_dirty_pages(inode->i_mapping);641 nilfs_copy_back_pages(inode->i_mapping, shadow->inode->i_mapping);642 643 nilfs_clear_dirty_pages(ii->i_assoc_inode->i_mapping);644 nilfs_copy_back_pages(ii->i_assoc_inode->i_mapping,645 NILFS_I(shadow->inode)->i_assoc_inode->i_mapping);646 647 nilfs_bmap_restore(ii->i_bmap, &shadow->bmap_store);648 649 up_write(&mi->mi_sem);650}651 652/**653 * nilfs_mdt_clear_shadow_map - truncate pages in shadow map caches654 * @inode: inode of the metadata file655 */656void nilfs_mdt_clear_shadow_map(struct inode *inode)657{658 struct nilfs_mdt_info *mi = NILFS_MDT(inode);659 struct nilfs_shadow_map *shadow = mi->mi_shadow;660 struct inode *shadow_btnc_inode = NILFS_I(shadow->inode)->i_assoc_inode;661 662 down_write(&mi->mi_sem);663 nilfs_release_frozen_buffers(shadow);664 truncate_inode_pages(shadow->inode->i_mapping, 0);665 truncate_inode_pages(shadow_btnc_inode->i_mapping, 0);666 up_write(&mi->mi_sem);667}668