From nobody Wed Dec 24 08:08:52 2025 Received: from smtpout.efficios.com (smtpout.efficios.com [167.114.26.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B035159560; Mon, 29 Jan 2024 21:06:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=167.114.26.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706562416; cv=none; b=noSmrtN383DTT0ORB6kbLZMzuLfh70cCA/U6X6dd51NAJvtdvI1pN/O+prOOHDxHzjn1HhVtEJt85NWoNgmXF5cEVpLaEZvPoA2+QE7vOVRrrgM+3rHWVLdvb2NljQIpq89ASm9hUF0ZhcDEADN07KhBATY1EkB4GCqVf3m9elw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706562416; c=relaxed/simple; bh=qE6d84dw/RHBezptIMoCUSoZjf7hEPQsPy+jBZ/P/F4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UkdhiQCe55PgMBfERtOheghaATa20KcDVgBWTXq4xAPfYqTXKbmYdRDGB/kHT1lMLT5xTO2mNQaffPUgG2WDZQcdsWUnTzDcj++zTRUi+nMEztYcVNdMsoPIgQBZC5ib5KegkJ3AGeRgKoe84LEn4cqoG48/19H+ma6kOxaV5jM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=efficios.com; spf=pass smtp.mailfrom=efficios.com; dkim=pass (2048-bit key) header.d=efficios.com header.i=@efficios.com header.b=Or9KKQbE; arc=none smtp.client-ip=167.114.26.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=efficios.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=efficios.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=efficios.com header.i=@efficios.com header.b="Or9KKQbE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1706562411; bh=qE6d84dw/RHBezptIMoCUSoZjf7hEPQsPy+jBZ/P/F4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Or9KKQbE01DFHpcvYQEjceuM4WZSaWEOvWctam+nWYmhRaiKWaY7y4HtQ+LAL/ra6 WnhCkdYwWZj1fXClvt1jc4U9MGLixIqC+hCRIm0pnM+eeQFIiNsW9gPQLzahPKQZip vRvFUs1OQNbZHK4eqX9cfuOZsbhSkZk4y/WO9vHGSkKQ21R8iTopGgKUiPYn3cVKKy NY2XTs9e84eCiZRaD6C5ObMVDsbSWAz48qTfj2g5hx+kNTA/IE6wmKHn6763C2ptlI DRA6nvmFJIFA0Neet56IfoOGTJ7CVKcNye2U8woci47wLQIqX7JopQB0ezWkW1cJQy Ap1Rsna8wszfQ== Received: from thinkos.internal.efficios.com (192-222-143-198.qc.cable.ebox.net [192.222.143.198]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4TP17v02t7zVfq; Mon, 29 Jan 2024 16:06:50 -0500 (EST) From: Mathieu Desnoyers To: Dan Williams , Vishal Verma , Dave Jiang Cc: linux-kernel@vger.kernel.org, Mathieu Desnoyers , Miklos Szeredi , linux-fsdevel@vger.kernel.org, Andrew Morton , Linus Torvalds , linux-mm@kvack.org, linux-arch@vger.kernel.org, Matthew Wilcox , nvdimm@lists.linux.dev, linux-cxl@vger.kernel.org Subject: [RFC PATCH 6/7] fuse: Introduce fuse_dax_is_supported() Date: Mon, 29 Jan 2024 16:06:30 -0500 Message-Id: <20240129210631.193493-7-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240129210631.193493-1-mathieu.desnoyers@efficios.com> References: <20240129210631.193493-1-mathieu.desnoyers@efficios.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use dax_is_supported() in addition to IS_ENABLED(CONFIG_FUSE_DAX) to validate whether CONFIG_FUSE_DAX is enabled and the architecture does not have virtually aliased caches. This is relevant for architectures which require a dynamic check to validate whether they have virtually aliased data caches (ARCH_HAS_CACHE_ALIASING_DYNAMIC=3Dy). Fixes: d92576f1167c ("dax: does not work correctly with virtual aliasing ca= ches") Signed-off-by: Mathieu Desnoyers Cc: Miklos Szeredi Cc: linux-fsdevel@vger.kernel.org Cc: Andrew Morton Cc: Linus Torvalds Cc: linux-mm@kvack.org Cc: linux-arch@vger.kernel.org Cc: Dan Williams Cc: Vishal Verma Cc: Dave Jiang Cc: Matthew Wilcox Cc: nvdimm@lists.linux.dev Cc: linux-cxl@vger.kernel.org --- fs/fuse/file.c | 2 +- fs/fuse/fuse_i.h | 36 +++++++++++++++++++++++++++++++++- fs/fuse/inode.c | 47 +++++++++++++++++++++++---------------------- fs/fuse/virtio_fs.c | 4 ++-- 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a660f1f21540..133ac8524064 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3247,6 +3247,6 @@ void fuse_init_file_inode(struct inode *inode, unsign= ed int flags) init_waitqueue_head(&fi->page_waitq); fi->writepages =3D RB_ROOT; =20 - if (IS_ENABLED(CONFIG_FUSE_DAX)) + if (fuse_dax_is_supported()) fuse_dax_inode_init(inode, flags); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 1df83eebda92..1cbe37106669 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -31,6 +31,7 @@ #include #include #include +#include =20 /** Default max number of pages that can be used in a single read request = */ #define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32 @@ -979,6 +980,38 @@ static inline void fuse_sync_bucket_dec(struct fuse_sy= nc_bucket *bucket) rcu_read_unlock(); } =20 +#ifdef CONFIG_FUSE_DAX +static inline struct fuse_inode_dax *fuse_inode_get_dax(struct fuse_inode = *inode) +{ + return inode->dax; +} + +static inline enum fuse_dax_mode fuse_conn_get_dax_mode(struct fuse_conn *= fc) +{ + return fc->dax_mode; +} + +static inline struct fuse_conn_dax *fuse_conn_get_dax(struct fuse_conn *fc) +{ + return fc->dax; +} +#else +static inline struct fuse_inode_dax *fuse_inode_get_dax(struct fuse_inode = *inode) +{ + return NULL; +} + +static inline enum fuse_dax_mode fuse_conn_get_dax_mode(struct fuse_conn *= fc) +{ + return FUSE_DAX_INODE_DEFAULT; +} + +static inline struct fuse_conn_dax *fuse_conn_get_dax(struct fuse_conn *fc) +{ + return NULL; +} +#endif + /** Device operations */ extern const struct file_operations fuse_dev_operations; =20 @@ -1324,7 +1357,8 @@ void fuse_free_conn(struct fuse_conn *fc); =20 /* dax.c */ =20 -#define FUSE_IS_DAX(inode) (IS_ENABLED(CONFIG_FUSE_DAX) && IS_DAX(inode)) +#define fuse_dax_is_supported() (IS_ENABLED(CONFIG_FUSE_DAX) && dax_is_sup= ported()) +#define FUSE_IS_DAX(inode) (fuse_dax_is_supported() && IS_DAX(inode)) =20 ssize_t fuse_dax_read_iter(struct kiocb *iocb, struct iov_iter *to); ssize_t fuse_dax_write_iter(struct kiocb *iocb, struct iov_iter *from); diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 2a6d44f91729..030e6ce5486d 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -108,7 +108,7 @@ static struct inode *fuse_alloc_inode(struct super_bloc= k *sb) if (!fi->forget) goto out_free; =20 - if (IS_ENABLED(CONFIG_FUSE_DAX) && !fuse_dax_inode_alloc(sb, fi)) + if (fuse_dax_is_supported() && !fuse_dax_inode_alloc(sb, fi)) goto out_free_forget; =20 return &fi->inode; @@ -126,9 +126,8 @@ static void fuse_free_inode(struct inode *inode) =20 mutex_destroy(&fi->mutex); kfree(fi->forget); -#ifdef CONFIG_FUSE_DAX - kfree(fi->dax); -#endif + if (fuse_dax_is_supported()) + kfree(fuse_inode_get_dax(fi)); kmem_cache_free(fuse_inode_cachep, fi); } =20 @@ -361,7 +360,7 @@ void fuse_change_attributes(struct inode *inode, struct= fuse_attr *attr, invalidate_inode_pages2(inode->i_mapping); } =20 - if (IS_ENABLED(CONFIG_FUSE_DAX)) + if (fuse_dax_is_supported()) fuse_dax_dontcache(inode, attr->flags); } =20 @@ -856,14 +855,16 @@ static int fuse_show_options(struct seq_file *m, stru= ct dentry *root) if (sb->s_bdev && sb->s_blocksize !=3D FUSE_DEFAULT_BLKSIZE) seq_printf(m, ",blksize=3D%lu", sb->s_blocksize); } -#ifdef CONFIG_FUSE_DAX - if (fc->dax_mode =3D=3D FUSE_DAX_ALWAYS) - seq_puts(m, ",dax=3Dalways"); - else if (fc->dax_mode =3D=3D FUSE_DAX_NEVER) - seq_puts(m, ",dax=3Dnever"); - else if (fc->dax_mode =3D=3D FUSE_DAX_INODE_USER) - seq_puts(m, ",dax=3Dinode"); -#endif + if (fuse_dax_is_supported()) { + enum fuse_dax_mode dax_mode =3D fuse_conn_get_dax_mode(fc); + + if (dax_mode =3D=3D FUSE_DAX_ALWAYS) + seq_puts(m, ",dax=3Dalways"); + else if (dax_mode =3D=3D FUSE_DAX_NEVER) + seq_puts(m, ",dax=3Dnever"); + else if (dax_mode =3D=3D FUSE_DAX_INODE_USER) + seq_puts(m, ",dax=3Dinode"); + } =20 return 0; } @@ -936,7 +937,7 @@ void fuse_conn_put(struct fuse_conn *fc) struct fuse_iqueue *fiq =3D &fc->iq; struct fuse_sync_bucket *bucket; =20 - if (IS_ENABLED(CONFIG_FUSE_DAX)) + if (fuse_dax_is_supported()) fuse_dax_conn_free(fc); if (fiq->ops->release) fiq->ops->release(fiq); @@ -1264,7 +1265,7 @@ static void process_init_reply(struct fuse_mount *fm,= struct fuse_args *args, min_t(unsigned int, fc->max_pages_limit, max_t(unsigned int, arg->max_pages, 1)); } - if (IS_ENABLED(CONFIG_FUSE_DAX)) { + if (fuse_dax_is_supported()) { if (flags & FUSE_MAP_ALIGNMENT && !fuse_dax_check_alignment(fc, arg->map_alignment)) { ok =3D false; @@ -1331,12 +1332,12 @@ void fuse_send_init(struct fuse_mount *fm) FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT | FUSE_INIT_EXT | FUSE_SECURITY_CTX | FUSE_CREATE_SUPP_GROUP | FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_ALLOW_MMAP; -#ifdef CONFIG_FUSE_DAX - if (fm->fc->dax) - flags |=3D FUSE_MAP_ALIGNMENT; - if (fuse_is_inode_dax_mode(fm->fc->dax_mode)) - flags |=3D FUSE_HAS_INODE_DAX; -#endif + if (fuse_dax_is_supported()) { + if (fuse_conn_get_dax(fm->fc)) + flags |=3D FUSE_MAP_ALIGNMENT; + if (fuse_is_inode_dax_mode(fuse_conn_get_dax_mode(fm->fc))) + flags |=3D FUSE_HAS_INODE_DAX; + } if (fm->fc->auto_submounts) flags |=3D FUSE_SUBMOUNTS; =20 @@ -1643,7 +1644,7 @@ int fuse_fill_super_common(struct super_block *sb, st= ruct fuse_fs_context *ctx) =20 sb->s_subtype =3D ctx->subtype; ctx->subtype =3D NULL; - if (IS_ENABLED(CONFIG_FUSE_DAX)) { + if (fuse_dax_is_supported()) { err =3D fuse_dax_conn_alloc(fc, ctx->dax_mode, ctx->dax_dev); if (err) goto err; @@ -1709,7 +1710,7 @@ int fuse_fill_super_common(struct super_block *sb, st= ruct fuse_fs_context *ctx) if (fud) fuse_dev_free(fud); err_free_dax: - if (IS_ENABLED(CONFIG_FUSE_DAX)) + if (fuse_dax_is_supported()) fuse_dax_conn_free(fc); err: return err; diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 5f1be1da92ce..99f8f2a18ee4 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -801,7 +801,7 @@ static int virtio_fs_setup_dax(struct virtio_device *vd= ev, struct virtio_fs *fs) struct dev_pagemap *pgmap; bool have_cache; =20 - if (!IS_ENABLED(CONFIG_FUSE_DAX)) + if (fuse_dax_is_supported()) return 0; =20 /* Get cache region */ @@ -1366,7 +1366,7 @@ static void virtio_fs_conn_destroy(struct fuse_mount = *fm) /* Stop dax worker. Soon evict_inodes() will be called which * will free all memory ranges belonging to all inodes. */ - if (IS_ENABLED(CONFIG_FUSE_DAX)) + if (fuse_dax_is_supported()) fuse_dax_cancel_work(fc); =20 /* Stop forget queue. Soon destroy will be sent */ --=20 2.39.2