From nobody Wed Dec 17 00:34:40 2025 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2628A18E33 for ; Mon, 15 Jan 2024 18:38:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--surenb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="racXoa4T" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dbe9dacc912so10598302276.2 for ; Mon, 15 Jan 2024 10:38:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1705343925; x=1705948725; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ch6T6Lsnf4fqmqV9A6xFsxD4eG+jCeNRaJgu+LlgQig=; b=racXoa4TnsLPy0OFLS+xzftOB6e28+Lm+G2K0Tue45QfDYhuBJN8zPqvCSUGQLIRGB Ex7Z6px6V8c6e9Z+zu1ZevP638iygpxyIbCeKxw+/zA1/m3DWs3ASyzMRqrxxKdRy5d2 wDUSFiLSWkykFnGsS1vGxi/zl/FfuDuWQ9fqAKrxd/AzlFxQhDZmsmgQtFs+EA3fu0AC UhGvm4g0XgBnaKtwq1QV/3UFtrDZHaafByjh3e66qJ3jjE7xnQcwWxNoEKsCr8pl5Mbz boLb+9tYXQq2eQtoiY8sAg8FH99i29PfnKLuRpSLH30hqUjWZm6ROwwLw6d7ZAfmClIa zW0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705343925; x=1705948725; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ch6T6Lsnf4fqmqV9A6xFsxD4eG+jCeNRaJgu+LlgQig=; b=EeQ8lqTg772sP3R347QcFA8htAQMFEDazVdjNl1Sg5nZW2iMH5A2uDcZV3W9FA3v1C VvUEJBYEsXgSad/lJ6dXZaZSo5nj/b7Muk81vpKa7bSwOp8WhJ0AHiFx3qO0VKozEgiJ pK7Kq9lIvq8VI61EBOo8VTkmp2LxGMnuLtFtQjsODYVRUynzGBXGI/gIWM3RCaoKifRn DHWAwUR6UmpgAkI5L6HNseMyRonR6jGbJiGPT6Kyk7k/s8hbyTUDUx1U921rWnVFqXlW awIEktXYA/NSuPJu/soToy2qh8FpTd1U/y80KSk73Gw0nHURPL7uivB+QSUco1vyrABB qWow== X-Gm-Message-State: AOJu0YxwmOJP+pQc4jGN9nWaImhKuPnCpEX1pQSlZQaFZIUpxyeaXyGA U/JKvTz0qXTebkPRAzVCuK48A29s3VC4igLptw== X-Google-Smtp-Source: AGHT+IGN2VvUUxNx3HDpn+LUP1maSJ793VbScOs1XRHuqJsGhFfM1RNtInfsiW1wKVri/L8s95oaaZe3g/g= X-Received: from surenb-desktop.mtv.corp.google.com ([2620:15c:211:201:3af2:e48e:2785:270]) (user=surenb job=sendgmr) by 2002:a05:6902:1364:b0:dbd:7149:a389 with SMTP id bt4-20020a056902136400b00dbd7149a389mr269675ybb.11.1705343925137; Mon, 15 Jan 2024 10:38:45 -0800 (PST) Date: Mon, 15 Jan 2024 10:38:35 -0800 In-Reply-To: <20240115183837.205694-1-surenb@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240115183837.205694-1-surenb@google.com> X-Mailer: git-send-email 2.43.0.381.gb435a96ce8-goog Message-ID: <20240115183837.205694-3-surenb@google.com> Subject: [RFC 2/3] seq_file: add validate() operation to seq_operations From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz, dchinner@redhat.com, casey@schaufler-ca.com, ben.wolsieffer@hefring.com, paulmck@kernel.org, david@redhat.com, avagin@google.com, usama.anjum@collabora.com, peterx@redhat.com, hughd@google.com, ryan.roberts@arm.com, wangkefeng.wang@huawei.com, Liam.Howlett@Oracle.com, yuzhao@google.com, axelrasmussen@google.com, lstoakes@gmail.com, talumbau@google.com, willy@infradead.org, vbabka@suse.cz, mgorman@techsingularity.net, jhubbard@nvidia.com, vishal.moola@gmail.com, mathieu.desnoyers@efficios.com, dhowells@redhat.com, jgg@ziepe.ca, sidhartha.kumar@oracle.com, andriy.shevchenko@linux.intel.com, yangxingui@huawei.com, keescook@chromium.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, kernel-team@android.com, surenb@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" seq_file outputs data in chunks using seq_file.buf as the intermediate storage before outputting the generated data for the current chunk. It is possible for already buffered data to become stale before it gets reported. In certain situations it is desirable to regenerate that data instead of reporting the stale one. Provide a validate() operation called before outputting the buffered data to allow users to validate buffered data. To indicate valid data, user's validate callback should return 0, to request regeneration of the stale data it should return -EAGAIN, any other error will be considered fatal and read operation will be aborted. Signed-off-by: Suren Baghdasaryan --- fs/seq_file.c | 24 +++++++++++++++++++++++- include/linux/seq_file.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/fs/seq_file.c b/fs/seq_file.c index f5fdaf3b1572..77833bbe5909 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -172,6 +172,8 @@ ssize_t seq_read_iter(struct kiocb *iocb, struct iov_it= er *iter) { struct seq_file *m =3D iocb->ki_filp->private_data; size_t copied =3D 0; + loff_t orig_index; + size_t orig_count; size_t n; void *p; int err =3D 0; @@ -220,6 +222,10 @@ ssize_t seq_read_iter(struct kiocb *iocb, struct iov_i= ter *iter) if (m->count) // hadn't managed to copy everything goto Done; } + + orig_index =3D m->index; + orig_count =3D m->count; +Again: // get a non-empty record in the buffer m->from =3D 0; p =3D m->op->start(m, &m->index); @@ -278,6 +284,22 @@ ssize_t seq_read_iter(struct kiocb *iocb, struct iov_i= ter *iter) } } m->op->stop(m, p); + /* Note: we validate even if err<0 to prevent publishing copied data */ + if (m->op->validate) { + int val_err =3D m->op->validate(m, p); + + if (val_err) { + if (val_err =3D=3D -EAGAIN) { + m->index =3D orig_index; + m->count =3D orig_count; + // data is stale, retry + goto Again; + } + // data is invalid, return the last error + err =3D val_err; + goto Done; + } + } n =3D copy_to_iter(m->buf, m->count, iter); copied +=3D n; m->count -=3D n; @@ -572,7 +594,7 @@ static void single_stop(struct seq_file *p, void *v) int single_open(struct file *file, int (*show)(struct seq_file *, void *), void *data) { - struct seq_operations *op =3D kmalloc(sizeof(*op), GFP_KERNEL_ACCOUNT); + struct seq_operations *op =3D kzalloc(sizeof(*op), GFP_KERNEL_ACCOUNT); int res =3D -ENOMEM; =20 if (op) { diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 234bcdb1fba4..d0fefac2990f 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -34,6 +34,7 @@ struct seq_operations { void (*stop) (struct seq_file *m, void *v); void * (*next) (struct seq_file *m, void *v, loff_t *pos); int (*show) (struct seq_file *m, void *v); + int (*validate)(struct seq_file *m, void *v); }; =20 #define SEQ_SKIP 1 --=20 2.43.0.381.gb435a96ce8-goog