summaryrefslogtreecommitdiffstats
path: root/sys/fs/fdescfs/fdesc_vnops.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-03-14 08:42:40 +0000
committerkib <kib@FreeBSD.org>2015-03-14 08:42:40 +0000
commit7379a65eb4cbe935de371ffbb78a78ae03a29bcc (patch)
tree38633234fb5048ad12f5fa84684b1ce74f2f8fb8 /sys/fs/fdescfs/fdesc_vnops.c
parent78e2d91db987fb153c49b634b9037edc908c6018 (diff)
downloadFreeBSD-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/fs/fdescfs/fdesc_vnops.c')
-rw-r--r--sys/fs/fdescfs/fdesc_vnops.c42
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)
OpenPOWER on IntegriCloud