Пример #1
0
/*
 * Close a mounted file descriptor.
 * Remove any locks and apply the VOP_CLOSE operation to the vnode for
 * the file descriptor.
 */
static int
nm_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *crp,
	caller_context_t *ct)
{
	struct namenode *nodep = VTONM(vp);
	int error = 0;

	(void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
	cleanshares(vp, ttoproc(curthread)->p_pid);
	error = VOP_CLOSE(nodep->nm_filevp, flag, count, offset, crp, ct);
	if (count == 1) {
		(void) VOP_FSYNC(nodep->nm_filevp, FSYNC, crp, ct);
		/*
		 * Before VN_RELE() we need to remove the vnode from
		 * the hash table.  We should only do so in the  NMNMNT case.
		 * In other cases, nodep->nm_filep keeps a reference
		 * to nm_filevp and the entry in the hash table doesn't
		 * hurt.
		 */
		if ((nodep->nm_flag & NMNMNT) != 0) {
			mutex_enter(&ntable_lock);
			nameremove(nodep);
			mutex_exit(&ntable_lock);
		}
		VN_RELE(nodep->nm_filevp);
	}
	return (error);
}
Пример #2
0
/*
 * Unmount a file descriptor from a node in the file system.
 * If the user is not the owner of the file and is not privileged,
 * the request is denied.
 * Otherwise, remove the namenode from the hash list.
 * If the mounted file descriptor was that of a stream and this
 * was the last mount of the stream, turn off the STRMOUNT flag.
 * If the rootvp is referenced other than through the mount,
 * nm_inactive will clean up.
 */
static int
nm_unmount(vfs_t *vfsp, int flag, cred_t *crp)
{
	struct namenode *nodep = (struct namenode *)vfsp->vfs_data;
	vnode_t *vp, *thisvp;
	struct file *fp = NULL;

	ASSERT((nodep->nm_flag & NMNMNT) == 0);

	/*
	 * forced unmount is not supported by this file system
	 * and thus, ENOTSUP, is being returned.
	 */
	if (flag & MS_FORCE) {
		return (ENOTSUP);
	}

	vp = nodep->nm_filevp;
	mutex_enter(&nodep->nm_lock);
	if (secpolicy_vnode_owner(crp, nodep->nm_vattr.va_uid) != 0) {
		mutex_exit(&nodep->nm_lock);
		return (EPERM);
	}

	mutex_exit(&nodep->nm_lock);

	mutex_enter(&ntable_lock);
	nameremove(nodep);
	thisvp = NMTOV(nodep);
	mutex_enter(&thisvp->v_lock);
	if (thisvp->v_count-- == 1) {
		fp = nodep->nm_filep;
		mutex_exit(&thisvp->v_lock);
		vn_invalid(thisvp);
		vn_free(thisvp);
		VFS_RELE(vfsp);
		namenodeno_free(nodep->nm_vattr.va_nodeid);
		kmem_free(nodep, sizeof (struct namenode));
	} else {
		thisvp->v_flag &= ~VROOT;
		mutex_exit(&thisvp->v_lock);
	}
	if (namefind(vp, NULLVP) == NULL && vp->v_stream) {
		struct stdata *stp = vp->v_stream;
		mutex_enter(&stp->sd_lock);
		stp->sd_flag &= ~STRMOUNT;
		mutex_exit(&stp->sd_lock);
	}
	mutex_exit(&ntable_lock);
	if (fp != NULL)
		(void) closef(fp);
	return (0);
}