linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Konstantinos Skarlatos <k.skarlatos@gmail.com>
To: liubo <liubo2009@cn.fujitsu.com>
Cc: Linux Btrfs <linux-btrfs@vger.kernel.org>,
	Chris Mason <chris.mason@oracle.com>
Subject: Re: [PATCH 2/2 v2] Btrfs: Per file/directory controls for COW and compression
Date: Mon, 04 Apr 2011 12:31:44 +0300	[thread overview]
Message-ID: <4D999000.1000608@gmail.com> (raw)
In-Reply-To: <4D8712E9.108@cn.fujitsu.com>

Hello,
I would like to ask about the status of this feature/patch, is it=20
accepted into btrfs code, and how can I use it?

I am interested in enabling compression in a specific=20
folder(force-compress would be ideal) of a large btrfs volume, and=20
disabling it for the rest.


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 pe=
r
> directory basis.  This has been proposed previously, but VFS develope=
rs
> wanted us to use generic ioctls rather than btrfs-specific ones.
>
> According to chris's comment, there should be just one true compressi=
on
> method(probably LZO) stored in the super.  However, before this, we w=
ould
> wait for that one method is stable enough to be adopted into the supe=
r.
> 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" i=
octl 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 i=
s 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<liubo2009@cn.fujitsu.com>
> ---
>   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.  Th=
is
>    * assumes there is a lefoo_to_cpu for every type, so lets make a s=
imple
> 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_blo=
ck *sb,
>
>   	btrfs_check_super_valid(fs_info, sb->s_flags&  MS_RDONLY);
>
> +	/*
> +	 * In the long term, we'll store the compression type in the super
> +	 * 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_NOFS);
>
> @@ -1253,7 +1254,8 @@ static int run_delalloc_range(struct inode *ino=
de, 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 btr=
fs_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 btr=
fs_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 flags=
 of the new
> + * directory.
> + */
> +static void fixup_inode_flags(struct inode *dir, struct inode *inode=
)
> +{
> +	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_d=
entry,
>   			   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 *fil=
e, 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 *arg=
)
>   {
>   	struct inode *inode =3D file->f_path.dentry->d_inode;
> @@ -153,10 +171,9 @@ static int btrfs_ioctl_setflags(struct file *fil=
e, 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 *fil=
e, void __user *arg)
>   	else
>   		ip->flags&=3D ~BTRFS_INODE_DIRSYNC;
>
> +	/*
> +	 * The COMPRESS flag can only be changed by users, while the NOCOMP=
RESS
> +	 * 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));

--
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

  parent reply	other threads:[~2011-04-04  9:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-21  8:57 [PATCH 2/2 v2] Btrfs: Per file/directory controls for COW and compression liubo
2011-03-21 17:43 ` Johann Lombardi
2011-03-22  2:06   ` liubo
2011-03-22 10:12   ` [PATCH 2/2 v3] " liubo
2011-04-04  9:31 ` Konstantinos Skarlatos [this message]
2011-04-06  1:23   ` [PATCH 2/2 v2] " liubo
2011-04-06  1:26     ` Li Zefan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D999000.1000608@gmail.com \
    --to=k.skarlatos@gmail.com \
    --cc=chris.mason@oracle.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=liubo2009@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).