Re: [PATCH] nbd: add a missed nbd_config_put() in nbd_xmit_timeout()
Thanks for your review. 在 2019/8/12 23:34, Mike Christie 写道: On 08/12/2019 07:31 AM, Sun Ke wrote: When try to get the lock failed, before return, execute the nbd_config_put() to decrease the nbd->config_refs. If the nbd->config_refs is added but not decreased. Then will not execute nbd_clear_sock() in nbd_config_put(). bd->task_setup will not be cleared away. Finally, print"Device being setup by another task" in nbd_add_sock() and nbd device can not be reused. Fixes: 8f3ea35929a0 ("nbd: handle unexpected replies better") Signed-off-by: Sun Ke --- drivers/block/nbd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index e21d2de..a69a90a 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -357,8 +357,10 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, } config = nbd->config; - if (!mutex_trylock(&cmd->lock)) + if (!mutex_trylock(&cmd->lock)) { + nbd_config_put(nbd); return BLK_EH_RESET_TIMER; + } if (config->num_connections > 1) { dev_err_ratelimited(nbd_to_dev(nbd), I just sent the same patch https://www.spinics.net/lists/linux-block/msg43718.html here https://www.spinics.net/lists/linux-block/msg43715.html so it looks good to me. Reviewed-by: Mike Christie .
[PATCH] fs/sync.c: Fix UBSAN Undefined behaviour in sync_file_range
There is a UBSAN report: UBSAN: Undefined behaviour in ../fs/sync.c:298:10 signed integer overflow: -8 + -9223372036854775807 cannot be represented in type 'long long int' CPU: 0 PID: 15876 Comm: syz-executor.3 Not tainted Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 Call trace: [] dump_backtrace+0x0/0x698 arch/arm64/kernel/traps.c:96 [] show_stack+0x38/0x60 arch/arm64/kernel/traps.c:234 [] __dump_stack lib/dump_stack.c:15 [inline] [] dump_stack+0x1a8/0x230 lib/dump_stack.c:51 [] ubsan_epilogue+0x34/0x9c lib/ubsan.c:164 [] handle_overflow+0x228/0x280 lib/ubsan.c:195 [] __ubsan_handle_add_overflow+0x4c/0x68 lib/ubsan.c:203 [] SYSC_sync_file_range fs/sync.c:298 [inline] [] SyS_sync_file_range+0x350/0x3e8 fs/sync.c:285 [] el0_svc_naked+0x30/0x34 When calculate the endbyte, there maybe an overflow, even if no effect the kernel, but I also want to avoid overflowing and avoid UBSAN reporting. The original compare is to ensure the offset >= 0 && nbytes >= 0 && no overflow happened. I do the calculate after compare. ensure the offset >= 0 && nbytes >= 0 && no overflow may happen first. Signed-off-by: SunKe --- fs/sync.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/sync.c b/fs/sync.c index 4d1ff01..5827471 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -246,15 +246,15 @@ int sync_file_range(struct file *file, loff_t offset, loff_t nbytes, if (flags & ~VALID_FLAGS) goto out; - endbyte = offset + nbytes; - if ((s64)offset < 0) goto out; - if ((s64)endbyte < 0) + if ((s64)nbytes < 0) goto out; - if (endbyte < offset) + if (S64_MAX - offset < nbytes) goto out; + endbyte = offset + nbytes; + if (sizeof(pgoff_t) == 4) { if (offset >= (0x1ULL << PAGE_SHIFT)) { /* -- 2.7.4
[PATCH] sample_configfs: bin_file read and write
Add bin_file read and write function Signed-off-by: SunKe --- samples/configfs/configfs_sample.c | 43 ++ 1 file changed, 43 insertions(+) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index 004a4e2..c76b784 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -146,6 +146,8 @@ static struct childless childless_subsys = { struct simple_child { struct config_item item; int storeme; + void *data; + size_t len; }; static inline struct simple_child *to_simple_child(struct config_item *item) @@ -153,6 +155,46 @@ static inline struct simple_child *to_simple_child(struct config_item *item) return item ? container_of(item, struct simple_child, item) : NULL; } +static ssize_t simple_child_bin_storeme_bin_write(struct config_item *item, + const void *data, size_t size) +{ + struct simple_child *simple_child = to_simple_child(item); + + kfree(simple_child->data); + simple_child->data = NULL; + + simple_child->data = kmemdup(data, size, GFP_KERNEL); + if (!simple_child->data) + return -ENOMEM; + simple_child->len = size; + + return 0; +} + +static ssize_t simple_child_bin_storeme_bin_read(struct config_item *item, + void *data, size_t size) +{ + struct simple_child *simple_child = to_simple_child(item); + + if (!data) { + size = simple_child->len; + } else { + memcpy(data, simple_child->data, simple_child->len); + size = simple_child->len; + } + + return size; +} + +#define MAX_SIZE (128 * 1024) + +CONFIGFS_BIN_ATTR(simple_child_bin_, storeme_bin, NULL, MAX_SIZE); + +static struct configfs_bin_attribute *simple_child_bin_attrs[] = { + &simple_child_bin_attr_storeme_bin, + NULL, +}; + static ssize_t simple_child_storeme_show(struct config_item *item, char *page) { return sprintf(page, "%d\n", to_simple_child(item)->storeme); @@ -196,6 +238,7 @@ static struct configfs_item_operations simple_child_item_ops = { static const struct config_item_type simple_child_type = { .ct_item_ops= &simple_child_item_ops, .ct_attrs = simple_child_attrs, + .ct_bin_attrs = simple_child_bin_attrs, .ct_owner = THIS_MODULE, }; -- 2.7.4
[PATCH 2/2] sample_configfs: soft link creat and delete
Add soft link creation and deletion Signed-off-by: SunKe --- samples/configfs/configfs_sample.c | 41 ++ 1 file changed, 41 insertions(+) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index c76b784..58915b8 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -392,6 +392,46 @@ static struct configfs_subsystem group_children_subsys = { /* - */ /* + * 04-link-children + * + */ +static int link_children_allow_link(struct config_item *parent, + struct config_item *target) +{ + return 0; +} + +static void link_children_drop_link(struct config_item *parent, + struct config_item *target) +{ + +} + + +static struct configfs_item_operations link_children_item_ops = { + .allow_link = link_children_allow_link, + .drop_link = link_children_drop_link, +}; + + +static const struct config_item_type link_children_type = { + .ct_item_ops= &link_children_item_ops, + .ct_owner = THIS_MODULE, + +}; + +static struct configfs_subsystem link_children_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "04-link-children", + .ci_type = &link_children_type, + }, + }, +}; + +/* - */ + +/* * We're now done with our subsystem definitions. * For convenience in this module, here's a list of them all. It * allows the init function to easily register them. Most modules @@ -402,6 +442,7 @@ static struct configfs_subsystem *example_subsys[] = { &childless_subsys.subsys, &simple_children_subsys, &group_children_subsys, + &link_children_subsys, NULL, }; -- 2.7.4
[PATCH 0/2] two test samples for configfs
Add two test samples for configfs. include read and write bin_file and creat soft link. *** BLURB HERE *** SunKe (2): sample_configfs: bin_file read and write sample_configfs: soft link creat and delete samples/configfs/configfs_sample.c | 84 ++ 1 file changed, 84 insertions(+) -- 2.7.4
[PATCH 1/2] sample_configfs: bin_file read and write
Add bin_file read and write function Signed-off-by: SunKe --- samples/configfs/configfs_sample.c | 43 ++ 1 file changed, 43 insertions(+) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index 004a4e2..c76b784 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -146,6 +146,8 @@ static struct childless childless_subsys = { struct simple_child { struct config_item item; int storeme; + void *data; + size_t len; }; static inline struct simple_child *to_simple_child(struct config_item *item) @@ -153,6 +155,46 @@ static inline struct simple_child *to_simple_child(struct config_item *item) return item ? container_of(item, struct simple_child, item) : NULL; } +static ssize_t simple_child_bin_storeme_bin_write(struct config_item *item, + const void *data, size_t size) +{ + struct simple_child *simple_child = to_simple_child(item); + + kfree(simple_child->data); + simple_child->data = NULL; + + simple_child->data = kmemdup(data, size, GFP_KERNEL); + if (!simple_child->data) + return -ENOMEM; + simple_child->len = size; + + return 0; +} + +static ssize_t simple_child_bin_storeme_bin_read(struct config_item *item, + void *data, size_t size) +{ + struct simple_child *simple_child = to_simple_child(item); + + if (!data) { + size = simple_child->len; + } else { + memcpy(data, simple_child->data, simple_child->len); + size = simple_child->len; + } + + return size; +} + +#define MAX_SIZE (128 * 1024) + +CONFIGFS_BIN_ATTR(simple_child_bin_, storeme_bin, NULL, MAX_SIZE); + +static struct configfs_bin_attribute *simple_child_bin_attrs[] = { + &simple_child_bin_attr_storeme_bin, + NULL, +}; + static ssize_t simple_child_storeme_show(struct config_item *item, char *page) { return sprintf(page, "%d\n", to_simple_child(item)->storeme); @@ -196,6 +238,7 @@ static struct configfs_item_operations simple_child_item_ops = { static const struct config_item_type simple_child_type = { .ct_item_ops= &simple_child_item_ops, .ct_attrs = simple_child_attrs, + .ct_bin_attrs = simple_child_bin_attrs, .ct_owner = THIS_MODULE, }; -- 2.7.4