From mboxrd@z Thu Jan 1 00:00:00 1970 From: liubo Subject: Re: [PATCH 2/2 v2] Btrfs: Per file/directory controls for COW and compression Date: Wed, 06 Apr 2011 09:23:30 +0800 Message-ID: <4D9BC092.1030307@cn.fujitsu.com> References: <4D8712E9.108@cn.fujitsu.com> <4D999000.1000608@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Cc: Linux Btrfs , Chris Mason To: Konstantinos Skarlatos Return-path: In-Reply-To: <4D999000.1000608@gmail.com> List-ID: On 04/04/2011 05:31 PM, Konstantinos Skarlatos wrote: > Hello, > I would like to ask about the status of this feature/patch, is it > accepted into btrfs code, and how can I use it? >=20 Yes, it is now in the latest 2.6.39-rc1. > I am interested in enabling compression in a specific > folder(force-compress would be ideal) of a large btrfs volume, and > disabling it for the rest. >=20 hmm, I'm making the tool's patch, and will come soon. :) >=20 > On 21/3/2011 10:57 =CF=80=CE=BC, liubo wrote: >> Data compression and data cow are controlled across the entire FS by >> mount >> options right now. ioctls are needed to set this on a per file or p= er >> directory basis. This has been proposed previously, but VFS develop= ers >> wanted us to use generic ioctls rather than btrfs-specific ones. >> >> According to chris's comment, there should be just one true compress= ion >> method(probably LZO) stored in the super. However, before this, we = would >> wait for that one method is stable enough to be adopted into the sup= er. >> So I list it as a long term goal, and just store it in ram today. >> >> After applying this patch, we can use the generic "FS_IOC_SETFLAGS" >> ioctl to >> control file and directory's datacow and compression attribute. >> >> NOTE: >> - The compression type is selected by such rules: >> If we mount btrfs with compress options, ie, zlib/lzo, the type = is >> it. >> Otherwise, we'll use the default compress type (zlib today). >> >> v1->v2: >> Rebase the patch with the latest btrfs. >> >> Signed-off-by: Liu Bo >> --- >> fs/btrfs/ctree.h | 1 + >> fs/btrfs/disk-io.c | 6 ++++++ >> fs/btrfs/inode.c | 32 ++++++++++++++++++++++++++++---- >> fs/btrfs/ioctl.c | 41 +++++++++++++++++++++++++++++++++++++---= - >> 4 files changed, 72 insertions(+), 8 deletions(-) >> >> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h >> index 8b4b9d1..b77d1a5 100644 >> --- a/fs/btrfs/ctree.h >> +++ b/fs/btrfs/ctree.h >> @@ -1283,6 +1283,7 @@ struct btrfs_root { >> #define BTRFS_INODE_NODUMP (1<< 8) >> #define BTRFS_INODE_NOATIME (1<< 9) >> #define BTRFS_INODE_DIRSYNC (1<< 10) >> +#define BTRFS_INODE_COMPRESS (1<< 11) >> >> /* some macros to generate set/get funcs for the struct fields. T= his >> * assumes there is a lefoo_to_cpu for every type, so lets make a >> simple >> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c >> index 3e1ea3e..a894c12 100644 >> --- a/fs/btrfs/disk-io.c >> +++ b/fs/btrfs/disk-io.c >> @@ -1762,6 +1762,12 @@ struct btrfs_root *open_ctree(struct >> super_block *sb, >> >> btrfs_check_super_valid(fs_info, sb->s_flags& MS_RDONLY); >> >> + /* >> + * In the long term, we'll store the compression type in the su= per >> + * block, and it'll be used for per file compression control. >> + */ >> + fs_info->compress_type =3D BTRFS_COMPRESS_ZLIB; >> + >> ret =3D btrfs_parse_options(tree_root, options); >> if (ret) { >> err =3D ret; >> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c >> index db67821..e687bb9 100644 >> --- a/fs/btrfs/inode.c >> +++ b/fs/btrfs/inode.c >> @@ -381,7 +381,8 @@ again: >> */ >> if (!(BTRFS_I(inode)->flags& BTRFS_INODE_NOCOMPRESS)&& >> (btrfs_test_opt(root, COMPRESS) || >> - (BTRFS_I(inode)->force_compress))) { >> + (BTRFS_I(inode)->force_compress) || >> + (BTRFS_I(inode)->flags& BTRFS_INODE_COMPRESS))) { >> WARN_ON(pages); >> pages =3D kzalloc(sizeof(struct page *) * nr_pages, GFP_NO= =46S); >> >> @@ -1253,7 +1254,8 @@ static int run_delalloc_range(struct inode >> *inode, struct page *locked_page, >> ret =3D run_delalloc_nocow(inode, locked_page, start, end, >> page_started, 0, nr_written); >> else if (!btrfs_test_opt(root, COMPRESS)&& >> - !(BTRFS_I(inode)->force_compress)) >> + !(BTRFS_I(inode)->force_compress)&& >> + !(BTRFS_I(inode)->flags& BTRFS_INODE_COMPRESS)) >> ret =3D cow_file_range(inode, locked_page, start, end, >> page_started, nr_written, 1); >> else >> @@ -4581,8 +4583,6 @@ static struct inode *btrfs_new_inode(struct >> btrfs_trans_handle *trans, >> location->offset =3D 0; >> btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); >> >> - btrfs_inherit_iflags(inode, dir); >> - >> if ((mode& S_IFREG)) { >> if (btrfs_test_opt(root, NODATASUM)) >> BTRFS_I(inode)->flags |=3D BTRFS_INODE_NODATASUM; >> @@ -4590,6 +4590,8 @@ static struct inode *btrfs_new_inode(struct >> btrfs_trans_handle *trans, >> BTRFS_I(inode)->flags |=3D BTRFS_INODE_NODATACOW; >> } >> >> + btrfs_inherit_iflags(inode, dir); >> + >> insert_inode_hash(inode); >> inode_tree_add(inode); >> return inode; >> @@ -6803,6 +6805,26 @@ static int btrfs_getattr(struct vfsmount *mnt= , >> return 0; >> } >> >> +/* >> + * If a file is moved, it will inherit the cow and compression flag= s >> of the new >> + * directory. >> + */ >> +static void fixup_inode_flags(struct inode *dir, struct inode *inod= e) >> +{ >> + struct btrfs_inode *b_dir =3D BTRFS_I(dir); >> + struct btrfs_inode *b_inode =3D BTRFS_I(inode); >> + >> + if (b_dir->flags& BTRFS_INODE_NODATACOW) >> + b_inode->flags |=3D BTRFS_INODE_NODATACOW; >> + else >> + b_inode->flags&=3D ~BTRFS_INODE_NODATACOW; >> + >> + if (b_dir->flags& BTRFS_INODE_COMPRESS) >> + b_inode->flags |=3D BTRFS_INODE_COMPRESS; >> + else >> + b_inode->flags&=3D ~BTRFS_INODE_COMPRESS; >> +} >> + >> static int btrfs_rename(struct inode *old_dir, struct dentry >> *old_dentry, >> struct inode *new_dir, struct dentry *new_dentry) >> { >> @@ -6936,6 +6958,8 @@ static int btrfs_rename(struct inode *old_dir, >> struct dentry *old_dentry, >> } >> } >> >> + fixup_inode_flags(new_dir, old_inode); >> + >> ret =3D btrfs_add_link(trans, new_dir, old_inode, >> new_dentry->d_name.name, >> new_dentry->d_name.len, 0, index); >> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c >> index 5fdb2ab..93e7f6c 100644 >> --- a/fs/btrfs/ioctl.c >> +++ b/fs/btrfs/ioctl.c >> @@ -138,6 +138,24 @@ static int btrfs_ioctl_getflags(struct file >> *file, void __user *arg) >> return 0; >> } >> >> +static int check_flags(unsigned int flags) >> +{ >> + if (flags& ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ >> + FS_NOATIME_FL | FS_NODUMP_FL | \ >> + FS_SYNC_FL | FS_DIRSYNC_FL | \ >> + FS_NOCOMP_FL | FS_COMPR_FL | \ >> + FS_NOCOW_FL | FS_COW_FL)) >> + return -EOPNOTSUPP; >> + >> + if ((flags& FS_NOCOMP_FL)&& (flags& FS_COMPR_FL)) >> + return -EINVAL; >> + >> + if ((flags& FS_NOCOW_FL)&& (flags& FS_COW_FL)) >> + return -EINVAL; >> + >> + return 0; >> +} >> + >> static int btrfs_ioctl_setflags(struct file *file, void __user *ar= g) >> { >> struct inode *inode =3D file->f_path.dentry->d_inode; >> @@ -153,10 +171,9 @@ static int btrfs_ioctl_setflags(struct file >> *file, void __user *arg) >> if (copy_from_user(&flags, arg, sizeof(flags))) >> return -EFAULT; >> >> - if (flags& ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ >> - FS_NOATIME_FL | FS_NODUMP_FL | \ >> - FS_SYNC_FL | FS_DIRSYNC_FL)) >> - return -EOPNOTSUPP; >> + ret =3D check_flags(flags); >> + if (ret) >> + return ret; >> >> if (!is_owner_or_cap(inode)) >> return -EACCES; >> @@ -201,6 +218,22 @@ static int btrfs_ioctl_setflags(struct file >> *file, void __user *arg) >> else >> ip->flags&=3D ~BTRFS_INODE_DIRSYNC; >> >> + /* >> + * The COMPRESS flag can only be changed by users, while the >> NOCOMPRESS >> + * flag may be changed automatically if compression code won't = make >> + * things smaller. >> + */ >> + if (flags& FS_NOCOMP_FL) { >> + ip->flags&=3D ~BTRFS_INODE_COMPRESS; >> + ip->flags |=3D BTRFS_INODE_NOCOMPRESS; >> + } else if (flags& FS_COMPR_FL) { >> + ip->flags |=3D BTRFS_INODE_COMPRESS; >> + ip->flags&=3D ~BTRFS_INODE_NOCOMPRESS; >> + } >> + if (flags& FS_NOCOW_FL) >> + ip->flags |=3D BTRFS_INODE_NODATACOW; >> + else if (flags& FS_COW_FL) >> + ip->flags&=3D ~BTRFS_INODE_NODATACOW; >> >> trans =3D btrfs_join_transaction(root, 1); >> BUG_ON(IS_ERR(trans)); >=20 >=20 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" = in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html