static int sfs_bmap_get_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, uint32_t index, bool create, uint32_t *ino_store) { struct sfs_disk_inode *din = sin->din; int ret; uint32_t ent, ino; if (index < SFS_NDIRECT) { if ((ino = din->direct[index]) == 0 && create) { if ((ret = sfs_block_alloc(sfs, &ino)) != 0) { return ret; } din->direct[index] = ino; sin->dirty = 1; } goto out; } index -= SFS_NDIRECT; if (index < SFS_BLK_NENTRY) { ent = din->indirect; if ((ret = sfs_bmap_get_sub_nolock(sfs, &ent, index, create, &ino)) != 0) { return ret; } if (ent != din->indirect) { assert(din->indirect == 0); din->indirect = ent; sin->dirty = 1; } goto out; } index -= SFS_BLK_NENTRY; ent = din->db_indirect; if ((ret = sfs_bmap_get_sub_nolock(sfs, &ent, index / SFS_BLK_NENTRY, create, &ino)) != 0) { return ret; } if (ent != din->db_indirect) { assert(din->db_indirect == 0); din->db_indirect = ent; sin->dirty = 1; } if ((ent = ino) != 0) { if ((ret = sfs_bmap_get_sub_nolock(sfs, &ent, index % SFS_BLK_NENTRY, create, &ino)) != 0) { return ret; } } out: assert(ino == 0 || sfs_block_inuse(sfs, ino)); *ino_store = ino; return 0; }
/* * sfs_bmap_get_nolock - according sfs_inode and index of block, find the NO. of disk block * no lock protect * @sfs: sfs file system * @sin: sfs inode in memory * @index: the index of block in inode * @create: BOOL, if the block isn't allocated, if create = 1 the alloc a block, otherwise just do nothing * @ino_store: 0 OR the index of already inused block or new allocated block. */ static int sfs_bmap_get_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, uint32_t index, bool create, uint32_t *ino_store) { struct sfs_disk_inode *din = sin->din; int ret; uint32_t ent, ino; // the index of disk block is in the fist SFS_NDIRECT direct blocks if (index < SFS_NDIRECT) { if ((ino = din->direct[index]) == 0 && create) { if ((ret = sfs_block_alloc(sfs, &ino)) != 0) { return ret; } din->direct[index] = ino; sin->dirty = 1; } goto out; } // the index of disk block is in the indirect blocks. index -= SFS_NDIRECT; if (index < SFS_BLK_NENTRY) { ent = din->indirect; if ((ret = sfs_bmap_get_sub_nolock(sfs, &ent, index, create, &ino)) != 0) { return ret; } if (ent != din->indirect) { assert(din->indirect == 0); din->indirect = ent; sin->dirty = 1; } goto out; } else { panic ("sfs_bmap_get_nolock - index out of range"); } out: assert(ino == 0 || sfs_block_inuse(sfs, ino)); *ino_store = ino; return 0; }
static int sfs_bmap_free_nolock(struct sfs_fs *sfs, struct sfs_inode *sin, uint32_t index) { struct sfs_disk_inode *din = sin->din; int ret; uint32_t ent, ino; if (index < SFS_NDIRECT) { if ((ino = din->direct[index]) != 0) { sfs_block_free(sfs, ino); din->direct[index] = 0; sin->dirty = 1; } return 0; } index -= SFS_NDIRECT; if (index < SFS_BLK_NENTRY) { if ((ent = din->indirect) != 0) { if ((ret = sfs_bmap_free_sub_nolock(sfs, ent, index)) != 0) { return ret; } } return 0; } index -= SFS_BLK_NENTRY; if ((ent = din->db_indirect) != 0) { if ((ret = sfs_bmap_get_sub_nolock(sfs, &ent, index / SFS_BLK_NENTRY, 0, &ino)) != 0) { return ret; } if ((ent = ino) != 0) { if ((ret = sfs_bmap_free_sub_nolock(sfs, ent, index % SFS_BLK_NENTRY)) != 0) { return ret; } } } return 0; }