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
This commit is contained in:
kib 2015-12-22 20:37:34 +00:00
parent 3808bf980c
commit 76abdf80ab
2 changed files with 14 additions and 3 deletions

View File

@ -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);

View File

@ -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)