On 11/11/16 11:05 AM, Omar Sandoval wrote: > On Sat, Nov 05, 2016 at 01:26:34PM -0400, je...@suse.com wrote: >> From: Jeff Mahoney <je...@suse.com> >> >> Commit 3de4586c527 (Btrfs: Allow subvolumes and snapshots anywhere >> in the directory tree) introduced the current system of placing >> snapshots in the directory tree. It also introduced the behavior of >> creating the snapshot and then creating the directory entries for it. >> >> We've kept this code around for compatibility reasons, but it turns >> out that no file systems with the old tree_root based snapshots can >> be mounted on newer (>= 2009) kernels anyway. About a month after the >> above commit, commit 2a7108ad89e (Btrfs: rev the disk format for the >> inode compat and csum selection changes) landed, changing the superblock >> magic number. >> >> As a result, we know that we'll never encounter tree_root-based dirents >> or have to deal with skipping our own snapshot dirents. Since that >> also means that we're now only iterating over DIR_INDEX items, which only >> contain one directory entry per leaf item, we don't need to loop over >> the leaf item contents anymore either. >> >> Signed-off-by: Jeff Mahoney <je...@suse.com> > > Hi, Jeff,
Hi Omar - > One comment below. > >> --- >> fs/btrfs/inode.c | 118 >> +++++++++++++++++-------------------------------------- >> 1 file changed, 37 insertions(+), 81 deletions(-) >> >> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c >> index 2b790bd..c52239d 100644 >> --- a/fs/btrfs/inode.c >> +++ b/fs/btrfs/inode.c >> @@ -5805,20 +5805,13 @@ static int btrfs_real_readdir(struct file *file, >> struct dir_context *ctx) >> int slot; >> unsigned char d_type; >> int over = 0; >> - u32 di_cur; >> - u32 di_total; >> - u32 di_len; >> - int key_type = BTRFS_DIR_INDEX_KEY; >> char tmp_name[32]; >> char *name_ptr; >> int name_len; >> int is_curr = 0; /* ctx->pos points to the current index? */ >> bool emitted; >> bool put = false; >> - >> - /* FIXME, use a real flag for deciding about the key type */ >> - if (root->fs_info->tree_root == root) >> - key_type = BTRFS_DIR_ITEM_KEY; >> + struct btrfs_key location; >> >> if (!dir_emit_dots(file, ctx)) >> return 0; >> @@ -5829,14 +5822,11 @@ static int btrfs_real_readdir(struct file *file, >> struct dir_context *ctx) >> >> path->reada = READA_FORWARD; >> >> - if (key_type == BTRFS_DIR_INDEX_KEY) { >> - INIT_LIST_HEAD(&ins_list); >> - INIT_LIST_HEAD(&del_list); >> - put = btrfs_readdir_get_delayed_items(inode, &ins_list, >> - &del_list); >> - } >> + INIT_LIST_HEAD(&ins_list); >> + INIT_LIST_HEAD(&del_list); >> + put = btrfs_readdir_get_delayed_items(inode, &ins_list, &del_list); >> >> - key.type = key_type; >> + key.type = BTRFS_DIR_INDEX_KEY; >> key.offset = ctx->pos; >> key.objectid = btrfs_ino(inode); >> >> @@ -5862,85 +5852,53 @@ static int btrfs_real_readdir(struct file *file, >> struct dir_context *ctx) >> >> if (found_key.objectid != key.objectid) >> break; >> - if (found_key.type != key_type) >> + if (found_key.type != BTRFS_DIR_INDEX_KEY) >> break; >> if (found_key.offset < ctx->pos) >> goto next; >> - if (key_type == BTRFS_DIR_INDEX_KEY && >> - btrfs_should_delete_dir_index(&del_list, >> - found_key.offset)) >> + if (btrfs_should_delete_dir_index(&del_list, found_key.offset)) >> goto next; >> >> ctx->pos = found_key.offset; >> is_curr = 1; >> >> di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); >> - di_cur = 0; >> - di_total = btrfs_item_size(leaf, item); >> - >> - while (di_cur < di_total) { >> - struct btrfs_key location; >> - >> - if (verify_dir_item(root, leaf, di)) >> - break; >> + if (verify_dir_item(root, leaf, di)) >> + goto next; >> >> - name_len = btrfs_dir_name_len(leaf, di); >> - if (name_len <= sizeof(tmp_name)) { >> - name_ptr = tmp_name; >> - } else { >> - name_ptr = kmalloc(name_len, GFP_KERNEL); >> - if (!name_ptr) { >> - ret = -ENOMEM; >> - goto err; >> - } >> + name_len = btrfs_dir_name_len(leaf, di); >> + if (name_len <= sizeof(tmp_name)) { >> + name_ptr = tmp_name; >> + } else { >> + name_ptr = kmalloc(name_len, GFP_KERNEL); >> + if (!name_ptr) { >> + ret = -ENOMEM; >> + goto err; >> } >> - read_extent_buffer(leaf, name_ptr, >> - (unsigned long)(di + 1), name_len); >> - >> - d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; >> - btrfs_dir_item_key_to_cpu(leaf, di, &location); >> + } >> + read_extent_buffer(leaf, name_ptr, (unsigned long)(di + 1), >> + name_len); >> >> + d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; >> + btrfs_dir_item_key_to_cpu(leaf, di, &location); >> >> - /* is this a reference to our own snapshot? If so >> - * skip it. >> - * >> - * In contrast to old kernels, we insert the snapshot's >> - * dir item and dir index after it has been created, so >> - * we won't find a reference to our own snapshot. We >> - * still keep the following code for backward >> - * compatibility. >> - */ >> - if (location.type == BTRFS_ROOT_ITEM_KEY && >> - location.objectid == root->root_key.objectid) { >> - over = 0; >> - goto skip; >> - } >> - over = !dir_emit(ctx, name_ptr, name_len, >> - location.objectid, d_type); >> + over = !dir_emit(ctx, name_ptr, name_len, location.objectid, >> + d_type); >> >> -skip: >> - if (name_ptr != tmp_name) >> - kfree(name_ptr); >> + if (name_ptr != tmp_name) >> + kfree(name_ptr); >> >> - if (over) >> - goto nopos; >> - emitted = true; > > Shouldn't this line (getting rid of emitted) be in the next patch? Yep. Good catch. Thanks, -Jeff >> - di_len = btrfs_dir_name_len(leaf, di) + >> - btrfs_dir_data_len(leaf, di) + sizeof(*di); >> - di_cur += di_len; >> - di = (struct btrfs_dir_item *)((char *)di + di_len); >> - } >> + if (over) >> + goto nopos; >> next: >> path->slots[0]++; >> } >> >> - if (key_type == BTRFS_DIR_INDEX_KEY) { >> - if (is_curr) >> - ctx->pos++; >> - ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list, &emitted); >> - if (ret) >> - goto nopos; >> - } >> + if (is_curr) >> + ctx->pos++; >> + 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 >> @@ -5971,12 +5929,10 @@ static int btrfs_real_readdir(struct file *file, >> struct dir_context *ctx) >> * last entry requires it because doing so has broken 32bit apps >> * in the past. >> */ >> - if (key_type == BTRFS_DIR_INDEX_KEY) { >> - if (ctx->pos >= INT_MAX) >> - ctx->pos = LLONG_MAX; >> - else >> - ctx->pos = INT_MAX; >> - } >> + if (ctx->pos >= INT_MAX) >> + ctx->pos = LLONG_MAX; >> + else >> + ctx->pos = INT_MAX; >> nopos: >> ret = 0; >> err: >> -- >> 2.7.1 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >> the body of a message to majord...@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Jeff Mahoney SUSE Labs
signature.asc
Description: OpenPGP digital signature