diff options
author | kib <kib@FreeBSD.org> | 2015-03-14 08:42:40 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-03-14 08:42:40 +0000 |
commit | 7379a65eb4cbe935de371ffbb78a78ae03a29bcc (patch) | |
tree | 38633234fb5048ad12f5fa84684b1ce74f2f8fb8 /sys | |
parent | 78e2d91db987fb153c49b634b9037edc908c6018 (diff) | |
download | FreeBSD-src-7379a65eb4cbe935de371ffbb78a78ae03a29bcc.zip FreeBSD-src-7379a65eb4cbe935de371ffbb78a78ae03a29bcc.tar.gz |
MFC r279401:
Some fixes for fdescfs lookup code Do not ever return doomed vnode from.
lookup. Reuse the vn_vget_ino_gen() helper to handle parallel unmounts .
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/fdescfs/fdesc_vnops.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index b976504..1ed531b 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -247,6 +247,28 @@ loop: return (0); } +struct fdesc_get_ino_args { + fdntype ftype; + unsigned fd_fd; + int ix; + struct file *fp; + struct thread *td; +}; + +static int +fdesc_get_ino_alloc(struct mount *mp, void *arg, int lkflags, + struct vnode **rvp) +{ + struct fdesc_get_ino_args *a; + int error; + + a = arg; + error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp); + fdrop(a->fp, a->td); + return (error); +} + + /* * vp is the current namei directory * ndp is the name to locate in that directory... @@ -265,6 +287,7 @@ fdesc_lookup(ap) char *pname = cnp->cn_nameptr; struct thread *td = cnp->cn_thread; struct file *fp; + struct fdesc_get_ino_args arg; int nlen = cnp->cn_namelen; u_int fd, fd1; int error; @@ -326,6 +349,8 @@ fdesc_lookup(ap) vn_lock(dvp, LK_RETRY | LK_EXCLUSIVE); vdrop(dvp); fvp = dvp; + if ((dvp->v_iflag & VI_DOOMED) != 0) + error = ENOENT; } else { /* * Unlock our root node (dvp) when doing this, since we might @@ -335,16 +360,13 @@ fdesc_lookup(ap) * opposite lock order. Vhold the root vnode first so we don't * lose it. */ - vhold(dvp); - VOP_UNLOCK(dvp, 0); - error = fdesc_allocvp(Fdesc, fd, FD_DESC + fd, dvp->v_mount, - &fvp); - fdrop(fp, td); - /* - * The root vnode must be locked last to prevent deadlock condition. - */ - vn_lock(dvp, LK_RETRY | LK_EXCLUSIVE); - vdrop(dvp); + arg.ftype = Fdesc; + arg.fd_fd = fd; + arg.ix = FD_DESC + fd; + arg.fp = fp; + arg.td = td; + error = vn_vget_ino_gen(dvp, fdesc_get_ino_alloc, &arg, + LK_EXCLUSIVE, &fvp); } if (error) |