^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) * bmap.c - NILFS block mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006-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 Koji Sato.
^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/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "nilfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "bmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "direct.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "btnode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "mdt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "dat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct the_nilfs *nilfs = bmap->b_inode->i_sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return nilfs->ns_dat;
^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 nilfs_bmap_convert_error(struct nilfs_bmap *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) const char *fname, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct inode *inode = bmap->b_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (err == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __nilfs_error(inode->i_sb, fname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "broken bmap (inode number=%lu)", inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * nilfs_bmap_lookup_at_level - find a data block or node block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @key: key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @level: level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @ptrp: place to store the value associated to @key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Description: nilfs_bmap_lookup_at_level() finds a record whose key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * matches @key in the block at @level of the bmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Return Value: On success, 0 is returned and the record associated with @key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * is stored in the place pointed by @ptrp. On error, one of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * %-ENOENT - A record associated with @key does not exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) __u64 *ptrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) sector_t blocknr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) down_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ret = nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (NILFS_BMAP_USE_VBN(bmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) &blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *ptrp = blocknr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) up_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int maxblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) down_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) up_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) __u64 keys[NILFS_BMAP_SMALL_HIGH + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) __u64 ptrs[NILFS_BMAP_SMALL_HIGH + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int ret, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (bmap->b_ops->bop_check_insert != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ret = bmap->b_ops->bop_check_insert(bmap, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) n = bmap->b_ops->bop_gather_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bmap, keys, ptrs, NILFS_BMAP_SMALL_HIGH + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = nilfs_btree_convert_and_insert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bmap, key, ptr, keys, ptrs, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bmap->b_u.u_flags |= NILFS_BMAP_LARGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) } else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return bmap->b_ops->bop_insert(bmap, key, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * nilfs_bmap_insert - insert a new key-record pair into a bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @key: key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @rec: record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Description: nilfs_bmap_insert() inserts the new key-record pair specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * by @key and @rec into @bmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Return Value: On success, 0 is returned. On error, one of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * %-EEXIST - A record associated with @key already exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = nilfs_bmap_do_insert(bmap, key, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) __u64 keys[NILFS_BMAP_LARGE_LOW + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) __u64 ptrs[NILFS_BMAP_LARGE_LOW + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int ret, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (bmap->b_ops->bop_check_delete != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ret = bmap->b_ops->bop_check_delete(bmap, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) n = bmap->b_ops->bop_gather_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) bmap, keys, ptrs, NILFS_BMAP_LARGE_LOW + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ret = nilfs_direct_delete_and_convert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) bmap, key, keys, ptrs, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) bmap->b_u.u_flags &= ~NILFS_BMAP_LARGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) } else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return bmap->b_ops->bop_delete(bmap, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * nilfs_bmap_seek_key - seek a valid entry and return its key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * @bmap: bmap struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * @start: start key number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * @keyp: place to store valid key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Description: nilfs_bmap_seek_key() seeks a valid key on @bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * starting from @start, and stores it to @keyp if found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * Return Value: On success, 0 is returned. On error, one of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * %-ENOENT - No valid entry was found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) down_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ret = bmap->b_ops->bop_seek_key(bmap, start, keyp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) up_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int nilfs_bmap_last_key(struct nilfs_bmap *bmap, __u64 *keyp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) down_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = bmap->b_ops->bop_last_key(bmap, keyp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) up_read(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * nilfs_bmap_delete - delete a key-record pair from a bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * @key: key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Description: nilfs_bmap_delete() deletes the key-record pair specified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @key from @bmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Return Value: On success, 0 is returned. On error, one of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * %-ENOENT - A record associated with @key does not exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = nilfs_bmap_do_delete(bmap, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, __u64 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) __u64 lastkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return ret;
^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) while (key <= lastkey) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = nilfs_bmap_do_delete(bmap, lastkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ret == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * nilfs_bmap_truncate - truncate a bmap to a specified key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * @key: key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * Description: nilfs_bmap_truncate() removes key-record pairs whose keys are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * greater than or equal to @key from @bmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * Return Value: On success, 0 is returned. On error, one of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int nilfs_bmap_truncate(struct nilfs_bmap *bmap, __u64 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ret = nilfs_bmap_do_truncate(bmap, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * nilfs_bmap_clear - free resources a bmap holds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * Description: nilfs_bmap_clear() frees resources associated with @bmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) void nilfs_bmap_clear(struct nilfs_bmap *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (bmap->b_ops->bop_clear != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) bmap->b_ops->bop_clear(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) up_write(&bmap->b_sem);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * nilfs_bmap_propagate - propagate dirty state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * @bh: buffer head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Description: nilfs_bmap_propagate() marks the buffers that directly or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * indirectly refer to the block specified by @bh dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Return Value: On success, 0 is returned. On error, one of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int nilfs_bmap_propagate(struct nilfs_bmap *bmap, struct buffer_head *bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ret = bmap->b_ops->bop_propagate(bmap, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * nilfs_bmap_lookup_dirty_buffers -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * @listp: pointer to buffer head list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct list_head *listp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (bmap->b_ops->bop_lookup_dirty_buffers != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) bmap->b_ops->bop_lookup_dirty_buffers(bmap, listp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * nilfs_bmap_assign - assign a new block number to a block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * @bh: pointer to buffer head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * @blocknr: block number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @binfo: block information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * Description: nilfs_bmap_assign() assigns the block number @blocknr to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * buffer specified by @bh.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * Return Value: On success, 0 is returned and the buffer head of a newly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * create buffer and the block information associated with the buffer are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * stored in the place pointed by @bh and @binfo, respectively. On error, one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * of the following negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int nilfs_bmap_assign(struct nilfs_bmap *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct buffer_head **bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) unsigned long blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) union nilfs_binfo *binfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^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) * nilfs_bmap_mark - mark block dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * @key: key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * @level: level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * Description: nilfs_bmap_mark() marks the block specified by @key and @level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * as dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * Return Value: On success, 0 is returned. On error, one of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * negative error codes is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * %-EIO - I/O error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int nilfs_bmap_mark(struct nilfs_bmap *bmap, __u64 key, int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (bmap->b_ops->bop_mark == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = bmap->b_ops->bop_mark(bmap, key, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return nilfs_bmap_convert_error(bmap, __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^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) * nilfs_bmap_test_and_clear_dirty - test and clear a bmap dirty state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * Description: nilfs_test_and_clear() is the atomic operation to test and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * clear the dirty state of @bmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * Return Value: 1 is returned if @bmap is dirty, or 0 if clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = nilfs_bmap_dirty(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) nilfs_bmap_clear_dirty(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^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) * Internal use only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) const struct buffer_head *bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct buffer_head *pbh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) __u64 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) key = page_index(bh->b_page) << (PAGE_SHIFT -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) bmap->b_inode->i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) for (pbh = page_buffers(bh->b_page); pbh != bh; pbh = pbh->b_this_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) key++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) __s64 diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) diff = key - bmap->b_last_allocated_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if ((nilfs_bmap_keydiff_abs(diff) < NILFS_INODE_BMAP_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) (bmap->b_last_allocated_ptr != NILFS_BMAP_INVALID_PTR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) (bmap->b_last_allocated_ptr + diff > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return bmap->b_last_allocated_ptr + diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return NILFS_BMAP_INVALID_PTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) #define NILFS_BMAP_GROUP_DIV 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct inode *dat = nilfs_bmap_get_dat(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unsigned long group = bmap->b_inode->i_ino / entries_per_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return group * entries_per_group +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) (entries_per_group / NILFS_BMAP_GROUP_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static struct lock_class_key nilfs_bmap_dat_lock_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static struct lock_class_key nilfs_bmap_mdt_lock_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * nilfs_bmap_read - read a bmap from an inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * @raw_inode: on-disk inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * Description: nilfs_bmap_read() initializes the bmap @bmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * Return Value: On success, 0 is returned. On error, the following negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * error code is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * %-ENOMEM - Insufficient amount of memory available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (raw_inode == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) memset(bmap->b_u.u_data, 0, NILFS_BMAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) memcpy(bmap->b_u.u_data, raw_inode->i_bmap, NILFS_BMAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) init_rwsem(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) bmap->b_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) switch (bmap->b_inode->i_ino) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case NILFS_DAT_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) bmap->b_ptr_type = NILFS_BMAP_PTR_P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) bmap->b_last_allocated_key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) case NILFS_CPFILE_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) case NILFS_SUFILE_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) bmap->b_ptr_type = NILFS_BMAP_PTR_VS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) bmap->b_last_allocated_key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) case NILFS_IFILE_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) bmap->b_ptr_type = NILFS_BMAP_PTR_VM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) bmap->b_last_allocated_key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return (bmap->b_u.u_flags & NILFS_BMAP_LARGE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) nilfs_btree_init(bmap) : nilfs_direct_init(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * nilfs_bmap_write - write back a bmap to an inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * @bmap: bmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * @raw_inode: on-disk inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * Description: nilfs_bmap_write() stores @bmap in @raw_inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) void nilfs_bmap_write(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) down_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) memcpy(raw_inode->i_bmap, bmap->b_u.u_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) NILFS_INODE_BMAP_SIZE * sizeof(__le64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (bmap->b_inode->i_ino == NILFS_DAT_INO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) up_write(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) void nilfs_bmap_init_gc(struct nilfs_bmap *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) memset(&bmap->b_u, 0, NILFS_BMAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) init_rwsem(&bmap->b_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) bmap->b_ptr_type = NILFS_BMAP_PTR_U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) bmap->b_last_allocated_key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) bmap->b_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) nilfs_btree_init_gc(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) void nilfs_bmap_save(const struct nilfs_bmap *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct nilfs_bmap_store *store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) memcpy(store->data, bmap->b_u.u_data, sizeof(store->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) store->last_allocated_key = bmap->b_last_allocated_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) store->last_allocated_ptr = bmap->b_last_allocated_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) store->state = bmap->b_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) void nilfs_bmap_restore(struct nilfs_bmap *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) const struct nilfs_bmap_store *store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) memcpy(bmap->b_u.u_data, store->data, sizeof(store->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) bmap->b_last_allocated_key = store->last_allocated_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) bmap->b_last_allocated_ptr = store->last_allocated_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) bmap->b_state = store->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }