[PATCH v3 13/13] fuse: remove pages for requests and exclusively use folios

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



All fuse requests use folios instead of pages for transferring data.
Remove pages from the requests and exclusively use folios.

No functional changes.

Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx>
Reviewed-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
---
 fs/fuse/cuse.c      |  1 -
 fs/fuse/dev.c       | 49 ++++++++---------------
 fs/fuse/dir.c       |  1 -
 fs/fuse/file.c      |  4 --
 fs/fuse/fuse_i.h    | 16 ++------
 fs/fuse/ioctl.c     |  1 -
 fs/fuse/readdir.c   |  1 -
 fs/fuse/virtio_fs.c | 95 +++++++++++++++++----------------------------
 8 files changed, 56 insertions(+), 112 deletions(-)

diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index eed78e303139..ef9fb30b9bdc 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -460,7 +460,6 @@ static int cuse_send_init(struct cuse_conn *cc)
 	ap->args.out_args[1].size = CUSE_INIT_INFO_MAX;
 	ap->args.out_argvar = true;
 	ap->args.out_pages = true;
-	ap->uses_folios = true;
 	ap->num_folios = 1;
 	ap->folios = &ia->folio;
 	ap->folio_descs = &ia->desc;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 9467b05d3d4a..ee698e3ea32f 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1028,41 +1028,27 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
 	struct fuse_req *req = cs->req;
 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
 
-	if (ap->uses_folios) {
-		for (i = 0; i < ap->num_folios && (nbytes || zeroing); i++) {
-			int err;
-			unsigned int offset = ap->folio_descs[i].offset;
-			unsigned int count = min(nbytes, ap->folio_descs[i].length);
-			struct page *orig, *pagep;
+	for (i = 0; i < ap->num_folios && (nbytes || zeroing); i++) {
+		int err;
+		unsigned int offset = ap->folio_descs[i].offset;
+		unsigned int count = min(nbytes, ap->folio_descs[i].length);
+		struct page *orig, *pagep;
 
-			orig = pagep = &ap->folios[i]->page;
+		orig = pagep = &ap->folios[i]->page;
 
-			err = fuse_copy_page(cs, &pagep, offset, count, zeroing);
-			if (err)
-				return err;
-
-			nbytes -= count;
-
-			/*
-			 *  fuse_copy_page may have moved a page from a pipe
-			 *  instead of copying into our given page, so update
-			 *  the folios if it was replaced.
-			 */
-			if (pagep != orig)
-				ap->folios[i] = page_folio(pagep);
-		}
-	} else {
-		for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
-			int err;
-			unsigned int offset = ap->descs[i].offset;
-			unsigned int count = min(nbytes, ap->descs[i].length);
+		err = fuse_copy_page(cs, &pagep, offset, count, zeroing);
+		if (err)
+			return err;
 
-			err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
-			if (err)
-				return err;
+		nbytes -= count;
 
-			nbytes -= count;
-		}
+		/*
+		 *  fuse_copy_page may have moved a page from a pipe instead of
+		 *  copying into our given page, so update the folios if it was
+		 *  replaced.
+		 */
+		if (pagep != orig)
+			ap->folios[i] = page_folio(pagep);
 	}
 	return 0;
 }
@@ -1770,7 +1756,6 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
 	ap = &ra->ap;
 	ap->folios = (void *) (ra + 1);
 	ap->folio_descs = (void *) (ap->folios + num_pages);
-	ap->uses_folios = true;
 
 	args = &ap->args;
 	args->nodeid = outarg->nodeid;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index a08c532068d0..2661f0cab349 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1590,7 +1590,6 @@ static int fuse_readlink_page(struct inode *inode, struct folio *folio)
 	struct fuse_mount *fm = get_fuse_mount(inode);
 	struct fuse_folio_desc desc = { .length = PAGE_SIZE - 1 };
 	struct fuse_args_pages ap = {
-		.uses_folios = true,
 		.num_folios = 1,
 		.folios = &folio,
 		.folio_descs = &desc,
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 14af8c41fc83..070db159ba7b 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -750,7 +750,6 @@ static struct fuse_io_args *fuse_io_folios_alloc(struct fuse_io_priv *io,
 	ia = kzalloc(sizeof(*ia), GFP_KERNEL);
 	if (ia) {
 		ia->io = io;
-		ia->ap.uses_folios = true;
 		ia->ap.folios = fuse_folios_alloc(nfolios, GFP_KERNEL,
 						  &ia->ap.folio_descs);
 		if (!ia->ap.folios) {
@@ -880,7 +879,6 @@ static int fuse_do_readfolio(struct file *file, struct folio *folio)
 	struct fuse_io_args ia = {
 		.ap.args.page_zeroing = true,
 		.ap.args.out_pages = true,
-		.ap.uses_folios = true,
 		.ap.num_folios = 1,
 		.ap.folios = &folio,
 		.ap.folio_descs = &desc,
@@ -1318,7 +1316,6 @@ static ssize_t fuse_perform_write(struct kiocb *iocb, struct iov_iter *ii)
 		unsigned int nr_pages = fuse_wr_pages(pos, iov_iter_count(ii),
 						      fc->max_pages);
 
-		ap->uses_folios = true;
 		ap->folios = fuse_folios_alloc(nr_pages, GFP_KERNEL, &ap->folio_descs);
 		if (!ap->folios) {
 			err = -ENOMEM;
@@ -2093,7 +2090,6 @@ static struct fuse_writepage_args *fuse_writepage_args_alloc(void)
 	if (wpa) {
 		ap = &wpa->ia.ap;
 		ap->num_folios = 0;
-		ap->uses_folios = true;
 		ap->folios = fuse_folios_alloc(1, GFP_NOFS, &ap->folio_descs);
 		if (!ap->folios) {
 			kfree(wpa);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index d26d278da886..55d371016c97 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -325,19 +325,9 @@ struct fuse_args {
 
 struct fuse_args_pages {
 	struct fuse_args args;
-	union {
-		struct {
-			struct page **pages;
-			struct fuse_page_desc *descs;
-			unsigned int num_pages;
-		};
-		struct {
-			struct folio **folios;
-			struct fuse_folio_desc *folio_descs;
-			unsigned int num_folios;
-		};
-	};
-	bool uses_folios;
+	struct folio **folios;
+	unsigned int num_folios;
+	struct fuse_folio_desc *folio_descs;
 };
 
 struct fuse_release_args {
diff --git a/fs/fuse/ioctl.c b/fs/fuse/ioctl.c
index 1c77d8a27950..28138c838d49 100644
--- a/fs/fuse/ioctl.c
+++ b/fs/fuse/ioctl.c
@@ -306,7 +306,6 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
 	err = -ENOMEM;
 	if (max_pages > fm->fc->max_pages)
 		goto out;
-	ap.uses_folios = true;
 	while (ap.num_folios < max_pages) {
 		ap.folios[ap.num_folios] = folio_alloc(GFP_KERNEL | __GFP_HIGHMEM, 0);
 		if (!ap.folios[ap.num_folios])
diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c
index fd0eff1b9f2d..aeb5ea534c96 100644
--- a/fs/fuse/readdir.c
+++ b/fs/fuse/readdir.c
@@ -346,7 +346,6 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
 
 	plus = fuse_use_readdirplus(inode, ctx);
 	ap->args.out_pages = true;
-	ap->uses_folios = true;
 	ap->num_folios = 1;
 	ap->folios = &folio;
 	ap->folio_descs = &desc;
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 9f0d98cc20d3..b8d31a93f2d6 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -765,7 +765,6 @@ static void virtio_fs_request_complete(struct fuse_req *req,
 	struct fuse_args *args;
 	struct fuse_args_pages *ap;
 	unsigned int len, i, thislen;
-	struct page *page;
 	struct folio *folio;
 
 	/*
@@ -778,29 +777,15 @@ static void virtio_fs_request_complete(struct fuse_req *req,
 	if (args->out_pages && args->page_zeroing) {
 		len = args->out_args[args->out_numargs - 1].size;
 		ap = container_of(args, typeof(*ap), args);
-		if (ap->uses_folios) {
-			for (i = 0; i < ap->num_folios; i++) {
-				thislen = ap->folio_descs[i].length;
-				if (len < thislen) {
-					WARN_ON(ap->folio_descs[i].offset);
-					folio = ap->folios[i];
-					folio_zero_segment(folio, len, thislen);
-					len = 0;
-				} else {
-					len -= thislen;
-				}
-			}
-		} else {
-			for (i = 0; i < ap->num_pages; i++) {
-				thislen = ap->descs[i].length;
-				if (len < thislen) {
-					WARN_ON(ap->descs[i].offset);
-					page = ap->pages[i];
-					zero_user_segment(page, len, thislen);
-					len = 0;
-				} else {
-					len -= thislen;
-				}
+		for (i = 0; i < ap->num_folios; i++) {
+			thislen = ap->folio_descs[i].length;
+			if (len < thislen) {
+				WARN_ON(ap->folio_descs[i].offset);
+				folio = ap->folios[i];
+				folio_zero_segment(folio, len, thislen);
+				len = 0;
+			} else {
+				len -= thislen;
 			}
 		}
 	}
@@ -1287,22 +1272,16 @@ static void virtio_fs_send_interrupt(struct fuse_iqueue *fiq, struct fuse_req *r
 }
 
 /* Count number of scatter-gather elements required */
-static unsigned int sg_count_fuse_pages(struct fuse_args_pages *ap,
-					unsigned int total_len)
+static unsigned int sg_count_fuse_folios(struct fuse_folio_desc *folio_descs,
+					 unsigned int num_folios,
+					 unsigned int total_len)
 {
 	unsigned int i;
 	unsigned int this_len;
 
-	if (ap->uses_folios) {
-		for (i = 0; i < ap->num_folios && total_len; i++) {
-			this_len =  min(ap->folio_descs[i].length, total_len);
-			total_len -= this_len;
-		}
-	} else {
-		for (i = 0; i < ap->num_pages && total_len; i++) {
-			this_len =  min(ap->descs[i].length, total_len);
-			total_len -= this_len;
-		}
+	for (i = 0; i < num_folios && total_len; i++) {
+		this_len =  min(folio_descs[i].length, total_len);
+		total_len -= this_len;
 	}
 
 	return i;
@@ -1320,7 +1299,8 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
 
 	if (args->in_pages) {
 		size = args->in_args[args->in_numargs - 1].size;
-		total_sgs += sg_count_fuse_pages(ap, size);
+		total_sgs += sg_count_fuse_folios(ap->folio_descs, ap->num_folios,
+						  size);
 	}
 
 	if (!test_bit(FR_ISREPLY, &req->flags))
@@ -1333,35 +1313,29 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
 
 	if (args->out_pages) {
 		size = args->out_args[args->out_numargs - 1].size;
-		total_sgs += sg_count_fuse_pages(ap, size);
+		total_sgs += sg_count_fuse_folios(ap->folio_descs, ap->num_folios,
+						  size);
 	}
 
 	return total_sgs;
 }
 
-/* Add pages/folios to scatter-gather list and return number of elements used */
-static unsigned int sg_init_fuse_pages(struct scatterlist *sg,
-				       struct fuse_args_pages *ap,
-				       unsigned int total_len)
+/* Add folios to scatter-gather list and return number of elements used */
+static unsigned int sg_init_fuse_folios(struct scatterlist *sg,
+					struct folio **folios,
+					struct fuse_folio_desc *folio_descs,
+					unsigned int num_folios,
+				        unsigned int total_len)
 {
 	unsigned int i;
 	unsigned int this_len;
 
-	if (ap->uses_folios) {
-		for (i = 0; i < ap->num_folios && total_len; i++) {
-			sg_init_table(&sg[i], 1);
-			this_len =  min(ap->folio_descs[i].length, total_len);
-			sg_set_folio(&sg[i], ap->folios[i], this_len,
-				     ap->folio_descs[i].offset);
-			total_len -= this_len;
-		}
-	} else {
-		for (i = 0; i < ap->num_pages && total_len; i++) {
-			sg_init_table(&sg[i], 1);
-			this_len =  min(ap->descs[i].length, total_len);
-			sg_set_page(&sg[i], ap->pages[i], this_len, ap->descs[i].offset);
-			total_len -= this_len;
-		}
+	for (i = 0; i < num_folios && total_len; i++) {
+		sg_init_table(&sg[i], 1);
+		this_len =  min(folio_descs[i].length, total_len);
+		sg_set_folio(&sg[i], folios[i], this_len,
+			     folio_descs[i].offset);
+		total_len -= this_len;
 	}
 
 	return i;
@@ -1385,8 +1359,11 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg,
 		sg_init_one(&sg[total_sgs++], argbuf, len);
 
 	if (argpages)
-		total_sgs += sg_init_fuse_pages(&sg[total_sgs], ap,
-						args[numargs - 1].size);
+		total_sgs += sg_init_fuse_folios(&sg[total_sgs],
+						 ap->folios,
+						 ap->folio_descs,
+						 ap->num_folios,
+						 args[numargs - 1].size);
 
 	if (len_used)
 		*len_used = len;
-- 
2.43.5





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux