1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
/********************* implementation of iterate ******************************/
/*
* routine called when the VFS needs to read the directory contents
*
* @file: the VFS file structure of the directory
* @ctx: directory context
*
* return: 0 on success, error code otherwise
*/
static int wtfs_iterate(struct file * file, struct dir_context * ctx)
{
struct inode * dir_vi = file_inode(file);
struct super_block * vsb = dir_vi->i_sb;
struct wtfs_inode_info * info = WTFS_INODE_INFO(dir_vi);
struct wtfs_dir_block * block = NULL;
struct buffer_head * bh = NULL;
uint64_t count, offset, next, inode_no;
char * filename = NULL;
int i, j, k;
int ret = -EINVAL;
/* calculate how many entries we have counted, including null entries */
count = ctx->pos / sizeof(struct wtfs_dentry);
offset = ctx->pos % sizeof(struct wtfs_dentry);
if (offset != 0) {
wtfs_error("bad position %llu at %s:%lu\n", ctx->pos,
dir_vi->i_sb->s_id, dir_vi->i_ino);
goto error;
}
/* do iterate */
next = info->first_block;
i = 0; /* valid entry counter */
j = 0; /* total entry counter, including null ones */
while (next != 0) {
if ((bh = sb_bread(vsb, next)) == NULL) {
wtfs_error("unable to read the block %llu\n", next);
goto error;
}
block = (struct wtfs_dir_block *)bh->b_data;
for (k = 0; k < WTFS_DENTRY_COUNT_PER_BLOCK; ++k) {
inode_no = wtfs64_to_cpu(block->entries[k].inode_no);
filename = block->entries[k].filename;
if (inode_no != 0) {
if (j >= count && i < info->dir_entry_count) {
wtfs_debug("emitting entry '%s' of "
"inode %llu\n",
filename, inode_no);
if (dir_emit(ctx, filename,
strnlen(filename,
WTFS_FILENAME_MAX),
inode_no, DT_UNKNOWN) == 0) {
brelse(bh);
return 0;
}
}
++i;
}
++j;
ctx->pos += sizeof(struct wtfs_dentry);
}
next = wtfs64_to_cpu(block->next);
brelse(bh);
}
return 0;
error:
if (bh != NULL) {
brelse(bh);
}
return ret;
} |
Partager