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