msdosfs deget(): add locking flags argument

LK_EXCLUSIVE must be passed always, some consumers need the ability to
specify LK_NOWAIT

Reviewed by:	mckusick
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31464
This commit is contained in:
Konstantin Belousov 2021-08-01 20:53:12 +03:00
parent 92d4e08827
commit ae7e8a02e6
7 changed files with 24 additions and 17 deletions

View File

@ -275,7 +275,7 @@ int msdosfs_lookup_ino(struct vnode *vdp, struct vnode **vpp,
* Internal service routine prototypes. * Internal service routine prototypes.
*/ */
struct componentname; struct componentname;
int deget(struct msdosfsmount *, u_long, u_long, struct denode **); int deget(struct msdosfsmount *, u_long, u_long, int, struct denode **);
int uniqdosname(struct denode *, struct componentname *, u_char *); int uniqdosname(struct denode *, struct componentname *, u_char *);
int readep(struct msdosfsmount *pmp, u_long dirclu, u_long dirofs, struct buf **bpp, struct direntry **epp); int readep(struct msdosfsmount *pmp, u_long dirclu, u_long dirofs, struct buf **bpp, struct direntry **epp);

View File

@ -92,11 +92,12 @@ de_vncmpf(struct vnode *vp, void *arg)
* diroffset is relative to the beginning of the root directory, * diroffset is relative to the beginning of the root directory,
* otherwise it is cluster relative. * otherwise it is cluster relative.
* diroffset - offset past begin of cluster of denode we want * diroffset - offset past begin of cluster of denode we want
* lkflags - locking flags (LK_NOWAIT)
* depp - returns the address of the gotten denode. * depp - returns the address of the gotten denode.
*/ */
int int
deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset, deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
struct denode **depp) int lkflags, struct denode **depp)
{ {
int error; int error;
uint64_t inode; uint64_t inode;
@ -107,9 +108,11 @@ deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
struct buf *bp; struct buf *bp;
#ifdef MSDOSFS_DEBUG #ifdef MSDOSFS_DEBUG
printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n", printf("deget(pmp %p, dirclust %lu, diroffset %lx, flags %#x, "
pmp, dirclust, diroffset, depp); "depp %p)\n",
pmp, dirclust, diroffset, flags, depp);
#endif #endif
MPASS((lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE);
/* /*
* On FAT32 filesystems, root is a (more or less) normal * On FAT32 filesystems, root is a (more or less) normal
@ -133,7 +136,7 @@ deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
*/ */
inode = (uint64_t)pmp->pm_bpcluster * dirclust + diroffset; inode = (uint64_t)pmp->pm_bpcluster * dirclust + diroffset;
error = vfs_hash_get(mntp, inode, LK_EXCLUSIVE, curthread, &nvp, error = vfs_hash_get(mntp, inode, lkflags, curthread, &nvp,
de_vncmpf, &inode); de_vncmpf, &inode);
if (error) if (error)
return (error); return (error);
@ -171,7 +174,7 @@ deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
*depp = NULL; *depp = NULL;
return (error); return (error);
} }
error = vfs_hash_insert(nvp, inode, LK_EXCLUSIVE, curthread, &xvp, error = vfs_hash_insert(nvp, inode, lkflags, curthread, &xvp,
de_vncmpf, &inode); de_vncmpf, &inode);
if (error) { if (error) {
*depp = NULL; *depp = NULL;

View File

@ -86,7 +86,8 @@ msdosfs_deget_dotdot(struct mount *mp, void *arg, int lkflags,
pmp = VFSTOMSDOSFS(mp); pmp = VFSTOMSDOSFS(mp);
dd_arg = arg; dd_arg = arg;
error = deget(pmp, dd_arg->cluster, dd_arg->blkoff, &rdp); error = deget(pmp, dd_arg->cluster, dd_arg->blkoff,
LK_EXCLUSIVE, &rdp);
if (error == 0) if (error == 0)
*rvp = DETOV(rdp); *rvp = DETOV(rdp);
return (error); return (error);
@ -495,7 +496,7 @@ foundroot:
*vpp = vdp; *vpp = vdp;
return (0); return (0);
} }
error = deget(pmp, cluster, blkoff, &tdp); error = deget(pmp, cluster, blkoff, LK_EXCLUSIVE, &tdp);
if (error) if (error)
return (error); return (error);
*vpp = DETOV(tdp); *vpp = DETOV(tdp);
@ -523,7 +524,8 @@ foundroot:
if (dp->de_StartCluster == scn && isadir) if (dp->de_StartCluster == scn && isadir)
return (EISDIR); return (EISDIR);
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) if ((error = deget(pmp, cluster, blkoff, LK_EXCLUSIVE,
&tdp)) != 0)
return (error); return (error);
*vpp = DETOV(tdp); *vpp = DETOV(tdp);
cnp->cn_flags |= SAVENAME; cnp->cn_flags |= SAVENAME;
@ -569,7 +571,8 @@ foundroot:
VREF(vdp); /* we want ourself, ie "." */ VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp; *vpp = vdp;
} else { } else {
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) if ((error = deget(pmp, cluster, blkoff, LK_EXCLUSIVE,
&tdp)) != 0)
return (error); return (error);
*vpp = DETOV(tdp); *vpp = DETOV(tdp);
} }
@ -708,7 +711,7 @@ createde(struct denode *dep, struct denode *ddep, struct denode **depp,
else else
diroffset = 0; diroffset = 0;
} }
return deget(pmp, dirclust, diroffset, depp); return (deget(pmp, dirclust, diroffset, LK_EXCLUSIVE, depp));
} }
return 0; return 0;
@ -862,7 +865,7 @@ doscheckpath(struct denode *source, struct denode *target)
brelse(bp); brelse(bp);
bp = NULL; bp = NULL;
/* NOTE: deget() clears dep on error */ /* NOTE: deget() clears dep on error */
if ((error = deget(pmp, scn, 0, &dep)) != 0) if ((error = deget(pmp, scn, 0, LK_EXCLUSIVE, &dep)) != 0)
break; break;
} }
out:; out:;

View File

@ -847,7 +847,7 @@ msdosfs_root(struct mount *mp, int flags, struct vnode **vpp)
#ifdef MSDOSFS_DEBUG #ifdef MSDOSFS_DEBUG
printf("msdosfs_root(); mp %p, pmp %p\n", mp, pmp); printf("msdosfs_root(); mp %p, pmp %p\n", mp, pmp);
#endif #endif
error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, &ndep); error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, LK_EXCLUSIVE, &ndep);
if (error) if (error)
return (error); return (error);
*vpp = DETOV(ndep); *vpp = DETOV(ndep);
@ -988,7 +988,8 @@ msdosfs_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp)
struct denode *dep; struct denode *dep;
int error; int error;
error = deget(pmp, defhp->defid_dirclust, defhp->defid_dirofs, &dep); error = deget(pmp, defhp->defid_dirclust, defhp->defid_dirofs,
LK_EXCLUSIVE, &dep);
if (error) { if (error) {
*vpp = NULLVP; *vpp = NULLVP;
return (error); return (error);

View File

@ -84,7 +84,7 @@ __FBSDID("$FreeBSD$");
*/ */
int int
deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset, deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
struct denode **depp) int lkflags __unused, struct denode **depp)
{ {
int error; int error;
uint64_t inode; uint64_t inode;

View File

@ -187,7 +187,7 @@ createde(struct denode *dep, struct denode *ddep, struct denode **depp,
else else
diroffset = 0; diroffset = 0;
} }
return deget(pmp, dirclust, diroffset, depp); return deget(pmp, dirclust, diroffset, 0, depp);
} }
return 0; return 0;

View File

@ -349,7 +349,7 @@ msdosfs_root(struct msdosfsmount *pmp, struct m_vnode *vp) {
int error; int error;
*vp = *(struct m_vnode *)pmp->pm_devvp; *vp = *(struct m_vnode *)pmp->pm_devvp;
if ((error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, &ndep)) != 0) { if ((error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, 0, &ndep)) != 0) {
errno = error; errno = error;
return -1; return -1;
} }