/* Get pblock for a given inode and lblock. If extent is not NULL, it will * store the length of extent, that is, the number of consecutive pblocks * that are also consecutive lblocks (not counting the requested one). */ uint64_t inode_get_data_pblock(struct ext4_inode *inode, uint32_t lblock, uint32_t *extent_len) { if (extent_len) *extent_len = 1; if (inode->i_flags & EXT4_EXTENTS_FL) { return extent_get_pblock(&inode->i_block, lblock, extent_len); } else { ASSERT(lblock <= BYTES2BLOCKS(inode_get_size(inode))); if (lblock < EXT4_NDIR_BLOCKS) { return inode->i_block[lblock]; } else if (lblock < MAX_IND_BLOCK) { uint32_t index_block = inode->i_block[EXT4_IND_BLOCK]; return __inode_get_data_pblock_ind(lblock - EXT4_NDIR_BLOCKS, index_block); } else if (lblock < MAX_DIND_BLOCK) { uint32_t dindex_block = inode->i_block[EXT4_DIND_BLOCK]; return __inode_get_data_pblock_dind(lblock - MAX_IND_BLOCK, dindex_block); } else if (lblock < MAX_TIND_BLOCK) { uint32_t tindex_block = inode->i_block[EXT4_TIND_BLOCK]; return __inode_get_data_pblock_tind(lblock - MAX_DIND_BLOCK, tindex_block); } else { /* File-system corruption? */ ASSERT(0); } } /* Should never reach here */ ASSERT(0); return 0; }
struct ext4_dir_entry_2 *inode_dentry_get(struct ext4_inode *inode, off_t offset, struct inode_dir_ctx *ctx) { uint32_t lblock = offset / BLOCK_SIZE; uint32_t blk_offset = offset % BLOCK_SIZE; uint64_t inode_size = inode_get_size(inode); size_t un_offset = (size_t)offset; DEBUG("%zd/%"PRIu64"", un_offset, inode_size); ASSERT(inode_size >= un_offset); if (inode_size == un_offset) { return NULL; } if (lblock == ctx->lblock) { return (struct ext4_dir_entry_2 *)&ctx->buf[blk_offset]; } else { dir_ctx_update(inode, lblock, ctx); return inode_dentry_get(inode, un_offset, ctx); } }
int op_getattr(const char *path, struct stat *stbuf) { struct ext4_inode raw_inode; struct inode *inode; int ret = 0; uint64_t size; DEBUG("getattr(%s)", path); memset(stbuf, 0, sizeof(struct stat)); ret = inode_get_by_path(path, &raw_inode); if (ret < 0) { return ret; } inode = inode_get(0, &raw_inode); if (!inode) return -ENOMEM; size = inode_get_size(inode); inode_put(inode); DEBUG("getattr done"); stbuf->st_mode = raw_inode.i_mode; stbuf->st_nlink = raw_inode.i_links_count; stbuf->st_size = size; stbuf->st_blocks = raw_inode.i_blocks_lo; stbuf->st_uid = raw_inode.i_uid; stbuf->st_gid = raw_inode.i_gid; stbuf->st_atime = raw_inode.i_atime; stbuf->st_mtime = raw_inode.i_mtime; stbuf->st_ctime = raw_inode.i_ctime; return 0; }