On 2018/02/16 4:04, Omar Sandoval wrote:
> From: Omar Sandoval
>
> set_default_subvolume() is a trivial ioctl(), but there's no ioctl() for
> get_default_subvolume(), so we need to search the root tree.
>
> Signed-off-by: Omar Sandoval
> ---
> libbtrfsutil/btrfsutil.h| 41 ++
> libbtrfsutil/python/btrfsutilpy.h | 2 +
> libbtrfsutil/python/module.c| 14
> libbtrfsutil/python/subvolume.c | 50
> libbtrfsutil/python/tests/test_subvolume.py | 14
> libbtrfsutil/subvolume.c| 113
>
> 6 files changed, 234 insertions(+)
>
> diff --git a/libbtrfsutil/btrfsutil.h b/libbtrfsutil/btrfsutil.h
> index 8bd2b847..54777f1d 100644
> --- a/libbtrfsutil/btrfsutil.h
> +++ b/libbtrfsutil/btrfsutil.h
> @@ -256,6 +256,8 @@ enum btrfs_util_error
> btrfs_util_get_subvolume_read_only_fd(int fd, bool *ret);
> * @path: Subvolume path.
> * @read_only: New value of read-only flag.
> *
> + * This requires appropriate privilege (CAP_SYS_ADMIN).
> + *
> * Return: %BTRFS_UTIL_OK on success, non-zero error code on failure.
> */
> enum btrfs_util_error btrfs_util_set_subvolume_read_only(const char *path,
> @@ -268,6 +270,45 @@ enum btrfs_util_error
> btrfs_util_set_subvolume_read_only(const char *path,
> enum btrfs_util_error btrfs_util_set_subvolume_read_only_fd(int fd,
> bool read_only);
>
> +/**
> + * btrfs_util_get_default_subvolume() - Get the default subvolume for a
> + * filesystem.
> + * @path: Path on a Btrfs filesystem.
> + * @id_ret: Returned subvolume ID.
> + *
> + * This requires appropriate privilege (CAP_SYS_ADMIN).
> + *
> + * Return: %BTRFS_UTIL_OK on success, non-zero error code on failure.
> + */
> +enum btrfs_util_error btrfs_util_get_default_subvolume(const char *path,
> +uint64_t *id_ret);
> +
> +/**
> + * btrfs_util_get_default_subvolume_fd() - See
> + * btrfs_util_get_default_subvolume().
> + */
> +enum btrfs_util_error btrfs_util_get_default_subvolume_fd(int fd,
> + uint64_t *id_ret);
> +
> +/**
> + * btrfs_util_set_default_subvolume() - Set the default subvolume for a
> + * filesystem.
> + * @path: Path in a Btrfs filesystem. This may be any path in the
> filesystem; it
> + * does not have to refer to a subvolume unless @id is zero.
> + * @id: ID of subvolume to set as the default. If zero is given, the
> subvolume
> + * ID of @path is used.
The line "This requires appropriate privilege (CAP_SYS_ADMIN)." is missing here.
> + *
> + * Return: %BTRFS_UTIL_OK on success, non-zero error code on failure.
> + */
> +enum btrfs_util_error btrfs_util_set_default_subvolume(const char *path,
> +uint64_t id);
> +
> +/**
> + * btrfs_util_set_default_subvolume_fd() - See
> + * btrfs_util_set_default_subvolume().
> + */
> +enum btrfs_util_error btrfs_util_set_default_subvolume_fd(int fd, uint64_t
> id);
> +
> struct btrfs_util_qgroup_inherit;
>
> /**
> diff --git a/libbtrfsutil/python/btrfsutilpy.h
> b/libbtrfsutil/python/btrfsutilpy.h
> index 21253e51..41314d4a 100644
> --- a/libbtrfsutil/python/btrfsutilpy.h
> +++ b/libbtrfsutil/python/btrfsutilpy.h
> @@ -66,6 +66,8 @@ PyObject *subvolume_path(PyObject *self, PyObject *args,
> PyObject *kwds);
> PyObject *subvolume_info(PyObject *self, PyObject *args, PyObject *kwds);
> PyObject *get_subvolume_read_only(PyObject *self, PyObject *args, PyObject
> *kwds);
> PyObject *set_subvolume_read_only(PyObject *self, PyObject *args, PyObject
> *kwds);
> +PyObject *get_default_subvolume(PyObject *self, PyObject *args, PyObject
> *kwds);
> +PyObject *set_default_subvolume(PyObject *self, PyObject *args, PyObject
> *kwds);
> PyObject *create_subvolume(PyObject *self, PyObject *args, PyObject *kwds);
>
> void add_module_constants(PyObject *m);
> diff --git a/libbtrfsutil/python/module.c b/libbtrfsutil/python/module.c
> index 3395fb14..0ac4d63a 100644
> --- a/libbtrfsutil/python/module.c
> +++ b/libbtrfsutil/python/module.c
> @@ -173,6 +173,20 @@ static PyMethodDef btrfsutil_methods[] = {
>"Arguments:\n"
>"path -- string, bytes, path-like object, or open file descriptor\n"
>"read_only -- bool flag value"},
> + {"get_default_subvolume", (PyCFunction)get_default_subvolume,
> + METH_VARARGS | METH_KEYWORDS,
> + "get_default_subvolume(path) -> int\n\n"
> + "Get the ID of the default subvolume of a filesystem.\n\n"
> + "Arguments:\n"
> + "path -- string, bytes, path-like object, or open file descriptor"},
> + {"set_default_subvolume", (PyCFunction)set_default_subvolume,
> + METH_VARARGS | METH_KEYWORDS,
> + "set_default_subvolume(path, id=0)\n\n"
> + "Set the default subvolume of a filesystem.\n\n"
> + "Arguments:\n"
> + "p