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