mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 08:31:13 +00:00
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>
This commit is contained in:
parent
32471f6e19
commit
75e7cb7fe0
4 changed files with 72 additions and 7 deletions
|
@ -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 *arg)
|
||||
{
|
||||
struct inode *inode = 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 = 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 &= ~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 &= ~BTRFS_INODE_COMPRESS;
|
||||
ip->flags |= BTRFS_INODE_NOCOMPRESS;
|
||||
} else if (flags & FS_COMPR_FL) {
|
||||
ip->flags |= BTRFS_INODE_COMPRESS;
|
||||
ip->flags &= ~BTRFS_INODE_NOCOMPRESS;
|
||||
}
|
||||
if (flags & FS_NOCOW_FL)
|
||||
ip->flags |= BTRFS_INODE_NODATACOW;
|
||||
else if (flags & FS_COW_FL)
|
||||
ip->flags &= ~BTRFS_INODE_NODATACOW;
|
||||
|
||||
trans = btrfs_join_transaction(root, 1);
|
||||
BUG_ON(IS_ERR(trans));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue