Commit 9cdda8d3 authored by Al Viro's avatar Al Viro
Browse files

[readdir] convert btrfs



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 8e28bc7e
Loading
Loading
Loading
Loading
+4 −5
Original line number Original line Diff line number Diff line
@@ -1681,8 +1681,7 @@ int btrfs_should_delete_dir_index(struct list_head *del_list,
 * btrfs_readdir_delayed_dir_index - read dir info stored in the delayed tree
 * btrfs_readdir_delayed_dir_index - read dir info stored in the delayed tree
 *
 *
 */
 */
int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent,
int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
				    filldir_t filldir,
				    struct list_head *ins_list)
				    struct list_head *ins_list)
{
{
	struct btrfs_dir_item *di;
	struct btrfs_dir_item *di;
@@ -1704,13 +1703,13 @@ int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent,
	list_for_each_entry_safe(curr, next, ins_list, readdir_list) {
	list_for_each_entry_safe(curr, next, ins_list, readdir_list) {
		list_del(&curr->readdir_list);
		list_del(&curr->readdir_list);


		if (curr->key.offset < filp->f_pos) {
		if (curr->key.offset < ctx->pos) {
			if (atomic_dec_and_test(&curr->refs))
			if (atomic_dec_and_test(&curr->refs))
				kfree(curr);
				kfree(curr);
			continue;
			continue;
		}
		}


		filp->f_pos = curr->key.offset;
		ctx->pos = curr->key.offset;


		di = (struct btrfs_dir_item *)curr->data;
		di = (struct btrfs_dir_item *)curr->data;
		name = (char *)(di + 1);
		name = (char *)(di + 1);
@@ -1719,7 +1718,7 @@ int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent,
		d_type = btrfs_filetype_table[di->type];
		d_type = btrfs_filetype_table[di->type];
		btrfs_disk_key_to_cpu(&location, &di->location);
		btrfs_disk_key_to_cpu(&location, &di->location);


		over = filldir(dirent, name, name_len, curr->key.offset,
		over = !dir_emit(ctx, name, name_len,
			       location.objectid, d_type);
			       location.objectid, d_type);


		if (atomic_dec_and_test(&curr->refs))
		if (atomic_dec_and_test(&curr->refs))
+1 −2
Original line number Original line Diff line number Diff line
@@ -139,8 +139,7 @@ void btrfs_put_delayed_items(struct list_head *ins_list,
			     struct list_head *del_list);
			     struct list_head *del_list);
int btrfs_should_delete_dir_index(struct list_head *del_list,
int btrfs_should_delete_dir_index(struct list_head *del_list,
				  u64 index);
				  u64 index);
int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent,
int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
				    filldir_t filldir,
				    struct list_head *ins_list);
				    struct list_head *ins_list);


/* for init */
/* for init */
+16 −33
Original line number Original line Diff line number Diff line
@@ -5137,10 +5137,9 @@ unsigned char btrfs_filetype_table[] = {
	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
};
};


static int btrfs_real_readdir(struct file *filp, void *dirent,
static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
			      filldir_t filldir)
{
{
	struct inode *inode = file_inode(filp);
	struct inode *inode = file_inode(file);
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_item *item;
	struct btrfs_item *item;
	struct btrfs_dir_item *di;
	struct btrfs_dir_item *di;
@@ -5161,29 +5160,15 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
	char tmp_name[32];
	char tmp_name[32];
	char *name_ptr;
	char *name_ptr;
	int name_len;
	int name_len;
	int is_curr = 0;	/* filp->f_pos points to the current index? */
	int is_curr = 0;	/* ctx->pos points to the current index? */


	/* FIXME, use a real flag for deciding about the key type */
	/* FIXME, use a real flag for deciding about the key type */
	if (root->fs_info->tree_root == root)
	if (root->fs_info->tree_root == root)
		key_type = BTRFS_DIR_ITEM_KEY;
		key_type = BTRFS_DIR_ITEM_KEY;


	/* special case for "." */
	if (!dir_emit_dots(file, ctx))
	if (filp->f_pos == 0) {
		over = filldir(dirent, ".", 1,
			       filp->f_pos, btrfs_ino(inode), DT_DIR);
		if (over)
			return 0;
		filp->f_pos = 1;
	}
	/* special case for .., just use the back ref */
	if (filp->f_pos == 1) {
		u64 pino = parent_ino(filp->f_path.dentry);
		over = filldir(dirent, "..", 2,
			       filp->f_pos, pino, DT_DIR);
		if (over)
		return 0;
		return 0;
		filp->f_pos = 2;

	}
	path = btrfs_alloc_path();
	path = btrfs_alloc_path();
	if (!path)
	if (!path)
		return -ENOMEM;
		return -ENOMEM;
@@ -5197,7 +5182,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
	}
	}


	btrfs_set_key_type(&key, key_type);
	btrfs_set_key_type(&key, key_type);
	key.offset = filp->f_pos;
	key.offset = ctx->pos;
	key.objectid = btrfs_ino(inode);
	key.objectid = btrfs_ino(inode);


	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
@@ -5223,14 +5208,14 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
			break;
			break;
		if (btrfs_key_type(&found_key) != key_type)
		if (btrfs_key_type(&found_key) != key_type)
			break;
			break;
		if (found_key.offset < filp->f_pos)
		if (found_key.offset < ctx->pos)
			goto next;
			goto next;
		if (key_type == BTRFS_DIR_INDEX_KEY &&
		if (key_type == BTRFS_DIR_INDEX_KEY &&
		    btrfs_should_delete_dir_index(&del_list,
		    btrfs_should_delete_dir_index(&del_list,
						  found_key.offset))
						  found_key.offset))
			goto next;
			goto next;


		filp->f_pos = found_key.offset;
		ctx->pos = found_key.offset;
		is_curr = 1;
		is_curr = 1;


		di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
		di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
@@ -5274,9 +5259,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
				over = 0;
				over = 0;
				goto skip;
				goto skip;
			}
			}
			over = filldir(dirent, name_ptr, name_len,
			over = !dir_emit(ctx, name_ptr, name_len,
				       found_key.offset, location.objectid,
				       location.objectid, d_type);
				       d_type);


skip:
skip:
			if (name_ptr != tmp_name)
			if (name_ptr != tmp_name)
@@ -5295,9 +5279,8 @@ next:


	if (key_type == BTRFS_DIR_INDEX_KEY) {
	if (key_type == BTRFS_DIR_INDEX_KEY) {
		if (is_curr)
		if (is_curr)
			filp->f_pos++;
			ctx->pos++;
		ret = btrfs_readdir_delayed_dir_index(filp, dirent, filldir,
		ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list);
						      &ins_list);
		if (ret)
		if (ret)
			goto nopos;
			goto nopos;
	}
	}
@@ -5308,9 +5291,9 @@ next:
		 * 32-bit glibc will use getdents64, but then strtol -
		 * 32-bit glibc will use getdents64, but then strtol -
		 * so the last number we can serve is this.
		 * so the last number we can serve is this.
		 */
		 */
		filp->f_pos = 0x7fffffff;
		ctx->pos = 0x7fffffff;
	else
	else
		filp->f_pos++;
		ctx->pos++;
nopos:
nopos:
	ret = 0;
	ret = 0;
err:
err:
@@ -8731,7 +8714,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
static const struct file_operations btrfs_dir_file_operations = {
static const struct file_operations btrfs_dir_file_operations = {
	.llseek		= generic_file_llseek,
	.llseek		= generic_file_llseek,
	.read		= generic_read_dir,
	.read		= generic_read_dir,
	.readdir	= btrfs_real_readdir,
	.iterate	= btrfs_real_readdir,
	.unlocked_ioctl	= btrfs_ioctl,
	.unlocked_ioctl	= btrfs_ioctl,
#ifdef CONFIG_COMPAT
#ifdef CONFIG_COMPAT
	.compat_ioctl	= btrfs_ioctl,
	.compat_ioctl	= btrfs_ioctl,