]> git.hungrycats.org Git - linux/commitdiff
btrfs: change the DEV_ITEM 'type' field via sysfs
authorGoffredo Baroncelli <kreijack@inwind.it>
Sun, 24 Oct 2021 15:31:06 +0000 (17:31 +0200)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Fri, 18 Sep 2026 21:36:34 +0000 (17:36 -0400)
(cherry picked from commit 0aabc3870ced23a2d5771e17531f3300a96d19d0)

fs/btrfs/sysfs.c

index 797f81b49d5eb0fad38eb175dcaf8c94951eaaa7..79dc559f8d394104d8f5ce480b8e946dffdfbaca 100644 (file)
@@ -2150,7 +2150,61 @@ static ssize_t btrfs_devinfo_type_show(struct kobject *kobj,
 
        return scnprintf(buf, PAGE_SIZE, "0x%08llx\n", device->type);
 }
-BTRFS_ATTR(devid, type, btrfs_devinfo_type_show);
+
+static ssize_t btrfs_devinfo_type_store(struct kobject *kobj,
+                                struct kobj_attribute *a,
+                                const char *buf, size_t len)
+{
+       struct btrfs_fs_info *fs_info;
+       struct btrfs_root *root;
+       struct btrfs_device *device;
+       int ret;
+       struct btrfs_trans_handle *trans;
+
+       u64 type, prev_type;
+
+       device = container_of(kobj, struct btrfs_device, devid_kobj);
+       fs_info = device->fs_info;
+       if (!fs_info)
+               return -EPERM;
+
+       root = fs_info->chunk_root;
+       if (sb_rdonly(fs_info->sb))
+               return -EROFS;
+
+       ret = kstrtou64(buf, 0, &type);
+       if (ret < 0)
+               return -EINVAL;
+
+       /* for now, allow to touch only the 'allocation hint' bits */
+       if (type & ~((1 << BTRFS_DEV_ALLOCATION_MASK_BIT_COUNT) - 1))
+               return -EINVAL;
+
+       trans = btrfs_start_transaction(root, 1);
+       if (IS_ERR(trans))
+               return PTR_ERR(trans);
+
+       prev_type = device->type;
+       device->type = type;
+
+       ret = btrfs_update_device(trans, device);
+
+       if (ret < 0) {
+               btrfs_abort_transaction(trans, ret);
+               btrfs_end_transaction(trans);
+               goto abort;
+       }
+
+       ret = btrfs_commit_transaction(trans);
+       if (ret < 0)
+               goto abort;
+
+       return len;
+abort:
+       device->type = prev_type;
+       return  ret;
+}
+BTRFS_ATTR_RW(devid, type, btrfs_devinfo_type_show, btrfs_devinfo_type_store);
 
 /*
  * Information about one device.