Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }