Btrfs: avoid setting ->d_op twice
PATCH 1/1 Btrfs: avoid setting ->d_op twice
Follow those instructions, and you'll trigger a warning in the beginning of d_set_d_op():
# mkfs.btrfs /dev/loop3 # mount /dev/loop3 /mnt # btrfs sub create /mnt/sub # btrfs sub snap /mnt /mnt/snap # touch /mnt/snap/sub touch: cannot touch `tmp': Permission denied
__d_alloc() set d_op to sb->s_d_op (btrfs_dentry_operations), and then simple_lookup() reset it to simple_dentry_operations, which triggered the warning.
--- fs/btrfs/inode.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-)
fs/btrfs/inode.c +9 -5
@@ -3908,7 +3908,7 @@ static struct inode *new_simple_dir(struct super_block *s,BTRFS_I (inode)->dummy_inode =1 ; inode->i_ino =BTRFS_EMPTY_SUBVOL_DIR_OBJECTID ; - inode->i_op = &simple_dir_inode_operations; + inode->i_op = &btrfs_dir_ro_inode_operations; inode->i_fop = &simple_dir_operations; inode->i_mode =S_IFDIR |S_IRUGO |S_IWUSR |S_IXUGO ; inode->i_mtime = inode->i_atime = inode->i_ctime =CURRENT_TIME ;
@@ -3979,14 +3979,18 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)static int btrfs_dentry_delete (const struct dentry *dentry) {struct btrfs_root *root; +struct inode *inode = dentry->d_inode; -if (!dentry->d_inode && !IS_ROOT (dentry)) - dentry = dentry->d_parent; +if (!inode && !IS_ROOT (dentry)) + inode = dentry->d_parent->d_inode; -if (dentry->d_inode) { - root =BTRFS_I (dentry->d_inode)->root; +if (inode) { + root =BTRFS_I (inode)->root;if (btrfs_root_refs (&root->root_item) ==0 )return 1 ; + +if (btrfs_ino (inode) ==BTRFS_EMPTY_SUBVOL_DIR_OBJECTID ) +return 1 ; }return 0 ; }
Signature · 1 line
1.7.3.1
Hi,
thanks for the patch!
Quoted 9 lines · Li Zefan
Follow those instructions, and you'll trigger a warning in the beginning of
d_set_d_op():# mkfs.btrfs /dev/loop3 # mount /dev/loop3 /mnt # btrfs sub create /mnt/sub # btrfs sub snap /mnt /mnt/snap # touch /mnt/snap/sub touch: cannot touch `tmp': Permission denied
is this the right error code? permission denied == EACCESS and this is returned in case of file
(strace touch file)
open("file", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = -1 EACCES (Permission denied)
while mkdir returns (strace mkdir a-dir)
mkdir("a-dir", 0777) = -1 EPERM (Operation not permitted)
The commands were run as root and EPERM looks more adequate than EACCESS.
david
Quoted 22 lines · David Sterba
Hi,
thanks for the patch!
Quoted 9 lines · Li Zefan
Follow those instructions, and you'll trigger a warning in the beginning of
d_set_d_op():# mkfs.btrfs /dev/loop3 # mount /dev/loop3 /mnt # btrfs sub create /mnt/sub # btrfs sub snap /mnt /mnt/snap # touch /mnt/snap/sub touch: cannot touch `tmp': Permission deniedis this the right error code? permission denied == EACCESS and this is returned in case of file
(strace touch file)
open("file", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666)= -1 EACCES (Permission denied)
Quoted 8 lines
while mkdir returns (strace mkdir a-dir)
mkdir("a-dir", 0777)= -1 EPERM (Operation not permitted)The commands were run as root and EPERM looks more adequate than EACCESS.
This is a different issue, and EPERM is returned by VFS not btrfs.
Feel free to submit a patch to fsdevel for discussion.