mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-13 10:02:38 +00:00
Do refcounting of open devices (more) correctly.
count_dev funtion by phk.
This commit is contained in:
parent
a9ec39136b
commit
e8359a57de
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=57025
@ -451,13 +451,13 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
return EBUSY;
|
||||
|
||||
if (flags & FWRITE) {
|
||||
if (cdp->refcnt)
|
||||
if (count_dev(dev) > 1)
|
||||
return EBUSY;
|
||||
else
|
||||
cdp->flags |= F_WRITING;
|
||||
}
|
||||
|
||||
if (!cdp->refcnt++) {
|
||||
if (count_dev(dev) == 1) {
|
||||
acd_prevent_allow(cdp, 1);
|
||||
cdp->flags |= F_LOCKED;
|
||||
if (!(flags & O_NONBLOCK) && !(flags & FWRITE))
|
||||
@ -473,7 +473,7 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
{
|
||||
struct acd_softc *cdp = dev->si_drv1;
|
||||
|
||||
if (!--cdp->refcnt)
|
||||
if (count_dev(dev) == 1)
|
||||
acd_prevent_allow(cdp, 0);
|
||||
|
||||
cdp->flags &= ~(F_LOCKED | F_WRITING);
|
||||
@ -536,7 +536,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
|
||||
break;
|
||||
|
||||
case CDIOCEJECT:
|
||||
if (cdp->refcnt > 1) {
|
||||
if (count_dev(dev) > 1) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
@ -544,7 +544,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
|
||||
break;
|
||||
|
||||
case CDIOCCLOSE:
|
||||
if (cdp->refcnt > 1)
|
||||
if (count_dev(dev) > 1)
|
||||
break;
|
||||
error = acd_eject(cdp, 1);
|
||||
break;
|
||||
|
@ -317,7 +317,6 @@ struct acd_softc {
|
||||
#define F_DISK_OPEN 0x0008 /* disk open for writing */
|
||||
#define F_TRACK_OPEN 0x0010 /* track open for writing */
|
||||
|
||||
int32_t refcnt; /* the number of raw opens */
|
||||
struct buf_queue_head buf_queue; /* Queue of i/o requests */
|
||||
struct toc toc; /* table of disc contents */
|
||||
struct {
|
||||
|
@ -215,7 +215,7 @@ afdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
|
||||
atapi_test_ready(fdp->atp);
|
||||
|
||||
if (!fdp->refcnt++)
|
||||
if (count_dev(dev) == 1)
|
||||
afd_prevent_allow(fdp, 1);
|
||||
|
||||
if (afd_sense(fdp))
|
||||
@ -238,7 +238,7 @@ afdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
{
|
||||
struct afd_softc *fdp = dev->si_drv1;
|
||||
|
||||
if (!--fdp->refcnt)
|
||||
if (count_dev(dev) == 1)
|
||||
afd_prevent_allow(fdp, 0);
|
||||
return 0;
|
||||
}
|
||||
@ -250,12 +250,12 @@ afdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
|
||||
|
||||
switch (cmd) {
|
||||
case CDIOCEJECT:
|
||||
if (fdp->refcnt > 1)
|
||||
if (count_dev(dev) > 1)
|
||||
return EBUSY;
|
||||
return afd_eject(fdp, 0);
|
||||
|
||||
case CDIOCCLOSE:
|
||||
if (fdp->refcnt > 1)
|
||||
if (count_dev(dev) > 1)
|
||||
return 0;
|
||||
return afd_eject(fdp, 1);
|
||||
|
||||
@ -305,7 +305,7 @@ afd_start(struct afd_softc *fdp)
|
||||
}
|
||||
|
||||
lba = bp->b_pblkno / (fdp->cap.sector_size / DEV_BSIZE);
|
||||
count = (bp->b_bcount + (fdp->cap.sector_size - 1)) / fdp->cap.sector_size;
|
||||
count = bp->b_bcount;
|
||||
data_ptr = bp->b_data;
|
||||
bp->b_resid = 0;
|
||||
|
||||
|
@ -73,7 +73,6 @@ struct afd_cappage {
|
||||
struct afd_softc {
|
||||
struct atapi_softc *atp; /* controller structure */
|
||||
int32_t lun; /* logical device unit */
|
||||
int32_t refcnt; /* the number of raw opens */
|
||||
int32_t transfersize; /* max size of each transfer */
|
||||
struct buf_queue_head buf_queue; /* queue of i/o requests */
|
||||
struct afd_header header; /* capabilities page info */
|
||||
|
@ -240,7 +240,7 @@ astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
if (!stp)
|
||||
return ENXIO;
|
||||
|
||||
if (stp->flags == F_OPEN)
|
||||
if (count_dev(dev) > 1)
|
||||
return EBUSY;
|
||||
|
||||
atapi_test_ready(stp->atp);
|
||||
@ -253,7 +253,6 @@ astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
|
||||
stp->atp->flags &= ~ATAPI_F_MEDIA_CHANGED;
|
||||
stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN);
|
||||
stp->flags |= F_OPEN;
|
||||
ast_total = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -276,10 +275,10 @@ astclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
if (!(minor(dev) & 0x01))
|
||||
ast_rewind(stp);
|
||||
|
||||
if (stp->cap.lock)
|
||||
if (stp->cap.lock && count_dev(dev) == 1)
|
||||
ast_prevent_allow(stp, 0);
|
||||
|
||||
stp->flags &= ~(F_OPEN | F_CTL_WARN);
|
||||
stp->flags &= F_CTL_WARN;
|
||||
#ifdef AST_DEBUG
|
||||
printf("ast%d: %llu total bytes transferred\n", stp->lun, ast_total);
|
||||
#endif
|
||||
|
@ -147,11 +147,10 @@ struct ast_softc {
|
||||
struct atapi_softc *atp; /* controller structure */
|
||||
int32_t lun; /* logical device unit */
|
||||
int32_t flags; /* device state flags */
|
||||
#define F_OPEN 0x0001 /* the device is opened */
|
||||
#define F_CTL_WARN 0x0002 /* warned about CTL wrong? */
|
||||
#define F_WRITEPROTECT 0x0004 /* media is writeprotected */
|
||||
#define F_DATA_WRITTEN 0x0010 /* data has been written */
|
||||
#define F_FM_WRITTEN 0x0020 /* filemark has been written */
|
||||
#define F_CTL_WARN 0x0001 /* warned about CTL wrong? */
|
||||
#define F_WRITEPROTECT 0x0002 /* media is writeprotected */
|
||||
#define F_DATA_WRITTEN 0x0004 /* data has been written */
|
||||
#define F_FM_WRITTEN 0x0008 /* filemark has been written */
|
||||
#define F_ONSTREAM 0x0100 /* OnStream ADR device */
|
||||
|
||||
int32_t blksize; /* block size (512 | 1024) */
|
||||
|
@ -1932,6 +1932,22 @@ vcount(vp)
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as above, but using the dev_t as argument
|
||||
*/
|
||||
|
||||
int
|
||||
count_dev(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
struct vnode *vp;
|
||||
|
||||
vp = SLIST_FIRST(&dev->si_hlist);
|
||||
if (vp == NULL)
|
||||
return (0);
|
||||
return(vcount(vp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out a description of a vnode.
|
||||
*/
|
||||
|
@ -1932,6 +1932,22 @@ vcount(vp)
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as above, but using the dev_t as argument
|
||||
*/
|
||||
|
||||
int
|
||||
count_dev(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
struct vnode *vp;
|
||||
|
||||
vp = SLIST_FIRST(&dev->si_hlist);
|
||||
if (vp == NULL)
|
||||
return (0);
|
||||
return(vcount(vp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out a description of a vnode.
|
||||
*/
|
||||
|
@ -258,6 +258,7 @@ DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
|
||||
|
||||
int cdevsw_add __P((struct cdevsw *new));
|
||||
int cdevsw_remove __P((struct cdevsw *old));
|
||||
int count_dev __P((dev_t dev));
|
||||
void destroy_dev __P((dev_t dev));
|
||||
struct cdevsw *devsw __P((dev_t dev));
|
||||
const char *devtoname __P((dev_t dev));
|
||||
|
@ -258,6 +258,7 @@ DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
|
||||
|
||||
int cdevsw_add __P((struct cdevsw *new));
|
||||
int cdevsw_remove __P((struct cdevsw *old));
|
||||
int count_dev __P((dev_t dev));
|
||||
void destroy_dev __P((dev_t dev));
|
||||
struct cdevsw *devsw __P((dev_t dev));
|
||||
const char *devtoname __P((dev_t dev));
|
||||
|
Loading…
Reference in New Issue
Block a user