summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2017-07-17 19:41:31 +0200
committerDavid Sterba <dsterba@suse.com>2017-08-16 16:12:05 +0200
commiteec63c65dcbeb14b59c95159eb225b1fc2310806 (patch)
treef2c54de48515e48eea07a5ccd0ead6c990fe3a8f
parentb52aa8c93e1fec97fcd87345b13f532f0dee8239 (diff)
downloadlinux-eec63c65dcbeb14b59c95159eb225b1fc2310806.tar.bz2
btrfs: separate defrag and property compression
Add new value for compression to distinguish between defrag and property. Previously, a single variable was used and this caused clashes when the per-file 'compression' was set and a defrag -c was called. The property-compression is loaded when the file is open, defrag will overwrite the same variable and reset to 0 (ie. NONE) at when the file defragmentaion is finished. That's considered a usability bug. Now we won't touch the property value, use the defrag-compression. The precedence of defrag is higher than for property (and whole-filesystem). Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/btrfs_inode.h5
-rw-r--r--fs/btrfs/inode.c8
-rw-r--r--fs/btrfs/ioctl.c4
3 files changed, 14 insertions, 3 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index fa118036a84e..eccadb5f62a5 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -182,6 +182,11 @@ struct btrfs_inode {
* Cached values of inode properties
*/
unsigned prop_compress; /* per-file compression algorithm */
+ /*
+ * Force compression on the file using the defrag ioctl, could be
+ * different from prop_compress and takes precedence if set
+ */
+ unsigned defrag_compress;
struct btrfs_delayed_node *delayed_node;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c60a6d692bc1..1e8eb5e8551c 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -402,6 +402,9 @@ static inline int inode_need_compress(struct inode *inode, u64 start, u64 end)
/* bad compression ratios */
if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS)
return 0;
+ /* defrag ioctl */
+ if (BTRFS_I(inode)->defrag_compress)
+ return 1;
if (btrfs_test_opt(fs_info, COMPRESS) ||
BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS ||
BTRFS_I(inode)->prop_compress)
@@ -511,7 +514,9 @@ again:
goto cont;
}
- if (BTRFS_I(inode)->prop_compress)
+ if (BTRFS_I(inode)->defrag_compress)
+ compress_type = BTRFS_I(inode)->defrag_compress;
+ else if (BTRFS_I(inode)->prop_compress)
compress_type = BTRFS_I(inode)->prop_compress;
/*
@@ -9434,6 +9439,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
ei->runtime_flags = 0;
ei->prop_compress = BTRFS_COMPRESS_NONE;
+ ei->defrag_compress = BTRFS_COMPRESS_NONE;
ei->delayed_node = NULL;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index e1c15a2ac785..1d6603dc1d59 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1371,7 +1371,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
inode_lock(inode);
if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
- BTRFS_I(inode)->prop_compress = compress_type;
+ BTRFS_I(inode)->defrag_compress = compress_type;
ret = cluster_pages_for_defrag(inode, pages, i, cluster);
if (ret < 0) {
inode_unlock(inode);
@@ -1442,7 +1442,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
out_ra:
if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) {
inode_lock(inode);
- BTRFS_I(inode)->prop_compress = BTRFS_COMPRESS_NONE;
+ BTRFS_I(inode)->defrag_compress = BTRFS_COMPRESS_NONE;
inode_unlock(inode);
}
if (!file)