All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.