aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.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/ioctl.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/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 88d3cb2eaf75..32c980ae0f1c 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)
138 return 0; 138 return 0;
139} 139}
140 140
141static int check_flags(unsigned int flags)
142{
143 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
144 FS_NOATIME_FL | FS_NODUMP_FL | \
145 FS_SYNC_FL | FS_DIRSYNC_FL | \
146 FS_NOCOMP_FL | FS_COMPR_FL | \
147 FS_NOCOW_FL | FS_COW_FL))
148 return -EOPNOTSUPP;
149
150 if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL))
151 return -EINVAL;
152
153 if ((flags & FS_NOCOW_FL) && (flags & FS_COW_FL))
154 return -EINVAL;
155
156 return 0;
157}
158
141static int btrfs_ioctl_setflags(struct file *file, void __user *arg) 159static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
142{ 160{
143 struct inode *inode = file->f_path.dentry->d_inode; 161 struct inode *inode = file->f_path.dentry->d_inode;
@@ -153,10 +171,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
153 if (copy_from_user(&flags, arg, sizeof(flags))) 171 if (copy_from_user(&flags, arg, sizeof(flags)))
154 return -EFAULT; 172 return -EFAULT;
155 173
156 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ 174 ret = check_flags(flags);
157 FS_NOATIME_FL | FS_NODUMP_FL | \ 175 if (ret)
158 FS_SYNC_FL | FS_DIRSYNC_FL)) 176 return ret;
159 return -EOPNOTSUPP;
160 177
161 if (!is_owner_or_cap(inode)) 178 if (!is_owner_or_cap(inode))
162 return -EACCES; 179 return -EACCES;
@@ -201,6 +218,22 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
201 else 218 else
202 ip->flags &= ~BTRFS_INODE_DIRSYNC; 219 ip->flags &= ~BTRFS_INODE_DIRSYNC;
203 220
221 /*
222 * The COMPRESS flag can only be changed by users, while the NOCOMPRESS
223 * flag may be changed automatically if compression code won't make
224 * things smaller.
225 */
226 if (flags & FS_NOCOMP_FL) {
227 ip->flags &= ~BTRFS_INODE_COMPRESS;
228 ip->flags |= BTRFS_INODE_NOCOMPRESS;
229 } else if (flags & FS_COMPR_FL) {
230 ip->flags |= BTRFS_INODE_COMPRESS;
231 ip->flags &= ~BTRFS_INODE_NOCOMPRESS;
232 }
233 if (flags & FS_NOCOW_FL)
234 ip->flags |= BTRFS_INODE_NODATACOW;
235 else if (flags & FS_COW_FL)
236 ip->flags &= ~BTRFS_INODE_NODATACOW;
204 237
205 trans = btrfs_join_transaction(root, 1); 238 trans = btrfs_join_transaction(root, 1);
206 BUG_ON(IS_ERR(trans)); 239 BUG_ON(IS_ERR(trans));