提交 9cdda8d3 编写于 作者: A Al Viro

[readdir] convert btrfs

Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 8e28bc7e
...@@ -1681,8 +1681,7 @@ int btrfs_should_delete_dir_index(struct list_head *del_list, ...@@ -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, ...@@ -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, ...@@ -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))
......
...@@ -139,8 +139,7 @@ void btrfs_put_delayed_items(struct list_head *ins_list, ...@@ -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 */
......
...@@ -5137,10 +5137,9 @@ unsigned char btrfs_filetype_table[] = { ...@@ -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, ...@@ -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) { return 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;
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, ...@@ -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, ...@@ -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, ...@@ -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 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, ...@@ -5295,9 +5279,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
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 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, ...@@ -5308,9 +5291,9 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
* 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 = { ...@@ -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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册