aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3e3620e69bb9..e163b1b74707 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3038,8 +3038,7 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3038 return inode; 3038 return inode;
3039} 3039}
3040 3040
3041static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, 3041struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
3042 struct nameidata *nd)
3043{ 3042{
3044 struct inode * inode; 3043 struct inode * inode;
3045 struct btrfs_inode *bi = BTRFS_I(dir); 3044 struct btrfs_inode *bi = BTRFS_I(dir);
@@ -3067,13 +3066,21 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
3067 inode = btrfs_iget(dir->i_sb, &location, sub_root, &new); 3066 inode = btrfs_iget(dir->i_sb, &location, sub_root, &new);
3068 if (IS_ERR(inode)) 3067 if (IS_ERR(inode))
3069 return ERR_CAST(inode); 3068 return ERR_CAST(inode);
3070
3071 /* the inode and parent dir are two different roots */
3072 if (new && root != sub_root) {
3073 igrab(inode);
3074 sub_root->inode = inode;
3075 }
3076 } 3069 }
3070 return inode;
3071}
3072
3073static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
3074 struct nameidata *nd)
3075{
3076 struct inode *inode;
3077
3078 if (dentry->d_name.len > BTRFS_NAME_LEN)
3079 return ERR_PTR(-ENAMETOOLONG);
3080
3081 inode = btrfs_lookup_dentry(dir, dentry);
3082 if (IS_ERR(inode))
3083 return ERR_CAST(inode);
3077 3084
3078 return d_splice_alias(inode, dentry); 3085 return d_splice_alias(inode, dentry);
3079} 3086}
@@ -3129,7 +3136,6 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
3129 return 0; 3136 return 0;
3130 filp->f_pos = 2; 3137 filp->f_pos = 2;
3131 } 3138 }
3132
3133 path = btrfs_alloc_path(); 3139 path = btrfs_alloc_path();
3134 path->reada = 2; 3140 path->reada = 2;
3135 3141
@@ -3159,6 +3165,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
3159 path->slots[0]++; 3165 path->slots[0]++;
3160 } 3166 }
3161 } 3167 }
3168
3162 advance = 1; 3169 advance = 1;
3163 item = btrfs_item_nr(leaf, slot); 3170 item = btrfs_item_nr(leaf, slot);
3164 btrfs_item_key_to_cpu(leaf, &found_key, slot); 3171 btrfs_item_key_to_cpu(leaf, &found_key, slot);
@@ -3194,16 +3201,25 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
3194 3201
3195 d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; 3202 d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
3196 btrfs_dir_item_key_to_cpu(leaf, di, &location); 3203 btrfs_dir_item_key_to_cpu(leaf, di, &location);
3204
3205 /* is this a reference to our own snapshot? If so
3206 * skip it
3207 */
3208 if (location.type == BTRFS_ROOT_ITEM_KEY &&
3209 location.objectid == root->root_key.objectid) {
3210 over = 0;
3211 goto skip;
3212 }
3197 over = filldir(dirent, name_ptr, name_len, 3213 over = filldir(dirent, name_ptr, name_len,
3198 found_key.offset, location.objectid, 3214 found_key.offset, location.objectid,
3199 d_type); 3215 d_type);
3200 3216
3217skip:
3201 if (name_ptr != tmp_name) 3218 if (name_ptr != tmp_name)
3202 kfree(name_ptr); 3219 kfree(name_ptr);
3203 3220
3204 if (over) 3221 if (over)
3205 goto nopos; 3222 goto nopos;
3206
3207 di_len = btrfs_dir_name_len(leaf, di) + 3223 di_len = btrfs_dir_name_len(leaf, di) +
3208 btrfs_dir_data_len(leaf, di) + sizeof(*di); 3224 btrfs_dir_data_len(leaf, di) + sizeof(*di);
3209 di_cur += di_len; 3225 di_cur += di_len;
@@ -3318,8 +3334,7 @@ out:
3318 * helper to find a free sequence number in a given directory. This current 3334 * helper to find a free sequence number in a given directory. This current
3319 * code is very simple, later versions will do smarter things in the btree 3335 * code is very simple, later versions will do smarter things in the btree
3320 */ 3336 */
3321static int btrfs_set_inode_index(struct inode *dir, struct inode *inode, 3337int btrfs_set_inode_index(struct inode *dir, u64 *index)
3322 u64 *index)
3323{ 3338{
3324 int ret = 0; 3339 int ret = 0;
3325 3340
@@ -3365,7 +3380,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3365 return ERR_PTR(-ENOMEM); 3380 return ERR_PTR(-ENOMEM);
3366 3381
3367 if (dir) { 3382 if (dir) {
3368 ret = btrfs_set_inode_index(dir, inode, index); 3383 ret = btrfs_set_inode_index(dir, index);
3369 if (ret) 3384 if (ret)
3370 return ERR_PTR(ret); 3385 return ERR_PTR(ret);
3371 } 3386 }
@@ -3651,7 +3666,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
3651 err = btrfs_check_free_space(root, 1, 0); 3666 err = btrfs_check_free_space(root, 1, 0);
3652 if (err) 3667 if (err)
3653 goto fail; 3668 goto fail;
3654 err = btrfs_set_inode_index(dir, inode, &index); 3669 err = btrfs_set_inode_index(dir, &index);
3655 if (err) 3670 if (err)
3656 goto fail; 3671 goto fail;
3657 3672
@@ -4349,13 +4364,13 @@ out:
4349 * Invalidate a single dcache entry at the root of the filesystem. 4364 * Invalidate a single dcache entry at the root of the filesystem.
4350 * Needed after creation of snapshot or subvolume. 4365 * Needed after creation of snapshot or subvolume.
4351 */ 4366 */
4352void btrfs_invalidate_dcache_root(struct btrfs_root *root, char *name, 4367void btrfs_invalidate_dcache_root(struct inode *dir, char *name,
4353 int namelen) 4368 int namelen)
4354{ 4369{
4355 struct dentry *alias, *entry; 4370 struct dentry *alias, *entry;
4356 struct qstr qstr; 4371 struct qstr qstr;
4357 4372
4358 alias = d_find_alias(root->fs_info->sb->s_root->d_inode); 4373 alias = d_find_alias(dir);
4359 if (alias) { 4374 if (alias) {
4360 qstr.name = name; 4375 qstr.name = name;
4361 qstr.len = namelen; 4376 qstr.len = namelen;
@@ -4387,7 +4402,6 @@ int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry,
4387 return PTR_ERR(inode); 4402 return PTR_ERR(inode);
4388 inode->i_op = &btrfs_dir_inode_operations; 4403 inode->i_op = &btrfs_dir_inode_operations;
4389 inode->i_fop = &btrfs_dir_file_operations; 4404 inode->i_fop = &btrfs_dir_file_operations;
4390 new_root->inode = inode;
4391 4405
4392 inode->i_nlink = 1; 4406 inode->i_nlink = 1;
4393 btrfs_i_size_write(inode, 0); 4407 btrfs_i_size_write(inode, 0);
@@ -4590,7 +4604,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
4590 } 4604 }
4591 4605
4592 } 4606 }
4593 ret = btrfs_set_inode_index(new_dir, old_inode, &index); 4607 ret = btrfs_set_inode_index(new_dir, &index);
4594 if (ret) 4608 if (ret)
4595 goto out_fail; 4609 goto out_fail;
4596 4610