Blob Blame History Raw
From: Miklos Szeredi <mszeredi@redhat.com>
Date: Tue, 10 Sep 2019 15:04:09 +0200
Subject: fuse: convert readlink to simple api
Git-commit: 4c29afece8729c6f6c1dd4865b6b7c972b7b3bbd
Patch-mainline: v5.4-rc1
References: jsc#SLE-13782

Also turn BUG_ON into gracefully recovered WARN_ON.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Acked-by: Luis Henriques <lhenriques@suse.com>
---
 fs/fuse/dir.c | 52 +++++++++++++++++++++++++---------------------------
 1 file changed, 25 insertions(+), 27 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 30a96098e64a..11334ee01dc9 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1152,38 +1152,36 @@ static int fuse_permission(struct inode *inode, int mask)
 static int fuse_readlink_page(struct inode *inode, struct page *page)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	struct fuse_req *req;
-	int err;
+	struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 };
+	struct fuse_args_pages ap = {
+		.num_pages = 1,
+		.pages = &page,
+		.descs = &desc,
+	};
+	char *link;
+	ssize_t res;
+
+	ap.args.opcode = FUSE_READLINK;
+	ap.args.nodeid = get_node_id(inode);
+	ap.args.out_pages = true;
+	ap.args.out_argvar = true;
+	ap.args.page_zeroing = true;
+	ap.args.out_numargs = 1;
+	ap.args.out_args[0].size = desc.length;
+	res = fuse_simple_request(fc, &ap.args);
 
-	req = fuse_get_req(fc, 1);
-	if (IS_ERR(req))
-		return PTR_ERR(req);
-
-	req->out.page_zeroing = 1;
-	req->out.argpages = 1;
-	req->num_pages = 1;
-	req->pages[0] = page;
-	req->page_descs[0].length = PAGE_SIZE - 1;
-	req->in.h.opcode = FUSE_READLINK;
-	req->in.h.nodeid = get_node_id(inode);
-	req->out.argvar = 1;
-	req->out.numargs = 1;
-	req->out.args[0].size = PAGE_SIZE - 1;
-	fuse_request_send(fc, req);
-	err = req->out.h.error;
+	fuse_invalidate_atime(inode);
 
-	if (!err) {
-		char *link = page_address(page);
-		size_t len = req->out.args[0].size;
+	if (res < 0)
+		return res;
 
-		BUG_ON(len >= PAGE_SIZE);
-		link[len] = '\0';
-	}
+	if (WARN_ON(res >= PAGE_SIZE))
+		return -EIO;
 
-	fuse_put_request(fc, req);
-	fuse_invalidate_atime(inode);
+	link = page_address(page);
+	link[res] = '\0';
 
-	return err;
+	return 0;
 }
 
 static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,