93 lines
3.1 KiB
Diff
93 lines
3.1 KiB
Diff
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
|
|
--- a/fs/btrfs/dev-replace.c
|
|
+++ b/fs/btrfs/dev-replace.c
|
|
@@ -627,7 +627,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
|
|
|
|
ret = mark_block_group_to_copy(fs_info, src_device);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto leave;
|
|
|
|
down_write(&dev_replace->rwsem);
|
|
dev_replace->replace_task = current;
|
|
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
|
|
--- a/fs/btrfs/ioctl.c
|
|
+++ b/fs/btrfs/ioctl.c
|
|
@@ -384,6 +384,7 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
|
|
inode_flags &= ~BTRFS_INODE_COMPRESS;
|
|
inode_flags |= BTRFS_INODE_NOCOMPRESS;
|
|
} else if (fsflags & FS_COMPR_FL) {
|
|
+ enum btrfs_compression_type comp_type;
|
|
|
|
if (IS_SWAPFILE(&inode->vfs_inode))
|
|
return -ETXTBSY;
|
|
@@ -391,9 +392,23 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
|
|
inode_flags |= BTRFS_INODE_COMPRESS;
|
|
inode_flags &= ~BTRFS_INODE_NOCOMPRESS;
|
|
|
|
- comp = btrfs_compress_type2str(fs_info->compress_type);
|
|
- if (!comp || comp[0] == 0)
|
|
- comp = btrfs_compress_type2str(BTRFS_COMPRESS_ZLIB);
|
|
+ /*
|
|
+ * Keep the algorithm recorded in the compression property,
|
|
+ * otherwise changing an unrelated attribute would reset it to
|
|
+ * the mount default, since FS_IOC_SETFLAGS callers write back
|
|
+ * the whole flag set they got from FS_IOC_GETFLAGS and that
|
|
+ * includes FS_COMPR_FL for any inode carrying the property.
|
|
+ *
|
|
+ * Inodes with the compress flag set but no property keep using
|
|
+ * the mount default, so they behave as before.
|
|
+ */
|
|
+ if (inode->prop_compress)
|
|
+ comp_type = inode->prop_compress;
|
|
+ else if (fs_info->compress_type)
|
|
+ comp_type = fs_info->compress_type;
|
|
+ else
|
|
+ comp_type = BTRFS_COMPRESS_ZLIB;
|
|
+ comp = btrfs_compress_type2str(comp_type);
|
|
} else {
|
|
inode_flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS);
|
|
}
|
|
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
|
|
--- a/fs/btrfs/send.c
|
|
+++ b/fs/btrfs/send.c
|
|
@@ -6417,6 +6417,13 @@ static int process_extent(struct send_ctx *sctx,
|
|
|
|
if (S_ISLNK(sctx->cur_inode_mode))
|
|
return 0;
|
|
+ if (unlikely(!S_ISREG(sctx->cur_inode_mode))) {
|
|
+ btrfs_crit(sctx->send_root->fs_info,
|
|
+ "send: extent for non-regular inode %llu root %llu mode 0%llo",
|
|
+ key->objectid, btrfs_root_id(sctx->send_root),
|
|
+ sctx->cur_inode_mode & S_IFMT);
|
|
+ return -EUCLEAN;
|
|
+ }
|
|
|
|
if (sctx->parent_root && !sctx->cur_inode_new) {
|
|
ret = is_extent_unchanged(sctx, path, key);
|
|
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
|
|
--- a/fs/btrfs/zoned.c
|
|
+++ b/fs/btrfs/zoned.c
|
|
@@ -2710,6 +2710,7 @@ int btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 leng
|
|
{
|
|
struct btrfs_block_group *block_group;
|
|
u64 min_alloc_bytes;
|
|
+ int ret = 0;
|
|
|
|
if (!btrfs_is_zoned(fs_info))
|
|
return 0;
|
|
@@ -2729,11 +2730,11 @@ int btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 leng
|
|
block_group->start + block_group->zone_capacity)
|
|
goto out;
|
|
|
|
- do_zone_finish(block_group, true);
|
|
+ ret = do_zone_finish(block_group, true);
|
|
|
|
out:
|
|
btrfs_put_block_group(block_group);
|
|
- return 0;
|
|
+ return ret;
|
|
}
|
|
|
|
static void btrfs_zone_finish_endio_workfn(struct work_struct *work)
|