Ejemplo n.º 1
0
int f2fs_read_inline_dir(struct file *file, void *dirent, filldir_t filldir,
                         struct f2fs_str *fstr)
{
    unsigned long pos = file->f_pos;
    unsigned int bit_pos = 0;
    struct inode *inode = file_inode(file);
    struct f2fs_inline_dentry *inline_dentry = NULL;
    struct page *ipage = NULL;
    struct f2fs_dentry_ptr d;

    if (pos >= NR_INLINE_DENTRY)
        return 0;

    bit_pos = (pos % NR_INLINE_DENTRY);

    ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
    if (IS_ERR(ipage))
        return PTR_ERR(ipage);

    inline_dentry = inline_data_addr(ipage);

    make_dentry_ptr(inode, &d, (void *)inline_dentry, 2);

    if (!f2fs_fill_dentries(file, dirent, filldir, &d, 0, bit_pos, fstr))
        file->f_pos = NR_INLINE_DENTRY;

    f2fs_put_page(ipage, 1);
    return 0;
}
Ejemplo n.º 2
0
Archivo: inline.c Proyecto: mdamt/linux
int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
				struct fscrypt_str *fstr)
{
	struct inode *inode = file_inode(file);
	struct f2fs_inline_dentry *inline_dentry = NULL;
	struct page *ipage = NULL;
	struct f2fs_dentry_ptr d;
	int err;

	if (ctx->pos == NR_INLINE_DENTRY)
		return 0;

	ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
	if (IS_ERR(ipage))
		return PTR_ERR(ipage);

	inline_dentry = inline_data_addr(ipage);

	make_dentry_ptr_inline(inode, &d, inline_dentry);

	err = f2fs_fill_dentries(ctx, &d, 0, fstr);
	if (!err)
		ctx->pos = NR_INLINE_DENTRY;

	f2fs_put_page(ipage, 1);
	return err < 0 ? err : 0;
}
Ejemplo n.º 3
0
static int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	unsigned long pos = file->f_pos;
	unsigned int bit_pos = 0;
	struct inode *inode = file_inode(file);
	unsigned long npages = dir_blocks(inode);
	struct f2fs_dentry_block *dentry_blk = NULL;
	struct page *dentry_page = NULL;
	struct file_ra_state *ra = &file->f_ra;
	struct f2fs_dentry_ptr d;
	unsigned int n = 0;

	if (f2fs_has_inline_dentry(inode))
		return f2fs_read_inline_dir(file, dirent, filldir);

	bit_pos = (pos % NR_DENTRY_IN_BLOCK);
	n = (pos / NR_DENTRY_IN_BLOCK);

	/* readahead for multi pages of dir */
	if (npages - n > 1 && !ra_has_index(ra, n))
		page_cache_sync_readahead(inode->i_mapping, ra, file, n,
				min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES));

	for (; n < npages; n++) {
		dentry_page = get_lock_data_page(inode, n);
		if (IS_ERR(dentry_page))
			continue;

		dentry_blk = kmap(dentry_page);

		make_dentry_ptr(&d, (void *)dentry_blk, 1);

		if (f2fs_fill_dentries(file, dirent, filldir, &d, n, bit_pos))
			goto stop;

		bit_pos = 0;
		file->f_pos = (n + 1) * NR_DENTRY_IN_BLOCK;
		kunmap(dentry_page);
		f2fs_put_page(dentry_page, 1);
		dentry_page = NULL;
	}
stop:
	if (dentry_page && !IS_ERR(dentry_page)) {
		kunmap(dentry_page);
		f2fs_put_page(dentry_page, 1);
	}

	return 0;
}