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); |
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) { |
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 |
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 |
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) { |
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 |
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 } |
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 |
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) { |
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 |
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) && |
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); |
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 |