From patchwork Mon Jan 29 14:34:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13535767 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A348BC47DB3 for ; Mon, 29 Jan 2024 14:35:43 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 3C09C6B00AA; Mon, 29 Jan 2024 09:35:43 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 321C56B00AB; Mon, 29 Jan 2024 09:35:43 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 199D26B00AC; Mon, 29 Jan 2024 09:35:43 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 02F996B00AA for ; Mon, 29 Jan 2024 09:35:43 -0500 (EST) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id C77F51C0940 for ; Mon, 29 Jan 2024 14:35:42 +0000 (UTC) X-FDA: 81732597324.17.FED5CE4 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) by imf12.hostedemail.com (Postfix) with ESMTP id 1356E40010 for ; Mon, 29 Jan 2024 14:35:40 +0000 (UTC) Authentication-Results: imf12.hostedemail.com; dkim=pass header.d=infradead.org header.s=bombadil.20210309 header.b=kj9jwzgH; spf=none (imf12.hostedemail.com: domain of BATV+95c35c30fd22f84c25d9+7463+infradead.org+hch@bombadil.srs.infradead.org has no SPF policy when checking 198.137.202.133) smtp.mailfrom=BATV+95c35c30fd22f84c25d9+7463+infradead.org+hch@bombadil.srs.infradead.org; dmarc=none ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1706538941; a=rsa-sha256; cv=none; b=duc48BXOm/Op9DO5UWlgvPutBvEXEA/26Y52fLWq5yOkMXWoX2BQkhGCBaz2lVB3hSU9pa 9jply33xyfDOQWp+DtTGK88ozEq71wy7KIdv12qC3pR3LdDAHadcawaAF6y5rIavnta5ff zVzL5RqGH+10/bPrr8ZQEt0H3T9afbI= ARC-Authentication-Results: i=1; imf12.hostedemail.com; dkim=pass header.d=infradead.org header.s=bombadil.20210309 header.b=kj9jwzgH; spf=none (imf12.hostedemail.com: domain of BATV+95c35c30fd22f84c25d9+7463+infradead.org+hch@bombadil.srs.infradead.org has no SPF policy when checking 198.137.202.133) smtp.mailfrom=BATV+95c35c30fd22f84c25d9+7463+infradead.org+hch@bombadil.srs.infradead.org; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1706538941; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=UlrBswDRelEXcgNVOaWvSi/EUS+jJGBmCPE4n+9PxvU=; b=6Zbtrt87tazVCv1BKeBS1vTujyIUYgZ6iWgEwcxtuLogAAaNOHcAup8OIcIfSgvX7mYHu5 6RZTQ4kecl7ZtV7xvI9C5Cm6WK8q514UsgcsY0UL1rHCPLRhjmrEZT51U2I0AGWTUi09vT m8uPisUPw2eI+la450t0rGK43Ydywzc= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=UlrBswDRelEXcgNVOaWvSi/EUS+jJGBmCPE4n+9PxvU=; b=kj9jwzgH1z5ubr1AKZwgByeVZE 1MJdXgQc+Z1jipsrPKvENHUkhLNswtsHRbMvdEjgBgdsyj6kFGcATJ+0Ut4CeZSiBq2moNq9RvjJ9 XHdgnlhYeuphXSTOOoWyigtHMgl+zpptq2gwMJsssrp07nlMbqVAPeVE08ULq8s8qvsS+5bMdkDst WK2283IsgCT01lZRMZMrCtVEQa1yIQU9RbVwSB4SedBRXyeGkpjHFvhQcst/oObBCqbM1jqeaO9Sm k/qwjh3L8CnnUgW16ac7jG1r/3EV7AjcxKPMzapb4uskp7l5Y9iCjcU8hGxY5lndaJdZdxIBBIapA LT0WHEPQ==; Received: from [2001:4bb8:182:6550:c70:4a89:bc61:3] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1rUSjZ-0000000D6Fi-2zlr; Mon, 29 Jan 2024 14:35:38 +0000 From: Christoph Hellwig To: Chandan Babu R , "Darrick J. Wong" , Hugh Dickins , Andrew Morton Cc: linux-xfs@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 09/20] xfs: remove the xfile_pread/pwrite APIs Date: Mon, 29 Jan 2024 15:34:51 +0100 Message-Id: <20240129143502.189370-10-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240129143502.189370-1-hch@lst.de> References: <20240129143502.189370-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html X-Rspamd-Server: rspam08 X-Rspamd-Queue-Id: 1356E40010 X-Stat-Signature: jenoc3fq9z1eo49yr4oo3tq6guzgtzn7 X-Rspam-User: X-HE-Tag: 1706538940-948592 X-HE-Meta: U2FsdGVkX1/sppUykVG3jrnExhQHJ6ElwyiIAQlPRDs1UDTqcyVcSMZ9Aw9/mU6E4Td8+TJbth75SH9ozTPYwGxgvzZ7axlYn5/p1qlnvZuPyGfgGzi4LVML0Vn7RY6MW+1F37q2fqyF0m7llXAV+OO2hRZWRTbIaH2KlnF8V/UPomCIE6rccuRsJvcUVdG479zXff/8e78mqjNlQqC47TZmLZ5bd1S1Br2gDj1hXBsWSVlFfNZ821jJtkQ5Dg8bzGfa6Z9KICzw7jiNg35LEqoUJReC7AhNxOHOMKSKHkk8HTSbHFnvB+/D6KKjjUNtbf7M/ZpZsYbXZ00S+5Cy+EEgxfRGBpmUsC6jgwNfJb8P4+fxJrYZmKJt66Zcg4CYQ3c3oNiIOHT+WqSIFIge47w077lu0tYDz/KeaLQLtTV2VYQ/iW9DXNkNJ/1Tqx2DdawuFI906B/hVcx6dQTj8h4mGCAs2pimXLkxADCPJWGhcVS0oyEqLtf7EWi4zD8lzsEl2Bbswxg0dV2gX/N/XEatz114ITT9OfYTreakODJRbmQSpubv1/ztIKcnYUEJqd8B8wXB/5l4dU/y9aaxa2U4fZ6I709xEIOI32NRKMMHgtWEp60fTr1+gkEB7zIPl/Ddj7V6B/OBg7iAhgmLUzr6UUI+RgHfT+VJNnqI9KA1GYMaYiGffp99LuHl5YSVgy5rTVN5ixls5SVferkEOr6pyyGFB0rUPGBqdb8RZyd/5J4AT4XaqDy0xbRDriCCASlT+5GsL27oslZca0zK2ljJbI4U2oZN3gok8D95XtACnDEZUiab34MPT+HIijp+YIBj0LNJzyVSzsv38Qv4be4m/QV1vRn/NXwlwzUWXfoylo7MExJkl/nCUUpftXNNThoW9Mxy/QAHeS/h4tAIoWtTz5B8FbI7wl5QjjWn4J+fom54pt1ZCjVqXHosIpUG2YSQRWBDdjRHy/aNY4G knXGVuJJ 3Bg/TDUbf9CMdL7z2U1TAw388GcMKfTEn/dZQk1ucBlsQOTHmlX9ZASEJgljTvwVN9loYFjDGp6B6wHYu5WERTBXm8FxJXZZYkoOtxhOc8S6iJgvjGv85LYa7q/dj0x9eX0M5ZSINljA7jfqoc1T5y1C3E7TQHjLpbYoUFdD4OgL5Y9TyjItxny9nfXrIUUqrY/hWgyvxtZm91a6sWR22ZcXvy99sstujbCVssoY4xpN5nNKhVrA77G6xwt97Dd/wjS/7Ih1iHFA4OcByvdFgDYqkm+P6t9NFhuVaTnfduiuAzzLUieC5eOmdjpcD4wt6zIXvhQO7jphvHwjIxq8QcDT/txyEewkJVtaR48ai4ymO8mCb4GkNfykcz9HsnH2/0MmhBfjunmt2VaKCiM1dMtAHLKfYwupQZxVZ+LxUShG+UiyVZP1R1FwXwkf6MyfaXFPKqAPEbd5xc+RvXHpvW8YnsVkSDHD/OWylxSIWF2J0RLDz6y+f40ZpHEFqTwVayx1U8St8vno0mok= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: All current and pending xfile users use the xfile_obj_load and xfile_obj_store API, so make those the actual implementation. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong --- .../xfs/xfs-online-fsck-design.rst | 23 +++----- fs/xfs/scrub/rtsummary.c | 6 +-- fs/xfs/scrub/trace.h | 4 +- fs/xfs/scrub/xfarray.c | 18 +++---- fs/xfs/scrub/xfile.c | 54 +++++++++---------- fs/xfs/scrub/xfile.h | 32 +---------- 6 files changed, 48 insertions(+), 89 deletions(-) diff --git a/Documentation/filesystems/xfs/xfs-online-fsck-design.rst b/Documentation/filesystems/xfs/xfs-online-fsck-design.rst index 352516feef6ffe..216c99ce511f7c 100644 --- a/Documentation/filesystems/xfs/xfs-online-fsck-design.rst +++ b/Documentation/filesystems/xfs/xfs-online-fsck-design.rst @@ -1915,19 +1915,13 @@ four of those five higher level data structures. The fifth use case is discussed in the :ref:`realtime summary ` case study. -The most general storage interface supported by the xfile enables the reading -and writing of arbitrary quantities of data at arbitrary offsets in the xfile. -This capability is provided by ``xfile_pread`` and ``xfile_pwrite`` functions, -which behave similarly to their userspace counterparts. XFS is very record-based, which suggests that the ability to load and store complete records is important. -To support these cases, a pair of ``xfile_obj_load`` and ``xfile_obj_store`` -functions are provided to read and persist objects into an xfile. -They are internally the same as pread and pwrite, except that they treat any -error as an out of memory error. -For online repair, squashing error conditions in this manner is an acceptable -behavior because the only reaction is to abort the operation back to userspace. -All five xfile usecases can be serviced by these four functions. +To support these cases, a pair of ``xfile_load`` and ``xfile_store`` +functions are provided to read and persist objects into an xfile that treat any +error as an out of memory error. For online repair, squashing error conditions +in this manner is an acceptable behavior because the only reaction is to abort +the operation back to userspace. However, no discussion of file access idioms is complete without answering the question, "But what about mmap?" @@ -1939,10 +1933,9 @@ tmpfs can only push a pagecache folio to the swap cache if the folio is neither pinned nor locked, which means the xfile must not pin too many folios. Short term direct access to xfile contents is done by locking the pagecache -folio and mapping it into kernel address space. -Programmatic access (e.g. pread and pwrite) uses this mechanism. -Folio locks are not supposed to be held for long periods of time, so long -term direct access to xfile contents is done by bumping the folio refcount, +folio and mapping it into kernel address space. Object load and store uses this +mechanism. Folio locks are not supposed to be held for long periods of time, so +long term direct access to xfile contents is done by bumping the folio refcount, mapping it into kernel address space, and dropping the folio lock. These long term users *must* be responsive to memory reclaim by hooking into the shrinker infrastructure to know when to release folios. diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index fabd0ed9dfa676..30b5a3952513f8 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -118,7 +118,7 @@ xfsum_load( xfs_rtsumoff_t sumoff, union xfs_suminfo_raw *rawinfo) { - return xfile_obj_load(sc->xfile, rawinfo, + return xfile_load(sc->xfile, rawinfo, sizeof(union xfs_suminfo_raw), sumoff << XFS_WORDLOG); } @@ -129,7 +129,7 @@ xfsum_store( xfs_rtsumoff_t sumoff, const union xfs_suminfo_raw rawinfo) { - return xfile_obj_store(sc->xfile, &rawinfo, + return xfile_store(sc->xfile, &rawinfo, sizeof(union xfs_suminfo_raw), sumoff << XFS_WORDLOG); } @@ -141,7 +141,7 @@ xfsum_copyout( union xfs_suminfo_raw *rawinfo, unsigned int nr_words) { - return xfile_obj_load(sc->xfile, rawinfo, nr_words << XFS_WORDLOG, + return xfile_load(sc->xfile, rawinfo, nr_words << XFS_WORDLOG, sumoff << XFS_WORDLOG); } diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index 260b8fe0a80296..0327cab606b070 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -903,8 +903,8 @@ DECLARE_EVENT_CLASS(xfile_class, DEFINE_EVENT(xfile_class, name, \ TP_PROTO(struct xfile *xf, loff_t pos, unsigned long long bytecount), \ TP_ARGS(xf, pos, bytecount)) -DEFINE_XFILE_EVENT(xfile_pread); -DEFINE_XFILE_EVENT(xfile_pwrite); +DEFINE_XFILE_EVENT(xfile_load); +DEFINE_XFILE_EVENT(xfile_store); DEFINE_XFILE_EVENT(xfile_seek_data); DEFINE_XFILE_EVENT(xfile_get_page); DEFINE_XFILE_EVENT(xfile_put_page); diff --git a/fs/xfs/scrub/xfarray.c b/fs/xfs/scrub/xfarray.c index f0f532c10a5acc..95ac14bceeadd6 100644 --- a/fs/xfs/scrub/xfarray.c +++ b/fs/xfs/scrub/xfarray.c @@ -136,7 +136,7 @@ xfarray_load( if (idx >= array->nr) return -ENODATA; - return xfile_obj_load(array->xfile, ptr, array->obj_size, + return xfile_load(array->xfile, ptr, array->obj_size, xfarray_pos(array, idx)); } @@ -152,7 +152,7 @@ xfarray_is_unset( if (array->unset_slots == 0) return false; - error = xfile_obj_load(array->xfile, temp, array->obj_size, pos); + error = xfile_load(array->xfile, temp, array->obj_size, pos); if (!error && xfarray_element_is_null(array, temp)) return true; @@ -184,7 +184,7 @@ xfarray_unset( return 0; memset(temp, 0, array->obj_size); - error = xfile_obj_store(array->xfile, temp, array->obj_size, pos); + error = xfile_store(array->xfile, temp, array->obj_size, pos); if (error) return error; @@ -209,7 +209,7 @@ xfarray_store( ASSERT(!xfarray_element_is_null(array, ptr)); - ret = xfile_obj_store(array->xfile, ptr, array->obj_size, + ret = xfile_store(array->xfile, ptr, array->obj_size, xfarray_pos(array, idx)); if (ret) return ret; @@ -245,12 +245,12 @@ xfarray_store_anywhere( for (pos = 0; pos < endpos && array->unset_slots > 0; pos += array->obj_size) { - error = xfile_obj_load(array->xfile, temp, array->obj_size, + error = xfile_load(array->xfile, temp, array->obj_size, pos); if (error || !xfarray_element_is_null(array, temp)) continue; - error = xfile_obj_store(array->xfile, ptr, array->obj_size, + error = xfile_store(array->xfile, ptr, array->obj_size, pos); if (error) return error; @@ -552,7 +552,7 @@ xfarray_isort( trace_xfarray_isort(si, lo, hi); xfarray_sort_bump_loads(si); - error = xfile_obj_load(si->array->xfile, scratch, len, lo_pos); + error = xfile_load(si->array->xfile, scratch, len, lo_pos); if (error) return error; @@ -560,7 +560,7 @@ xfarray_isort( sort(scratch, hi - lo + 1, si->array->obj_size, si->cmp_fn, NULL); xfarray_sort_bump_stores(si); - return xfile_obj_store(si->array->xfile, scratch, len, lo_pos); + return xfile_store(si->array->xfile, scratch, len, lo_pos); } /* Grab a page for sorting records. */ @@ -858,7 +858,7 @@ xfarray_sort_load_cached( if (xfarray_sort_terminated(si, &error)) return error; - return xfile_obj_load(si->array->xfile, ptr, + return xfile_load(si->array->xfile, ptr, si->array->obj_size, idx_pos); } diff --git a/fs/xfs/scrub/xfile.c b/fs/xfs/scrub/xfile.c index 87654cdd5ac6f9..d65681372a7458 100644 --- a/fs/xfs/scrub/xfile.c +++ b/fs/xfs/scrub/xfile.c @@ -118,13 +118,11 @@ xfile_destroy( } /* - * Read a memory object directly from the xfile's page cache. Unlike regular - * pread, we return -E2BIG and -EFBIG for reads that are too large or at too - * high an offset, instead of truncating the read. Otherwise, we return - * bytes read or an error code, like regular pread. + * Load an object. Since we're treating this file as "memory", any error or + * short IO is treated as a failure to allocate memory. */ -ssize_t -xfile_pread( +int +xfile_load( struct xfile *xf, void *buf, size_t count, @@ -133,16 +131,15 @@ xfile_pread( struct inode *inode = file_inode(xf->file); struct address_space *mapping = inode->i_mapping; struct page *page = NULL; - ssize_t read = 0; unsigned int pflags; int error = 0; if (count > MAX_RW_COUNT) - return -E2BIG; + return -ENOMEM; if (inode->i_sb->s_maxbytes - pos < count) - return -EFBIG; + return -ENOMEM; - trace_xfile_pread(xf, pos, count); + trace_xfile_load(xf, pos, count); pflags = memalloc_nofs_save(); while (count > 0) { @@ -160,8 +157,10 @@ xfile_pread( __GFP_NOWARN); if (IS_ERR(page)) { error = PTR_ERR(page); - if (error != -ENOMEM) + if (error != -ENOMEM) { + error = -ENOMEM; break; + } memset(buf, 0, len); goto advance; @@ -185,23 +184,18 @@ xfile_pread( count -= len; pos += len; buf += len; - read += len; } memalloc_nofs_restore(pflags); - if (read > 0) - return read; return error; } /* - * Write a memory object directly to the xfile's page cache. Unlike regular - * pwrite, we return -E2BIG and -EFBIG for writes that are too large or at too - * high an offset, instead of truncating the write. Otherwise, we return - * bytes written or an error code, like regular pwrite. + * Store an object. Since we're treating this file as "memory", any error or + * short IO is treated as a failure to allocate memory. */ -ssize_t -xfile_pwrite( +int +xfile_store( struct xfile *xf, const void *buf, size_t count, @@ -211,16 +205,15 @@ xfile_pwrite( struct address_space *mapping = inode->i_mapping; const struct address_space_operations *aops = mapping->a_ops; struct page *page = NULL; - ssize_t written = 0; unsigned int pflags; int error = 0; if (count > MAX_RW_COUNT) - return -E2BIG; + return -ENOMEM; if (inode->i_sb->s_maxbytes - pos < count) - return -EFBIG; + return -ENOMEM; - trace_xfile_pwrite(xf, pos, count); + trace_xfile_store(xf, pos, count); pflags = memalloc_nofs_save(); while (count > 0) { @@ -239,8 +232,10 @@ xfile_pwrite( */ error = aops->write_begin(NULL, mapping, pos, len, &page, &fsdata); - if (error) + if (error) { + error = -ENOMEM; break; + } /* * xfile pages must never be mapped into userspace, so we skip @@ -259,13 +254,14 @@ xfile_pwrite( ret = aops->write_end(NULL, mapping, pos, len, len, page, fsdata); if (ret < 0) { - error = ret; + error = -ENOMEM; break; } - written += ret; - if (ret != len) + if (ret != len) { + error = -ENOMEM; break; + } count -= ret; pos += ret; @@ -273,8 +269,6 @@ xfile_pwrite( } memalloc_nofs_restore(pflags); - if (written > 0) - return written; return error; } diff --git a/fs/xfs/scrub/xfile.h b/fs/xfs/scrub/xfile.h index c602d11560d8ee..465b10f492b66d 100644 --- a/fs/xfs/scrub/xfile.h +++ b/fs/xfs/scrub/xfile.h @@ -29,38 +29,10 @@ struct xfile { int xfile_create(const char *description, loff_t isize, struct xfile **xfilep); void xfile_destroy(struct xfile *xf); -ssize_t xfile_pread(struct xfile *xf, void *buf, size_t count, loff_t pos); -ssize_t xfile_pwrite(struct xfile *xf, const void *buf, size_t count, +int xfile_load(struct xfile *xf, void *buf, size_t count, loff_t pos); +int xfile_store(struct xfile *xf, const void *buf, size_t count, loff_t pos); -/* - * Load an object. Since we're treating this file as "memory", any error or - * short IO is treated as a failure to allocate memory. - */ -static inline int -xfile_obj_load(struct xfile *xf, void *buf, size_t count, loff_t pos) -{ - ssize_t ret = xfile_pread(xf, buf, count, pos); - - if (ret < 0 || ret != count) - return -ENOMEM; - return 0; -} - -/* - * Store an object. Since we're treating this file as "memory", any error or - * short IO is treated as a failure to allocate memory. - */ -static inline int -xfile_obj_store(struct xfile *xf, const void *buf, size_t count, loff_t pos) -{ - ssize_t ret = xfile_pwrite(xf, buf, count, pos); - - if (ret < 0 || ret != count) - return -ENOMEM; - return 0; -} - loff_t xfile_seek_data(struct xfile *xf, loff_t pos); int xfile_get_page(struct xfile *xf, loff_t offset, unsigned int len,