From 65a13d84940cfbdfaea4d38837c1d4b2e4f6ef33 Mon Sep 17 00:00:00 2001 From: Aliaksandr Shcherba Date: Thu, 13 Jun 2024 09:17:36 -0400 Subject: [PATCH 1/7] Use dattobd_blkdev_by_path wrapper --- src/bdev_state_handler.c | 4 +- src/blkdev.c | 38 +++++++++++++++---- src/blkdev.h | 9 ++--- .../feature-tests/blkdev_get_by_path_4.c | 17 +++++++++ src/ioctl_handlers.c | 2 +- src/tracer.c | 2 +- 6 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 src/configure-tests/feature-tests/blkdev_get_by_path_4.c diff --git a/src/bdev_state_handler.c b/src/bdev_state_handler.c index c7e6cd33..c492f59a 100644 --- a/src/bdev_state_handler.c +++ b/src/bdev_state_handler.c @@ -122,7 +122,7 @@ int __handle_bdev_mount_writable(const char *dir_name, if (test_bit(UNVERIFIED, &dev->sd_state)) { // get the block device for the unverified tracer we are // looking into - cur_bdev = blkdev_get_by_path(dev->sd_bdev_path, + cur_bdev = dattodb_blkdev_by_path(dev->sd_bdev_path, FMODE_READ, NULL); if (IS_ERR(cur_bdev)) { cur_bdev = NULL; @@ -257,7 +257,7 @@ void post_umount_check(int dormant_ret, int umount_ret, unsigned int idx, // reactivate if (umount_ret) { struct block_device *bdev; - bdev = blkdev_get_by_path(dev->sd_bdev_path, FMODE_READ, NULL); + bdev = dattodb_blkdev_by_path(dev->sd_bdev_path, FMODE_READ, NULL); if (!bdev || IS_ERR(bdev)) { LOG_DEBUG("device gone, moving to error state"); tracer_set_fail_state(dev, -ENODEV); diff --git a/src/blkdev.c b/src/blkdev.c index 73850c13..c3d97d4d 100644 --- a/src/blkdev.c +++ b/src/blkdev.c @@ -6,7 +6,7 @@ #include "blkdev.h" -#ifndef HAVE_BLKDEV_GET_BY_PATH +#if !defined HAVE_BLKDEV_GET_BY_PATH && !defined HAVE_BLKDEV_GET_BY_PATH_4 /** * dattobd_lookup_bdev() - Looks up the inode associated with the path, verifies @@ -58,13 +58,8 @@ static struct block_device *dattobd_lookup_bdev(const char *pathname, goto out; } -#endif - -#ifndef HAVE_BLKDEV_GET_BY_PATH -//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) - /** - * blkdev_get_by_path() - Fetches the @block_device struct associated with the + * _blkdev_get_by_path() - Fetches the @block_device struct associated with the * @pathname. This is very similar to @dattobd_lookup_bdev with minor * additional validation. * @@ -76,7 +71,7 @@ static struct block_device *dattobd_lookup_bdev(const char *pathname, * On success the @block_device structure otherwise an error created via * ERR_PTR(). */ -struct block_device *blkdev_get_by_path(const char *pathname, fmode_t mode, +static struct block_device *_blkdev_get_by_path(const char *pathname, fmode_t mode, void *holder) { struct block_device *bdev; @@ -97,3 +92,30 @@ struct block_device *blkdev_get_by_path(const char *pathname, fmode_t mode, } #endif + +/** + * dattodb_blkdev_by_path() - Fetches the @block_device struct associated with the + * @path. This function uses different methods based on available kernel functions + * to retrieve the block device. + * + * @path: the path name of a block special file. + * @mode: The mode used to open the block special file, likely just FMODE_READ. + * @holder: unused + * + * Return: + * On success the @block_device structure otherwise an error created via + * ERR_PTR(). + */ +struct block_device *dattodb_blkdev_by_path(const char *path, fmode_t mode, + void *holder) +{ +#if defined HAVE_BLKDEV_GET_BY_PATH_4 + return blkdev_get_by_path(path, mode, holder, NULL); + +#elif defined HAVE_BLKDEV_GET_BY_PATH + return blkdev_get_by_path(path, mode, holder); + +#else + return _blkdev_get_by_path(path, mode, holder); +#endif +} \ No newline at end of file diff --git a/src/blkdev.h b/src/blkdev.h index 2061d389..f8c65a82 100644 --- a/src/blkdev.h +++ b/src/blkdev.h @@ -33,12 +33,6 @@ struct block_device; #define dattobd_bdev_size(bdev) part_nr_sects_read((bdev)->bd_part) #endif -#ifndef HAVE_BLKDEV_GET_BY_PATH -//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) -struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, - void *holder); -#endif - #ifdef HAVE_BD_SUPER #define dattobd_get_super(bdev) (bdev)->bd_super #define dattobd_drop_super(sb) @@ -47,4 +41,7 @@ struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, #define dattobd_drop_super(sb) drop_super(sb) #endif +struct block_device *dattodb_blkdev_by_path(const char *path, fmode_t mode, + void *holder); + #endif /* BLKDEV_H_ */ diff --git a/src/configure-tests/feature-tests/blkdev_get_by_path_4.c b/src/configure-tests/feature-tests/blkdev_get_by_path_4.c new file mode 100644 index 00000000..a42a03ec --- /dev/null +++ b/src/configure-tests/feature-tests/blkdev_get_by_path_4.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Datto Inc. + */ + +#include "includes.h" + +MODULE_LICENSE("GPL"); + +static inline void dummy(void){ + struct block_device *bd = blkdev_get_by_path("path", FMODE_READ, NULL, NULL); + if(bd) { + blkdev_put(bd, FMODE_READ); + bd = NULL; + } +} diff --git a/src/ioctl_handlers.c b/src/ioctl_handlers.c index 607a52df..38d18c82 100644 --- a/src/ioctl_handlers.c +++ b/src/ioctl_handlers.c @@ -100,7 +100,7 @@ int __verify_bdev_writable(const char *bdev_path, int *out) struct super_block *sb; // open the base block device - bdev = blkdev_get_by_path(bdev_path, FMODE_READ, NULL); + bdev = dattodb_blkdev_by_path(bdev_path, FMODE_READ, NULL); if (IS_ERR(bdev)) { *out = 0; diff --git a/src/tracer.c b/src/tracer.c index 685573d5..72d009e0 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -730,7 +730,7 @@ static int __tracer_setup_base_dev(struct snap_device *dev, // open the base block device LOG_DEBUG("ENTER __tracer_setup_base_dev"); - dev->sd_base_dev = blkdev_get_by_path(bdev_path, FMODE_READ, NULL); + dev->sd_base_dev = dattodb_blkdev_by_path(bdev_path, FMODE_READ, NULL); if (IS_ERR(dev->sd_base_dev)) { ret = PTR_ERR(dev->sd_base_dev); dev->sd_base_dev = NULL; From ce54bad193c4d7dbb8222a7b9402bd35f21a7235 Mon Sep 17 00:00:00 2001 From: Aliaksandr Shcherba Date: Thu, 13 Jun 2024 11:18:40 -0400 Subject: [PATCH 2/7] Use dattobd_get/drop_super wrapper --- src/blkdev.c | 49 ++++++++++++++++++- src/blkdev.h | 11 ++--- src/configure-tests/feature-tests/get_super.c | 14 ++++++ 3 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 src/configure-tests/feature-tests/get_super.c diff --git a/src/blkdev.c b/src/blkdev.c index c3d97d4d..39bf5584 100644 --- a/src/blkdev.c +++ b/src/blkdev.c @@ -100,7 +100,7 @@ static struct block_device *_blkdev_get_by_path(const char *pathname, fmode_t mo * * @path: the path name of a block special file. * @mode: The mode used to open the block special file, likely just FMODE_READ. - * @holder: unused + * @holder: unused. * * Return: * On success the @block_device structure otherwise an error created via @@ -118,4 +118,51 @@ struct block_device *dattodb_blkdev_by_path(const char *path, fmode_t mode, #else return _blkdev_get_by_path(path, mode, holder); #endif +} + +/** + * dattobd_get_super() - Scans the superblock list and finds the superblock of the + * file system mounted on the @bd given. This function uses different methods + * based on available kernel functions to retrieve the super block. + * + * @block_device: mounted block device structure pointer. + * + * Return: + * On success the @super_block structure pointer otherwise NULL. + */ +struct super_block *dattobd_get_super(struct block_device * bd) +{ +#if defined HAVE_BD_SUPER + return (bd != NULL) ? bd->bd_super : NULL; + +#elif defined HAVE_GET_SUPER + return get_super(bdev); + +#else + struct super_block* (*get_active_superblock)(struct block_device*)= (GET_ACTIVE_SUPER_ADDR != 0) ? (struct super_block* (*)(struct block_device*))(GET_ACTIVE_SUPER_ADDR +(long long)(((void*)kfree)-(void*)KFREE_ADDR)):NULL; + return get_active_superblock(bd); +#endif +} + +/** + * dattobd_drop_super() - Releases the superblock of the file system. + * This function performs the appropriate action based on the available + * kernel functions to release or drop the superblock. + * + * @sb: super block structure pointer to be released. + * + * Return: + * void. + */ +void dattobd_drop_super(struct super_block *sb) +{ +#if defined HAVE_BD_SUPER + return; + +#elif defined HAVE_GET_SUPER + return drop_super(sb); + +#else + return; +#endif } \ No newline at end of file diff --git a/src/blkdev.h b/src/blkdev.h index f8c65a82..fe1c9c6f 100644 --- a/src/blkdev.h +++ b/src/blkdev.h @@ -33,15 +33,12 @@ struct block_device; #define dattobd_bdev_size(bdev) part_nr_sects_read((bdev)->bd_part) #endif -#ifdef HAVE_BD_SUPER -#define dattobd_get_super(bdev) (bdev)->bd_super -#define dattobd_drop_super(sb) -#else -#define dattobd_get_super(bdev) get_super(bdev) -#define dattobd_drop_super(sb) drop_super(sb) -#endif struct block_device *dattodb_blkdev_by_path(const char *path, fmode_t mode, void *holder); +struct super_block *dattobd_get_super(struct block_device * bd); + +void dattobd_drop_super(struct super_block *sb); + #endif /* BLKDEV_H_ */ diff --git a/src/configure-tests/feature-tests/get_super.c b/src/configure-tests/feature-tests/get_super.c new file mode 100644 index 00000000..dedd40e9 --- /dev/null +++ b/src/configure-tests/feature-tests/get_super.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Datto Inc. + */ + +#include "includes.h" + +MODULE_LICENSE("GPL"); + +static inline void dummy(void){ + struct block_device bdev; + get_super(&bdev); +} \ No newline at end of file From 2e0f0c205ac41b26f0725a0cf182d53552a7a043 Mon Sep 17 00:00:00 2001 From: Aliaksandr Shcherba Date: Thu, 13 Jun 2024 11:49:40 -0400 Subject: [PATCH 3/7] Use dattobd_blkdev_put wrapper --- src/blkdev.c | 29 +++++++++++++++---- src/blkdev.h | 9 ++---- .../feature-tests/blkdev_get_by_path_4.c | 5 +--- .../feature-tests/blkdev_put_2.c | 15 ++++++++++ 4 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 src/configure-tests/feature-tests/blkdev_put_2.c diff --git a/src/blkdev.c b/src/blkdev.c index 39bf5584..45a9dcd3 100644 --- a/src/blkdev.c +++ b/src/blkdev.c @@ -80,11 +80,7 @@ static struct block_device *_blkdev_get_by_path(const char *pathname, fmode_t mo return bdev; if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) { -#ifdef HAVE_BLKDEV_PUT_1 - blkdev_put(bdev); -#else - blkdev_put(bdev, mode); -#endif + dattobd_blkdev_put(bdev); return ERR_PTR(-EACCES); } @@ -165,4 +161,27 @@ void dattobd_drop_super(struct super_block *sb) #else return; #endif +} + +/** + * dattobd_blkdev_put() - Releases a reference to a block device. + * This function performs the appropriate action based on the available + * kernel functions to release or drop the superblock. + * + * @bd: block device structure pointer to be released. + * + * Return: + * void. + */ +void dattobd_blkdev_put(struct block_device *bd) +{ +#if defined HAVE_BLKDEV_PUT_1 + return blkdev_put(bd); + +#elif defined HAVE_BLKDEV_PUT_2 + return blkdev_put(bd,NULL); + +#else + return blkdev_put(bd, FMODE_READ); +#endif } \ No newline at end of file diff --git a/src/blkdev.h b/src/blkdev.h index fe1c9c6f..22b3a295 100644 --- a/src/blkdev.h +++ b/src/blkdev.h @@ -11,13 +11,6 @@ struct block_device; -#ifdef HAVE_BLKDEV_PUT_1 -//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) -#define dattobd_blkdev_put(bdev) blkdev_put(bdev); -#else -#define dattobd_blkdev_put(bdev) blkdev_put(bdev, FMODE_READ); -#endif - #ifndef bdev_whole //#if LINUX_VERSION_CODE < KERNEL_VERSION(5,11,0) #define bdev_whole(bdev) ((bdev)->bd_contains) @@ -41,4 +34,6 @@ struct super_block *dattobd_get_super(struct block_device * bd); void dattobd_drop_super(struct super_block *sb); +void dattobd_blkdev_put(struct block_device *bd); + #endif /* BLKDEV_H_ */ diff --git a/src/configure-tests/feature-tests/blkdev_get_by_path_4.c b/src/configure-tests/feature-tests/blkdev_get_by_path_4.c index a42a03ec..e1fbaadc 100644 --- a/src/configure-tests/feature-tests/blkdev_get_by_path_4.c +++ b/src/configure-tests/feature-tests/blkdev_get_by_path_4.c @@ -10,8 +10,5 @@ MODULE_LICENSE("GPL"); static inline void dummy(void){ struct block_device *bd = blkdev_get_by_path("path", FMODE_READ, NULL, NULL); - if(bd) { - blkdev_put(bd, FMODE_READ); - bd = NULL; - } + bd = NULL; } diff --git a/src/configure-tests/feature-tests/blkdev_put_2.c b/src/configure-tests/feature-tests/blkdev_put_2.c new file mode 100644 index 00000000..75448587 --- /dev/null +++ b/src/configure-tests/feature-tests/blkdev_put_2.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Datto Inc. + */ + +#include "includes.h" + +MODULE_LICENSE("GPL"); + +static inline void dummy(void){ + struct block_device dev; + void* info; + blkdev_put(&dev,info); +} From 6afcdc896f44c92e5181920f5b8e2e50a16556b5 Mon Sep 17 00:00:00 2001 From: Aliaksandr Shcherba Date: Thu, 13 Jun 2024 12:36:32 -0400 Subject: [PATCH 4/7] Use snap_open/release with gendisk and blk_mode type --- .../feature-tests/bdops_open_with_blk_mode.c | 30 +++++++++++++++++++ src/snap_ops.c | 11 +++++++ 2 files changed, 41 insertions(+) create mode 100644 src/configure-tests/feature-tests/bdops_open_with_blk_mode.c diff --git a/src/configure-tests/feature-tests/bdops_open_with_blk_mode.c b/src/configure-tests/feature-tests/bdops_open_with_blk_mode.c new file mode 100644 index 00000000..da5c5960 --- /dev/null +++ b/src/configure-tests/feature-tests/bdops_open_with_blk_mode.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Datto Inc. + */ + +#include "includes.h" + +MODULE_LICENSE("GPL"); + +static int snap_open(struct gendisk *gd, blk_mode_t mode){ + (void)gd; + (void)mode; + return 0; +} + +static void snap_release(struct gendisk *gd){ + (void)gd; +} + +static inline void dummy(void){ + struct gendisk gd; + struct block_device_operations bdo = { + .open = snap_open, + .release = snap_release, + }; + + bdo.open(&gd, FMODE_READ); + bdo.release(&gd); +} \ No newline at end of file diff --git a/src/snap_ops.c b/src/snap_ops.c index 9adfe033..d18f0272 100644 --- a/src/snap_ops.c +++ b/src/snap_ops.c @@ -64,6 +64,17 @@ static int snap_release(struct gendisk *gd, fmode_t mode) { return __tracer_close(gd->private_data); } +#elif defined HAVE_BDOPS_OPEN_WITH_BLK_MODE +static int snap_open(struct gendisk *gd, blk_mode_t mode) +{ + (void)mode; + return __tracer_open(gd->private_data); +} + +static void snap_release(struct gendisk *gd) +{ + __tracer_close(gd->private_data); +} #else static int snap_open(struct block_device *bdev, fmode_t mode) { From 2491b751ec6f1e3f8fcbf2f2068a8b98bcb70775 Mon Sep 17 00:00:00 2001 From: Aliaksandr Shcherba Date: Thu, 13 Jun 2024 13:32:13 -0400 Subject: [PATCH 5/7] Use has_submit_bio in block device --- .../feature-tests/bd_has_submit_bio.c | 14 ++++++++++++++ src/snap_device.h | 3 +++ src/tracer.c | 13 ++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/configure-tests/feature-tests/bd_has_submit_bio.c diff --git a/src/configure-tests/feature-tests/bd_has_submit_bio.c b/src/configure-tests/feature-tests/bd_has_submit_bio.c new file mode 100644 index 00000000..afdbe938 --- /dev/null +++ b/src/configure-tests/feature-tests/bd_has_submit_bio.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Datto Inc. + */ + +#include "includes.h" + +MODULE_LICENSE("GPL"); + +static inline void dummy(void){ + struct block_device* bd; + bd->bd_has_submit_bio=false; +} \ No newline at end of file diff --git a/src/snap_device.h b/src/snap_device.h index 28d6590c..f3df0d3f 100644 --- a/src/snap_device.h +++ b/src/snap_device.h @@ -23,6 +23,9 @@ struct tracing_ops { struct block_device_operations *bd_ops; atomic_t refs; +#ifdef HAVE_BD_HAS_SUBMIT_BIO + bool has_submit_bio; +#endif }; static inline struct tracing_ops* tracing_ops_get(struct tracing_ops *trops) { diff --git a/src/tracer.c b/src/tracer.c index 72d009e0..a22a4334 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -976,7 +976,9 @@ static void __tracer_destroy_snap(struct snap_device *dev) #ifdef HAVE_BLK_CLEANUP_QUEUE blk_cleanup_queue(dev->sd_queue); #else +#ifndef HAVE_BD_HAS_SUBMIT_BIO blk_put_queue(dev->sd_queue); +#endif #endif dev->sd_queue = NULL; } @@ -1317,6 +1319,9 @@ static int __tracer_transition_tracing( if(bd_ops){ bdev->bd_disk->fops= bd_ops; } +#ifdef HAVE_BD_HAS_SUBMIT_BIO + bdev->bd_has_submit_bio=true; +#endif #endif atomic_inc(&(*dev_ptr)->sd_active); } else { @@ -1332,6 +1337,9 @@ static int __tracer_transition_tracing( if(bd_ops){ bdev->bd_disk->fops= bd_ops; } +#ifdef HAVE_BD_HAS_SUBMIT_BIO + bdev->bd_has_submit_bio=dev->sd_tracing_ops->has_submit_bio; +#endif #endif *dev_ptr = dev; smp_wmb(); @@ -1523,7 +1531,7 @@ int find_orig_bdops(struct block_device *bdev, struct block_device_operations ** } int tracer_alloc_ops(struct snap_device* dev){ - LOG_DEBUG("tracer_alloc_ops"); + LOG_DEBUG("%s", __func__); struct tracing_ops* trops; trops = kmalloc(sizeof(struct tracing_ops), GFP_KERNEL); if(!trops) { @@ -1539,6 +1547,9 @@ int tracer_alloc_ops(struct snap_device* dev){ } memcpy(trops->bd_ops, dattobd_get_bd_ops(dev->sd_base_dev),sizeof(struct block_device_operations)); trops->bd_ops->submit_bio = tracing_fn; +#ifdef HAVE_BD_HAS_SUBMIT_BIO + trops->has_submit_bio=dev->sd_base_dev->bd_has_submit_bio; +#endif atomic_set(&trops->refs, 1); dev->sd_tracing_ops = trops; return 0; From b64bfac8c44b56e8a0f38fc33fcc68b635e2472f Mon Sep 17 00:00:00 2001 From: Aliaksandr Shcherba Date: Fri, 14 Jun 2024 07:39:31 -0400 Subject: [PATCH 6/7] Use non-idmapped mount idmap --- src/bio_helper.c | 2 +- src/configure-tests/feature-tests/gd_owns_queue.c | 2 +- .../feature-tests/user_namespace_args_2.c | 14 ++++++++++++++ src/configure-tests/symbol-tests | 1 + src/filesystem.c | 4 ++++ 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 src/configure-tests/feature-tests/user_namespace_args_2.c diff --git a/src/bio_helper.c b/src/bio_helper.c index eef515fe..4ea7734c 100644 --- a/src/bio_helper.c +++ b/src/bio_helper.c @@ -124,7 +124,7 @@ void dattobd_set_bio_ops(struct bio *bio, req_op_t op, unsigned op_flags) } #endif -#ifndef HAVE_BIO_BI_OPF +#if !defined(HAVE_BIO_BI_OPF) && defined(HAVE_ENUM_REQ_OP) void dattobd_set_bio_ops(struct bio *bio, req_op_t op, unsigned op_flags) { bio->bi_rw = 0; diff --git a/src/configure-tests/feature-tests/gd_owns_queue.c b/src/configure-tests/feature-tests/gd_owns_queue.c index 9f14a279..5160e8c5 100644 --- a/src/configure-tests/feature-tests/gd_owns_queue.c +++ b/src/configure-tests/feature-tests/gd_owns_queue.c @@ -9,6 +9,6 @@ MODULE_LICENSE("GPL"); static inline void dummy(void){ - struct gendisk *sd_gd; = NULL; + struct gendisk *sd_gd = NULL; set_bit(GD_OWNS_QUEUE, &sd_gd->state); } \ No newline at end of file diff --git a/src/configure-tests/feature-tests/user_namespace_args_2.c b/src/configure-tests/feature-tests/user_namespace_args_2.c new file mode 100644 index 00000000..8677dabd --- /dev/null +++ b/src/configure-tests/feature-tests/user_namespace_args_2.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2024 Datto Inc. + */ + +#include "includes.h" + +MODULE_LICENSE("GPL"); + +static inline void dummy(void){ + struct mnt_idmap* map = &nop_mnt_idmap ; + (void)vfs_unlink(map, NULL, NULL, NULL); +} \ No newline at end of file diff --git a/src/configure-tests/symbol-tests b/src/configure-tests/symbol-tests index 70ff0995..66c18d7f 100644 --- a/src/configure-tests/symbol-tests +++ b/src/configure-tests/symbol-tests @@ -8,3 +8,4 @@ vm_area_alloc vm_area_free insert_vm_struct vm_area_cachep +get_active_super diff --git a/src/filesystem.c b/src/filesystem.c index ef157a85..a22014fa 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -662,6 +662,8 @@ static int dattobd_do_truncate(struct dentry *dentry, loff_t length, #elif defined HAVE_USER_NAMESPACE_ARGS //#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,12,0) ret = notify_change(&init_user_ns, dentry, &newattrs, NULL); +#elif defined HAVE_USER_NAMESPACE_ARGS_2 + ret = notify_change(&nop_mnt_idmap, dentry, &newattrs, NULL); #else ret = notify_change(dentry, &newattrs, NULL); #endif @@ -904,6 +906,8 @@ int __file_unlink(struct file *filp, int close, int force) #elif defined HAVE_USER_NAMESPACE_ARGS //#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,12,0) ret = vfs_unlink(&init_user_ns, dir_inode, file_dentry, NULL); +#elif defined HAVE_USER_NAMESPACE_ARGS_2 + ret = vfs_unlink(file_mnt_idmap(filp), dir_inode, file_dentry, NULL); #else ret = vfs_unlink(dir_inode, file_dentry, NULL); #endif From 3ef2367eb5edaa5a2254ce57b78456a11c768488 Mon Sep 17 00:00:00 2001 From: Aliaksandr Shcherba Date: Tue, 18 Jun 2024 11:44:39 +0200 Subject: [PATCH 7/7] Use snap device in cow manager initialization --- dist/dattobd.spec | 4 ++-- src/bdev_state_handler.c | 17 ++++++++++------- src/blkdev.c | 2 +- src/cow_manager.c | 4 +++- src/cow_manager.h | 2 +- src/tracer.c | 9 +++++---- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/dist/dattobd.spec b/dist/dattobd.spec index a2192fd5..7a1f5c04 100644 --- a/dist/dattobd.spec +++ b/dist/dattobd.spec @@ -473,7 +473,7 @@ fi if [ ! -d %{_systemd_services}/reboot.target.wants/ ]; then mkdir -p %{_systemd_services}/reboot.target.wants fi -ln -s %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service +ln -fs %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service %postun -n %{libname} /sbin/ldconfig @@ -517,7 +517,7 @@ rm -rf %{buildroot} %post -ln -s %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service +ln -fs %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service %doc README.md doc/STRUCTURE.md %if "%{_vendor}" == "redhat" diff --git a/src/bdev_state_handler.c b/src/bdev_state_handler.c index c492f59a..7e515e62 100644 --- a/src/bdev_state_handler.c +++ b/src/bdev_state_handler.c @@ -28,7 +28,7 @@ void auto_transition_active(unsigned int minor, const char *dir_name) { struct snap_device *dev = snap_devices[minor]; -LOG_DEBUG("ENTER %s minor: %d", __func__, minor); + LOG_DEBUG("ENTER %s minor: %d", __func__, minor); mutex_lock(&ioctl_mutex); if (test_bit(UNVERIFIED, &dev->sd_state)) { @@ -107,8 +107,7 @@ int __handle_bdev_mount_writable(const char *dir_name, struct snap_device *dev; struct block_device *cur_bdev; - LOG_DEBUG("ENTER __handle_bdev_mount_writable"); - + LOG_DEBUG("ENTER %s", __func__); tracer_for_each(dev, i) { if (!dev || test_bit(ACTIVE, &dev->sd_state) || @@ -159,7 +158,7 @@ int __handle_bdev_mount_writable(const char *dir_name, ret = -ENODEV; out: - LOG_DEBUG("EXIT __handle_bdev_mount_writable"); + LOG_DEBUG("EXIT %s", __func__); *idx_out = i; return ret; } @@ -194,6 +193,10 @@ int handle_bdev_mount_event(const char *dir_name, int follow_flags, #else ret = user_path_at(AT_FDCWD, dir_name, lookup_flags, &path); #endif //LINUX_VERSION_CODE + if (ret) { + LOG_DEBUG("error finding path"); + goto out; + } LOG_DEBUG("path->dentry: %s, path->mnt->mnt_root: %s", path.dentry->d_name.name, path.mnt->mnt_root->d_name.name); @@ -245,10 +248,10 @@ void post_umount_check(int dormant_ret, int umount_ret, unsigned int idx, struct snap_device *dev; struct super_block *sb; - //LOG_DEBUG("ENTER %s", __func__); + LOG_DEBUG("ENTER %s", __func__); // if we didn't do anything or failed, just return - if (dormant_ret){ - //LOG_DEBUG("dormant_ret"); + if (dormant_ret) { + LOG_DEBUG("EXIT %s, dormant_ret", __func__); return; } dev = snap_devices[idx]; diff --git a/src/blkdev.c b/src/blkdev.c index 45a9dcd3..f54502f3 100644 --- a/src/blkdev.c +++ b/src/blkdev.c @@ -166,7 +166,7 @@ void dattobd_drop_super(struct super_block *sb) /** * dattobd_blkdev_put() - Releases a reference to a block device. * This function performs the appropriate action based on the available - * kernel functions to release or drop the superblock. + * kernel functions to release block device. * * @bd: block device structure pointer to be released. * diff --git a/src/cow_manager.c b/src/cow_manager.c index 4fbf799a..45ff43a9 100644 --- a/src/cow_manager.c +++ b/src/cow_manager.c @@ -642,6 +642,7 @@ int cow_reload(const char *path, uint64_t elements, unsigned long sect_size, * cow_init() - Allocates a &struct cow_manager object and initializes it. * Also creates the COW backing file on disk and writes a * header into it. + * @dev: The &struct snap_device that keeps snapshot device state. * @path: The path to the COW file. * @elements: typically the number of sectors on the block device. * @sect_size: The basic unit of size that the &struct cow_manager works with. @@ -656,7 +657,7 @@ int cow_reload(const char *path, uint64_t elements, unsigned long sect_size, * * 0 - success * * !0 - errno indicating the error */ -int cow_init(const char *path, uint64_t elements, unsigned long sect_size, +int cow_init(struct snap_device *dev, const char *path, uint64_t elements, unsigned long sect_size, unsigned long cache_size, uint64_t file_max, const uint8_t *uuid, uint64_t seqid, struct cow_manager **cm_out) { @@ -691,6 +692,7 @@ int cow_init(const char *path, uint64_t elements, unsigned long sect_size, __cow_calculate_allowed_sects(cache_size, cm->total_sects); cm->data_offset = COW_HEADER_SIZE + (cm->total_sects * (sect_size * 8)); cm->curr_pos = cm->data_offset / COW_BLOCK_SIZE; + cm->dev = dev; if (uuid) memcpy(cm->uuid, uuid, COW_UUID_SIZE); diff --git a/src/cow_manager.h b/src/cow_manager.h index ddd64716..626b37bd 100644 --- a/src/cow_manager.h +++ b/src/cow_manager.h @@ -81,7 +81,7 @@ int cow_reload(const char *path, uint64_t elements, unsigned long sect_size, unsigned long cache_size, int index_only, struct cow_manager **cm_out); -int cow_init(const char *path, uint64_t elements, unsigned long sect_size, +int cow_init(struct snap_device *dev, const char *path, uint64_t elements, unsigned long sect_size, unsigned long cache_size, uint64_t file_max, const uint8_t *uuid, uint64_t seqid, struct cow_manager **cm_out); diff --git a/src/tracer.c b/src/tracer.c index a22a4334..5dc2dceb 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -646,7 +646,7 @@ static int __tracer_setup_cow(struct snap_device *dev, // create and open the cow manager LOG_DEBUG("creating cow manager"); - ret = cow_init(cow_path, SECTOR_TO_BLOCK(size), + ret = cow_init(dev, cow_path, SECTOR_TO_BLOCK(size), COW_SECTION_SIZE, dev->sd_cache_size, max_file_size, uuid, seqid, &dev->sd_cow); @@ -858,10 +858,11 @@ static void __tracer_copy_cow(const struct snap_device *src, { dest->sd_cow = src->sd_cow; // copy cow file extents and update the device - dest->sd_cow_extents = src->sd_cow_extents; - dest->sd_cow_ext_cnt = src->sd_cow_ext_cnt; - + dest->sd_cow_extents = src->sd_cow_extents; + dest->sd_cow_ext_cnt = src->sd_cow_ext_cnt; dest->sd_cow_inode = src->sd_cow_inode; + dest->sd_cow->dev = dest; + dest->sd_cache_size = src->sd_cache_size; dest->sd_falloc_size = src->sd_falloc_size; }