From patchwork Fri Nov 24 16:59:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Shtepa X-Patchwork-Id: 169523 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ce62:0:b0:403:3b70:6f57 with SMTP id o2csp1370344vqx; Fri, 24 Nov 2023 09:01:44 -0800 (PST) X-Google-Smtp-Source: AGHT+IHAqIWQ0pQkUFEtAw0ZVtrDINlNzzrzQ1oiET0k5v1LmKDqYz7iLiLMdtLqmKX2S+zLrm14 X-Received: by 2002:a05:6870:2196:b0:1f0:1c00:d860 with SMTP id l22-20020a056870219600b001f01c00d860mr3845335oae.51.1700845303771; Fri, 24 Nov 2023 09:01:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700845303; cv=none; d=google.com; s=arc-20160816; b=sUQo3h+LJgXiw0PensIFZ0CDUPxLhtos82rFJf4q7RCl33ACAEjhigC7uMh5NHqXGT Clv22UF5TFfGXWixduDxJSkhIZ1uQ70PJcMNfTItlAUY5fAjMHbZSbicRivS6+fec1Z3 hLT2QCdP7LLRAHQCMl2QnQUOZ6DQ+NqQr/AL5152WAvdH75nhCWVxs0hPUHMfcttAws/ bUPoeU98Ju3Ml1PR2waDyqLr6varbr3kIAtc0K33Pl3kN9M4ZyKQ6uMlNKHY5wR74VwX QyXiNkyNYcW4JJFaT2zTdd53+I5C8j9RGEJDgvhptCJVoJ65HeZIIFmyJPXCUMmCUSDB qHng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=HWENQVeTzgUlxGLBDIpOkaJ8YTyPuR19yc5enxAnFIw=; fh=2mCdnEsEQzaNNg7WB3fw4oVqqq+eEoqCz0tNA1gXC/4=; b=MgTDYBz1m4NBqfiKdywyWoic17PVs3KIHkZWqdYnQKYZSdN6zWv47+1w7izci1SaKU mnpSgN0FLTP352EZaLf0VrmcJmQVNDSvPFzmBH+Q0qpZmMWxxSRkA6jiDcCF0pO9E/bo aC1jUdZDEFpQKc+H/7amDcTSOt6Pt+gtNLJV+WZupZFrRGEHl+KluR6y+PAt5vzvkY3y j+wZHpt931J7uiJLozXLl2tMdNrsl1IkD1nFUFbb28p6cW/rNlxXXQWuolPJq0lcsN7X hgEA4eItZBqz650nh4iDJTtI2DwzvAxxqmj2tl3PQDfCL2j3blGygbX38bBYwru7J34P LmNA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=Y89b0090; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from morse.vger.email (morse.vger.email. [23.128.96.31]) by mx.google.com with ESMTPS id j4-20020a056830270400b006d7e9a52180si1756005otu.132.2023.11.24.09.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 09:01:43 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) client-ip=23.128.96.31; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=Y89b0090; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id A492080B028C; Fri, 24 Nov 2023 09:01:30 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231436AbjKXRAu (ORCPT + 99 others); Fri, 24 Nov 2023 12:00:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235154AbjKXRAU (ORCPT ); Fri, 24 Nov 2023 12:00:20 -0500 Received: from out-189.mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D666B210C for ; Fri, 24 Nov 2023 09:00:17 -0800 (PST) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1700845216; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HWENQVeTzgUlxGLBDIpOkaJ8YTyPuR19yc5enxAnFIw=; b=Y89b0090oahW/UxVCcF6BkmwTPuu68hFa995OMYMDYfcq8LCEx3UtwuMuNYlcfZfEcA9fW Jujin1UGL0IJ5fMsZcq+bOcwCmQU5pcmjH9rGA+pVxVJ0GsaS+VOsVqYPB7VFglGsNcCzE EoVw9De+WKKzL3juazloK4Uw9Frg2ys= From: Sergei Shtepa To: axboe@kernel.dk, hch@infradead.org, corbet@lwn.net, snitzer@kernel.org Cc: mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com, viro@zeniv.linux.org.uk, brauner@kernel.org, linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Sergei Shtepa Subject: [PATCH v6 08/11] blksnap: event queue from the difference storage Date: Fri, 24 Nov 2023 17:59:30 +0100 Message-Id: <20231124165933.27580-9-sergei.shtepa@linux.dev> In-Reply-To: <20231124165933.27580-1-sergei.shtepa@linux.dev> References: <20231124165933.27580-1-sergei.shtepa@linux.dev> MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Fri, 24 Nov 2023 09:01:30 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783465565223553780 X-GMAIL-MSGID: 1783465565223553780 From: Sergei Shtepa Events are used to immediately notify the user land of a change in the snapshot state. For example, if an error occurred while snapshot holding when reading data from the original block device or from the difference storage. Co-developed-by: Christoph Hellwig Signed-off-by: Christoph Hellwig Signed-off-by: Sergei Shtepa --- drivers/block/blksnap/event_queue.c | 81 +++++++++++++++++++++++++++++ drivers/block/blksnap/event_queue.h | 64 +++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 drivers/block/blksnap/event_queue.c create mode 100644 drivers/block/blksnap/event_queue.h diff --git a/drivers/block/blksnap/event_queue.c b/drivers/block/blksnap/event_queue.c new file mode 100644 index 000000000000..2256167b631b --- /dev/null +++ b/drivers/block/blksnap/event_queue.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2023 Veeam Software Group GmbH */ +#define pr_fmt(fmt) KBUILD_MODNAME "-event_queue: " fmt + +#include +#include +#include "event_queue.h" + +void event_queue_init(struct event_queue *event_queue) +{ + INIT_LIST_HEAD(&event_queue->list); + spin_lock_init(&event_queue->lock); + init_waitqueue_head(&event_queue->wq_head); +} + +void event_queue_done(struct event_queue *event_queue) +{ + struct event *event; + + spin_lock(&event_queue->lock); + while (!list_empty(&event_queue->list)) { + event = list_first_entry(&event_queue->list, struct event, + link); + list_del(&event->link); + event_free(event); + } + spin_unlock(&event_queue->lock); +} + +int event_gen(struct event_queue *event_queue, gfp_t flags, int code, + const void *data, int data_size) +{ + struct event *event; + + event = kzalloc(sizeof(struct event) + data_size + 1, flags); + if (!event) + return -ENOMEM; + + event->time = ktime_get(); + event->code = code; + event->data_size = data_size; + memcpy(event->data, data, data_size); + + pr_debug("Generate event: time=%lld code=%d data_size=%d\n", + event->time, event->code, event->data_size); + + spin_lock(&event_queue->lock); + list_add_tail(&event->link, &event_queue->list); + spin_unlock(&event_queue->lock); + + wake_up(&event_queue->wq_head); + return 0; +} + +struct event *event_wait(struct event_queue *event_queue, + unsigned long timeout_ms) +{ + int ret; + + ret = wait_event_interruptible_timeout(event_queue->wq_head, + !list_empty(&event_queue->list), timeout_ms); + if (ret >= 0) { + struct event *event = ERR_PTR(-ENOENT); + + spin_lock(&event_queue->lock); + if (!list_empty(&event_queue->list)) { + event = list_first_entry(&event_queue->list, + struct event, link); + list_del(&event->link); + } + spin_unlock(&event_queue->lock); + return event; + } + if (ret == -ERESTARTSYS) { + pr_debug("event waiting interrupted\n"); + return ERR_PTR(-EINTR); + } + + pr_err("Failed to wait event. errno=%d\n", abs(ret)); + return ERR_PTR(ret); +} diff --git a/drivers/block/blksnap/event_queue.h b/drivers/block/blksnap/event_queue.h new file mode 100644 index 000000000000..c919eee3ed96 --- /dev/null +++ b/drivers/block/blksnap/event_queue.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2023 Veeam Software Group GmbH */ +#ifndef __BLKSNAP_EVENT_QUEUE_H +#define __BLKSNAP_EVENT_QUEUE_H + +#include +#include +#include +#include +#include + +/** + * struct event - An event to be passed to the user space. + * @link: + * The list header allows to combine events from the queue. + * @time: + * A timestamp indicates when an event occurred. + * @code: + * Event code. + * @data_size: + * The number of bytes in the event data array. + * @data: + * An array of event data. + * + * Events can be different, so they contain different data. The size of the + * data array is not defined exactly, but it has limitations. The size of + * the event structure is limited by the PAGE_SIZE (4096 bytes). + */ +struct event { + struct list_head link; + ktime_t time; + int code; + int data_size; + char data[]; +}; + +/** + * struct event_queue - A queue of &struct event. + * @list: + * Linked list for storing events. + * @lock: + * Spinlock allows to guarantee safety of the linked list. + * @wq_head: + * A wait queue allows to put a user thread in a waiting state until + * an event appears in the linked list. + */ +struct event_queue { + struct list_head list; + spinlock_t lock; + struct wait_queue_head wq_head; +}; + +void event_queue_init(struct event_queue *event_queue); +void event_queue_done(struct event_queue *event_queue); + +int event_gen(struct event_queue *event_queue, gfp_t flags, int code, + const void *data, int data_size); +struct event *event_wait(struct event_queue *event_queue, + unsigned long timeout_ms); +static inline void event_free(struct event *event) +{ + kfree(event); +}; +#endif /* __BLKSNAP_EVENT_QUEUE_H */