+/*
+ * Delete a whiteout from the filesystem.
+ */
+struct unwhiteout_args {
+ char *path;
+};
+/* ARGSUSED */
+unwhiteout(p, uap, retval)
+ struct proc *p;
+ struct unwhiteout_args *uap;
+ int *retval;
+{
+ int error;
+ struct nameidata nd;
+
+ NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE, uap->path, p);
+ error = namei(&nd);
+ if (error)
+ return (error);
+
+ if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
+ VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+ if (nd.ni_dvp == nd.ni_vp)
+ vrele(nd.ni_dvp);
+ else
+ vput(nd.ni_dvp);
+ if (nd.ni_vp)
+ vrele(nd.ni_vp);
+ return (EEXIST);
+ }
+
+ VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
+ if (error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE))
+ VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+ vput(nd.ni_dvp);
+ return (error);
+}
+