Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2019 14:06:04 -0000
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r345766 - projects/fuse2/sys/fs/fuse
Message-ID:  <201904011423.x31ENhtx045849@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Mon Apr  1 14:23:43 2019
New Revision: 345766
URL: https://svnweb.freebsd.org/changeset/base/345766

Log:
  fusefs: replace obsolete array idioms
  
  r345742 replaced fusefs's fufh array with a fufh list.  But it left a few
  array idioms in place.  This commit replaces those idioms with more
  efficient list idioms.  One location is in fuse_filehandle_close, which now
  takes a pointer argument.  Three other locations are places that had to loop
  over all of a vnode's fuse filehandles.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_file.c
  projects/fuse2/sys/fs/fuse/fuse_file.h
  projects/fuse2/sys/fs/fuse/fuse_internal.c
  projects/fuse2/sys/fs/fuse/fuse_vnops.c

Modified: projects/fuse2/sys/fs/fuse/fuse_file.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_file.c	Mon Apr  1 14:21:32 2019	(r345765)
+++ projects/fuse2/sys/fs/fuse/fuse_file.c	Mon Apr  1 14:23:43 2019	(r345766)
@@ -154,21 +154,15 @@ out:
 }
 
 int
-fuse_filehandle_close(struct vnode *vp, fufh_type_t fufh_type,
+fuse_filehandle_close(struct vnode *vp, struct fuse_filehandle *fufh,
     struct thread *td, struct ucred *cred)
 {
 	struct fuse_dispatcher fdi;
 	struct fuse_release_in *fri;
-	struct fuse_filehandle *fufh = NULL;
 
 	int err = 0;
 	int op = FUSE_RELEASE;
 
-	if (fuse_filehandle_get(vp, fufh_type, &fufh)) {
-		panic("FUSE: fuse_filehandle_close called on invalid fufh "
-		    "(type=%d)", fufh_type);
-		/* NOTREACHED */
-	}
 	if (fuse_isdeadfs(vp)) {
 		goto out;
 	}
@@ -178,7 +172,7 @@ fuse_filehandle_close(struct vnode *vp, fufh_type_t fu
 	fdisp_make_vp(&fdi, op, vp, td, cred);
 	fri = fdi.indata;
 	fri->fh = fufh->fh_id;
-	fri->flags = fuse_filehandle_xlate_to_oflags(fufh_type);
+	fri->flags = fufh->flags;
 
 	err = fdisp_wait_answ(&fdi);
 	fdisp_destroy(&fdi);
@@ -221,10 +215,10 @@ fuse_filehandle_get(struct vnode *vp, fufh_type_t fufh
 	struct fuse_vnode_data *fvdat = VTOFUD(vp);
 	struct fuse_filehandle *fufh;
 
-	/* TODO: Find a list entry with the same mode, pid, gid, and uid */
-	/* Fallback: find a list entry with the right mode */
+	/* TODO: Find a list entry with the same flags, pid, gid, and uid */
+	/* Fallback: find a list entry with the right flags */
 	LIST_FOREACH(fufh, &fvdat->handles, next) {
-		if (fufh->mode == fufh_type)
+		if (fufh->flags == fufh_type)
 			break;
 	}
 
@@ -258,7 +252,7 @@ fuse_filehandle_init(struct vnode *vp, fufh_type_t fuf
 		M_WAITOK);
 	MPASS(fufh != NULL);
 	fufh->fh_id = fh_id;
-	fufh->mode = fufh_type;
+	fufh->flags = fufh_type;
 	/* TODO: initialize fufh credentials and open flags */
 	if (!FUFH_IS_VALID(fufh)) {
 		panic("FUSE: init: invalid filehandle id (type=%d)", fufh_type);

Modified: projects/fuse2/sys/fs/fuse/fuse_file.h
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_file.h	Mon Apr  1 14:21:32 2019	(r345765)
+++ projects/fuse2/sys/fs/fuse/fuse_file.h	Mon Apr  1 14:23:43 2019	(r345766)
@@ -66,12 +66,16 @@
 #include <sys/mman.h>
 #include <sys/vnode.h>
 
+/* 
+ * The fufh type is the access mode of the fuse file handle.  It's the portion
+ * of the open(2) flags related to permission.
+ */
 typedef enum fufh_type {
 	FUFH_INVALID = -1,
 	FUFH_RDONLY  = 0,
 	FUFH_WRONLY  = 1,
 	FUFH_RDWR    = 2,
-	FUFH_MAXTYPE = 3,
+	/* TODO: add FUFH_EXEC */
 } fufh_type_t;
 _Static_assert(FUFH_RDONLY == O_RDONLY, "RDONLY");
 _Static_assert(FUFH_WRONLY == O_WRONLY, "WRONLY");
@@ -86,8 +90,8 @@ struct fuse_filehandle {
 	/* flags returned by FUSE_OPEN */
 	uint32_t fuse_open_flags;
 
-	/* The mode used to open(2) the file (using O_RDONLY, not FREAD) */
-	uint32_t mode;
+	/* The flags used to open(2) the file (using O_RDONLY, not FREAD) */
+	uint32_t flags;
 
 	/* Credentials used to open the file */
 	gid_t gid;
@@ -95,7 +99,7 @@ struct fuse_filehandle {
 	uid_t uid;
 };
 
-#define FUFH_IS_VALID(f)  ((f)->mode != FUFH_INVALID)
+#define FUFH_IS_VALID(f)  ((f)->flags != FUFH_INVALID)
 
 static inline fufh_type_t
 fuse_filehandle_xlate_from_fflags(int fflags)
@@ -140,7 +144,7 @@ void fuse_filehandle_init(struct vnode *vp, fufh_type_
 int fuse_filehandle_open(struct vnode *vp, fufh_type_t fufh_type,
                          struct fuse_filehandle **fufhp, struct thread *td,
                          struct ucred *cred);
-int fuse_filehandle_close(struct vnode *vp, fufh_type_t fufh_type,
+int fuse_filehandle_close(struct vnode *vp, struct fuse_filehandle *fufh,
                           struct thread *td, struct ucred *cred);
 
 #endif /* _FUSE_FILE_H_ */

Modified: projects/fuse2/sys/fs/fuse/fuse_internal.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_internal.c	Mon Apr  1 14:21:32 2019	(r345765)
+++ projects/fuse2/sys/fs/fuse/fuse_internal.c	Mon Apr  1 14:23:43 2019	(r345766)
@@ -285,36 +285,37 @@ fuse_internal_fsync(struct vnode *vp,
 	struct fuse_fsync_in *ffsi;
 	struct fuse_dispatcher fdi;
 	struct fuse_filehandle *fufh;
+	struct fuse_vnode_data *fvdat = VTOFUD(vp);
 	int op = FUSE_FSYNC;
-	int type = 0;
 	int err = 0;
 
 	if (!fsess_isimpl(vnode_mount(vp),
 	    (vnode_vtype(vp) == VDIR ? FUSE_FSYNCDIR : FUSE_FSYNC))) {
 		return 0;
 	}
-	for (type = 0; type < FUFH_MAXTYPE; type++) {
-		if (fuse_filehandle_get(vp, type, &fufh) == 0) {
-			if (vnode_isdir(vp)) {
-				op = FUSE_FSYNCDIR;
-			}
-			fdisp_init(&fdi, sizeof(*ffsi));
-			fdisp_make_vp(&fdi, op, vp, td, NULL);
-			ffsi = fdi.indata;
-			ffsi->fh = fufh->fh_id;
+	if (vnode_isdir(vp))
+		op = FUSE_FSYNCDIR;
+	/*
+	 * fsync every open file handle for this file, because we can't be sure
+	 * which file handle the caller is really referring to.
+	 */
+	LIST_FOREACH(fufh, &fvdat->handles, next) {
+		fdisp_init(&fdi, sizeof(*ffsi));
+		fdisp_make_vp(&fdi, op, vp, td, NULL);
+		ffsi = fdi.indata;
+		ffsi->fh = fufh->fh_id;
 
-			if (datasync)
-				ffsi->fsync_flags = 1;
+		if (datasync)
+			ffsi->fsync_flags = 1;
 
-			if (waitfor == MNT_WAIT) {
-				err = fdisp_wait_answ(&fdi);
-			} else {
-				fuse_insert_callback(fdi.tick,
-					fuse_internal_fsync_callback);
-				fuse_insert_message(fdi.tick);
-			}
-			fdisp_destroy(&fdi);
+		if (waitfor == MNT_WAIT) {
+			err = fdisp_wait_answ(&fdi);
+		} else {
+			fuse_insert_callback(fdi.tick,
+				fuse_internal_fsync_callback);
+			fuse_insert_message(fdi.tick);
 		}
+		fdisp_destroy(&fdi);
 	}
 
 	return err;

Modified: projects/fuse2/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_vnops.c	Mon Apr  1 14:21:32 2019	(r345765)
+++ projects/fuse2/sys/fs/fuse/fuse_vnops.c	Mon Apr  1 14:23:43 2019	(r345766)
@@ -278,33 +278,22 @@ fuse_vnop_close(struct vop_close_args *ap)
 	struct vnode *vp = ap->a_vp;
 	struct ucred *cred = ap->a_cred;
 	int fflag = ap->a_fflag;
-	fufh_type_t fufh_type;
 
 	if (fuse_isdeadfs(vp)) {
 		return 0;
 	}
 	if (vnode_isdir(vp)) {
-		if (fuse_filehandle_valid(vp, FUFH_RDONLY)) {
-			fuse_filehandle_close(vp, FUFH_RDONLY, NULL, cred);
+		struct fuse_filehandle *fufh;
+
+		if (fuse_filehandle_get(vp, O_RDONLY, &fufh)) {
+			fuse_filehandle_close(vp, fufh, NULL, cred);
 		}
 		return 0;
 	}
 	if (fflag & IO_NDELAY) {
 		return 0;
 	}
-	fufh_type = fuse_filehandle_xlate_from_fflags(fflag);
-
-	if (!fuse_filehandle_valid(vp, fufh_type)) {
-		int i;
-
-		for (i = 0; i < FUFH_MAXTYPE; i++)
-			if (fuse_filehandle_valid(vp, i))
-				break;
-		if (i == FUFH_MAXTYPE)
-			panic("FUSE: fufh type %d found to be invalid in close"
-			      " (fflag=0x%x)\n",
-			      fufh_type, fflag);
-	}
+	/* TODO: close the file handle, if we're sure it's no longer used */
 	if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) {
 		fuse_vnode_savesize(vp, cred);
 	}
@@ -601,25 +590,23 @@ fuse_vnop_inactive(struct vop_inactive_args *ap)
 	struct thread *td = ap->a_td;
 
 	struct fuse_vnode_data *fvdat = VTOFUD(vp);
-	struct fuse_filehandle *fufh = NULL;
+	struct fuse_filehandle *fufh, *fufh_tmp;
 
-	int type, need_flush = 1;
+	int need_flush = 1;
 
-	for (type = 0; type < FUFH_MAXTYPE; type++) {
-		if (!fuse_filehandle_get(vp, type, &fufh)) {
-			if (need_flush && vp->v_type == VREG) {
-				if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) {
-					fuse_vnode_savesize(vp, NULL);
-				}
-				if (fuse_data_cache_invalidate ||
-				    (fvdat->flag & FN_REVOKED) != 0)
-					fuse_io_invalbuf(vp, td);
-				else
-					fuse_io_flushbuf(vp, MNT_WAIT, td);
-				need_flush = 0;
+	LIST_FOREACH_SAFE(fufh, &fvdat->handles, next, fufh_tmp) {
+		if (need_flush && vp->v_type == VREG) {
+			if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) {
+				fuse_vnode_savesize(vp, NULL);
 			}
-			fuse_filehandle_close(vp, type, td, NULL);
+			if (fuse_data_cache_invalidate ||
+			    (fvdat->flag & FN_REVOKED) != 0)
+				fuse_io_invalbuf(vp, td);
+			else
+				fuse_io_flushbuf(vp, MNT_WAIT, td);
+			need_flush = 0;
 		}
+		fuse_filehandle_close(vp, fufh, td, NULL);
 	}
 
 	if ((fvdat->flag & FN_REVOKED) != 0 && fuse_reclaim_revoked) {
@@ -1317,13 +1304,11 @@ fuse_vnop_readdir(struct vop_readdir_args *ap)
 		return EINVAL;
 	}
 
-	if (!fuse_filehandle_valid(vp, FUFH_RDONLY)) {
+	if ((err = fuse_filehandle_get(vp, O_RDONLY, &fufh)) != 0) {
 		SDT_PROBE2(fuse, , vnops, trace, 1,
 			"calling readdir() before open()");
-		err = fuse_filehandle_open(vp, FUFH_RDONLY, &fufh, NULL, cred);
+		err = fuse_filehandle_open(vp, O_RDONLY, &fufh, NULL, cred);
 		freefufh = 1;
-	} else {
-		err = fuse_filehandle_get(vp, FUFH_RDONLY, &fufh);
 	}
 	if (err) {
 		return (err);
@@ -1334,9 +1319,9 @@ fuse_vnop_readdir(struct vop_readdir_args *ap)
 	err = fuse_internal_readdir(vp, uio, fufh, &cookediov);
 
 	fiov_teardown(&cookediov);
-	if (freefufh) {
-		fuse_filehandle_close(vp, FUFH_RDONLY, NULL, cred);
-	}
+	if (freefufh)
+		fuse_filehandle_close(vp, fufh, NULL, cred);
+
 	return err;
 }
 
@@ -1393,20 +1378,16 @@ fuse_vnop_reclaim(struct vop_reclaim_args *ap)
 {
 	struct vnode *vp = ap->a_vp;
 	struct thread *td = ap->a_td;
-
 	struct fuse_vnode_data *fvdat = VTOFUD(vp);
+	struct fuse_filehandle *fufh, *fufh_tmp;
 
-	int type;
-
 	if (!fvdat) {
 		panic("FUSE: no vnode data during recycling");
 	}
-	for (type = 0; type < FUFH_MAXTYPE; type++) {
-		if (fuse_filehandle_get(vp, type, NULL) == 0) {
-			printf("FUSE: vnode being reclaimed but fufh (type=%d) is valid",
-			    type);
-			fuse_filehandle_close(vp, type, td, NULL);
-		}
+	LIST_FOREACH_SAFE(fufh, &fvdat->handles, next, fufh_tmp) {
+		printf("FUSE: vnode being reclaimed with open fufh "
+			"(flags=%#x)", fufh->flags);
+		fuse_filehandle_close(vp, fufh, td, NULL);
 	}
 
 	if ((!fuse_isdeadfs(vp)) && (fvdat->nlookup)) {





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904011423.x31ENhtx045849>