usr/src/uts/common/fs/cachefs/cachefs_vnops.c
changeset 6264 1f18b17afbef
parent 6036 c98c367c32cb
child 7240 c4957ab6a78e
equal deleted inserted replaced
6263:60af2e048340 6264:1f18b17afbef
   227 static int cachefs_getsecattr_connected(vnode_t *vp, vsecattr_t *vsec, int flag,
   227 static int cachefs_getsecattr_connected(vnode_t *vp, vsecattr_t *vsec, int flag,
   228     cred_t *cr);
   228     cred_t *cr);
   229 static int cachefs_getsecattr_disconnected(vnode_t *vp, vsecattr_t *vsec,
   229 static int cachefs_getsecattr_disconnected(vnode_t *vp, vsecattr_t *vsec,
   230     int flag, cred_t *cr);
   230     int flag, cred_t *cr);
   231 
   231 
   232 static int	cachefs_dump(struct vnode *, caddr_t, int, int,
   232 static int	cachefs_dump(struct vnode *, caddr_t, offset_t, offset_t,
   233 			caller_context_t *);
   233 			caller_context_t *);
   234 static int	cachefs_pageio(struct vnode *, page_t *,
   234 static int	cachefs_pageio(struct vnode *, page_t *,
   235 		    u_offset_t, size_t, int, cred_t *, caller_context_t *);
   235 		    u_offset_t, size_t, int, cred_t *, caller_context_t *);
   236 static int	cachefs_writepage(struct vnode *vp, caddr_t base,
   236 static int	cachefs_writepage(struct vnode *vp, caddr_t base,
   237 		    int tcount, struct uio *uiop);
   237 		    int tcount, struct uio *uiop);
   309 
   309 
   310 int
   310 int
   311 cachefs_init_vnops(char *name)
   311 cachefs_init_vnops(char *name)
   312 {
   312 {
   313 	return (vn_make_ops(name,
   313 	return (vn_make_ops(name,
   314 		    cachefs_vnodeops_template, &cachefs_vnodeops));
   314 	    cachefs_vnodeops_template, &cachefs_vnodeops));
   315 }
   315 }
   316 
   316 
   317 struct vnodeops *
   317 struct vnodeops *
   318 cachefs_getvnodeops(void)
   318 cachefs_getvnodeops(void)
   319 {
   319 {
   403 			 * credentials don't match the creds in the
   403 			 * credentials don't match the creds in the
   404 			 * cnode disallow writing while disconnected.
   404 			 * cnode disallow writing while disconnected.
   405 			 */
   405 			 */
   406 			if (crcmp(cp->c_cred, CRED()) != 0 &&
   406 			if (crcmp(cp->c_cred, CRED()) != 0 &&
   407 			    secpolicy_vnode_access(CRED(), *vpp,
   407 			    secpolicy_vnode_access(CRED(), *vpp,
   408 					    cp->c_attr.va_uid, VWRITE) != 0) {
   408 			    cp->c_attr.va_uid, VWRITE) != 0) {
   409 				mutex_exit(&cp->c_statelock);
   409 				mutex_exit(&cp->c_statelock);
   410 				connected = 1;
   410 				connected = 1;
   411 				continue;
   411 				continue;
   412 			}
   412 			}
   413 			/* to get here, we know that the WRITE flag is on */
   413 			/* to get here, we know that the WRITE flag is on */
   425 
   425 
   426 			/* pass open to the back file */
   426 			/* pass open to the back file */
   427 			if (cp->c_backvp) {
   427 			if (cp->c_backvp) {
   428 				cp->c_flags &= ~CN_NEEDOPEN;
   428 				cp->c_flags &= ~CN_NEEDOPEN;
   429 				CFS_DPRINT_BACKFS_NFSV4(fscp,
   429 				CFS_DPRINT_BACKFS_NFSV4(fscp,
   430 					("cachefs_open (nfsv4): cnode %p, "
   430 				    ("cachefs_open (nfsv4): cnode %p, "
   431 					"backvp %p\n", cp, cp->c_backvp));
   431 				    "backvp %p\n", cp, cp->c_backvp));
   432 				error = VOP_OPEN(&cp->c_backvp, flag, cr, ct);
   432 				error = VOP_OPEN(&cp->c_backvp, flag, cr, ct);
   433 				if (CFS_TIMEOUT(fscp, error)) {
   433 				if (CFS_TIMEOUT(fscp, error)) {
   434 					mutex_exit(&cp->c_statelock);
   434 					mutex_exit(&cp->c_statelock);
   435 					cachefs_cd_release(fscp);
   435 					cachefs_cd_release(fscp);
   436 					held = 0;
   436 					held = 0;
   564 			if (fscp->fs_cdconnected != CFS_CD_CONNECTED)
   564 			if (fscp->fs_cdconnected != CFS_CD_CONNECTED)
   565 				goto out;
   565 				goto out;
   566 			mutex_enter(&cp->c_statelock);
   566 			mutex_enter(&cp->c_statelock);
   567 			if (cp->c_backvp) {
   567 			if (cp->c_backvp) {
   568 				CFS_DPRINT_BACKFS_NFSV4(fscp,
   568 				CFS_DPRINT_BACKFS_NFSV4(fscp,
   569 					("cachefs_close (nfsv4): cnode %p, "
   569 				    ("cachefs_close (nfsv4): cnode %p, "
   570 					"backvp %p\n", cp, cp->c_backvp));
   570 				    "backvp %p\n", cp, cp->c_backvp));
   571 				error = VOP_CLOSE(cp->c_backvp, flag, count,
   571 				error = VOP_CLOSE(cp->c_backvp, flag, count,
   572 				    offset, cr, ct);
   572 				    offset, cr, ct);
   573 				if (CFS_TIMEOUT(fscp, error)) {
   573 				if (CFS_TIMEOUT(fscp, error)) {
   574 					mutex_exit(&cp->c_statelock);
   574 					mutex_exit(&cp->c_statelock);
   575 					cachefs_cd_release(fscp);
   575 					cachefs_cd_release(fscp);
   599 			/* always call VOP_CLOSE() for back fs vnode */
   599 			/* always call VOP_CLOSE() for back fs vnode */
   600 		}
   600 		}
   601 
   601 
   602 		/* force dirty data to stable storage */
   602 		/* force dirty data to stable storage */
   603 		else if ((vp->v_type == VREG) && (flag & FWRITE) &&
   603 		else if ((vp->v_type == VREG) && (flag & FWRITE) &&
   604 				!CFS_ISFS_BACKFS_NFSV4(fscp)) {
   604 		    !CFS_ISFS_BACKFS_NFSV4(fscp)) {
   605 			/* clean the cachefs pages synchronously */
   605 			/* clean the cachefs pages synchronously */
   606 			error = cachefs_putpage_common(vp, (offset_t)0,
   606 			error = cachefs_putpage_common(vp, (offset_t)0,
   607 			    0, 0, cr);
   607 			    0, 0, cr);
   608 			if (CFS_TIMEOUT(fscp, error)) {
   608 			if (CFS_TIMEOUT(fscp, error)) {
   609 				if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
   609 				if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
   722 		goto out;
   722 		goto out;
   723 	}
   723 	}
   724 
   724 
   725 	if (MANDLOCK(vp, cp->c_attr.va_mode)) {
   725 	if (MANDLOCK(vp, cp->c_attr.va_mode)) {
   726 		error = chklock(vp, FREAD, (offset_t)uiop->uio_loffset,
   726 		error = chklock(vp, FREAD, (offset_t)uiop->uio_loffset,
   727 			    uiop->uio_resid, uiop->uio_fmode, ct);
   727 		    uiop->uio_resid, uiop->uio_fmode, ct);
   728 		if (error)
   728 		if (error)
   729 			return (error);
   729 			return (error);
   730 	}
   730 	}
   731 
   731 
   732 	/*
   732 	/*
   772 			n = diff;
   772 			n = diff;
   773 
   773 
   774 		base = segmap_getmapflt(segkmap, vp, off, (uint_t)n, 1, S_READ);
   774 		base = segmap_getmapflt(segkmap, vp, off, (uint_t)n, 1, S_READ);
   775 
   775 
   776 		error = segmap_fault(kas.a_hat, segkmap, base, n,
   776 		error = segmap_fault(kas.a_hat, segkmap, base, n,
   777 			F_SOFTLOCK, S_READ);
   777 		    F_SOFTLOCK, S_READ);
   778 		if (error) {
   778 		if (error) {
   779 			(void) segmap_release(segkmap, base, 0);
   779 			(void) segmap_release(segkmap, base, 0);
   780 			if (FC_CODE(error) == FC_OBJERR)
   780 			if (FC_CODE(error) == FC_OBJERR)
   781 				error =  FC_ERRNO(error);
   781 				error =  FC_ERRNO(error);
   782 			else
   782 			else
   783 				error = EIO;
   783 				error = EIO;
   784 			break;
   784 			break;
   785 		}
   785 		}
   786 		error = uiomove(base+mapoff, n, UIO_READ, uiop);
   786 		error = uiomove(base+mapoff, n, UIO_READ, uiop);
   787 		(void) segmap_fault(kas.a_hat, segkmap, base, n,
   787 		(void) segmap_fault(kas.a_hat, segkmap, base, n,
   788 				F_SOFTUNLOCK, S_READ);
   788 		    F_SOFTUNLOCK, S_READ);
   789 		if (error == 0) {
   789 		if (error == 0) {
   790 			/*
   790 			/*
   791 			 * if we read a whole page(s), or to eof,
   791 			 * if we read a whole page(s), or to eof,
   792 			 *  we won't need this page(s) again soon.
   792 			 *  we won't need this page(s) again soon.
   793 			 */
   793 			 */
   794 			if (n + mapoff == MAXBSIZE ||
   794 			if (n + mapoff == MAXBSIZE ||
   795 				uiop->uio_loffset == cp->c_size)
   795 			    uiop->uio_loffset == cp->c_size)
   796 				flags |= SM_DONTNEED;
   796 				flags |= SM_DONTNEED;
   797 		}
   797 		}
   798 		(void) segmap_release(segkmap, base, flags);
   798 		(void) segmap_release(segkmap, base, flags);
   799 	} while (error == 0 && uiop->uio_resid > 0);
   799 	} while (error == 0 && uiop->uio_resid > 0);
   800 
   800 
   801 out:
   801 out:
   802 #ifdef CFSDEBUG
   802 #ifdef CFSDEBUG
   803 	CFS_DEBUG(CFSDEBUG_VOPS)
   803 	CFS_DEBUG(CFSDEBUG_VOPS)
   804 		printf("cachefs_read: EXIT error %d resid %ld\n", error,
   804 		printf("cachefs_read: EXIT error %d resid %ld\n", error,
   805 			uiop->uio_resid);
   805 		    uiop->uio_resid);
   806 #endif
   806 #endif
   807 	return (error);
   807 	return (error);
   808 }
   808 }
   809 
   809 
   810 /*
   810 /*
   835 	mutex_enter(&cp->c_statelock);
   835 	mutex_enter(&cp->c_statelock);
   836 	backvp = cp->c_backvp;
   836 	backvp = cp->c_backvp;
   837 	mutex_exit(&cp->c_statelock);
   837 	mutex_exit(&cp->c_statelock);
   838 
   838 
   839 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_read_backfs_nfsv4: cnode %p, "
   839 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_read_backfs_nfsv4: cnode %p, "
   840 					"backvp %p\n", cp, backvp));
   840 	    "backvp %p\n", cp, backvp));
   841 
   841 
   842 	(void) VOP_RWLOCK(backvp, V_WRITELOCK_FALSE, ct);
   842 	(void) VOP_RWLOCK(backvp, V_WRITELOCK_FALSE, ct);
   843 	error = VOP_READ(backvp, uiop, ioflag, cr, ct);
   843 	error = VOP_READ(backvp, uiop, ioflag, cr, ct);
   844 	VOP_RWUNLOCK(backvp, V_WRITELOCK_FALSE, ct);
   844 	VOP_RWUNLOCK(backvp, V_WRITELOCK_FALSE, ct);
   845 
   845 
   869 
   869 
   870 #ifdef CFSDEBUG
   870 #ifdef CFSDEBUG
   871 	CFS_DEBUG(CFSDEBUG_VOPS)
   871 	CFS_DEBUG(CFSDEBUG_VOPS)
   872 		printf(
   872 		printf(
   873 		"cachefs_write: ENTER vp %p offset %llu count %ld cflags %x\n",
   873 		"cachefs_write: ENTER vp %p offset %llu count %ld cflags %x\n",
   874 			(void *)vp, uiop->uio_loffset, uiop->uio_resid,
   874 		    (void *)vp, uiop->uio_loffset, uiop->uio_resid,
   875 			cp->c_flags);
   875 		    cp->c_flags);
   876 #endif
   876 #endif
   877 	if (getzoneid() != GLOBAL_ZONEID) {
   877 	if (getzoneid() != GLOBAL_ZONEID) {
   878 		error = EPERM;
   878 		error = EPERM;
   879 		goto out;
   879 		goto out;
   880 	}
   880 	}
   895 		goto out2;
   895 		goto out2;
   896 	}
   896 	}
   897 
   897 
   898 	if (MANDLOCK(vp, cp->c_attr.va_mode)) {
   898 	if (MANDLOCK(vp, cp->c_attr.va_mode)) {
   899 		error = chklock(vp, FWRITE, (offset_t)uiop->uio_loffset,
   899 		error = chklock(vp, FWRITE, (offset_t)uiop->uio_loffset,
   900 			    uiop->uio_resid, uiop->uio_fmode, ct);
   900 		    uiop->uio_resid, uiop->uio_fmode, ct);
   901 		if (error)
   901 		if (error)
   902 			goto out;
   902 			goto out;
   903 	}
   903 	}
   904 
   904 
   905 	if (ioflag & FAPPEND) {
   905 	if (ioflag & FAPPEND) {
  1062 	mutex_enter(&cp->c_statelock);
  1062 	mutex_enter(&cp->c_statelock);
  1063 	backvp = cp->c_backvp;
  1063 	backvp = cp->c_backvp;
  1064 	mutex_exit(&cp->c_statelock);
  1064 	mutex_exit(&cp->c_statelock);
  1065 
  1065 
  1066 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_write_backfs_nfsv4: cnode %p, "
  1066 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_write_backfs_nfsv4: cnode %p, "
  1067 					"backvp %p\n", cp, backvp));
  1067 	    "backvp %p\n", cp, backvp));
  1068 	(void) VOP_RWLOCK(backvp, V_WRITELOCK_TRUE, ct);
  1068 	(void) VOP_RWLOCK(backvp, V_WRITELOCK_TRUE, ct);
  1069 	error = VOP_WRITE(backvp, uiop, ioflag, cr, ct);
  1069 	error = VOP_WRITE(backvp, uiop, ioflag, cr, ct);
  1070 	VOP_RWUNLOCK(backvp, V_WRITELOCK_TRUE, ct);
  1070 	VOP_RWUNLOCK(backvp, V_WRITELOCK_TRUE, ct);
  1071 
  1071 
  1072 	return (error);
  1072 	return (error);
  1195 		 * if we are going to rewrite the entire mapping
  1195 		 * if we are going to rewrite the entire mapping
  1196 		 * or if we are going to write to or beyond the current
  1196 		 * or if we are going to write to or beyond the current
  1197 		 * end of file from the beginning of the mapping.
  1197 		 * end of file from the beginning of the mapping.
  1198 		 */
  1198 		 */
  1199 		if ((offset > (lastpage_off + PAGEOFFSET)) ||
  1199 		if ((offset > (lastpage_off + PAGEOFFSET)) ||
  1200 			((cp->c_size == 0) && (offset < PAGESIZE)) ||
  1200 		    ((cp->c_size == 0) && (offset < PAGESIZE)) ||
  1201 			((uintptr_t)base & PAGEOFFSET) == 0 && (n == PAGESIZE ||
  1201 		    ((uintptr_t)base & PAGEOFFSET) == 0 && (n == PAGESIZE ||
  1202 			((offset + n) >= cp->c_size))) {
  1202 		    ((offset + n) >= cp->c_size))) {
  1203 			pagecreate = 1;
  1203 			pagecreate = 1;
  1204 
  1204 
  1205 			/*
  1205 			/*
  1206 			 * segmap_pagecreate() returns 1 if it calls
  1206 			 * segmap_pagecreate() returns 1 if it calls
  1207 			 * page_create_va() to allocate any pages.
  1207 			 * page_create_va() to allocate any pages.
  1222 			 * Unlock the page allocated by page_create_va()
  1222 			 * Unlock the page allocated by page_create_va()
  1223 			 * in segmap_pagecreate()
  1223 			 * in segmap_pagecreate()
  1224 			 */
  1224 			 */
  1225 			if (newpage)
  1225 			if (newpage)
  1226 				segmap_pageunlock(segkmap,
  1226 				segmap_pageunlock(segkmap,
  1227 					(caddr_t)((uintptr_t)base &
  1227 				    (caddr_t)((uintptr_t)base &
  1228 						(uintptr_t)PAGEMASK),
  1228 				    (uintptr_t)PAGEMASK),
  1229 					PAGESIZE, S_WRITE);
  1229 				    PAGESIZE, S_WRITE);
  1230 		} else {
  1230 		} else {
  1231 			/*
  1231 			/*
  1232 			 * KLUDGE ! Use segmap_fault instead of faulting and
  1232 			 * KLUDGE ! Use segmap_fault instead of faulting and
  1233 			 * using as_fault() to avoid a recursive readers lock
  1233 			 * using as_fault() to avoid a recursive readers lock
  1234 			 * on kas.
  1234 			 * on kas.
  1287 				 * we make here.
  1287 				 * we make here.
  1288 				 */
  1288 				 */
  1289 				if (cachefs_charge_page(cp, offset) == 0) {
  1289 				if (cachefs_charge_page(cp, offset) == 0) {
  1290 					cachefs_update_allocmap(cp,
  1290 					cachefs_update_allocmap(cp,
  1291 					    offset & (offset_t)PAGEMASK,
  1291 					    offset & (offset_t)PAGEMASK,
  1292 							(size_t)PAGESIZE);
  1292 					    (size_t)PAGESIZE);
  1293 				}
  1293 				}
  1294 
  1294 
  1295 				/* else we ran out of space */
  1295 				/* else we ran out of space */
  1296 				else {
  1296 				else {
  1297 					/* nocache file if connected */
  1297 					/* nocache file if connected */
  1368 	 * there is less file space allocated than a whole
  1368 	 * there is less file space allocated than a whole
  1369 	 * page, we'll shorten the i/o request below.
  1369 	 * page, we'll shorten the i/o request below.
  1370 	 */
  1370 	 */
  1371 
  1371 
  1372 	pp = pvn_write_kluster(vp, pp, &iooff, &iolen, lbn_off,
  1372 	pp = pvn_write_kluster(vp, pp, &iooff, &iolen, lbn_off,
  1373 			roundup(bsize, PAGESIZE), flags);
  1373 	    roundup(bsize, PAGESIZE), flags);
  1374 
  1374 
  1375 	/*
  1375 	/*
  1376 	 * The CN_CMODINPROG flag makes sure that we use a correct
  1376 	 * The CN_CMODINPROG flag makes sure that we use a correct
  1377 	 * value of c_size, below.  CN_CMODINPROG is set in
  1377 	 * value of c_size, below.  CN_CMODINPROG is set in
  1378 	 * cachefs_writepage().  When CN_CMODINPROG is set it
  1378 	 * cachefs_writepage().  When CN_CMODINPROG is set it
  1560 	    RLIM64_INFINITY, cr, &resid);
  1560 	    RLIM64_INFINITY, cr, &resid);
  1561 	if (error) {
  1561 	if (error) {
  1562 #ifdef CFSDEBUG
  1562 #ifdef CFSDEBUG
  1563 		CFS_DEBUG(CFSDEBUG_VOPS | CFSDEBUG_BACK)
  1563 		CFS_DEBUG(CFSDEBUG_VOPS | CFSDEBUG_BACK)
  1564 			printf("cachefspush: error %d cr %p\n",
  1564 			printf("cachefspush: error %d cr %p\n",
  1565 				error, (void *)cr);
  1565 			    error, (void *)cr);
  1566 #endif
  1566 #endif
  1567 		bp->b_flags |= B_ERROR;
  1567 		bp->b_flags |= B_ERROR;
  1568 	}
  1568 	}
  1569 	VN_RELE(backvp);
  1569 	VN_RELE(backvp);
  1570 out:
  1570 out:
  1692 		}
  1692 		}
  1693 	}
  1693 	}
  1694 
  1694 
  1695 	(void) cachefs_update_allocmap(cp, iooff, iolen);
  1695 	(void) cachefs_update_allocmap(cp, iooff, iolen);
  1696 	cp->c_flags |= (CN_UPDATED | CN_NEED_FRONT_SYNC |
  1696 	cp->c_flags |= (CN_UPDATED | CN_NEED_FRONT_SYNC |
  1697 		CN_POPULATION_PENDING);
  1697 	    CN_POPULATION_PENDING);
  1698 	if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
  1698 	if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
  1699 		gethrestime(&cp->c_metadata.md_localmtime);
  1699 		gethrestime(&cp->c_metadata.md_localmtime);
  1700 		cp->c_metadata.md_flags |= MD_LOCALMTIME;
  1700 		cp->c_metadata.md_flags |= MD_LOCALMTIME;
  1701 	}
  1701 	}
  1702 
  1702 
  1721 	return (error);
  1721 	return (error);
  1722 }
  1722 }
  1723 
  1723 
  1724 /*ARGSUSED*/
  1724 /*ARGSUSED*/
  1725 static int
  1725 static int
  1726 cachefs_dump(struct vnode *vp, caddr_t foo1, int foo2, int foo3,
  1726 cachefs_dump(struct vnode *vp, caddr_t foo1, offset_t foo2, offset_t foo3,
  1727     caller_context_t *ct)
  1727     caller_context_t *ct)
  1728 {
  1728 {
  1729 	return (ENOSYS); /* should we panic if we get here? */
  1729 	return (ENOSYS); /* should we panic if we get here? */
  1730 }
  1730 }
  1731 
  1731 
  1841 		/*
  1841 		/*
  1842 		 * Assert NFSv4 only allows the daemonid and getstats
  1842 		 * Assert NFSv4 only allows the daemonid and getstats
  1843 		 * daemon requests
  1843 		 * daemon requests
  1844 		 */
  1844 		 */
  1845 		ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0 ||
  1845 		ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0 ||
  1846 			STRUCT_FGET(dcmd, d_cmd) == CFSDCMD_DAEMONID ||
  1846 		    STRUCT_FGET(dcmd, d_cmd) == CFSDCMD_DAEMONID ||
  1847 			STRUCT_FGET(dcmd, d_cmd) == CFSDCMD_GETSTATS);
  1847 		    STRUCT_FGET(dcmd, d_cmd) == CFSDCMD_GETSTATS);
  1848 
  1848 
  1849 		/* get the routine to execute */
  1849 		/* get the routine to execute */
  1850 		dcmd_routine = NULL;
  1850 		dcmd_routine = NULL;
  1851 		switch (STRUCT_FGET(dcmd, d_cmd)) {
  1851 		switch (STRUCT_FGET(dcmd, d_cmd)) {
  1852 		case CFSDCMD_DAEMONID:
  1852 		case CFSDCMD_DAEMONID:
  2214 	mutex_enter(&cp->c_statelock);
  2214 	mutex_enter(&cp->c_statelock);
  2215 	backvp = cp->c_backvp;
  2215 	backvp = cp->c_backvp;
  2216 	mutex_exit(&cp->c_statelock);
  2216 	mutex_exit(&cp->c_statelock);
  2217 
  2217 
  2218 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_getattr_backfs_nfsv4: cnode %p,"
  2218 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_getattr_backfs_nfsv4: cnode %p,"
  2219 					" backvp %p\n", cp, backvp));
  2219 	    " backvp %p\n", cp, backvp));
  2220 	error = VOP_GETATTR(backvp, vap, flags, cr, ct);
  2220 	error = VOP_GETATTR(backvp, vap, flags, cr, ct);
  2221 
  2221 
  2222 	/* Update attributes */
  2222 	/* Update attributes */
  2223 	cp->c_attr = *vap;
  2223 	cp->c_attr = *vap;
  2224 
  2224 
  2383 	if (mask & AT_SIZE && !CFS_ISFS_BACKFS_NFSV4(fscp)) {
  2383 	if (mask & AT_SIZE && !CFS_ISFS_BACKFS_NFSV4(fscp)) {
  2384 		bcnt = (uint_t)(cp->c_size & PAGEOFFSET);
  2384 		bcnt = (uint_t)(cp->c_size & PAGEOFFSET);
  2385 		if (bcnt)
  2385 		if (bcnt)
  2386 			pvn_vpzero(vp, cp->c_size, PAGESIZE - bcnt);
  2386 			pvn_vpzero(vp, cp->c_size, PAGESIZE - bcnt);
  2387 		(void) pvn_vplist_dirty(vp, cp->c_size, cachefs_push,
  2387 		(void) pvn_vplist_dirty(vp, cp->c_size, cachefs_push,
  2388 			B_TRUNC | B_INVAL, cr);
  2388 		    B_TRUNC | B_INVAL, cr);
  2389 	}
  2389 	}
  2390 
  2390 
  2391 out:
  2391 out:
  2392 	rw_exit(&cp->c_rwlock);
  2392 	rw_exit(&cp->c_rwlock);
  2393 
  2393 
  2425 	error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
  2425 	error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
  2426 	if (error)
  2426 	if (error)
  2427 		goto out;
  2427 		goto out;
  2428 
  2428 
  2429 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_setattr (nfsv4): cnode %p, "
  2429 	CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_setattr (nfsv4): cnode %p, "
  2430 					"backvp %p\n", cp, cp->c_backvp));
  2430 	    "backvp %p\n", cp, cp->c_backvp));
  2431 	error = VOP_SETATTR(cp->c_backvp, vap, flags, cr, ct);
  2431 	error = VOP_SETATTR(cp->c_backvp, vap, flags, cr, ct);
  2432 	if (error) {
  2432 	if (error) {
  2433 		goto out;
  2433 		goto out;
  2434 	}
  2434 	}
  2435 
  2435 
  2522 	/* primary concern is to keep this routine as much like ufs_setattr */
  2522 	/* primary concern is to keep this routine as much like ufs_setattr */
  2523 
  2523 
  2524 	mutex_enter(&cp->c_statelock);
  2524 	mutex_enter(&cp->c_statelock);
  2525 
  2525 
  2526 	error = secpolicy_vnode_setattr(cr, vp, vap, &cp->c_attr, flags,
  2526 	error = secpolicy_vnode_setattr(cr, vp, vap, &cp->c_attr, flags,
  2527 			    cachefs_access_local, cp);
  2527 	    cachefs_access_local, cp);
  2528 
  2528 
  2529 	if (error)
  2529 	if (error)
  2530 		goto out;
  2530 		goto out;
  2531 
  2531 
  2532 	mask = vap->va_mask;
  2532 	mask = vap->va_mask;
  2858 			if (error)
  2858 			if (error)
  2859 				goto out;
  2859 				goto out;
  2860 		}
  2860 		}
  2861 
  2861 
  2862 		CFS_DPRINT_BACKFS_NFSV4(fscp,
  2862 		CFS_DPRINT_BACKFS_NFSV4(fscp,
  2863 			("cachefs_access (nfsv4): cnode %p, backvp %p\n",
  2863 		    ("cachefs_access (nfsv4): cnode %p, backvp %p\n",
  2864 			cp, cp->c_backvp));
  2864 		    cp, cp->c_backvp));
  2865 		error = VOP_ACCESS(cp->c_backvp, mode, flags, cr, NULL);
  2865 		error = VOP_ACCESS(cp->c_backvp, mode, flags, cr, NULL);
  2866 
  2866 
  2867 		/*
  2867 		/*
  2868 		 * even though we don't `need' the ACL to do access
  2868 		 * even though we don't `need' the ACL to do access
  2869 		 * via the backvp, we should cache it here to make our
  2869 		 * via the backvp, we should cache it here to make our
  3053 		}
  3053 		}
  3054 		if (cp->c_metadata.md_flags & MD_POPULATED) {
  3054 		if (cp->c_metadata.md_flags & MD_POPULATED) {
  3055 			/* read symlink data from frontfile */
  3055 			/* read symlink data from frontfile */
  3056 			uiop->uio_offset = 0;
  3056 			uiop->uio_offset = 0;
  3057 			(void) VOP_RWLOCK(cp->c_frontvp,
  3057 			(void) VOP_RWLOCK(cp->c_frontvp,
  3058 						V_WRITELOCK_FALSE, NULL);
  3058 			    V_WRITELOCK_FALSE, NULL);
  3059 			error = VOP_READ(cp->c_frontvp, uiop, 0, kcred, NULL);
  3059 			error = VOP_READ(cp->c_frontvp, uiop, 0, kcred, NULL);
  3060 			VOP_RWUNLOCK(cp->c_frontvp, V_WRITELOCK_FALSE, NULL);
  3060 			VOP_RWUNLOCK(cp->c_frontvp, V_WRITELOCK_FALSE, NULL);
  3061 
  3061 
  3062 			/* XXX KLUDGE! correct for insidious 0-len symlink */
  3062 			/* XXX KLUDGE! correct for insidious 0-len symlink */
  3063 			if (cp->c_size != 0) {
  3063 			if (cp->c_size != 0) {
  3122 		}
  3122 		}
  3123 		if (cp->c_metadata.md_flags & MD_POPULATED) {
  3123 		if (cp->c_metadata.md_flags & MD_POPULATED) {
  3124 			/* read symlink data from frontfile */
  3124 			/* read symlink data from frontfile */
  3125 			uiop->uio_offset = 0;
  3125 			uiop->uio_offset = 0;
  3126 			(void) VOP_RWLOCK(cp->c_frontvp,
  3126 			(void) VOP_RWLOCK(cp->c_frontvp,
  3127 						V_WRITELOCK_FALSE, NULL);
  3127 			    V_WRITELOCK_FALSE, NULL);
  3128 			error = VOP_READ(cp->c_frontvp, uiop, 0, kcred, NULL);
  3128 			error = VOP_READ(cp->c_frontvp, uiop, 0, kcred, NULL);
  3129 			VOP_RWUNLOCK(cp->c_frontvp, V_WRITELOCK_FALSE, NULL);
  3129 			VOP_RWUNLOCK(cp->c_frontvp, V_WRITELOCK_FALSE, NULL);
  3130 			readcache = 1;
  3130 			readcache = 1;
  3131 			goto out;
  3131 			goto out;
  3132 		}
  3132 		}
  3232 		if ((fscp->fs_cdconnected == CFS_CD_CONNECTED) &&
  3232 		if ((fscp->fs_cdconnected == CFS_CD_CONNECTED) &&
  3233 		    cp->c_backvp) {
  3233 		    cp->c_backvp) {
  3234 			mutex_enter(&cp->c_statelock);
  3234 			mutex_enter(&cp->c_statelock);
  3235 			if (cp->c_backvp) {
  3235 			if (cp->c_backvp) {
  3236 				CFS_DPRINT_BACKFS_NFSV4(fscp,
  3236 				CFS_DPRINT_BACKFS_NFSV4(fscp,
  3237 					("cachefs_fsync (nfsv4): cnode %p, "
  3237 				    ("cachefs_fsync (nfsv4): cnode %p, "
  3238 					"backvp %p\n", cp, cp->c_backvp));
  3238 				    "backvp %p\n", cp, cp->c_backvp));
  3239 				error = VOP_FSYNC(cp->c_backvp, syncflag, cr,
  3239 				error = VOP_FSYNC(cp->c_backvp, syncflag, cr,
  3240 				    ct);
  3240 				    ct);
  3241 				if (CFS_TIMEOUT(fscp, error)) {
  3241 				if (CFS_TIMEOUT(fscp, error)) {
  3242 					mutex_exit(&cp->c_statelock);
  3242 					mutex_exit(&cp->c_statelock);
  3243 					cachefs_cd_release(fscp);
  3243 					cachefs_cd_release(fscp);
  3290 	fscache_t *fscp = C_TO_FSCACHE(cp);
  3290 	fscache_t *fscp = C_TO_FSCACHE(cp);
  3291 
  3291 
  3292 #ifdef CFSDEBUG
  3292 #ifdef CFSDEBUG
  3293 	CFS_DEBUG(CFSDEBUG_VOPS)
  3293 	CFS_DEBUG(CFSDEBUG_VOPS)
  3294 		printf("c_sync_metadata: ENTER cp %p cflag %x\n",
  3294 		printf("c_sync_metadata: ENTER cp %p cflag %x\n",
  3295 			(void *)cp, cp->c_flags);
  3295 		    (void *)cp, cp->c_flags);
  3296 #endif
  3296 #endif
  3297 
  3297 
  3298 	mutex_enter(&cp->c_statelock);
  3298 	mutex_enter(&cp->c_statelock);
  3299 	if ((cp->c_flags & CN_UPDATED) == 0)
  3299 	if ((cp->c_flags & CN_UPDATED) == 0)
  3300 		goto out;
  3300 		goto out;
  3330 			if (error) {
  3330 			if (error) {
  3331 				cp->c_metadata.md_timestamp.tv_sec = 0;
  3331 				cp->c_metadata.md_timestamp.tv_sec = 0;
  3332 			} else {
  3332 			} else {
  3333 				va.va_mask = AT_MTIME;
  3333 				va.va_mask = AT_MTIME;
  3334 				error = VOP_GETATTR(cp->c_frontvp, &va, 0,
  3334 				error = VOP_GETATTR(cp->c_frontvp, &va, 0,
  3335 					kcred, NULL);
  3335 				    kcred, NULL);
  3336 				if (error)
  3336 				if (error)
  3337 					goto out;
  3337 					goto out;
  3338 				cp->c_metadata.md_timestamp = va.va_mtime;
  3338 				cp->c_metadata.md_timestamp = va.va_mtime;
  3339 				cp->c_flags &=
  3339 				cp->c_flags &=
  3340 				~(CN_NEED_FRONT_SYNC | CN_POPULATION_PENDING);
  3340 				    ~(CN_NEED_FRONT_SYNC |
       
  3341 				    CN_POPULATION_PENDING);
  3341 			}
  3342 			}
  3342 		} else {
  3343 		} else {
  3343 			cp->c_flags &=
  3344 			cp->c_flags &=
  3344 				~(CN_NEED_FRONT_SYNC | CN_POPULATION_PENDING);
  3345 			    ~(CN_NEED_FRONT_SYNC | CN_POPULATION_PENDING);
  3345 		}
  3346 		}
  3346 	}
  3347 	}
  3347 
  3348 
  3348 	/*
  3349 	/*
  3349 	 * XXX tony: How can CN_ALLOC_PENDING still be set??
  3350 	 * XXX tony: How can CN_ALLOC_PENDING still be set??
  3350 	 * XXX tony: How can CN_UPDATED not be set?????
  3351 	 * XXX tony: How can CN_UPDATED not be set?????
  3351 	 */
  3352 	 */
  3352 	if ((cp->c_flags & CN_ALLOC_PENDING) == 0 &&
  3353 	if ((cp->c_flags & CN_ALLOC_PENDING) == 0 &&
  3353 			(cp->c_flags & CN_UPDATED)) {
  3354 	    (cp->c_flags & CN_UPDATED)) {
  3354 		error = filegrp_write_metadata(fgp, &cp->c_id,
  3355 		error = filegrp_write_metadata(fgp, &cp->c_id,
  3355 				&cp->c_metadata);
  3356 		    &cp->c_metadata);
  3356 		if (error)
  3357 		if (error)
  3357 			goto out;
  3358 			goto out;
  3358 	}
  3359 	}
  3359 out:
  3360 out:
  3360 	if (error) {
  3361 	if (error) {
  3384 	mutex_exit(&cp->c_statelock);
  3385 	mutex_exit(&cp->c_statelock);
  3385 
  3386 
  3386 #ifdef CFSDEBUG
  3387 #ifdef CFSDEBUG
  3387 	CFS_DEBUG(CFSDEBUG_VOPS)
  3388 	CFS_DEBUG(CFSDEBUG_VOPS)
  3388 		printf("c_sync_metadata: EXIT cp %p cflag %x\n",
  3389 		printf("c_sync_metadata: EXIT cp %p cflag %x\n",
  3389 			(void *)cp, cp->c_flags);
  3390 		    (void *)cp, cp->c_flags);
  3390 #endif
  3391 #endif
  3391 
  3392 
  3392 	return (error);
  3393 	return (error);
  3393 }
  3394 }
  3394 
  3395 
  3668 
  3669 
  3669 	/* by now we have a valid cached front file that we can search */
  3670 	/* by now we have a valid cached front file that we can search */
  3670 
  3671 
  3671 	ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
  3672 	ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
  3672 	error = cachefs_dir_look(dcp, nm, &cookie, &flag,
  3673 	error = cachefs_dir_look(dcp, nm, &cookie, &flag,
  3673 			&d_offset, &cid);
  3674 	    &d_offset, &cid);
  3674 	mutex_exit(&dcp->c_statelock);
  3675 	mutex_exit(&dcp->c_statelock);
  3675 
  3676 
  3676 	if (error) {
  3677 	if (error) {
  3677 		/* if the entry does not have the fid, go get it */
  3678 		/* if the entry does not have the fid, go get it */
  3678 		if (error == EINVAL) {
  3679 		if (error == EINVAL) {
  3760 		if (error)
  3761 		if (error)
  3761 			goto out;
  3762 			goto out;
  3762 	}
  3763 	}
  3763 
  3764 
  3764 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  3765 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  3765 		("cachefs_lookup (nfsv4): dcp %p, dbackvp %p, name %s\n",
  3766 	    ("cachefs_lookup (nfsv4): dcp %p, dbackvp %p, name %s\n",
  3766 		dcp, dcp->c_backvp, nm));
  3767 	    dcp, dcp->c_backvp, nm));
  3767 	error = VOP_LOOKUP(dcp->c_backvp, nm, &backvp, (struct pathname *)NULL,
  3768 	error = VOP_LOOKUP(dcp->c_backvp, nm, &backvp, (struct pathname *)NULL,
  3768 	    0, (vnode_t *)NULL, cr, NULL, NULL, NULL);
  3769 	    0, (vnode_t *)NULL, cr, NULL, NULL, NULL);
  3769 	if (error)
  3770 	if (error)
  3770 		goto out;
  3771 		goto out;
  3771 	if (IS_DEVVP(backvp)) {
  3772 	if (IS_DEVVP(backvp)) {
  3800 	mutex_exit(&dcp->c_statelock);
  3801 	mutex_exit(&dcp->c_statelock);
  3801 
  3802 
  3802 	/* create the cnode */
  3803 	/* create the cnode */
  3803 	if (error == 0) {
  3804 	if (error == 0) {
  3804 		error = cachefs_cnode_make(&cid, fscp,
  3805 		error = cachefs_cnode_make(&cid, fscp,
  3805 					(valid_fid ? &cookie : NULL),
  3806 		    (valid_fid ? &cookie : NULL),
  3806 					&va, backvp, cr, 0, &cp);
  3807 		    &va, backvp, cr, 0, &cp);
  3807 		if (error == 0) {
  3808 		if (error == 0) {
  3808 			*vpp = CTOV(cp);
  3809 			*vpp = CTOV(cp);
  3809 		}
  3810 		}
  3810 	}
  3811 	}
  3811 
  3812 
  3999 		}
  4000 		}
  4000 	}
  4001 	}
  4001 
  4002 
  4002 	/* create the file on the back fs */
  4003 	/* create the file on the back fs */
  4003 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  4004 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  4004 		("cachefs_create (nfsv4): dcp %p, dbackvp %p,"
  4005 	    ("cachefs_create (nfsv4): dcp %p, dbackvp %p,"
  4005 		"name %s\n", dcp, dcp->c_backvp, nm));
  4006 	    "name %s\n", dcp, dcp->c_backvp, nm));
  4006 	error = VOP_CREATE(dcp->c_backvp, nm, vap, exclusive, mode,
  4007 	error = VOP_CREATE(dcp->c_backvp, nm, vap, exclusive, mode,
  4007 	    &devvp, cr, 0, NULL, NULL);
  4008 	    &devvp, cr, 0, NULL, NULL);
  4008 	mutex_exit(&dcp->c_statelock);
  4009 	mutex_exit(&dcp->c_statelock);
  4009 	if (error)
  4010 	if (error)
  4010 		goto out;
  4011 		goto out;
  4023 
  4024 
  4024 	/* make the cnode */
  4025 	/* make the cnode */
  4025 	cid.cid_fileno = va.va_nodeid;
  4026 	cid.cid_fileno = va.va_nodeid;
  4026 	cid.cid_flags = 0;
  4027 	cid.cid_flags = 0;
  4027 	error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
  4028 	error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
  4028 					&va, tvp, cr, 0, &ncp);
  4029 	    &va, tvp, cr, 0, &ncp);
  4029 	if (error)
  4030 	if (error)
  4030 		goto out;
  4031 		goto out;
  4031 
  4032 
  4032 	*vpp = CTOV(ncp);
  4033 	*vpp = CTOV(ncp);
  4033 
  4034 
  4436 				connected = 0;
  4437 				connected = 0;
  4437 				continue;
  4438 				continue;
  4438 			}
  4439 			}
  4439 		} else {
  4440 		} else {
  4440 			error = cachefs_remove_disconnected(dvp, nm, cr,
  4441 			error = cachefs_remove_disconnected(dvp, nm, cr,
  4441 				vp);
  4442 			    vp);
  4442 			if (CFS_TIMEOUT(fscp, error)) {
  4443 			if (CFS_TIMEOUT(fscp, error)) {
  4443 				connected = 1;
  4444 				connected = 1;
  4444 				continue;
  4445 				continue;
  4445 			}
  4446 			}
  4446 		}
  4447 		}
  4664 	mutex_enter(&dcp->c_statelock);
  4665 	mutex_enter(&dcp->c_statelock);
  4665 	dbackvp = dcp->c_backvp;
  4666 	dbackvp = dcp->c_backvp;
  4666 	mutex_exit(&dcp->c_statelock);
  4667 	mutex_exit(&dcp->c_statelock);
  4667 
  4668 
  4668 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  4669 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  4669 		("cachefs_remove (nfsv4): dcp %p, dbackvp %p, name %s\n",
  4670 	    ("cachefs_remove (nfsv4): dcp %p, dbackvp %p, name %s\n",
  4670 		dcp, dbackvp, nm));
  4671 	    dcp, dbackvp, nm));
  4671 	error = VOP_REMOVE(dbackvp, nm, cr, NULL, 0);
  4672 	error = VOP_REMOVE(dbackvp, nm, cr, NULL, 0);
  4672 	if (error) {
  4673 	if (error) {
  4673 		mutex_exit(&cp->c_statelock);
  4674 		mutex_exit(&cp->c_statelock);
  4674 		goto out;
  4675 		goto out;
  4675 	}
  4676 	}
  4829 	int connected = 0;
  4830 	int connected = 0;
  4830 
  4831 
  4831 #ifdef CFSDEBUG
  4832 #ifdef CFSDEBUG
  4832 	CFS_DEBUG(CFSDEBUG_VOPS)
  4833 	CFS_DEBUG(CFSDEBUG_VOPS)
  4833 		printf("cachefs_link: ENTER fvp %p tdvp %p tnm %s\n",
  4834 		printf("cachefs_link: ENTER fvp %p tdvp %p tnm %s\n",
  4834 			(void *)fvp, (void *)tdvp, tnm);
  4835 		    (void *)fvp, (void *)tdvp, tnm);
  4835 #endif
  4836 #endif
  4836 
  4837 
  4837 	if (getzoneid() != GLOBAL_ZONEID) {
  4838 	if (getzoneid() != GLOBAL_ZONEID) {
  4838 		error = EPERM;
  4839 		error = EPERM;
  4839 		goto out;
  4840 		goto out;
  4884 				connected = 0;
  4885 				connected = 0;
  4885 				continue;
  4886 				continue;
  4886 			}
  4887 			}
  4887 		} else {
  4888 		} else {
  4888 			error = cachefs_link_disconnected(tdvp, fvp, tnm,
  4889 			error = cachefs_link_disconnected(tdvp, fvp, tnm,
  4889 				cr);
  4890 			    cr);
  4890 			if (CFS_TIMEOUT(fscp, error)) {
  4891 			if (CFS_TIMEOUT(fscp, error)) {
  4891 				connected = 1;
  4892 				connected = 1;
  4892 				continue;
  4893 				continue;
  4893 			}
  4894 			}
  4894 		}
  4895 		}
  4905 #endif
  4906 #endif
  4906 out:
  4907 out:
  4907 #ifdef CFSDEBUG
  4908 #ifdef CFSDEBUG
  4908 	CFS_DEBUG(CFSDEBUG_VOPS)
  4909 	CFS_DEBUG(CFSDEBUG_VOPS)
  4909 		printf("cachefs_link: EXIT fvp %p tdvp %p tnm %s\n",
  4910 		printf("cachefs_link: EXIT fvp %p tdvp %p tnm %s\n",
  4910 			(void *)fvp, (void *)tdvp, tnm);
  4911 		    (void *)fvp, (void *)tdvp, tnm);
  4911 #endif
  4912 #endif
  4912 	return (error);
  4913 	return (error);
  4913 }
  4914 }
  4914 
  4915 
  4915 static int
  4916 static int
  4964 		VN_HOLD(backvp);
  4965 		VN_HOLD(backvp);
  4965 	}
  4966 	}
  4966 
  4967 
  4967 	/* perform the link on the back fs */
  4968 	/* perform the link on the back fs */
  4968 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  4969 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  4969 		("cachefs_link (nfsv4): tdcp %p, tdbackvp %p, "
  4970 	    ("cachefs_link (nfsv4): tdcp %p, tdbackvp %p, "
  4970 		"name %s\n", tdcp, tdcp->c_backvp, tnm));
  4971 	    "name %s\n", tdcp, tdcp->c_backvp, tnm));
  4971 	error = VOP_LINK(tdcp->c_backvp, backvp, tnm, cr, NULL, 0);
  4972 	error = VOP_LINK(tdcp->c_backvp, backvp, tnm, cr, NULL, 0);
  4972 	if (error) {
  4973 	if (error) {
  4973 		mutex_exit(&tdcp->c_statelock);
  4974 		mutex_exit(&tdcp->c_statelock);
  4974 		goto out;
  4975 		goto out;
  4975 	}
  4976 	}
  5160 
  5161 
  5161 	/*
  5162 	/*
  5162 	 * if the fs NOFILL or NOCACHE flags are on, then the old and new
  5163 	 * if the fs NOFILL or NOCACHE flags are on, then the old and new
  5163 	 * directory cnodes better indicate NOCACHE mode as well.
  5164 	 * directory cnodes better indicate NOCACHE mode as well.
  5164 	 */
  5165 	 */
  5165 	ASSERT
  5166 	ASSERT(
  5166 	    ((fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE)) == 0 ||
  5167 	    (fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE)) == 0 ||
  5167 	    ((VTOC(odvp)->c_flags & CN_NOCACHE) &&
  5168 	    ((VTOC(odvp)->c_flags & CN_NOCACHE) &&
  5168 	    (VTOC(ndvp)->c_flags & CN_NOCACHE)));
  5169 	    (VTOC(ndvp)->c_flags & CN_NOCACHE)));
  5169 
  5170 
  5170 	/*
  5171 	/*
  5171 	 * Cachefs only provides pass-through support for NFSv4,
  5172 	 * Cachefs only provides pass-through support for NFSv4,
  5253 			}
  5254 			}
  5254 		}
  5255 		}
  5255 
  5256 
  5256 		/* get the cnode if file being deleted */
  5257 		/* get the cnode if file being deleted */
  5257 		error = cachefs_lookup_common(ndvp, nnm, &delvp, NULL, 0,
  5258 		error = cachefs_lookup_common(ndvp, nnm, &delvp, NULL, 0,
  5258 			NULL, cr);
  5259 		    NULL, cr);
  5259 		if (error) {
  5260 		if (error) {
  5260 			delvp = NULL;
  5261 			delvp = NULL;
  5261 			if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  5262 			if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  5262 				if (CFS_TIMEOUT(fscp, error)) {
  5263 				if (CFS_TIMEOUT(fscp, error)) {
  5263 					cachefs_cd_release(fscp);
  5264 					cachefs_cd_release(fscp);
  5289 			}
  5290 			}
  5290 		}
  5291 		}
  5291 
  5292 
  5292 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  5293 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  5293 			error = cachefs_rename_connected(odvp, onm,
  5294 			error = cachefs_rename_connected(odvp, onm,
  5294 				ndvp, nnm, cr, delvp);
  5295 			    ndvp, nnm, cr, delvp);
  5295 			if (CFS_TIMEOUT(fscp, error)) {
  5296 			if (CFS_TIMEOUT(fscp, error)) {
  5296 				cachefs_cd_release(fscp);
  5297 				cachefs_cd_release(fscp);
  5297 				held = 0;
  5298 				held = 0;
  5298 				cachefs_cd_timedout(fscp);
  5299 				cachefs_cd_timedout(fscp);
  5299 				connected = 0;
  5300 				connected = 0;
  5300 				continue;
  5301 				continue;
  5301 			}
  5302 			}
  5302 		} else {
  5303 		} else {
  5303 			error = cachefs_rename_disconnected(odvp, onm,
  5304 			error = cachefs_rename_disconnected(odvp, onm,
  5304 				ndvp, nnm, cr, delvp);
  5305 			    ndvp, nnm, cr, delvp);
  5305 			if (CFS_TIMEOUT(fscp, error)) {
  5306 			if (CFS_TIMEOUT(fscp, error)) {
  5306 				connected = 1;
  5307 				connected = 1;
  5307 				continue;
  5308 				continue;
  5308 			}
  5309 			}
  5309 		}
  5310 		}
  5432 		}
  5433 		}
  5433 	}
  5434 	}
  5434 
  5435 
  5435 	/* do the rename on the back fs */
  5436 	/* do the rename on the back fs */
  5436 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  5437 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  5437 		("cachefs_rename (nfsv4): odcp %p, odbackvp %p, "
  5438 	    ("cachefs_rename (nfsv4): odcp %p, odbackvp %p, "
  5438 		" ndcp %p, ndbackvp %p, onm %s, nnm %s\n",
  5439 	    " ndcp %p, ndbackvp %p, onm %s, nnm %s\n",
  5439 		odcp, odcp->c_backvp, ndcp, ndcp->c_backvp, onm, nnm));
  5440 	    odcp, odcp->c_backvp, ndcp, ndcp->c_backvp, onm, nnm));
  5440 	error = VOP_RENAME(odcp->c_backvp, onm, ndcp->c_backvp, nnm, cr, NULL,
  5441 	error = VOP_RENAME(odcp->c_backvp, onm, ndcp->c_backvp, nnm, cr, NULL,
  5441 	    0);
  5442 	    0);
  5442 	if (error)
  5443 	if (error)
  5443 		goto out;
  5444 		goto out;
  5444 
  5445 
  5467 	gotdirent = 0;
  5468 	gotdirent = 0;
  5468 	cookiep = NULL;
  5469 	cookiep = NULL;
  5469 	if (CFS_ISFS_NONSHARED(fscp) &&
  5470 	if (CFS_ISFS_NONSHARED(fscp) &&
  5470 	    (odcp->c_metadata.md_flags & MD_POPULATED)) {
  5471 	    (odcp->c_metadata.md_flags & MD_POPULATED)) {
  5471 		error = cachefs_dir_look(odcp, onm, &cookie,
  5472 		error = cachefs_dir_look(odcp, onm, &cookie,
  5472 			NULL, NULL, &cid);
  5473 		    NULL, NULL, &cid);
  5473 		if (error == 0 || error == EINVAL) {
  5474 		if (error == 0 || error == EINVAL) {
  5474 			gotdirent = 1;
  5475 			gotdirent = 1;
  5475 			if (error == 0)
  5476 			if (error == 0)
  5476 				cookiep = &cookie;
  5477 				cookiep = &cookie;
  5477 		} else {
  5478 		} else {
  5863 		rw_enter(&dcp->c_rwlock, RW_WRITER);
  5864 		rw_enter(&dcp->c_rwlock, RW_WRITER);
  5864 		held = 1;
  5865 		held = 1;
  5865 
  5866 
  5866 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  5867 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  5867 			error = cachefs_mkdir_connected(dvp, nm, vap,
  5868 			error = cachefs_mkdir_connected(dvp, nm, vap,
  5868 				vpp, cr);
  5869 			    vpp, cr);
  5869 			if (CFS_TIMEOUT(fscp, error)) {
  5870 			if (CFS_TIMEOUT(fscp, error)) {
  5870 				rw_exit(&dcp->c_rwlock);
  5871 				rw_exit(&dcp->c_rwlock);
  5871 				cachefs_cd_release(fscp);
  5872 				cachefs_cd_release(fscp);
  5872 				held = 0;
  5873 				held = 0;
  5873 				cachefs_cd_timedout(fscp);
  5874 				cachefs_cd_timedout(fscp);
  5874 				connected = 0;
  5875 				connected = 0;
  5875 				continue;
  5876 				continue;
  5876 			}
  5877 			}
  5877 		} else {
  5878 		} else {
  5878 			error = cachefs_mkdir_disconnected(dvp, nm, vap,
  5879 			error = cachefs_mkdir_disconnected(dvp, nm, vap,
  5879 				vpp, cr);
  5880 			    vpp, cr);
  5880 			if (CFS_TIMEOUT(fscp, error)) {
  5881 			if (CFS_TIMEOUT(fscp, error)) {
  5881 				connected = 1;
  5882 				connected = 1;
  5882 				continue;
  5883 				continue;
  5883 			}
  5884 			}
  5884 		}
  5885 		}
  5954 	}
  5955 	}
  5955 	dircid = dcp->c_id;
  5956 	dircid = dcp->c_id;
  5956 
  5957 
  5957 	/* make the dir on the back fs */
  5958 	/* make the dir on the back fs */
  5958 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  5959 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  5959 		("cachefs_mkdir (nfsv4): dcp %p, dbackvp %p, "
  5960 	    ("cachefs_mkdir (nfsv4): dcp %p, dbackvp %p, "
  5960 		"name %s\n", dcp, dcp->c_backvp, nm));
  5961 	    "name %s\n", dcp, dcp->c_backvp, nm));
  5961 	error = VOP_MKDIR(dcp->c_backvp, nm, vap, &vp, cr, NULL, 0, NULL);
  5962 	error = VOP_MKDIR(dcp->c_backvp, nm, vap, &vp, cr, NULL, 0, NULL);
  5962 	mutex_exit(&dcp->c_statelock);
  5963 	mutex_exit(&dcp->c_statelock);
  5963 	if (error) {
  5964 	if (error) {
  5964 		goto out;
  5965 		goto out;
  5965 	}
  5966 	}
  5972 		goto out;
  5973 		goto out;
  5973 	}
  5974 	}
  5974 	cid.cid_flags = 0;
  5975 	cid.cid_flags = 0;
  5975 	cid.cid_fileno = attr.va_nodeid;
  5976 	cid.cid_fileno = attr.va_nodeid;
  5976 	error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
  5977 	error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
  5977 					&attr, vp, cr, 0, &newcp);
  5978 	    &attr, vp, cr, 0, &newcp);
  5978 	if (error) {
  5979 	if (error) {
  5979 		goto out;
  5980 		goto out;
  5980 	}
  5981 	}
  5981 	ASSERT(CTOV(newcp)->v_type == VDIR);
  5982 	ASSERT(CTOV(newcp)->v_type == VDIR);
  5982 	*vpp = CTOV(newcp);
  5983 	*vpp = CTOV(newcp);
  6145 	}
  6146 	}
  6146 	cachefs_modified(dcp);
  6147 	cachefs_modified(dcp);
  6147 
  6148 
  6148 	/* enter the new file in the directory */
  6149 	/* enter the new file in the directory */
  6149 	error = cachefs_dir_enter(dcp, nm, &newcp->c_metadata.md_cookie,
  6150 	error = cachefs_dir_enter(dcp, nm, &newcp->c_metadata.md_cookie,
  6150 		&newcp->c_id, SM_ASYNC);
  6151 	    &newcp->c_id, SM_ASYNC);
  6151 	if (error) {
  6152 	if (error) {
  6152 		mutex_exit(&dcp->c_statelock);
  6153 		mutex_exit(&dcp->c_statelock);
  6153 		goto out;
  6154 		goto out;
  6154 	}
  6155 	}
  6155 
  6156 
  6319 			break;
  6320 			break;
  6320 		}
  6321 		}
  6321 
  6322 
  6322 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  6323 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  6323 			error = cachefs_rmdir_connected(dvp, nm, cdir,
  6324 			error = cachefs_rmdir_connected(dvp, nm, cdir,
  6324 				cr, vp);
  6325 			    cr, vp);
  6325 			if (CFS_TIMEOUT(fscp, error)) {
  6326 			if (CFS_TIMEOUT(fscp, error)) {
  6326 				cachefs_cd_release(fscp);
  6327 				cachefs_cd_release(fscp);
  6327 				held = 0;
  6328 				held = 0;
  6328 				cachefs_cd_timedout(fscp);
  6329 				cachefs_cd_timedout(fscp);
  6329 				connected = 0;
  6330 				connected = 0;
  6330 				continue;
  6331 				continue;
  6331 			}
  6332 			}
  6332 		} else {
  6333 		} else {
  6333 			error = cachefs_rmdir_disconnected(dvp, nm, cdir,
  6334 			error = cachefs_rmdir_disconnected(dvp, nm, cdir,
  6334 				cr, vp);
  6335 			    cr, vp);
  6335 			if (CFS_TIMEOUT(fscp, error)) {
  6336 			if (CFS_TIMEOUT(fscp, error)) {
  6336 				connected = 1;
  6337 				connected = 1;
  6337 				continue;
  6338 				continue;
  6338 			}
  6339 			}
  6339 		}
  6340 		}
  6402 	if (error)
  6403 	if (error)
  6403 		goto out;
  6404 		goto out;
  6404 
  6405 
  6405 	/* rmdir on the back fs */
  6406 	/* rmdir on the back fs */
  6406 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  6407 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  6407 		("cachefs_rmdir (nfsv4): dcp %p, dbackvp %p, "
  6408 	    ("cachefs_rmdir (nfsv4): dcp %p, dbackvp %p, "
  6408 		"name %s\n", dcp, dcp->c_backvp, nm));
  6409 	    "name %s\n", dcp, dcp->c_backvp, nm));
  6409 	error = VOP_RMDIR(dcp->c_backvp, nm, cdir, cr, NULL, 0);
  6410 	error = VOP_RMDIR(dcp->c_backvp, nm, cdir, cr, NULL, 0);
  6410 	if (error)
  6411 	if (error)
  6411 		goto out;
  6412 		goto out;
  6412 
  6413 
  6413 	/* if the dir is populated, remove the entry from it */
  6414 	/* if the dir is populated, remove the entry from it */
  6594 		rw_enter(&dcp->c_rwlock, RW_WRITER);
  6595 		rw_enter(&dcp->c_rwlock, RW_WRITER);
  6595 		held = 1;
  6596 		held = 1;
  6596 
  6597 
  6597 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  6598 		if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
  6598 			error = cachefs_symlink_connected(dvp, lnm, tva,
  6599 			error = cachefs_symlink_connected(dvp, lnm, tva,
  6599 				tnm, cr);
  6600 			    tnm, cr);
  6600 			if (CFS_TIMEOUT(fscp, error)) {
  6601 			if (CFS_TIMEOUT(fscp, error)) {
  6601 				rw_exit(&dcp->c_rwlock);
  6602 				rw_exit(&dcp->c_rwlock);
  6602 				cachefs_cd_release(fscp);
  6603 				cachefs_cd_release(fscp);
  6603 				held = 0;
  6604 				held = 0;
  6604 				cachefs_cd_timedout(fscp);
  6605 				cachefs_cd_timedout(fscp);
  6605 				connected = 0;
  6606 				connected = 0;
  6606 				continue;
  6607 				continue;
  6607 			}
  6608 			}
  6608 		} else {
  6609 		} else {
  6609 			error = cachefs_symlink_disconnected(dvp, lnm, tva,
  6610 			error = cachefs_symlink_disconnected(dvp, lnm, tva,
  6610 				tnm, cr);
  6611 			    tnm, cr);
  6611 			if (CFS_TIMEOUT(fscp, error)) {
  6612 			if (CFS_TIMEOUT(fscp, error)) {
  6612 				connected = 1;
  6613 				connected = 1;
  6613 				continue;
  6614 				continue;
  6614 			}
  6615 			}
  6615 		}
  6616 		}
  6666 	if (error) {
  6667 	if (error) {
  6667 		mutex_exit(&dcp->c_statelock);
  6668 		mutex_exit(&dcp->c_statelock);
  6668 		goto out;
  6669 		goto out;
  6669 	}
  6670 	}
  6670 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  6671 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  6671 		("cachefs_symlink (nfsv4): dcp %p, dbackvp %p, "
  6672 	    ("cachefs_symlink (nfsv4): dcp %p, dbackvp %p, "
  6672 		"lnm %s, tnm %s\n", dcp, dcp->c_backvp, lnm, tnm));
  6673 	    "lnm %s, tnm %s\n", dcp, dcp->c_backvp, lnm, tnm));
  6673 	error = VOP_SYMLINK(dcp->c_backvp, lnm, tva, tnm, cr, NULL, 0);
  6674 	error = VOP_SYMLINK(dcp->c_backvp, lnm, tva, tnm, cr, NULL, 0);
  6674 	if (error) {
  6675 	if (error) {
  6675 		mutex_exit(&dcp->c_statelock);
  6676 		mutex_exit(&dcp->c_statelock);
  6676 		goto out;
  6677 		goto out;
  6677 	}
  6678 	}
  6717 	}
  6718 	}
  6718 	mutex_exit(&dcp->c_statelock);
  6719 	mutex_exit(&dcp->c_statelock);
  6719 
  6720 
  6720 	/* make the cnode for the sym link */
  6721 	/* make the cnode for the sym link */
  6721 	error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
  6722 	error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
  6722 						&va, backvp, cr, 0, &newcp);
  6723 	    &va, backvp, cr, 0, &newcp);
  6723 	if (error) {
  6724 	if (error) {
  6724 		ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
  6725 		ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
  6725 		cachefs_nocache(dcp);
  6726 		cachefs_nocache(dcp);
  6726 		error = 0;
  6727 		error = 0;
  6727 		goto out;
  6728 		goto out;
  6889 		mutex_exit(&dcp->c_statelock);
  6890 		mutex_exit(&dcp->c_statelock);
  6890 		goto out;
  6891 		goto out;
  6891 	}
  6892 	}
  6892 	cachefs_modified(dcp);
  6893 	cachefs_modified(dcp);
  6893 	error = cachefs_dir_enter(dcp, lnm, &newcp->c_metadata.md_cookie,
  6894 	error = cachefs_dir_enter(dcp, lnm, &newcp->c_metadata.md_cookie,
  6894 		&newcp->c_id, SM_ASYNC);
  6895 	    &newcp->c_id, SM_ASYNC);
  6895 	if (error) {
  6896 	if (error) {
  6896 		mutex_exit(&dcp->c_statelock);
  6897 		mutex_exit(&dcp->c_statelock);
  6897 		goto out;
  6898 		goto out;
  6898 	}
  6899 	}
  6899 
  6900 
  7014 		break;
  7015 		break;
  7015 	}
  7016 	}
  7016 
  7017 
  7017 	if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_READDIR))
  7018 	if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_READDIR))
  7018 		cachefs_log_readdir(cachep, error, fscp->fs_cfsvfsp,
  7019 		cachefs_log_readdir(cachep, error, fscp->fs_cfsvfsp,
  7019 		&dcp->c_metadata.md_cookie, dcp->c_id.cid_fileno,
  7020 		    &dcp->c_metadata.md_cookie, dcp->c_id.cid_fileno,
  7020 		crgetuid(cr), uiop->uio_loffset, *eofp);
  7021 		    crgetuid(cr), uiop->uio_loffset, *eofp);
  7021 
  7022 
  7022 	if (held) {
  7023 	if (held) {
  7023 		rw_exit(&dcp->c_rwlock);
  7024 		rw_exit(&dcp->c_rwlock);
  7024 		cachefs_cd_release(fscp);
  7025 		cachefs_cd_release(fscp);
  7025 	}
  7026 	}
  7104 	    CFS_ISFS_BACKFS_NFSV4(fscp) ||
  7105 	    CFS_ISFS_BACKFS_NFSV4(fscp) ||
  7105 	    (dcp->c_flags & (CN_NOCACHE | CN_ASYNC_POPULATE)) ||
  7106 	    (dcp->c_flags & (CN_NOCACHE | CN_ASYNC_POPULATE)) ||
  7106 	    ((dcp->c_metadata.md_flags & MD_POPULATED) == 0)) {
  7107 	    ((dcp->c_metadata.md_flags & MD_POPULATED) == 0)) {
  7107 
  7108 
  7108 		if (error && !(dcp->c_flags & CN_NOCACHE) &&
  7109 		if (error && !(dcp->c_flags & CN_NOCACHE) &&
  7109 			!CFS_ISFS_BACKFS_NFSV4(fscp))
  7110 		    !CFS_ISFS_BACKFS_NFSV4(fscp))
  7110 			cachefs_nocache(dcp);
  7111 			cachefs_nocache(dcp);
  7111 
  7112 
  7112 		/* get the back vp */
  7113 		/* get the back vp */
  7113 		if (dcp->c_backvp == NULL) {
  7114 		if (dcp->c_backvp == NULL) {
  7114 			error = cachefs_getbackvp(fscp, dcp);
  7115 			error = cachefs_getbackvp(fscp, dcp);
  7119 		if (fscp->fs_inum_size > 0) {
  7120 		if (fscp->fs_inum_size > 0) {
  7120 			error = cachefs_readback_translate(dcp, uiop, cr, eofp);
  7121 			error = cachefs_readback_translate(dcp, uiop, cr, eofp);
  7121 		} else {
  7122 		} else {
  7122 			/* do the dir read from the back fs */
  7123 			/* do the dir read from the back fs */
  7123 			(void) VOP_RWLOCK(dcp->c_backvp,
  7124 			(void) VOP_RWLOCK(dcp->c_backvp,
  7124 						V_WRITELOCK_FALSE, NULL);
  7125 			    V_WRITELOCK_FALSE, NULL);
  7125 			CFS_DPRINT_BACKFS_NFSV4(fscp,
  7126 			CFS_DPRINT_BACKFS_NFSV4(fscp,
  7126 				("cachefs_readdir (nfsv4): "
  7127 			    ("cachefs_readdir (nfsv4): "
  7127 				"dcp %p, dbackvp %p\n", dcp, dcp->c_backvp));
  7128 			    "dcp %p, dbackvp %p\n", dcp, dcp->c_backvp));
  7128 			error = VOP_READDIR(dcp->c_backvp, uiop, cr, eofp,
  7129 			error = VOP_READDIR(dcp->c_backvp, uiop, cr, eofp,
  7129 			    NULL, 0);
  7130 			    NULL, 0);
  7130 			VOP_RWUNLOCK(dcp->c_backvp, V_WRITELOCK_FALSE, NULL);
  7131 			VOP_RWUNLOCK(dcp->c_backvp, V_WRITELOCK_FALSE, NULL);
  7131 		}
  7132 		}
  7132 
  7133 
  7338 	}
  7339 	}
  7339 
  7340 
  7340 	/* Call backfilesystem if NFSv4 */
  7341 	/* Call backfilesystem if NFSv4 */
  7341 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
  7342 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
  7342 		error = cachefs_getpage_backfs_nfsv4(vp, off, len, protp, pl,
  7343 		error = cachefs_getpage_backfs_nfsv4(vp, off, len, protp, pl,
  7343 						plsz, seg, addr, rw, cr);
  7344 		    plsz, seg, addr, rw, cr);
  7344 		goto out;
  7345 		goto out;
  7345 	}
  7346 	}
  7346 
  7347 
  7347 	/* XXX sam: make this do an async populate? */
  7348 	/* XXX sam: make this do an async populate? */
  7348 	if (pl == NULL) {
  7349 	if (pl == NULL) {
  7368 		 * cachefs_write()
  7369 		 * cachefs_write()
  7369 		 * operation the local file size might not be extended yet.
  7370 		 * operation the local file size might not be extended yet.
  7370 		 * In this case we want to be able to return pages of zeroes.
  7371 		 * In this case we want to be able to return pages of zeroes.
  7371 		 */
  7372 		 */
  7372 		if ((u_offset_t)off + len >
  7373 		if ((u_offset_t)off + len >
  7373 			((cp->c_size + PAGEOFFSET) & (offset_t)PAGEMASK)) {
  7374 		    ((cp->c_size + PAGEOFFSET) & (offset_t)PAGEMASK)) {
  7374 			if (seg != segkmap) {
  7375 			if (seg != segkmap) {
  7375 				error = EFAULT;
  7376 				error = EFAULT;
  7376 				break;
  7377 				break;
  7377 			}
  7378 			}
  7378 		}
  7379 		}
  7478 	mutex_enter(&cp->c_statelock);
  7479 	mutex_enter(&cp->c_statelock);
  7479 	backvp = cp->c_backvp;
  7480 	backvp = cp->c_backvp;
  7480 	mutex_exit(&cp->c_statelock);
  7481 	mutex_exit(&cp->c_statelock);
  7481 
  7482 
  7482 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  7483 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  7483 		("cachefs_getpage_backfs_nfsv4: cnode %p, backvp %p\n",
  7484 	    ("cachefs_getpage_backfs_nfsv4: cnode %p, backvp %p\n",
  7484 		cp, backvp));
  7485 	    cp, backvp));
  7485 	error = VOP_GETPAGE(backvp, off, len, protp, pl, plsz, seg,
  7486 	error = VOP_GETPAGE(backvp, off, len, protp, pl, plsz, seg,
  7486 				    addr, rw, cr, NULL);
  7487 	    addr, rw, cr, NULL);
  7487 
  7488 
  7488 	return (error);
  7489 	return (error);
  7489 }
  7490 }
  7490 
  7491 
  7491 /*
  7492 /*
  7546 				error = cachefs_getbackvp(fscp, cp);
  7547 				error = cachefs_getbackvp(fscp, cp);
  7547 				if (error)
  7548 				if (error)
  7548 					goto out;
  7549 					goto out;
  7549 			}
  7550 			}
  7550 			error = VOP_GETPAGE(cp->c_backvp, off,
  7551 			error = VOP_GETPAGE(cp->c_backvp, off,
  7551 					PAGESIZE, protp, ourpl, PAGESIZE, seg,
  7552 			    PAGESIZE, protp, ourpl, PAGESIZE, seg,
  7552 					addr, S_READ, cr, NULL);
  7553 			    addr, S_READ, cr, NULL);
  7553 			/*
  7554 			/*
  7554 			 * backfs returns EFAULT when we are trying for a
  7555 			 * backfs returns EFAULT when we are trying for a
  7555 			 * page beyond EOF but cachefs has the knowledge that
  7556 			 * page beyond EOF but cachefs has the knowledge that
  7556 			 * it is not beyond EOF be cause cp->c_size is
  7557 			 * it is not beyond EOF be cause cp->c_size is
  7557 			 * greater then the offset requested.
  7558 			 * greater then the offset requested.
  7627 					popsize = PAGESIZE;
  7628 					popsize = PAGESIZE;
  7628 				}
  7629 				}
  7629 			}
  7630 			}
  7630 			/* else XXX assert CN_NOCACHE? */
  7631 			/* else XXX assert CN_NOCACHE? */
  7631 			error = VOP_GETPAGE(cp->c_backvp, (offset_t)off,
  7632 			error = VOP_GETPAGE(cp->c_backvp, (offset_t)off,
  7632 					PAGESIZE, protp, ourpl, popsize,
  7633 			    PAGESIZE, protp, ourpl, popsize,
  7633 					seg, addr, S_READ, cr, NULL);
  7634 			    seg, addr, S_READ, cr, NULL);
  7634 			if (error)
  7635 			if (error)
  7635 				goto out;
  7636 				goto out;
  7636 			fscp->fs_stats.st_misses++;
  7637 			fscp->fs_stats.st_misses++;
  7637 		} else {
  7638 		} else {
  7638 			if (cp->c_flags & CN_POPULATION_PENDING) {
  7639 			if (cp->c_flags & CN_POPULATION_PENDING) {
  7758 			error = cachefs_getbackvp(fscp, cp);
  7759 			error = cachefs_getbackvp(fscp, cp);
  7759 			if (error)
  7760 			if (error)
  7760 				goto out;
  7761 				goto out;
  7761 		}
  7762 		}
  7762 		error = VOP_GETPAGE(cp->c_backvp, (offset_t)off,
  7763 		error = VOP_GETPAGE(cp->c_backvp, (offset_t)off,
  7763 			PAGESIZE, protp, ourpl, PAGESIZE, seg,
  7764 		    PAGESIZE, protp, ourpl, PAGESIZE, seg,
  7764 			addr, S_READ, cr, NULL);
  7765 		    addr, S_READ, cr, NULL);
  7765 		if (error)
  7766 		if (error)
  7766 			goto out;
  7767 			goto out;
  7767 
  7768 
  7768 		if (have_statelock) {
  7769 		if (have_statelock) {
  7769 			mutex_exit(&cp->c_statelock);
  7770 			mutex_exit(&cp->c_statelock);
  7915 	mutex_enter(&cp->c_statelock);
  7916 	mutex_enter(&cp->c_statelock);
  7916 	backvp = cp->c_backvp;
  7917 	backvp = cp->c_backvp;
  7917 	mutex_exit(&cp->c_statelock);
  7918 	mutex_exit(&cp->c_statelock);
  7918 
  7919 
  7919 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  7920 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  7920 		("cachefs_putpage_backfs_nfsv4: cnode %p, backvp %p\n",
  7921 	    ("cachefs_putpage_backfs_nfsv4: cnode %p, backvp %p\n",
  7921 		cp, backvp));
  7922 	    cp, backvp));
  7922 	error = VOP_PUTPAGE(backvp, off, len, flags, cr, NULL);
  7923 	error = VOP_PUTPAGE(backvp, off, len, flags, cr, NULL);
  7923 
  7924 
  7924 	return (error);
  7925 	return (error);
  7925 }
  7926 }
  7926 
  7927 
  8038 		 * Do a range from [off...off + len] looking for pages
  8039 		 * Do a range from [off...off + len] looking for pages
  8039 		 * to deal with.
  8040 		 * to deal with.
  8040 		 */
  8041 		 */
  8041 		eoff = (u_offset_t)off + len;
  8042 		eoff = (u_offset_t)off + len;
  8042 		for (io_off = off; io_off < eoff && io_off < cp->c_size;
  8043 		for (io_off = off; io_off < eoff && io_off < cp->c_size;
  8043 			io_off += io_len) {
  8044 		    io_off += io_len) {
  8044 			/*
  8045 			/*
  8045 			 * If we are not invalidating, synchronously
  8046 			 * If we are not invalidating, synchronously
  8046 			 * freeing or writing pages use the routine
  8047 			 * freeing or writing pages use the routine
  8047 			 * page_lookup_nowait() to prevent reclaiming
  8048 			 * page_lookup_nowait() to prevent reclaiming
  8048 			 * them from the free list.
  8049 			 * them from the free list.
  8049 			 */
  8050 			 */
  8050 			if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0)) {
  8051 			if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0)) {
  8051 				pp = page_lookup(vp, io_off,
  8052 				pp = page_lookup(vp, io_off,
  8052 					(flags & (B_INVAL | B_FREE)) ?
  8053 				    (flags & (B_INVAL | B_FREE)) ?
  8053 					    SE_EXCL : SE_SHARED);
  8054 				    SE_EXCL : SE_SHARED);
  8054 			} else {
  8055 			} else {
  8055 				/* XXX this looks like dead code */
  8056 				/* XXX this looks like dead code */
  8056 				pp = page_lookup_nowait(vp, io_off,
  8057 				pp = page_lookup_nowait(vp, io_off,
  8057 					(flags & B_FREE) ? SE_EXCL : SE_SHARED);
  8058 				    (flags & B_FREE) ? SE_EXCL : SE_SHARED);
  8058 			}
  8059 			}
  8059 
  8060 
  8060 			if (pp == NULL || pvn_getdirty(pp, flags) == 0)
  8061 			if (pp == NULL || pvn_getdirty(pp, flags) == 0)
  8061 				io_len = PAGESIZE;
  8062 				io_len = PAGESIZE;
  8062 			else {
  8063 			else {
  8063 				error = cachefs_push(vp, pp, &io_off,
  8064 				error = cachefs_push(vp, pp, &io_off,
  8064 					&io_len, flags, cr);
  8065 				    &io_len, flags, cr);
  8065 				if (error != 0)
  8066 				if (error != 0)
  8066 					break;
  8067 					break;
  8067 				/*
  8068 				/*
  8068 				 * "io_off" and "io_len" are returned as
  8069 				 * "io_off" and "io_len" are returned as
  8069 				 * the range of pages we actually wrote.
  8070 				 * the range of pages we actually wrote.
  8105 #ifdef CFSDEBUG
  8106 #ifdef CFSDEBUG
  8106 	u_offset_t offx = (u_offset_t)off;
  8107 	u_offset_t offx = (u_offset_t)off;
  8107 
  8108 
  8108 	CFS_DEBUG(CFSDEBUG_VOPS)
  8109 	CFS_DEBUG(CFSDEBUG_VOPS)
  8109 		printf("cachefs_map: ENTER vp %p off %lld len %lu flags %d\n",
  8110 		printf("cachefs_map: ENTER vp %p off %lld len %lu flags %d\n",
  8110 			(void *)vp, offx, len, flags);
  8111 		    (void *)vp, offx, len, flags);
  8111 #endif
  8112 #endif
  8112 	if (getzoneid() != GLOBAL_ZONEID) {
  8113 	if (getzoneid() != GLOBAL_ZONEID) {
  8113 		error = EPERM;
  8114 		error = EPERM;
  8114 		goto out;
  8115 		goto out;
  8115 	}
  8116 	}
  8146 #endif
  8147 #endif
  8147 
  8148 
  8148 	/* call backfilesystem if NFSv4 */
  8149 	/* call backfilesystem if NFSv4 */
  8149 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
  8150 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
  8150 		error = cachefs_map_backfs_nfsv4(vp, off, as, addrp, len, prot,
  8151 		error = cachefs_map_backfs_nfsv4(vp, off, as, addrp, len, prot,
  8151 						maxprot, flags, cr);
  8152 		    maxprot, flags, cr);
  8152 		goto out;
  8153 		goto out;
  8153 	}
  8154 	}
  8154 
  8155 
  8155 	writing = (prot & PROT_WRITE && ((flags & MAP_PRIVATE) == 0));
  8156 	writing = (prot & PROT_WRITE && ((flags & MAP_PRIVATE) == 0));
  8156 
  8157 
  8258 	mutex_enter(&cp->c_statelock);
  8259 	mutex_enter(&cp->c_statelock);
  8259 	backvp = cp->c_backvp;
  8260 	backvp = cp->c_backvp;
  8260 	mutex_exit(&cp->c_statelock);
  8261 	mutex_exit(&cp->c_statelock);
  8261 
  8262 
  8262 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  8263 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  8263 		("cachefs_map_backfs_nfsv4: cnode %p, backvp %p\n",
  8264 	    ("cachefs_map_backfs_nfsv4: cnode %p, backvp %p\n",
  8264 		cp, backvp));
  8265 	    cp, backvp));
  8265 	error = VOP_MAP(backvp, off, as, addrp, len, prot, maxprot, flags, cr,
  8266 	error = VOP_MAP(backvp, off, as, addrp, len, prot, maxprot, flags, cr,
  8266 	    NULL);
  8267 	    NULL);
  8267 
  8268 
  8268 	return (error);
  8269 	return (error);
  8269 }
  8270 }
  8489 			}
  8490 			}
  8490 		}
  8491 		}
  8491 
  8492 
  8492 		/* do lock on the back file */
  8493 		/* do lock on the back file */
  8493 		CFS_DPRINT_BACKFS_NFSV4(fscp,
  8494 		CFS_DPRINT_BACKFS_NFSV4(fscp,
  8494 			("cachefs_frlock (nfsv4): cp %p, backvp %p\n",
  8495 		    ("cachefs_frlock (nfsv4): cp %p, backvp %p\n",
  8495 			cp, backvp));
  8496 		    cp, backvp));
  8496 		error = VOP_FRLOCK(backvp, cmd, bfp, flag, offset, NULL, cr,
  8497 		error = VOP_FRLOCK(backvp, cmd, bfp, flag, offset, NULL, cr,
  8497 		    ct);
  8498 		    ct);
  8498 		VN_RELE(backvp);
  8499 		VN_RELE(backvp);
  8499 		if (CFS_TIMEOUT(fscp, error)) {
  8500 		if (CFS_TIMEOUT(fscp, error)) {
  8500 			connected = 1;
  8501 			connected = 1;
  8551 		return (EINVAL);
  8552 		return (EINVAL);
  8552 
  8553 
  8553 	/* call backfilesystem if NFSv4 */
  8554 	/* call backfilesystem if NFSv4 */
  8554 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
  8555 	if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
  8555 		error = cachefs_space_backfs_nfsv4(vp, cmd, bfp, flag,
  8556 		error = cachefs_space_backfs_nfsv4(vp, cmd, bfp, flag,
  8556 						offset, cr, ct);
  8557 		    offset, cr, ct);
  8557 		goto out;
  8558 		goto out;
  8558 	}
  8559 	}
  8559 
  8560 
  8560 	if ((error = convoff(vp, bfp, 0, offset)) == 0) {
  8561 	if ((error = convoff(vp, bfp, 0, offset)) == 0) {
  8561 		ASSERT(bfp->l_start >= 0);
  8562 		ASSERT(bfp->l_start >= 0);
  8601 	mutex_enter(&cp->c_statelock);
  8602 	mutex_enter(&cp->c_statelock);
  8602 	backvp = cp->c_backvp;
  8603 	backvp = cp->c_backvp;
  8603 	mutex_exit(&cp->c_statelock);
  8604 	mutex_exit(&cp->c_statelock);
  8604 
  8605 
  8605 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  8606 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  8606 		("cachefs_space_backfs_nfsv4: cnode %p, backvp %p\n",
  8607 	    ("cachefs_space_backfs_nfsv4: cnode %p, backvp %p\n",
  8607 		cp, backvp));
  8608 	    cp, backvp));
  8608 	error = VOP_SPACE(backvp, cmd, bfp, flag, offset, cr, ct);
  8609 	error = VOP_SPACE(backvp, cmd, bfp, flag, offset, cr, ct);
  8609 
  8610 
  8610 	return (error);
  8611 	return (error);
  8611 }
  8612 }
  8612 
  8613 
  8655 		goto out;
  8656 		goto out;
  8656 	}
  8657 	}
  8657 
  8658 
  8658 
  8659 
  8659 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  8660 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  8660 		("cachefs_setsecattr (nfsv4): cp %p, backvp %p",
  8661 	    ("cachefs_setsecattr (nfsv4): cp %p, backvp %p",
  8661 		cp, cp->c_backvp));
  8662 	    cp, cp->c_backvp));
  8662 	error = VOP_SETSECATTR(cp->c_backvp, vsec, flag, cr, NULL);
  8663 	error = VOP_SETSECATTR(cp->c_backvp, vsec, flag, cr, NULL);
  8663 	if (error) {
  8664 	if (error) {
  8664 		goto out;
  8665 		goto out;
  8665 	}
  8666 	}
  8666 
  8667 
  8794 	int held = 0;
  8795 	int held = 0;
  8795 	int error = 0;
  8796 	int error = 0;
  8796 
  8797 
  8797 #ifdef CFSDEBUG
  8798 #ifdef CFSDEBUG
  8798 	CFS_DEBUG(CFSDEBUG_VOPS)
  8799 	CFS_DEBUG(CFSDEBUG_VOPS)
  8799 	    printf("cachefs_setsecattr: ENTER vp %p\n", (void *)vp);
  8800 		printf("cachefs_setsecattr: ENTER vp %p\n", (void *)vp);
  8800 #endif
  8801 #endif
  8801 	if (getzoneid() != GLOBAL_ZONEID) {
  8802 	if (getzoneid() != GLOBAL_ZONEID) {
  8802 		error = EPERM;
  8803 		error = EPERM;
  8803 		goto out;
  8804 		goto out;
  8804 	}
  8805 	}
  9055 	mutex_exit(&cp->c_statelock);
  9056 	mutex_exit(&cp->c_statelock);
  9056 	ASSERT((error != 0) || (backvp != NULL));
  9057 	ASSERT((error != 0) || (backvp != NULL));
  9057 
  9058 
  9058 	if (error == 0) {
  9059 	if (error == 0) {
  9059 		CFS_DPRINT_BACKFS_NFSV4(fscp,
  9060 		CFS_DPRINT_BACKFS_NFSV4(fscp,
  9060 			("cachefs_shrlock (nfsv4): cp %p, backvp %p",
  9061 		    ("cachefs_shrlock (nfsv4): cp %p, backvp %p",
  9061 			cp, backvp));
  9062 		    cp, backvp));
  9062 		error = VOP_SHRLOCK(backvp, cmd, shr, flag, cr, ct);
  9063 		error = VOP_SHRLOCK(backvp, cmd, shr, flag, cr, ct);
  9063 	}
  9064 	}
  9064 
  9065 
  9065 out:
  9066 out:
  9066 #ifdef CFSDEBUG
  9067 #ifdef CFSDEBUG
  9106 		error = cachefs_getbackvp(fscp, cp);
  9107 		error = cachefs_getbackvp(fscp, cp);
  9107 	if (error)
  9108 	if (error)
  9108 		goto out;
  9109 		goto out;
  9109 
  9110 
  9110 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  9111 	CFS_DPRINT_BACKFS_NFSV4(fscp,
  9111 		("cachefs_getsecattr (nfsv4): cp %p, backvp %p",
  9112 	    ("cachefs_getsecattr (nfsv4): cp %p, backvp %p",
  9112 		cp, cp->c_backvp));
  9113 	    cp, cp->c_backvp));
  9113 	error = VOP_GETSECATTR(cp->c_backvp, vsec, flag, cr, NULL);
  9114 	error = VOP_GETSECATTR(cp->c_backvp, vsec, flag, cr, NULL);
  9114 	if (error)
  9115 	if (error)
  9115 		goto out;
  9116 		goto out;
  9116 
  9117 
  9117 	if (((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0) &&
  9118 	if (((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0) &&
  9249 		for (i = 0; i < vsecp->vsa_aclcnt; i++) {
  9250 		for (i = 0; i < vsecp->vsa_aclcnt; i++) {
  9250 			aclp = ((aclent_t *)vsecp->vsa_aclentp) + i;
  9251 			aclp = ((aclent_t *)vsecp->vsa_aclentp) + i;
  9251 			switch (aclp->a_type) {
  9252 			switch (aclp->a_type) {
  9252 			case CLASS_OBJ:
  9253 			case CLASS_OBJ:
  9253 				cp->c_metadata.md_aclclass =
  9254 				cp->c_metadata.md_aclclass =
  9254 			    aclp->a_perm;
  9255 				    aclp->a_perm;
  9255 				/*FALLTHROUGH*/
  9256 				/*FALLTHROUGH*/
  9256 			case USER_OBJ:
  9257 			case USER_OBJ:
  9257 			case GROUP_OBJ:
  9258 			case GROUP_OBJ:
  9258 			case OTHER_OBJ:
  9259 			case OTHER_OBJ:
  9259 				aclp->a_perm = 06;
  9260 				aclp->a_perm = 06;
  9403 		va.va_type = VDIR;
  9404 		va.va_type = VDIR;
  9404 		va.va_mask = AT_TYPE | AT_MODE |
  9405 		va.va_mask = AT_TYPE | AT_MODE |
  9405 		    AT_UID | AT_GID;
  9406 		    AT_UID | AT_GID;
  9406 		error =
  9407 		error =
  9407 		    VOP_MKDIR(cp->c_filegrp->fg_dirvp,
  9408 		    VOP_MKDIR(cp->c_filegrp->fg_dirvp,
  9408 			name, &va, &cp->c_acldirvp, kcred, NULL, 0, NULL);
  9409 		    name, &va, &cp->c_acldirvp, kcred, NULL, 0, NULL);
  9409 		if (error != 0)
  9410 		if (error != 0)
  9410 			goto out;
  9411 			goto out;
  9411 	}
  9412 	}
  9412 
  9413 
  9413 	ASSERT(cp->c_acldirvp != NULL);
  9414 	ASSERT(cp->c_acldirvp != NULL);
  9932 			 */
  9933 			 */
  9933 
  9934 
  9934 			owner = aclp->a_id;
  9935 			owner = aclp->a_id;
  9935 			if (crgetuid(cr) == owner) {
  9936 			if (crgetuid(cr) == owner) {
  9936 				error = ACL_MODE_CHECK(mode, aclp->a_perm << 6,
  9937 				error = ACL_MODE_CHECK(mode, aclp->a_perm << 6,
  9937 							cr, cp);
  9938 				    cr, cp);
  9938 				goto out;
  9939 				goto out;
  9939 			}
  9940 			}
  9940 			break;
  9941 			break;
  9941 
  9942 
  9942 		case CLASS_OBJ:
  9943 		case CLASS_OBJ:
  9951 		aclp = ((aclent_t *)vsec.vsa_aclentp) + i;
  9952 		aclp = ((aclent_t *)vsec.vsa_aclentp) + i;
  9952 		switch (aclp->a_type) {
  9953 		switch (aclp->a_type) {
  9953 		case USER:
  9954 		case USER:
  9954 			if (crgetuid(cr) == aclp->a_id) {
  9955 			if (crgetuid(cr) == aclp->a_id) {
  9955 				error = ACL_MODE_CHECK(mode,
  9956 				error = ACL_MODE_CHECK(mode,
  9956 					(aclp->a_perm & mask) << 6, cr, cp);
  9957 				    (aclp->a_perm & mask) << 6, cr, cp);
  9957 				goto out;
  9958 				goto out;
  9958 			}
  9959 			}
  9959 			break;
  9960 			break;
  9960 
  9961 
  9961 		case GROUP_OBJ:
  9962 		case GROUP_OBJ:
  9962 			if (groupmember(aclp->a_id, cr)) {
  9963 			if (groupmember(aclp->a_id, cr)) {
  9963 				++ngroup;
  9964 				++ngroup;
  9964 				gperm |= aclp->a_perm;
  9965 				gperm |= aclp->a_perm;
  9965 				if (! ismask) {
  9966 				if (! ismask) {
  9966 					error = ACL_MODE_CHECK(mode,
  9967 					error = ACL_MODE_CHECK(mode,
  9967 							aclp->a_perm << 6,
  9968 					    aclp->a_perm << 6,
  9968 							cr, cp);
  9969 					    cr, cp);
  9969 					goto out;
  9970 					goto out;
  9970 				}
  9971 				}
  9971 			}
  9972 			}
  9972 			break;
  9973 			break;
  9973 
  9974 
  9979 			break;
  9980 			break;
  9980 
  9981 
  9981 		case OTHER_OBJ:
  9982 		case OTHER_OBJ:
  9982 			if (ngroup == 0) {
  9983 			if (ngroup == 0) {
  9983 				error = ACL_MODE_CHECK(mode, aclp->a_perm << 6,
  9984 				error = ACL_MODE_CHECK(mode, aclp->a_perm << 6,
  9984 						cr, cp);
  9985 				    cr, cp);
  9985 				goto out;
  9986 				goto out;
  9986 			}
  9987 			}
  9987 			break;
  9988 			break;
  9988 
  9989 
  9989 		default:
  9990 		default: