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:
parent
3808bf980c
commit
76abdf80ab
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user