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 * 16*4b420ab4SRyusuke Konishi * Written by Koji Sato. 17bdb265eaSKoji Sato */ 18bdb265eaSKoji Sato 19bdb265eaSKoji Sato #ifndef _NILFS_BMAP_H 20bdb265eaSKoji Sato #define _NILFS_BMAP_H 21bdb265eaSKoji Sato 22bdb265eaSKoji Sato #include <linux/types.h> 23bdb265eaSKoji Sato #include <linux/fs.h> 24bdb265eaSKoji Sato #include <linux/buffer_head.h> 25bdb265eaSKoji Sato #include <linux/nilfs2_fs.h> 26bdb265eaSKoji Sato #include "alloc.h" 272e0c2c73SRyusuke Konishi #include "dat.h" 28bdb265eaSKoji Sato 29bdb265eaSKoji Sato #define NILFS_BMAP_INVALID_PTR 0 30bdb265eaSKoji Sato 31bdb265eaSKoji Sato #define nilfs_bmap_keydiff_abs(diff) ((diff) < 0 ? -(diff) : (diff)) 32bdb265eaSKoji Sato 33bdb265eaSKoji Sato 34bdb265eaSKoji Sato struct nilfs_bmap; 35bdb265eaSKoji Sato 36bdb265eaSKoji Sato /** 37bdb265eaSKoji Sato * union nilfs_bmap_ptr_req - request for bmap ptr 38bdb265eaSKoji Sato * @bpr_ptr: bmap pointer 39bdb265eaSKoji Sato * @bpr_req: request for persistent allocator 40bdb265eaSKoji Sato */ 41bdb265eaSKoji Sato union nilfs_bmap_ptr_req { 42bdb265eaSKoji Sato __u64 bpr_ptr; 43bdb265eaSKoji Sato struct nilfs_palloc_req bpr_req; 44bdb265eaSKoji Sato }; 45bdb265eaSKoji Sato 46bdb265eaSKoji Sato /** 47bdb265eaSKoji Sato * struct nilfs_bmap_stats - bmap statistics 48bdb265eaSKoji Sato * @bs_nblocks: number of blocks created or deleted 49bdb265eaSKoji Sato */ 50bdb265eaSKoji Sato struct nilfs_bmap_stats { 51bdb265eaSKoji Sato unsigned int bs_nblocks; 52bdb265eaSKoji Sato }; 53bdb265eaSKoji Sato 54bdb265eaSKoji Sato /** 55bdb265eaSKoji Sato * struct nilfs_bmap_operations - bmap operation table 56bdb265eaSKoji Sato */ 57bdb265eaSKoji Sato struct nilfs_bmap_operations { 58bdb265eaSKoji Sato int (*bop_lookup)(const struct nilfs_bmap *, __u64, int, __u64 *); 59c3a7abf0SRyusuke Konishi int (*bop_lookup_contig)(const struct nilfs_bmap *, __u64, __u64 *, 60c3a7abf0SRyusuke Konishi unsigned); 61bdb265eaSKoji Sato int (*bop_insert)(struct nilfs_bmap *, __u64, __u64); 62bdb265eaSKoji Sato int (*bop_delete)(struct nilfs_bmap *, __u64); 63bdb265eaSKoji Sato void (*bop_clear)(struct nilfs_bmap *); 64bdb265eaSKoji Sato 65583ada47SRyusuke Konishi int (*bop_propagate)(struct nilfs_bmap *, struct buffer_head *); 66bdb265eaSKoji Sato void (*bop_lookup_dirty_buffers)(struct nilfs_bmap *, 67bdb265eaSKoji Sato struct list_head *); 68bdb265eaSKoji Sato 69bdb265eaSKoji Sato int (*bop_assign)(struct nilfs_bmap *, 70bdb265eaSKoji Sato struct buffer_head **, 71bdb265eaSKoji Sato sector_t, 72bdb265eaSKoji Sato union nilfs_binfo *); 73bdb265eaSKoji Sato int (*bop_mark)(struct nilfs_bmap *, __u64, int); 74bdb265eaSKoji Sato 755b20384fSRyusuke Konishi int (*bop_seek_key)(const struct nilfs_bmap *, __u64, __u64 *); 76bdb265eaSKoji Sato int (*bop_last_key)(const struct nilfs_bmap *, __u64 *); 775b20384fSRyusuke Konishi 785b20384fSRyusuke Konishi /* The following functions are internal use only. */ 79bdb265eaSKoji Sato int (*bop_check_insert)(const struct nilfs_bmap *, __u64); 80bdb265eaSKoji Sato int (*bop_check_delete)(struct nilfs_bmap *, __u64); 81bdb265eaSKoji Sato int (*bop_gather_data)(struct nilfs_bmap *, __u64 *, __u64 *, int); 82bdb265eaSKoji Sato }; 83bdb265eaSKoji Sato 84bdb265eaSKoji Sato 85bdb265eaSKoji Sato #define NILFS_BMAP_SIZE (NILFS_INODE_BMAP_SIZE * sizeof(__le64)) 86bdb265eaSKoji Sato #define NILFS_BMAP_KEY_BIT (sizeof(unsigned long) * 8 /* CHAR_BIT */) 87bdb265eaSKoji Sato #define NILFS_BMAP_NEW_PTR_INIT \ 88bdb265eaSKoji Sato (1UL << (sizeof(unsigned long) * 8 /* CHAR_BIT */ - 1)) 89bdb265eaSKoji Sato 90bdb265eaSKoji Sato static inline int nilfs_bmap_is_new_ptr(unsigned long ptr) 91bdb265eaSKoji Sato { 92bdb265eaSKoji Sato return !!(ptr & NILFS_BMAP_NEW_PTR_INIT); 93bdb265eaSKoji Sato } 94bdb265eaSKoji Sato 95bdb265eaSKoji Sato 96bdb265eaSKoji Sato /** 97bdb265eaSKoji Sato * struct nilfs_bmap - bmap structure 98bdb265eaSKoji Sato * @b_u: raw data 99bdb265eaSKoji Sato * @b_sem: semaphore 100bdb265eaSKoji Sato * @b_inode: owner of bmap 101bdb265eaSKoji Sato * @b_ops: bmap operation table 102bdb265eaSKoji Sato * @b_last_allocated_key: last allocated key for data block 103bdb265eaSKoji Sato * @b_last_allocated_ptr: last allocated ptr for data block 104d4b96157SRyusuke Konishi * @b_ptr_type: pointer type 105bdb265eaSKoji Sato * @b_state: state 1065ad2686eSRyusuke Konishi * @b_nchildren_per_block: maximum number of child nodes for non-root nodes 107bdb265eaSKoji Sato */ 108bdb265eaSKoji Sato struct nilfs_bmap { 109bdb265eaSKoji Sato union { 110bdb265eaSKoji Sato __u8 u_flags; 111bdb265eaSKoji Sato __le64 u_data[NILFS_BMAP_SIZE / sizeof(__le64)]; 112bdb265eaSKoji Sato } b_u; 113bdb265eaSKoji Sato struct rw_semaphore b_sem; 114bdb265eaSKoji Sato struct inode *b_inode; 115bdb265eaSKoji Sato const struct nilfs_bmap_operations *b_ops; 116bdb265eaSKoji Sato __u64 b_last_allocated_key; 117bdb265eaSKoji Sato __u64 b_last_allocated_ptr; 118d4b96157SRyusuke Konishi int b_ptr_type; 119bdb265eaSKoji Sato int b_state; 1205ad2686eSRyusuke Konishi __u16 b_nchildren_per_block; 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 136f5974c8fSVyacheslav Dubeyko /** 137f5974c8fSVyacheslav Dubeyko * struct nilfs_bmap_store - shadow copy of bmap state 138f5974c8fSVyacheslav Dubeyko * @data: cached raw block mapping of on-disk inode 139f5974c8fSVyacheslav Dubeyko * @last_allocated_key: cached value of last allocated key for data block 140f5974c8fSVyacheslav Dubeyko * @last_allocated_ptr: cached value of last allocated ptr for data block 141f5974c8fSVyacheslav Dubeyko * @state: cached value of state field of bmap structure 142f5974c8fSVyacheslav Dubeyko */ 143a8070dd3SRyusuke Konishi struct nilfs_bmap_store { 144a8070dd3SRyusuke Konishi __le64 data[NILFS_BMAP_SIZE / sizeof(__le64)]; 145a8070dd3SRyusuke Konishi __u64 last_allocated_key; 146a8070dd3SRyusuke Konishi __u64 last_allocated_ptr; 147a8070dd3SRyusuke Konishi int state; 148a8070dd3SRyusuke Konishi }; 149bdb265eaSKoji Sato 150bdb265eaSKoji Sato int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); 151bdb265eaSKoji Sato int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); 152bdb265eaSKoji Sato void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); 153c3a7abf0SRyusuke Konishi int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); 1543568a13fSRyusuke Konishi int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec); 1553568a13fSRyusuke Konishi int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key); 1565b20384fSRyusuke Konishi int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp); 1573568a13fSRyusuke Konishi int nilfs_bmap_last_key(struct nilfs_bmap *bmap, __u64 *keyp); 1583568a13fSRyusuke Konishi int nilfs_bmap_truncate(struct nilfs_bmap *bmap, __u64 key); 159bdb265eaSKoji Sato void nilfs_bmap_clear(struct nilfs_bmap *); 160bdb265eaSKoji Sato int nilfs_bmap_propagate(struct nilfs_bmap *, struct buffer_head *); 161bdb265eaSKoji Sato void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *, struct list_head *); 162bdb265eaSKoji Sato int nilfs_bmap_assign(struct nilfs_bmap *, struct buffer_head **, 163bdb265eaSKoji Sato unsigned long, union nilfs_binfo *); 164bdb265eaSKoji Sato int nilfs_bmap_lookup_at_level(struct nilfs_bmap *, __u64, int, __u64 *); 165bdb265eaSKoji Sato int nilfs_bmap_mark(struct nilfs_bmap *, __u64, int); 166bdb265eaSKoji Sato 167bdb265eaSKoji Sato void nilfs_bmap_init_gc(struct nilfs_bmap *); 168bdb265eaSKoji Sato 169a8070dd3SRyusuke Konishi void nilfs_bmap_save(const struct nilfs_bmap *, struct nilfs_bmap_store *); 170a8070dd3SRyusuke Konishi void nilfs_bmap_restore(struct nilfs_bmap *, const struct nilfs_bmap_store *); 171bdb265eaSKoji Sato 1720f3fe33bSRyusuke Konishi static inline int nilfs_bmap_lookup(struct nilfs_bmap *bmap, __u64 key, 1730f3fe33bSRyusuke Konishi __u64 *ptr) 1740f3fe33bSRyusuke Konishi { 1750f3fe33bSRyusuke Konishi return nilfs_bmap_lookup_at_level(bmap, key, 1, ptr); 1760f3fe33bSRyusuke Konishi } 1770f3fe33bSRyusuke Konishi 178bdb265eaSKoji Sato /* 179bdb265eaSKoji Sato * Internal use only 180bdb265eaSKoji Sato */ 181c3a7abf0SRyusuke Konishi struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *); 182d4b96157SRyusuke Konishi 183d4b96157SRyusuke Konishi static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap, 1842e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 1852e0c2c73SRyusuke Konishi struct inode *dat) 186d4b96157SRyusuke Konishi { 1872e0c2c73SRyusuke Konishi if (dat) 1882e0c2c73SRyusuke Konishi return nilfs_dat_prepare_alloc(dat, &req->bpr_req); 189d4b96157SRyusuke Konishi /* ignore target ptr */ 190d4b96157SRyusuke Konishi req->bpr_ptr = bmap->b_last_allocated_ptr++; 191d4b96157SRyusuke Konishi return 0; 192d4b96157SRyusuke Konishi } 193d4b96157SRyusuke Konishi 194d4b96157SRyusuke Konishi static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap, 1952e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 1962e0c2c73SRyusuke Konishi struct inode *dat) 197d4b96157SRyusuke Konishi { 1982e0c2c73SRyusuke Konishi if (dat) 1992e0c2c73SRyusuke Konishi nilfs_dat_commit_alloc(dat, &req->bpr_req); 200d4b96157SRyusuke Konishi } 201d4b96157SRyusuke Konishi 202d4b96157SRyusuke Konishi static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap, 2032e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 2042e0c2c73SRyusuke Konishi struct inode *dat) 205d4b96157SRyusuke Konishi { 2062e0c2c73SRyusuke Konishi if (dat) 2072e0c2c73SRyusuke Konishi nilfs_dat_abort_alloc(dat, &req->bpr_req); 208d4b96157SRyusuke Konishi else 209d4b96157SRyusuke Konishi bmap->b_last_allocated_ptr--; 210d4b96157SRyusuke Konishi } 211d4b96157SRyusuke Konishi 212d4b96157SRyusuke Konishi static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap, 2132e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 2142e0c2c73SRyusuke Konishi struct inode *dat) 215d4b96157SRyusuke Konishi { 2162e0c2c73SRyusuke Konishi return dat ? nilfs_dat_prepare_end(dat, &req->bpr_req) : 0; 217d4b96157SRyusuke Konishi } 218d4b96157SRyusuke Konishi 219d4b96157SRyusuke Konishi static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap, 2202e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 2212e0c2c73SRyusuke Konishi struct inode *dat) 222d4b96157SRyusuke Konishi { 2232e0c2c73SRyusuke Konishi if (dat) 2242e0c2c73SRyusuke Konishi nilfs_dat_commit_end(dat, &req->bpr_req, 2252e0c2c73SRyusuke Konishi bmap->b_ptr_type == NILFS_BMAP_PTR_VS); 226d4b96157SRyusuke Konishi } 227d4b96157SRyusuke Konishi 228d4b96157SRyusuke Konishi static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap, 2292e0c2c73SRyusuke Konishi union nilfs_bmap_ptr_req *req, 2302e0c2c73SRyusuke Konishi struct inode *dat) 231d4b96157SRyusuke Konishi { 2322e0c2c73SRyusuke Konishi if (dat) 2332e0c2c73SRyusuke Konishi nilfs_dat_abort_end(dat, &req->bpr_req); 234d4b96157SRyusuke Konishi } 235bdb265eaSKoji Sato 236dc935be2SRyusuke Konishi static inline void nilfs_bmap_set_target_v(struct nilfs_bmap *bmap, __u64 key, 237dc935be2SRyusuke Konishi __u64 ptr) 238dc935be2SRyusuke Konishi { 239dc935be2SRyusuke Konishi bmap->b_last_allocated_key = key; 240dc935be2SRyusuke Konishi bmap->b_last_allocated_ptr = ptr; 241dc935be2SRyusuke Konishi } 242dc935be2SRyusuke Konishi 243bdb265eaSKoji Sato __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *, 244bdb265eaSKoji Sato const struct buffer_head *); 245bdb265eaSKoji Sato 246bdb265eaSKoji Sato __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64); 247bdb265eaSKoji Sato __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *); 248bdb265eaSKoji Sato 249bdb265eaSKoji Sato 250bdb265eaSKoji Sato /* Assume that bmap semaphore is locked. */ 251bdb265eaSKoji Sato static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap) 252bdb265eaSKoji Sato { 253bdb265eaSKoji Sato return !!(bmap->b_state & NILFS_BMAP_DIRTY); 254bdb265eaSKoji Sato } 255bdb265eaSKoji Sato 256bdb265eaSKoji Sato /* Assume that bmap semaphore is locked. */ 257bdb265eaSKoji Sato static inline void nilfs_bmap_set_dirty(struct nilfs_bmap *bmap) 258bdb265eaSKoji Sato { 259bdb265eaSKoji Sato bmap->b_state |= NILFS_BMAP_DIRTY; 260bdb265eaSKoji Sato } 261bdb265eaSKoji Sato 262bdb265eaSKoji Sato /* Assume that bmap semaphore is locked. */ 263bdb265eaSKoji Sato static inline void nilfs_bmap_clear_dirty(struct nilfs_bmap *bmap) 264bdb265eaSKoji Sato { 265bdb265eaSKoji Sato bmap->b_state &= ~NILFS_BMAP_DIRTY; 266bdb265eaSKoji Sato } 267bdb265eaSKoji Sato 268bdb265eaSKoji Sato 269bdb265eaSKoji Sato #define NILFS_BMAP_LARGE 0x1 270bdb265eaSKoji Sato 271bdb265eaSKoji Sato #define NILFS_BMAP_SMALL_LOW NILFS_DIRECT_KEY_MIN 272bdb265eaSKoji Sato #define NILFS_BMAP_SMALL_HIGH NILFS_DIRECT_KEY_MAX 273bdb265eaSKoji Sato #define NILFS_BMAP_LARGE_LOW NILFS_BTREE_ROOT_NCHILDREN_MAX 274bdb265eaSKoji Sato #define NILFS_BMAP_LARGE_HIGH NILFS_BTREE_KEY_MAX 275bdb265eaSKoji Sato 276bdb265eaSKoji Sato #endif /* _NILFS_BMAP_H */ 277