svn commit: r292624 - in head/sys: fs/devfs sys

Konstantin Belousov kib at FreeBSD.org
Tue Dec 22 20:37:35 UTC 2015


Author: kib
Date: Tue Dec 22 20:37:34 2015
New Revision: 292624
URL: https://svnweb.freebsd.org/changeset/base/292624

Log:
  Make it possible for the cdevsw d_close() driver method to detect last
  close and close due to revoke(2)-like operation.
  
  A new FLASTCLOSE flag indicates that this is last close.  FREVOKE is
  set for revokes, and FNONBLOCK is also set, same as is already done
  for VOP_CLOSE() call from vgonel().
  
  The flags reuse user open(2) flags which are never stored in f_flag,
  to not consume bit space in the ABI visible way.  Assert this with the
  static check.
  
  Requested and reviewed by:	bde
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/fs/devfs/devfs_vnops.c
  head/sys/sys/fcntl.h

Modified: head/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- head/sys/fs/devfs/devfs_vnops.c	Tue Dec 22 20:36:14 2015	(r292623)
+++ head/sys/fs/devfs/devfs_vnops.c	Tue Dec 22 20:37:34 2015	(r292624)
@@ -557,7 +557,9 @@ devfs_access(struct vop_access_args *ap)
 	return (error);
 }
 
-/* ARGSUSED */
+_Static_assert(((FMASK | FCNTLFLAGS) & (FLASTCLOSE | FREVOKE)) == 0,
+    "devfs-only flag reuse failed");
+
 static int
 devfs_close(struct vop_close_args *ap)
 {
@@ -566,7 +568,7 @@ devfs_close(struct vop_close_args *ap)
 	struct proc *p;
 	struct cdev *dev = vp->v_rdev;
 	struct cdevsw *dsw;
-	int vp_locked, error, ref;
+	int dflags, error, ref, vp_locked;
 
 	/*
 	 * XXX: Don't call d_close() if we were called because of
@@ -621,9 +623,11 @@ devfs_close(struct vop_close_args *ap)
 	dsw = dev_refthread(dev, &ref);
 	if (dsw == NULL)
 		return (ENXIO);
+	dflags = 0;
 	VI_LOCK(vp);
 	if (vp->v_iflag & VI_DOOMED) {
 		/* Forced close. */
+		dflags |= FREVOKE | FNONBLOCK;
 	} else if (dsw->d_flags & D_TRACKCLOSE) {
 		/* Keep device updated on status. */
 	} else if (count_dev(dev) > 1) {
@@ -631,13 +635,15 @@ devfs_close(struct vop_close_args *ap)
 		dev_relthread(dev, ref);
 		return (0);
 	}
+	if (count_dev(dev) == 1)
+		dflags |= FLASTCLOSE;
 	vholdl(vp);
 	VI_UNLOCK(vp);
 	vp_locked = VOP_ISLOCKED(vp);
 	VOP_UNLOCK(vp, 0);
 	KASSERT(dev->si_refcount > 0,
 	    ("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev)));
-	error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
+	error = dsw->d_close(dev, ap->a_fflag | dflags, S_IFCHR, td);
 	dev_relthread(dev, ref);
 	vn_lock(vp, vp_locked | LK_RETRY);
 	vdrop(vp);

Modified: head/sys/sys/fcntl.h
==============================================================================
--- head/sys/sys/fcntl.h	Tue Dec 22 20:36:14 2015	(r292623)
+++ head/sys/sys/fcntl.h	Tue Dec 22 20:37:34 2015	(r292624)
@@ -138,6 +138,11 @@ typedef	__pid_t		pid_t;
  */
 
 #ifdef _KERNEL
+
+/* Only for devfs d_close() flags. */
+#define	FLASTCLOSE	O_DIRECTORY
+#define	FREVOKE		O_VERIFY
+
 /* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */
 #define	FFLAGS(oflags)	((oflags) & O_EXEC ? (oflags) : (oflags) + 1)
 #define	OFLAGS(fflags)	((fflags) & O_EXEC ? (fflags) : (fflags) - 1)


More information about the svn-src-all mailing list