Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nandfs/bmap.c
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
static int bmap_getlbns(struct nandfs_node *, nandfs_lbn_t, | static int bmap_getlbns(struct nandfs_node *, nandfs_lbn_t, | ||||
struct nandfs_indir *, int *); | struct nandfs_indir *, int *); | ||||
int | int | ||||
bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t *vblk) | bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t *vblk) | ||||
{ | { | ||||
struct nandfs_inode *ip; | struct nandfs_inode *ip; | ||||
struct nandfs_indir a[NIADDR + 1], *ap; | struct nandfs_indir a[NANDFS_NIADDR + 1], *ap; | ||||
nandfs_daddr_t daddr; | nandfs_daddr_t daddr; | ||||
struct buf *bp; | struct buf *bp; | ||||
int error; | int error; | ||||
int num, *nump; | int num, *nump; | ||||
DPRINTF(BMAP, ("%s: node %p lblk %jx enter\n", __func__, node, lblk)); | DPRINTF(BMAP, ("%s: node %p lblk %jx enter\n", __func__, node, lblk)); | ||||
ip = &node->nn_inode; | ip = &node->nn_inode; | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t *vblk) | ||||
*vblk = daddr; | *vblk = daddr; | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
bmap_dirty_meta(struct nandfs_node *node, nandfs_lbn_t lblk, int force) | bmap_dirty_meta(struct nandfs_node *node, nandfs_lbn_t lblk, int force) | ||||
{ | { | ||||
struct nandfs_indir a[NIADDR+1], *ap; | struct nandfs_indir a[NANDFS_NIADDR+1], *ap; | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
nandfs_daddr_t daddr; | nandfs_daddr_t daddr; | ||||
#endif | #endif | ||||
struct buf *bp; | struct buf *bp; | ||||
int error; | int error; | ||||
int num, *nump; | int num, *nump; | ||||
DPRINTF(BMAP, ("%s: node %p lblk=%jx\n", __func__, node, lblk)); | DPRINTF(BMAP, ("%s: node %p lblk=%jx\n", __func__, node, lblk)); | ||||
Show All 33 Lines | #endif | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk, | bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk, | ||||
nandfs_daddr_t vblk) | nandfs_daddr_t vblk) | ||||
{ | { | ||||
struct nandfs_inode *ip; | struct nandfs_inode *ip; | ||||
struct nandfs_indir a[NIADDR+1], *ap; | struct nandfs_indir a[NANDFS_NIADDR+1], *ap; | ||||
struct buf *bp; | struct buf *bp; | ||||
nandfs_daddr_t daddr; | nandfs_daddr_t daddr; | ||||
int error; | int error; | ||||
int num, *nump, i; | int num, *nump, i; | ||||
DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx\n", __func__, node, lblk, | DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx\n", __func__, node, lblk, | ||||
vblk)); | vblk)); | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | if (error) { | ||||
return (error); | return (error); | ||||
} | } | ||||
DPRINTF(BMAP, ("%s: exiting node %p lblk=%jx vblk=%jx\n", __func__, | DPRINTF(BMAP, ("%s: exiting node %p lblk=%jx vblk=%jx\n", __func__, | ||||
node, lblk, vblk)); | node, lblk, vblk)); | ||||
return (error); | return (error); | ||||
} | } | ||||
CTASSERT(NIADDR <= 3); | CTASSERT(NANDFS_NIADDR <= 3); | ||||
#define SINGLE 0 /* index of single indirect block */ | #define SINGLE 0 /* index of single indirect block */ | ||||
#define DOUBLE 1 /* index of double indirect block */ | #define DOUBLE 1 /* index of double indirect block */ | ||||
#define TRIPLE 2 /* index of triple indirect block */ | #define TRIPLE 2 /* index of triple indirect block */ | ||||
static __inline nandfs_lbn_t | static __inline nandfs_lbn_t | ||||
lbn_offset(struct nandfs_device *fsdev, int level) | lbn_offset(struct nandfs_device *fsdev, int level) | ||||
{ | { | ||||
nandfs_lbn_t res; | nandfs_lbn_t res; | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | bmap_truncate_indirect(struct nandfs_node *node, int level, nandfs_lbn_t *left, | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t lastblk, | bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t lastblk, | ||||
nandfs_lbn_t todo) | nandfs_lbn_t todo) | ||||
{ | { | ||||
struct nandfs_inode *ip; | struct nandfs_inode *ip; | ||||
struct nandfs_indir a[NIADDR + 1], f[NIADDR], *ap; | struct nandfs_indir a[NANDFS_NIADDR + 1], f[NANDFS_NIADDR], *ap; | ||||
nandfs_daddr_t indir_lbn[NIADDR]; | nandfs_daddr_t indir_lbn[NANDFS_NIADDR]; | ||||
nandfs_daddr_t *copy; | nandfs_daddr_t *copy; | ||||
int error, level; | int error, level; | ||||
nandfs_lbn_t left, tosub; | nandfs_lbn_t left, tosub; | ||||
struct nandfs_device *fsdev; | struct nandfs_device *fsdev; | ||||
int cleaned, i; | int cleaned, i; | ||||
int num, *nump; | int num, *nump; | ||||
DPRINTF(BMAP, ("%s: node %p lastblk %jx truncating by %jx\n", __func__, | DPRINTF(BMAP, ("%s: node %p lastblk %jx truncating by %jx\n", __func__, | ||||
node, lastblk, todo)); | node, lastblk, todo)); | ||||
ip = &node->nn_inode; | ip = &node->nn_inode; | ||||
fsdev = node->nn_nandfsdev; | fsdev = node->nn_nandfsdev; | ||||
ap = a; | ap = a; | ||||
nump = # | nump = # | ||||
error = bmap_getlbns(node, lastblk, ap, nump); | error = bmap_getlbns(node, lastblk, ap, nump); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
indir_lbn[SINGLE] = -NDADDR; | indir_lbn[SINGLE] = -NANDFS_NDADDR; | ||||
indir_lbn[DOUBLE] = indir_lbn[SINGLE] - MNINDIR(fsdev) - 1; | indir_lbn[DOUBLE] = indir_lbn[SINGLE] - MNINDIR(fsdev) - 1; | ||||
indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - MNINDIR(fsdev) | indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - MNINDIR(fsdev) | ||||
* MNINDIR(fsdev) - 1; | * MNINDIR(fsdev) - 1; | ||||
for (i = 0; i < NIADDR; i++) { | for (i = 0; i < NANDFS_NIADDR; i++) { | ||||
f[i].in_off = MNINDIR(fsdev) - 1; | f[i].in_off = MNINDIR(fsdev) - 1; | ||||
f[i].in_lbn = 0xdeadbeef; | f[i].in_lbn = 0xdeadbeef; | ||||
} | } | ||||
left = todo; | left = todo; | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
a[num].in_off = -1; | a[num].in_off = -1; | ||||
Show All 39 Lines | #endif | ||||
} | } | ||||
free(copy, M_NANDFSTEMP); | free(copy, M_NANDFSTEMP); | ||||
direct: | direct: | ||||
if (num < 0) | if (num < 0) | ||||
i = lastblk; | i = lastblk; | ||||
else | else | ||||
i = NDADDR - 1; | i = NANDFS_NDADDR - 1; | ||||
for (; i >= 0 && left > 0; i--) { | for (; i >= 0 && left > 0; i--) { | ||||
if (ip->i_db[i] != 0) { | if (ip->i_db[i] != 0) { | ||||
error = nandfs_bdestroy(node, ip->i_db[i]); | error = nandfs_bdestroy(node, ip->i_db[i]); | ||||
if (error) { | if (error) { | ||||
nandfs_error("%s: cannot destroy " | nandfs_error("%s: cannot destroy " | ||||
"block %jx, error %d\n", __func__, | "block %jx, error %d\n", __func__, | ||||
(uintmax_t)ip->i_db[i], error); | (uintmax_t)ip->i_db[i], error); | ||||
Show All 9 Lines | KASSERT(left == 0, | ||||
("truncated wrong number of blocks (%jd should be 0)", left)); | ("truncated wrong number of blocks (%jd should be 0)", left)); | ||||
return (error); | return (error); | ||||
} | } | ||||
nandfs_lbn_t | nandfs_lbn_t | ||||
get_maxfilesize(struct nandfs_device *fsdev) | get_maxfilesize(struct nandfs_device *fsdev) | ||||
{ | { | ||||
struct nandfs_indir f[NIADDR]; | struct nandfs_indir f[NANDFS_NIADDR]; | ||||
nandfs_lbn_t max; | nandfs_lbn_t max; | ||||
int i; | int i; | ||||
max = NDADDR; | max = NANDFS_NDADDR; | ||||
for (i = 0; i < NIADDR; i++) { | for (i = 0; i < NANDFS_NIADDR; i++) { | ||||
f[i].in_off = MNINDIR(fsdev) - 1; | f[i].in_off = MNINDIR(fsdev) - 1; | ||||
max += blocks_inside(fsdev, i, f); | max += blocks_inside(fsdev, i, f); | ||||
} | } | ||||
max *= fsdev->nd_blocksize; | max *= fsdev->nd_blocksize; | ||||
return (max); | return (max); | ||||
} | } | ||||
Show All 26 Lines | bmap_getlbns(struct nandfs_node *node, nandfs_lbn_t bn, struct nandfs_indir *ap, int *nump) | ||||
if (nump) | if (nump) | ||||
*nump = 0; | *nump = 0; | ||||
numlevels = 0; | numlevels = 0; | ||||
realbn = bn; | realbn = bn; | ||||
if (bn < 0) | if (bn < 0) | ||||
bn = -bn; | bn = -bn; | ||||
/* The first NDADDR blocks are direct blocks. */ | /* The first NANDFS_NDADDR blocks are direct blocks. */ | ||||
if (bn < NDADDR) | if (bn < NANDFS_NDADDR) | ||||
return (0); | return (0); | ||||
/* | /* | ||||
* Determine the number of levels of indirection. After this loop | * Determine the number of levels of indirection. After this loop | ||||
* is done, blockcnt indicates the number of data blocks possible | * is done, blockcnt indicates the number of data blocks possible | ||||
* at the previous level of indirection, and NIADDR - i is the number | * at the previous level of indirection, and NANDFS_NIADDR - i is the | ||||
* of levels of indirection needed to locate the requested block. | * number of levels of indirection needed to locate the requested block. | ||||
*/ | */ | ||||
for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) { | for (blockcnt = 1, i = NANDFS_NIADDR, bn -= NANDFS_NDADDR;; i--, bn -= blockcnt) { | ||||
DPRINTF(BMAP, ("%s: blockcnt=%jd i=%d bn=%jd\n", __func__, | DPRINTF(BMAP, ("%s: blockcnt=%jd i=%d bn=%jd\n", __func__, | ||||
blockcnt, i, bn)); | blockcnt, i, bn)); | ||||
if (i == 0) | if (i == 0) | ||||
return (EFBIG); | return (EFBIG); | ||||
blockcnt *= MNINDIR(fsdev); | blockcnt *= MNINDIR(fsdev); | ||||
if (bn < blockcnt) | if (bn < blockcnt) | ||||
break; | break; | ||||
} | } | ||||
/* Calculate the address of the first meta-block. */ | /* Calculate the address of the first meta-block. */ | ||||
if (realbn >= 0) | if (realbn >= 0) | ||||
metalbn = -(realbn - bn + NIADDR - i); | metalbn = -(realbn - bn + NANDFS_NIADDR - i); | ||||
else | else | ||||
metalbn = -(-realbn - bn + NIADDR - i); | metalbn = -(-realbn - bn + NANDFS_NIADDR - i); | ||||
/* | /* | ||||
* At each iteration, off is the offset into the bap array which is | * At each iteration, off is the offset into the bap array which is | ||||
* an array of disk addresses at the current level of indirection. | * an array of disk addresses at the current level of indirection. | ||||
* The logical block number and the offset in that block are stored | * The logical block number and the offset in that block are stored | ||||
* into the argument array. | * into the argument array. | ||||
*/ | */ | ||||
ap->in_lbn = metalbn; | ap->in_lbn = metalbn; | ||||
ap->in_off = off = NIADDR - i; | ap->in_off = off = NANDFS_NIADDR - i; | ||||
DPRINTF(BMAP, ("%s: initial: ap->in_lbn=%jx ap->in_off=%d\n", __func__, | DPRINTF(BMAP, ("%s: initial: ap->in_lbn=%jx ap->in_off=%d\n", __func__, | ||||
metalbn, off)); | metalbn, off)); | ||||
ap++; | ap++; | ||||
for (++numlevels; i <= NIADDR; i++) { | for (++numlevels; i <= NANDFS_NIADDR; i++) { | ||||
/* If searching for a meta-data block, quit when found. */ | /* If searching for a meta-data block, quit when found. */ | ||||
if (metalbn == realbn) | if (metalbn == realbn) | ||||
break; | break; | ||||
blockcnt /= MNINDIR(fsdev); | blockcnt /= MNINDIR(fsdev); | ||||
off = (bn / blockcnt) % MNINDIR(fsdev); | off = (bn / blockcnt) % MNINDIR(fsdev); | ||||
++numlevels; | ++numlevels; | ||||
Show All 16 Lines |