aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorLiu Bo <liubo2009@cn.fujitsu.com>2011-03-22 06:12:20 -0400
committerroot <Chris Mason chris.mason@oracle.com>2011-03-28 05:37:41 -0400
commit75e7cb7fe0c391561bd3af36515be3f3c64a04c6 (patch)
tree3738481e2db10b2904a4434e4ca42d326da02be7 /fs/btrfs/inode.c
parent32471f6e1983922473573da62cbee58699574aa4 (diff)
Btrfs: Per file/directory controls for COW and compression
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 per directory basis. This has been proposed previously, but VFS developers wanted us to use generic ioctls rather than btrfs-specific ones. According to Chris's comment, there should be just one true compression 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 super. 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 to the latest btrfs. v2->v3: - fix a problem, i.e. when a file is set NOCOW via mount option, then this NOCOW will be screwed by inheritance from parent directory. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index eaa271484199..7a7a202b82ab 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -384,7 +384,8 @@ again:
384 */ 384 */
385 if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) && 385 if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) &&
386 (btrfs_test_opt(root, COMPRESS) || 386 (btrfs_test_opt(root, COMPRESS) ||
387 (BTRFS_I(inode)->force_compress))) { 387 (BTRFS_I(inode)->force_compress) ||
388 (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))) {
388 WARN_ON(pages); 389 WARN_ON(pages);
389 pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); 390 pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
390 391
@@ -1256,7 +1257,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
1256 ret = run_delalloc_nocow(inode, locked_page, start, end, 1257 ret = run_delalloc_nocow(inode, locked_page, start, end,
1257 page_started, 0, nr_written); 1258 page_started, 0, nr_written);
1258 else if (!btrfs_test_opt(root, COMPRESS) && 1259 else if (!btrfs_test_opt(root, COMPRESS) &&
1259 !(BTRFS_I(inode)->force_compress)) 1260 !(BTRFS_I(inode)->force_compress) &&
1261 !(BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))
1260 ret = cow_file_range(inode, locked_page, start, end, 1262 ret = cow_file_range(inode, locked_page, start, end,
1261 page_started, nr_written, 1); 1263 page_started, nr_written, 1);
1262 else 1264 else
@@ -4584,7 +4586,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
4584 if ((mode & S_IFREG)) { 4586 if ((mode & S_IFREG)) {
4585 if (btrfs_test_opt(root, NODATASUM)) 4587 if (btrfs_test_opt(root, NODATASUM))
4586 BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM; 4588 BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM;
4587 if (btrfs_test_opt(root, NODATACOW)) 4589 if (btrfs_test_opt(root, NODATACOW) ||
4590 (BTRFS_I(dir)->flags & BTRFS_INODE_NODATACOW))
4588 BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW; 4591 BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW;
4589 } 4592 }
4590 4593
@@ -6866,6 +6869,26 @@ static int btrfs_getattr(struct vfsmount *mnt,
6866 return 0; 6869 return 0;
6867} 6870}
6868 6871
6872/*
6873 * If a file is moved, it will inherit the cow and compression flags of the new
6874 * directory.
6875 */
6876static void fixup_inode_flags(struct inode *dir, struct inode *inode)
6877{
6878 struct btrfs_inode *b_dir = BTRFS_I(dir);
6879 struct btrfs_inode *b_inode = BTRFS_I(inode);
6880
6881 if (b_dir->flags & BTRFS_INODE_NODATACOW)
6882 b_inode->flags |= BTRFS_INODE_NODATACOW;
6883 else
6884 b_inode->flags &= ~BTRFS_INODE_NODATACOW;
6885
6886 if (b_dir->flags & BTRFS_INODE_COMPRESS)
6887 b_inode->flags |= BTRFS_INODE_COMPRESS;
6888 else
6889 b_inode->flags &= ~BTRFS_INODE_COMPRESS;
6890}
6891
6869static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, 6892static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
6870 struct inode *new_dir, struct dentry *new_dentry) 6893 struct inode *new_dir, struct dentry *new_dentry)
6871{ 6894{
@@ -6999,6 +7022,8 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
6999 } 7022 }
7000 } 7023 }
7001 7024
7025 fixup_inode_flags(new_dir, old_inode);
7026
7002 ret = btrfs_add_link(trans, new_dir, old_inode, 7027 ret = btrfs_add_link(trans, new_dir, old_inode,
7003 new_dentry->d_name.name, 7028 new_dentry->d_name.name,
7004 new_dentry->d_name.len, 0, index); 7029 new_dentry->d_name.len, 0, index);