^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) * alloc.c - NILFS dat/inode allocator
^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) * Originally written by Koji Sato.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Two allocators were unified by Ryusuke Konishi and Amagai Yoshiji.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "mdt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * nilfs_palloc_groups_per_desc_block - get the number of groups that a group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * descriptor block can maintain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) nilfs_palloc_groups_per_desc_block(const struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return i_blocksize(inode) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) sizeof(struct nilfs_palloc_group_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * nilfs_palloc_groups_count - get maximum number of groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) nilfs_palloc_groups_count(const struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return 1UL << (BITS_PER_LONG - (inode->i_blkbits + 3 /* log2(8) */));
^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_palloc_init_blockgroup - initialize private variables for allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @entry_size: size of the persistent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned int entry_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct nilfs_mdt_info *mi = NILFS_MDT(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mi->mi_bgl = kmalloc(sizeof(*mi->mi_bgl), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (!mi->mi_bgl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) bgl_lock_init(mi->mi_bgl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) nilfs_mdt_set_entry_size(inode, entry_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mi->mi_blocks_per_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) DIV_ROUND_UP(nilfs_palloc_entries_per_group(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mi->mi_entries_per_block) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Number of blocks in a group including entry blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * and a bitmap block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) mi->mi_blocks_per_desc_block =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) nilfs_palloc_groups_per_desc_block(inode) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mi->mi_blocks_per_group + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Number of blocks per descriptor including the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * descriptor block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * nilfs_palloc_group - get group number and offset from an entry number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * @nr: serial number of the entry (e.g. inode number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @offset: pointer to store offset number in the group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static unsigned long nilfs_palloc_group(const struct inode *inode, __u64 nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) __u64 group = nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *offset = do_div(group, nilfs_palloc_entries_per_group(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * nilfs_palloc_desc_blkoff - get block offset of a group descriptor block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @group: group number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * nilfs_palloc_desc_blkoff() returns block offset of the descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * block which contains a descriptor of the specified group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) nilfs_palloc_desc_blkoff(const struct inode *inode, unsigned long group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned long desc_block =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) group / nilfs_palloc_groups_per_desc_block(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return desc_block * NILFS_MDT(inode)->mi_blocks_per_desc_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * nilfs_palloc_bitmap_blkoff - get block offset of a bitmap block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @group: group number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * nilfs_palloc_bitmap_blkoff() returns block offset of the bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * block used to allocate/deallocate entries in the specified group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) nilfs_palloc_bitmap_blkoff(const struct inode *inode, unsigned long group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned long desc_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) group % nilfs_palloc_groups_per_desc_block(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return nilfs_palloc_desc_blkoff(inode, group) + 1 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) desc_offset * NILFS_MDT(inode)->mi_blocks_per_group;
^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_palloc_group_desc_nfrees - get the number of free entries in a group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @desc: pointer to descriptor structure for the group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @lock: spin lock protecting @desc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) nilfs_palloc_group_desc_nfrees(const struct nilfs_palloc_group_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned long nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) spin_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) nfree = le32_to_cpu(desc->pg_nfrees);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) spin_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^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) * nilfs_palloc_group_desc_add_entries - adjust count of free entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @desc: pointer to descriptor structure for the group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @lock: spin lock protecting @desc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @n: delta to be added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) nilfs_palloc_group_desc_add_entries(struct nilfs_palloc_group_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) spinlock_t *lock, u32 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u32 nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) spin_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) le32_add_cpu(&desc->pg_nfrees, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) nfree = le32_to_cpu(desc->pg_nfrees);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) spin_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * nilfs_palloc_entry_blkoff - get block offset of an entry block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * @nr: serial number of the entry (e.g. inode number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) nilfs_palloc_entry_blkoff(const struct inode *inode, __u64 nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned long group, group_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) group = nilfs_palloc_group(inode, nr, &group_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return nilfs_palloc_bitmap_blkoff(inode, group) + 1 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) group_offset / NILFS_MDT(inode)->mi_entries_per_block;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * nilfs_palloc_desc_block_init - initialize buffer of a group descriptor block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * @inode: inode of metadata file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * @bh: buffer head of the buffer to be initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * @kaddr: kernel address mapped for the page including the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static void nilfs_palloc_desc_block_init(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct buffer_head *bh, void *kaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct nilfs_palloc_group_desc *desc = kaddr + bh_offset(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned long n = nilfs_palloc_groups_per_desc_block(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) __le32 nfrees;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) nfrees = cpu_to_le32(nilfs_palloc_entries_per_group(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) while (n-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) desc->pg_nfrees = nfrees;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) desc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^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) static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void (*init_block)(struct inode *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct buffer_head *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) void *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct buffer_head **bhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct nilfs_bh_assoc *prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) spin_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (prev->bh && blkoff == prev->blkoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) get_bh(prev->bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) *bhp = prev->bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) spin_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) spin_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret = nilfs_mdt_get_block(inode, blkoff, create, init_block, bhp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) spin_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * The following code must be safe for change of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * cache contents during the get block call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) brelse(prev->bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) get_bh(*bhp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) prev->bh = *bhp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) prev->blkoff = blkoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) spin_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * nilfs_palloc_delete_block - delete a block on the persistent allocator file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @blkoff: block offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @prev: nilfs_bh_assoc struct of the last used buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @lock: spin lock protecting @prev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int nilfs_palloc_delete_block(struct inode *inode, unsigned long blkoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct nilfs_bh_assoc *prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) spin_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (prev->bh && blkoff == prev->blkoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) brelse(prev->bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) prev->bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) spin_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return nilfs_mdt_delete_block(inode, blkoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * nilfs_palloc_get_desc_block - get buffer head of a group descriptor block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * @group: group number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @create: create flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @bhp: pointer to store the resultant buffer head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int nilfs_palloc_get_desc_block(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned long group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int create, struct buffer_head **bhp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return nilfs_palloc_get_block(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) nilfs_palloc_desc_blkoff(inode, group),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) create, nilfs_palloc_desc_block_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) bhp, &cache->prev_desc, &cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * nilfs_palloc_get_bitmap_block - get buffer head of a bitmap block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * @group: group number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * @create: create flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * @bhp: pointer to store the resultant buffer head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int nilfs_palloc_get_bitmap_block(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned long group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int create, struct buffer_head **bhp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return nilfs_palloc_get_block(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) nilfs_palloc_bitmap_blkoff(inode, group),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) create, NULL, bhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) &cache->prev_bitmap, &cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * nilfs_palloc_delete_bitmap_block - delete a bitmap block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @group: group number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static int nilfs_palloc_delete_bitmap_block(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) unsigned long group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return nilfs_palloc_delete_block(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) nilfs_palloc_bitmap_blkoff(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) group),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) &cache->prev_bitmap, &cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * nilfs_palloc_get_entry_block - get buffer head of an entry block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * @nr: serial number of the entry (e.g. inode number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * @create: create flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * @bhp: pointer to store the resultant buffer head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int create, struct buffer_head **bhp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return nilfs_palloc_get_block(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) nilfs_palloc_entry_blkoff(inode, nr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) create, NULL, bhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) &cache->prev_entry, &cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * nilfs_palloc_delete_entry_block - delete an entry block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * @nr: serial number of the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int nilfs_palloc_delete_entry_block(struct inode *inode, __u64 nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return nilfs_palloc_delete_block(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) nilfs_palloc_entry_blkoff(inode, nr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) &cache->prev_entry, &cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * nilfs_palloc_block_get_group_desc - get kernel address of a group descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * @group: group number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * @bh: buffer head of the buffer storing the group descriptor block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * @kaddr: kernel address mapped for the page including the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static struct nilfs_palloc_group_desc *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) nilfs_palloc_block_get_group_desc(const struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) unsigned long group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) const struct buffer_head *bh, void *kaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return (struct nilfs_palloc_group_desc *)(kaddr + bh_offset(bh)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) group % nilfs_palloc_groups_per_desc_block(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^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) * nilfs_palloc_block_get_entry - get kernel address of an entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * @nr: serial number of the entry (e.g. inode number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * @bh: buffer head of the buffer storing the entry block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * @kaddr: kernel address mapped for the page including the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) const struct buffer_head *bh, void *kaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned long entry_offset, group_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) nilfs_palloc_group(inode, nr, &group_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) entry_offset = group_offset % NILFS_MDT(inode)->mi_entries_per_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return kaddr + bh_offset(bh) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) entry_offset * NILFS_MDT(inode)->mi_entry_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * nilfs_palloc_find_available_slot - find available slot in a group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * @bitmap: bitmap of the group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * @target: offset number of an entry in the group (start point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * @bsize: size in bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * @lock: spin lock protecting @bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int nilfs_palloc_find_available_slot(unsigned char *bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) unsigned long target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned int bsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int pos, end = bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (likely(target < bsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pos = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pos = nilfs_find_next_zero_bit(bitmap, end, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (pos >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (!nilfs_set_bit_atomic(lock, pos, bitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) } while (++pos < end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) end = target;
^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) /* wrap around */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) for (pos = 0; pos < end; pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) pos = nilfs_find_next_zero_bit(bitmap, end, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (pos >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (!nilfs_set_bit_atomic(lock, pos, bitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * nilfs_palloc_rest_groups_in_desc_block - get the remaining number of groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * in a group descriptor block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * @curr: current group number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * @max: maximum number of groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) unsigned long curr, unsigned long max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return min_t(unsigned long,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) nilfs_palloc_groups_per_desc_block(inode) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) curr % nilfs_palloc_groups_per_desc_block(inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) max - curr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * nilfs_palloc_count_desc_blocks - count descriptor blocks number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * @desc_blocks: descriptor blocks number [out]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int nilfs_palloc_count_desc_blocks(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned long *desc_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) __u64 blknum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = nilfs_bmap_last_key(NILFS_I(inode)->i_bmap, &blknum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (likely(!ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) *desc_blocks = DIV_ROUND_UP(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) (unsigned long)blknum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) NILFS_MDT(inode)->mi_blocks_per_desc_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * nilfs_palloc_mdt_file_can_grow - check potential opportunity for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * MDT file growing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * @desc_blocks: known current descriptor blocks count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static inline bool nilfs_palloc_mdt_file_can_grow(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) unsigned long desc_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return (nilfs_palloc_groups_per_desc_block(inode) * desc_blocks) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) nilfs_palloc_groups_count(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * nilfs_palloc_count_max_entries - count max number of entries that can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * described by descriptor blocks count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * @nused: current number of used entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * @nmaxp: max number of entries [out]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int nilfs_palloc_count_max_entries(struct inode *inode, u64 nused, u64 *nmaxp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) unsigned long desc_blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u64 entries_per_desc_block, nmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) err = nilfs_palloc_count_desc_blocks(inode, &desc_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) entries_per_desc_block = (u64)nilfs_palloc_entries_per_group(inode) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) nilfs_palloc_groups_per_desc_block(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) nmax = entries_per_desc_block * desc_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (nused == nmax &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) nilfs_palloc_mdt_file_can_grow(inode, desc_blocks))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) nmax += entries_per_desc_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (nused > nmax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *nmaxp = nmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * nilfs_palloc_prepare_alloc_entry - prepare to allocate a persistent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * @req: nilfs_palloc_req structure exchanged for the allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct nilfs_palloc_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct buffer_head *desc_bh, *bitmap_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct nilfs_palloc_group_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) unsigned char *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) void *desc_kaddr, *bitmap_kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) unsigned long group, maxgroup, ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) unsigned long group_offset, maxgroup_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned long n, entries_per_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) unsigned long i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int pos, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ngroups = nilfs_palloc_groups_count(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) maxgroup = ngroups - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) entries_per_group = nilfs_palloc_entries_per_group(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) for (i = 0; i < ngroups; i += n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (group >= ngroups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* wrap around */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) group = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) maxgroup = nilfs_palloc_group(inode, req->pr_entry_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) &maxgroup_offset) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ret = nilfs_palloc_get_desc_block(inode, group, 1, &desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) desc_kaddr = kmap(desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) desc = nilfs_palloc_block_get_group_desc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) inode, group, desc_bh, desc_kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) n = nilfs_palloc_rest_groups_in_desc_block(inode, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) maxgroup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) for (j = 0; j < n; j++, desc++, group++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) lock = nilfs_mdt_bgl_lock(inode, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (nilfs_palloc_group_desc_nfrees(desc, lock) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ret = nilfs_palloc_get_bitmap_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) inode, group, 1, &bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) goto out_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) bitmap_kaddr = kmap(bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) pos = nilfs_palloc_find_available_slot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) bitmap, group_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) entries_per_group, lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (pos >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* found a free entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) nilfs_palloc_group_desc_add_entries(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) desc, lock, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) req->pr_entry_nr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) entries_per_group * group + pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) kunmap(desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) kunmap(bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) req->pr_desc_bh = desc_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) req->pr_bitmap_bh = bitmap_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) kunmap(bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) brelse(bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) group_offset = 0;
^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) kunmap(desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) brelse(desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* no entries left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) out_desc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) kunmap(desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) brelse(desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * nilfs_palloc_commit_alloc_entry - finish allocation of a persistent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * @req: nilfs_palloc_req structure exchanged for the allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) void nilfs_palloc_commit_alloc_entry(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct nilfs_palloc_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) mark_buffer_dirty(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) mark_buffer_dirty(req->pr_desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) nilfs_mdt_mark_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) brelse(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) brelse(req->pr_desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^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) * nilfs_palloc_commit_free_entry - finish deallocating a persistent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * @req: nilfs_palloc_req structure exchanged for the removal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) void nilfs_palloc_commit_free_entry(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct nilfs_palloc_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct nilfs_palloc_group_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) unsigned long group, group_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) unsigned char *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) void *desc_kaddr, *bitmap_kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) desc_kaddr = kmap(req->pr_desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) desc = nilfs_palloc_block_get_group_desc(inode, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) req->pr_desc_bh, desc_kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) lock = nilfs_mdt_bgl_lock(inode, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) nilfs_warn(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) "%s (ino=%lu): entry number %llu already freed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) __func__, inode->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) (unsigned long long)req->pr_entry_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) nilfs_palloc_group_desc_add_entries(desc, lock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) kunmap(req->pr_bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) kunmap(req->pr_desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) mark_buffer_dirty(req->pr_desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) mark_buffer_dirty(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) nilfs_mdt_mark_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) brelse(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) brelse(req->pr_desc_bh);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * nilfs_palloc_abort_alloc_entry - cancel allocation of a persistent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * @req: nilfs_palloc_req structure exchanged for the allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) void nilfs_palloc_abort_alloc_entry(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct nilfs_palloc_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct nilfs_palloc_group_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) void *desc_kaddr, *bitmap_kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) unsigned char *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned long group, group_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) desc_kaddr = kmap(req->pr_desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) desc = nilfs_palloc_block_get_group_desc(inode, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) req->pr_desc_bh, desc_kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) lock = nilfs_mdt_bgl_lock(inode, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) nilfs_warn(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) "%s (ino=%lu): entry number %llu already freed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) __func__, inode->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) (unsigned long long)req->pr_entry_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) nilfs_palloc_group_desc_add_entries(desc, lock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) kunmap(req->pr_bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) kunmap(req->pr_desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) brelse(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) brelse(req->pr_desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) req->pr_entry_nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) req->pr_bitmap_bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) req->pr_desc_bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * nilfs_palloc_prepare_free_entry - prepare to deallocate a persistent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * @req: nilfs_palloc_req structure exchanged for the removal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int nilfs_palloc_prepare_free_entry(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct nilfs_palloc_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct buffer_head *desc_bh, *bitmap_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned long group, group_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = nilfs_palloc_get_desc_block(inode, group, 1, &desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ret = nilfs_palloc_get_bitmap_block(inode, group, 1, &bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) brelse(desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) req->pr_desc_bh = desc_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) req->pr_bitmap_bh = bitmap_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * nilfs_palloc_abort_free_entry - cancel deallocating a persistent object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * @req: nilfs_palloc_req structure exchanged for the removal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) void nilfs_palloc_abort_free_entry(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct nilfs_palloc_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) brelse(req->pr_bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) brelse(req->pr_desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) req->pr_entry_nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) req->pr_bitmap_bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) req->pr_desc_bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * nilfs_palloc_freev - deallocate a set of persistent objects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * @inode: inode of metadata file using this allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * @entry_nrs: array of entry numbers to be deallocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * @nitems: number of entries stored in @entry_nrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct buffer_head *desc_bh, *bitmap_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct nilfs_palloc_group_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) unsigned char *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) void *desc_kaddr, *bitmap_kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) unsigned long group, group_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) __u64 group_min_nr, last_nrs[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) const unsigned long epg = nilfs_palloc_entries_per_group(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) const unsigned int epb = NILFS_MDT(inode)->mi_entries_per_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) unsigned int entry_start, end, pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) spinlock_t *lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int i, j, k, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) u32 nfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) for (i = 0; i < nitems; i = j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int change_group = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int nempties = 0, n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) group = nilfs_palloc_group(inode, entry_nrs[i], &group_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ret = nilfs_palloc_get_desc_block(inode, group, 0, &desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) ret = nilfs_palloc_get_bitmap_block(inode, group, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) &bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) brelse(desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /* Get the first entry number of the group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) group_min_nr = (__u64)group * epg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) bitmap_kaddr = kmap(bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) lock = nilfs_mdt_bgl_lock(inode, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) j = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) entry_start = rounddown(group_offset, epb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (!nilfs_clear_bit_atomic(lock, group_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) bitmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) nilfs_warn(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) "%s (ino=%lu): entry number %llu already freed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) __func__, inode->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) (unsigned long long)entry_nrs[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (j >= nitems || entry_nrs[j] < group_min_nr ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) entry_nrs[j] >= group_min_nr + epg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) change_group = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) group_offset = entry_nrs[j] - group_min_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (group_offset >= entry_start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) group_offset < entry_start + epb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /* This entry is in the same block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* Test if the entry block is empty or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) end = entry_start + epb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) pos = nilfs_find_next_bit(bitmap, end, entry_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (pos >= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) last_nrs[nempties++] = entry_nrs[j - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (nempties >= ARRAY_SIZE(last_nrs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (change_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /* Go on to the next entry block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) entry_start = rounddown(group_offset, epb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) } while (true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) kunmap(bitmap_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) mark_buffer_dirty(bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) brelse(bitmap_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) for (k = 0; k < nempties; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ret = nilfs_palloc_delete_entry_block(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) last_nrs[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (ret && ret != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) nilfs_warn(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) "error %d deleting block that object (entry=%llu, ino=%lu) belongs to",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ret, (unsigned long long)last_nrs[k],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) desc_kaddr = kmap_atomic(desc_bh->b_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) desc = nilfs_palloc_block_get_group_desc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) inode, group, desc_bh, desc_kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) nfree = nilfs_palloc_group_desc_add_entries(desc, lock, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) kunmap_atomic(desc_kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) mark_buffer_dirty(desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) nilfs_mdt_mark_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) brelse(desc_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (nfree == nilfs_palloc_entries_per_group(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ret = nilfs_palloc_delete_bitmap_block(inode, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (ret && ret != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) nilfs_warn(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) "error %d deleting bitmap block of group=%lu, ino=%lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ret, group, inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) void nilfs_palloc_setup_cache(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct nilfs_palloc_cache *cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) NILFS_MDT(inode)->mi_palloc_cache = cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) spin_lock_init(&cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) void nilfs_palloc_clear_cache(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) spin_lock(&cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) brelse(cache->prev_desc.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) brelse(cache->prev_bitmap.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) brelse(cache->prev_entry.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) cache->prev_desc.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) cache->prev_bitmap.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) cache->prev_entry.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) spin_unlock(&cache->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) void nilfs_palloc_destroy_cache(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) nilfs_palloc_clear_cache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) NILFS_MDT(inode)->mi_palloc_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }