1bdb265eaSKoji Sato /* 2bdb265eaSKoji Sato * bmap.h - NILFS block mapping. 3bdb265eaSKoji Sato * 4bdb265eaSKoji Sato * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation. 5bdb265eaSKoji Sato * 6bdb265eaSKoji Sato * This program is free software; you can redistribute it and/or modify 7bdb265eaSKoji Sato * it under the terms of the GNU General Public License as published by 8bdb265eaSKoji Sato * the Free Software Foundation; either version 2 of the License, or 9bdb265eaSKoji Sato * (at your option) any later version. 10bdb265eaSKoji Sato * 11bdb265eaSKoji Sato * This program is distributed in the hope that it will be useful, 12bdb265eaSKoji Sato * but WITHOUT ANY WARRANTY; without even the implied warranty of 13bdb265eaSKoji Sato * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14bdb265eaSKoji Sato * GNU General Public License for more details. 15bdb265eaSKoji Sato * 16bdb265eaSKoji Sato * You should have received a copy of the GNU General Public License 17bdb265eaSKoji Sato * along with this program; if not, write to the Free Software 18bdb265eaSKoji Sato * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19bdb265eaSKoji Sato * 20bdb265eaSKoji Sato * Written by Koji Sato <koji@osrg.net>. 21bdb265eaSKoji Sato */ 22bdb265eaSKoji Sato 23bdb265eaSKoji Sato #ifndef _NILFS_BMAP_H 24bdb265eaSKoji Sato #define _NILFS_BMAP_H 25bdb265eaSKoji Sato 26bdb265eaSKoji Sato #include <linux/types.h> 27bdb265eaSKoji Sato #include <linux/fs.h> 28bdb265eaSKoji Sato #include <linux/buffer_head.h> 29bdb265eaSKoji Sato #include <linux/nilfs2_fs.h> 30bdb265eaSKoji Sato #include "alloc.h" 312e0c2c73SRyusuke Konishi #include "dat.h" 32bdb265eaSKoji Sato 33bdb265eaSKoji Sato #define NILFS_BMAP_INVALID_PTR 0 34bdb265eaSKoji Sato 35bdb265eaSKoji Sato #define nilfs_bmap_keydiff_abs(diff) ((diff) < 0 ? -(diff) : (diff)) 36bdb265eaSKoji Sato 37bdb265eaSKoji Sato 38bdb265eaSKoji Sato struct nilfs_bmap; 39bdb265eaSKoji Sato 40bdb265eaSKoji Sato /** 41bdb265eaSKoji Sato * union nilfs_bmap_ptr_req - request for bmap ptr 42bdb265eaSKoji Sato * @bpr_ptr: bmap pointer 43bdb265eaSKoji Sato * @bpr_req: request for persistent allocator 44bdb265eaSKoji Sato */ 45bdb265eaSKoji Sato union nilfs_bmap_ptr_req { 46bdb265eaSKoji Sato __u64 bpr_ptr; 47bdb265eaSKoji Sato struct nilfs_palloc_req bpr_req; 48bdb265eaSKoji Sato }; 49bdb265eaSKoji Sato 50bdb265eaSKoji Sato /** 51bdb265eaSKoji Sato * struct nilfs_bmap_stats - bmap statistics 52bdb265eaSKoji Sato * @bs_nblocks: number of blocks created or deleted 53bdb265eaSKoji Sato */ 54bdb265eaSKoji Sato struct nilfs_bmap_stats { 55bdb265eaSKoji Sato unsigned int bs_nblocks; 56bdb265eaSKoji Sato }; 57bdb265eaSKoji Sato 58bdb265eaSKoji Sato /** 59bdb265eaSKoji Sato * struct nilfs_bmap_operations - bmap operation table 60bdb265eaSKoji Sato */ 61bdb265eaSKoji Sato struct nilfs_bmap_operations { 62bdb265eaSKoji Sato int (*bop_lookup)(const struct nilfs_bmap *, __u64, int, __u64 *); 63c3a7abf0SRyusuke Konishi int (*bop_lookup_contig)(const struct nilfs_bmap *, __u64, __u64 *, 64c3a7abf0SRyusuke Konishi unsigned); 65bdb265eaSKoji Sato int (*bop_insert)(struct nilfs_bmap *, __u64, __u64); 66bdb265eaSKoji Sato int (*bop_delete)(struct nilfs_bmap *, __u64); 67bdb265eaSKoji Sato void (*bop_clear)(struct nilfs_bmap *); 68bdb265eaSKoji Sato 69583ada47SRyusuke Konishi int (*bop_propagate)(struct nilfs_bmap *, struct buffer_head *); 70bdb265eaSKoji Sato void (*bop_lookup_dirty_buffers)(struct nilfs_bmap *, 71bdb265eaSKoji Sato struct list_head *); 72bdb265eaSKoji Sato 73bdb265eaSKoji Sato int (*bop_assign)(struct nilfs_bmap *, 74bdb265eaSKoji Sato struct buffer_head **, 75bdb265eaSKoji Sato sector_t, 76bdb265eaSKoji Sato union nilfs_binfo *); 77bdb265eaSKoji Sato int (*bop_mark)(struct nilfs_bmap *, __u64, int); 78bdb265eaSKoji Sato 79bdb265eaSKoji Sato /* The following functions are internal use only. */ 80bdb265eaSKoji Sato int (*bop_last_key)(const struct nilfs_bmap *, __u64 *); 81bdb265eaSKoji Sato int (*bop_check_insert)(const struct nilfs_bmap *, __u64); 82bdb265eaSKoji Sato int (*bop_check_delete)(struct nilfs_bmap *, __u64); 83bdb265eaSKoji Sato int (*bop_gather_data)(struct nilfs_bmap *, __u64 *, __u64 *, int); 84bdb265eaSKoji Sato }; 85bdb265eaSKoji Sato 86bdb265eaSKoji Sato 87bdb265eaSKoji Sato #define NILFS_BMAP_SIZE (NILFS_INODE_BMAP_SIZE * sizeof(__le64)) 88bdb265eaSKoji Sato #define NILFS_BMAP_KEY_BIT (sizeof(unsigned long) * 8 /* CHAR_BIT */) 89bdb265eaSKoji Sato #define NILFS_BMAP_NEW_PTR_INIT \ 90bdb265eaSKoji Sato (1UL << (sizeof(unsigned long) * 8 /* CHAR_BIT */ - 1)) 91bdb265eaSKoji Sato 92bdb265eaSKoji Sato static inline int nilfs_bmap_is_new_ptr(unsigned long ptr) 93bdb265eaSKoji Sato { 94bdb265eaSKoji Sato return !!(ptr & NILFS_BMAP_NEW_PTR_INIT); 95bdb265eaSKoji Sato } 96bdb265eaSKoji Sato 97bdb265eaSKoji Sato 98bdb265eaSKoji Sato /** 99bdb265eaSKoji Sato * struct nilfs_bmap - bmap structure 100bdb265eaSKoji Sato * @b_u: raw data 101bdb265eaSKoji Sato * @b_sem: semaphore 102bdb265eaSKoji Sato * @b_inode: owner of bmap 103bdb265eaSKoji Sato * @b_ops: bmap operation table 104bdb265eaSKoji Sato * @b_last_allocated_key: last allocated key for data block 105bdb265eaSKoji Sato * @b_last_allocated_ptr: last allocated ptr for data block 106d4b96157SRyusuke Konishi * @b_ptr_type: pointer type 107bdb265eaSKoji Sato * @b_state: state 108bdb265eaSKoji Sato */ 109bdb265eaSKoji Sato struct nilfs_bmap { 110bdb265eaSKoji Sato union { 111bdb265eaSKoji Sato __u8 u_flags; 112bdb265eaSKoji Sato __le64 u_data[NILFS_BMAP_SIZE / sizeof(__le64)]; 113bdb265eaSKoji Sato } b_u; 114bdb265eaSKoji Sato struct rw_semaphore b_sem; 115bdb265eaSKoji Sato struct inode *b_inode; 116bdb265eaSKoji Sato const struct nilfs_bmap_operations *b_ops; 117bdb265eaSKoji Sato __u64 b_last_allocated_key; 118bdb265eaSKoji Sato __u64 b_last_allocated_ptr; 119d4b96157SRyusuke Konishi int b_ptr_type; 120bdb265eaSKoji Sato int b_state; 121bdb265eaSKoji Sato }; 122bdb265eaSKoji Sato 123d4b96157SRyusuke Konishi /* pointer type */ 124d4b96157SRyusuke Konishi #define NILFS_BMAP_PTR_P 0 /* physical block number (i.e. LBN) */ 125d4b96157SRyusuke Konishi #define NILFS_BMAP_PTR_VS 1 /* virtual block number (single 126d4b96157SRyusuke Konishi version) */ 127d4b96157SRyusuke Konishi #define NILFS_BMAP_PTR_VM 2 /* virtual block number (has multiple 128d4b96157SRyusuke Konishi versions) */ 129d4b96157SRyusuke Konishi #define NILFS_BMAP_PTR_U (-1) /* never perform pointer operations */ 130d4b96157SRyusuke Konishi 131d4b96157SRyusuke Konishi #define NILFS_BMAP_USE_VBN(bmap) ((bmap)->b_ptr_type > 0) 132d4b96157SRyusuke Konishi 133bdb265eaSKoji Sato /* state */ 134bdb265eaSKoji Sato #define NILFS_BMAP_DIRTY 0x00000001 135bdb265eaSKoji Sato 136bdb265eaSKoji Sato 137bdb265eaSKoji Sato int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); 138bdb265eaSKoji Sato int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); 139bdb265eaSKoji Sato void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); 140c3a7abf0SRyusuke Konishi int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); 141bdb265eaSKoji Sato int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long); 142bdb265eaSKoji Sato int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long); 143bdb265eaSKoji Sato int nilfs_bmap_last_key(struct nilfs_bmap *, unsigned long *); 144bdb265eaSKoji Sato int nilfs_bmap_truncate(struct nilfs_bmap *, unsigned long); 145bdb265eaSKoji Sato void nilfs_bmap_clear(struct nilfs_bmap *); 146bdb265eaSKoji Sato int nilfs_bmap_propagate(struct nilfs_bmap *, struct buffer_head *); 147bdb265eaSKoji Sato void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *, struct list_head *); 148bdb265eaSKoji Sato int nilfs_bmap_assign(struct nilfs_bmap *, struct buffer_head **, 149bdb265eaSKoji Sato unsigned long, union nilfs_binfo *); 150bdb265eaSKoji Sato int nilfs_bmap_lookup_at_level(struct nilfs_bmap *, __u64, int, __u64 *); 151bdb265eaSKoji Sato int nilfs_bmap_mark(struct nilfs_bmap *, __u64, int); 152bdb265eaSKoji Sato 153bdb265eaSKoji Sato void nilfs_bmap_init_gc(struct nilfs_bmap *); 154bdb265eaSKoji Sato void nilfs_bmap_init_gcdat(struct nilfs_bmap *, struct nilfs_bmap *); 155bdb265eaSKoji Sato void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *); 156bdb265eaSKoji Sato 157bdb265eaSKoji Sato 1580f3fe33bSRyusuke Konishi static inline int nilfs_bmap_lookup(struct nilfs_bmap *bmap, __u64 key, 1590f3fe33bSRyusuke Konishi __u64 *ptr) 1600f3fe33bSRyusuke Konishi { 1610f3fe33bSRyusuke Konishi return nilfs_bmap_lookup_at_level(bmap, key, 1, ptr); 1620f3fe33bSRyusuke Konishi } 1630f3fe33bSRyusuke Konishi 164bdb265eaSKoji Sato /* 165bdb265eaSKoji Sato * Internal use only 166bdb265eaSKoji Sato */ 167c3a7abf0SRyusuke Konishi struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *); 168d4b96157SRyusuke Konishi 169d4b96157SRyusuke Konishi static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap, 1702e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 1712e0c2c73SRyusuke Konishi struct inode *dat) 172d4b96157SRyusuke Konishi { 1732e0c2c73SRyusuke Konishi if (dat) 1742e0c2c73SRyusuke Konishi return nilfs_dat_prepare_alloc(dat, &req->bpr_req); 175d4b96157SRyusuke Konishi /* ignore target ptr */ 176d4b96157SRyusuke Konishi req->bpr_ptr = bmap->b_last_allocated_ptr++; 177d4b96157SRyusuke Konishi return 0; 178d4b96157SRyusuke Konishi } 179d4b96157SRyusuke Konishi 180d4b96157SRyusuke Konishi static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap, 1812e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 1822e0c2c73SRyusuke Konishi struct inode *dat) 183d4b96157SRyusuke Konishi { 1842e0c2c73SRyusuke Konishi if (dat) 1852e0c2c73SRyusuke Konishi nilfs_dat_commit_alloc(dat, &req->bpr_req); 186d4b96157SRyusuke Konishi } 187d4b96157SRyusuke Konishi 188d4b96157SRyusuke Konishi static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap, 1892e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 1902e0c2c73SRyusuke Konishi struct inode *dat) 191d4b96157SRyusuke Konishi { 1922e0c2c73SRyusuke Konishi if (dat) 1932e0c2c73SRyusuke Konishi nilfs_dat_abort_alloc(dat, &req->bpr_req); 194d4b96157SRyusuke Konishi else 195d4b96157SRyusuke Konishi bmap->b_last_allocated_ptr--; 196d4b96157SRyusuke Konishi } 197d4b96157SRyusuke Konishi 198d4b96157SRyusuke Konishi static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap, 1992e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 2002e0c2c73SRyusuke Konishi struct inode *dat) 201d4b96157SRyusuke Konishi { 2022e0c2c73SRyusuke Konishi return dat ? nilfs_dat_prepare_end(dat, &req->bpr_req) : 0; 203d4b96157SRyusuke Konishi } 204d4b96157SRyusuke Konishi 205d4b96157SRyusuke Konishi static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap, 2062e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 2072e0c2c73SRyusuke Konishi struct inode *dat) 208d4b96157SRyusuke Konishi { 2092e0c2c73SRyusuke Konishi if (dat) 2102e0c2c73SRyusuke Konishi nilfs_dat_commit_end(dat, &req->bpr_req, 2112e0c2c73SRyusuke Konishi bmap->b_ptr_type == NILFS_BMAP_PTR_VS); 212d4b96157SRyusuke Konishi } 213d4b96157SRyusuke Konishi 214d4b96157SRyusuke Konishi static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap, 2152e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 2162e0c2c73SRyusuke Konishi struct inode *dat) 217d4b96157SRyusuke Konishi { 2182e0c2c73SRyusuke Konishi if (dat) 2192e0c2c73SRyusuke Konishi nilfs_dat_abort_end(dat, &req->bpr_req); 220d4b96157SRyusuke Konishi } 221bdb265eaSKoji Sato 222*dc935be2SRyusuke Konishi static inline void nilfs_bmap_set_target_v(struct nilfs_bmap *bmap, __u64 key, 223*dc935be2SRyusuke Konishi __u64 ptr) 224*dc935be2SRyusuke Konishi { 225*dc935be2SRyusuke Konishi bmap->b_last_allocated_key = key; 226*dc935be2SRyusuke Konishi bmap->b_last_allocated_ptr = ptr; 227*dc935be2SRyusuke Konishi } 228*dc935be2SRyusuke Konishi 229bdb265eaSKoji Sato __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *, 230bdb265eaSKoji Sato const struct buffer_head *); 231bdb265eaSKoji Sato 232bdb265eaSKoji Sato __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64); 233bdb265eaSKoji Sato __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *); 234bdb265eaSKoji Sato 235bdb265eaSKoji Sato void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int); 236bdb265eaSKoji Sato void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int); 237bdb265eaSKoji Sato 238bdb265eaSKoji Sato 239bdb265eaSKoji Sato /* Assume that bmap semaphore is locked. */ 240bdb265eaSKoji Sato static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap) 241bdb265eaSKoji Sato { 242bdb265eaSKoji Sato return !!(bmap->b_state & NILFS_BMAP_DIRTY); 243bdb265eaSKoji Sato } 244bdb265eaSKoji Sato 245bdb265eaSKoji Sato /* Assume that bmap semaphore is locked. */ 246bdb265eaSKoji Sato static inline void nilfs_bmap_set_dirty(struct nilfs_bmap *bmap) 247bdb265eaSKoji Sato { 248bdb265eaSKoji Sato bmap->b_state |= NILFS_BMAP_DIRTY; 249bdb265eaSKoji Sato } 250bdb265eaSKoji Sato 251bdb265eaSKoji Sato /* Assume that bmap semaphore is locked. */ 252bdb265eaSKoji Sato static inline void nilfs_bmap_clear_dirty(struct nilfs_bmap *bmap) 253bdb265eaSKoji Sato { 254bdb265eaSKoji Sato bmap->b_state &= ~NILFS_BMAP_DIRTY; 255bdb265eaSKoji Sato } 256bdb265eaSKoji Sato 257bdb265eaSKoji Sato 258bdb265eaSKoji Sato #define NILFS_BMAP_LARGE 0x1 259bdb265eaSKoji Sato 260bdb265eaSKoji Sato #define NILFS_BMAP_SMALL_LOW NILFS_DIRECT_KEY_MIN 261bdb265eaSKoji Sato #define NILFS_BMAP_SMALL_HIGH NILFS_DIRECT_KEY_MAX 262bdb265eaSKoji Sato #define NILFS_BMAP_LARGE_LOW NILFS_BTREE_ROOT_NCHILDREN_MAX 263bdb265eaSKoji Sato #define NILFS_BMAP_LARGE_HIGH NILFS_BTREE_KEY_MAX 264bdb265eaSKoji Sato 265bdb265eaSKoji Sato #endif /* _NILFS_BMAP_H */ 266