Merge branch 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "This has a few fixes from Filipe, along with a readdir fix from Dave that we've been testing for some time" * 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: btrfs: properly set the termination value of ctx->pos in readdir Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl Btrfs: remove no longer used function extent_read_full_page_nolock() Btrfs: fix page reading in extent_same ioctl leading to csum errors Btrfs: fix invalid page accesses in extent_same (dedup) ioctl
This commit is contained in:
@@ -5717,6 +5717,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
|
||||
char *name_ptr;
|
||||
int name_len;
|
||||
int is_curr = 0; /* ctx->pos points to the current index? */
|
||||
bool emitted;
|
||||
|
||||
/* FIXME, use a real flag for deciding about the key type */
|
||||
if (root->fs_info->tree_root == root)
|
||||
@@ -5745,6 +5746,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
emitted = false;
|
||||
while (1) {
|
||||
leaf = path->nodes[0];
|
||||
slot = path->slots[0];
|
||||
@@ -5824,6 +5826,7 @@ skip:
|
||||
|
||||
if (over)
|
||||
goto nopos;
|
||||
emitted = true;
|
||||
di_len = btrfs_dir_name_len(leaf, di) +
|
||||
btrfs_dir_data_len(leaf, di) + sizeof(*di);
|
||||
di_cur += di_len;
|
||||
@@ -5836,11 +5839,20 @@ next:
|
||||
if (key_type == BTRFS_DIR_INDEX_KEY) {
|
||||
if (is_curr)
|
||||
ctx->pos++;
|
||||
ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list);
|
||||
ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list, &emitted);
|
||||
if (ret)
|
||||
goto nopos;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we haven't emitted any dir entry, we must not touch ctx->pos as
|
||||
* it was was set to the termination value in previous call. We assume
|
||||
* that "." and ".." were emitted if we reach this point and set the
|
||||
* termination value as well for an empty directory.
|
||||
*/
|
||||
if (ctx->pos > 2 && !emitted)
|
||||
goto nopos;
|
||||
|
||||
/* Reached end of directory/root. Bump pos past the last item. */
|
||||
ctx->pos++;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user