2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * vnodeops structure and Digital Unix specific ops and support routines.
14 #include <afsconfig.h>
15 #include "afs/param.h"
21 #include "afs/sysincludes.h" /* Standard vendor system headers */
22 #include "afsincludes.h" /* Afs-based standard headers */
23 #include "afs/afs_stats.h" /* statistics */
24 #include <vm/vm_mmap.h>
25 #include <vm/vm_ubc.h>
26 #include "afs/afs_cbqueue.h"
27 #include "afs/nfsclient.h"
28 #include "afs/afs_osidnlc.h"
31 extern int afs_lookup(), afs_create(), afs_noop(), afs_open(), afs_close();
32 extern int afs_access(), afs_getattr(), afs_setattr(), afs_badop();
33 extern int afs_fsync(), afs_seek(), afs_remove(), afs_link(), afs_rename();
34 extern int afs_mkdir(), afs_rmdir(), afs_symlink(), afs_readdir();
35 extern int afs_readlink(), afs_lockctl();
36 extern int vn_pathconf_default(), seltrue();
38 int mp_afs_lookup(), mp_afs_create(), mp_afs_open();
39 int mp_afs_access(), mp_afs_getattr(), mp_afs_setattr(), mp_afs_ubcrdwr();
40 int mp_afs_ubcrdwr(), mp_afs_mmap();
41 int mp_afs_fsync(), mp_afs_seek(), mp_afs_remove(), mp_afs_link();
42 int mp_afs_rename(), mp_afs_mkdir(), mp_afs_rmdir(), mp_afs_symlink();
43 int mp_afs_readdir(), mp_afs_readlink(), mp_afs_abortop(), mp_afs_inactive();
44 int mp_afs_reclaim(), mp_afs_bmap(), mp_afs_strategy(), mp_afs_print();
45 int mp_afs_page_read(), mp_afs_page_write(), mp_afs_swap(), mp_afs_bread();
46 int mp_afs_brelse(), mp_afs_lockctl(), mp_afs_syncdata(), mp_afs_close();
51 struct vnodeops Afs_vnodeops = {
54 afs_noop, /* vn_mknod */
62 mp_afs_ioctl, /* vn_ioctl */
63 seltrue, /* vn_select */
89 afs_noop, /* unLock */
90 afs_noop, /* get ext attrs */
91 afs_noop, /* set ext attrs */
92 afs_noop, /* del ext attrs */
95 struct vnodeops *afs_ops = &Afs_vnodeops;
97 /* vnode file operations, and our own */
99 extern int vn_write();
100 extern int vn_ioctl();
101 extern int vn_select();
102 extern int afs_closex();
104 struct fileops afs_fileops = {
112 mp_afs_lookup(adp, ndp)
114 struct nameidata *ndp;
117 char aname[MAXNAMLEN + 1]; /* XXX */
118 struct vcache **avcp = (struct vcache **)&(ndp->ni_vp);
119 struct ucred *acred = ndp->ni_cred;
120 int wantparent = ndp->ni_nameiop & WANTPARENT;
121 int opflag = ndp->ni_nameiop & OPFLAG;
123 memcpy(aname, ndp->ni_ptr, ndp->ni_namelen);
124 aname[ndp->ni_namelen] = '\0';
125 code = afs_lookup(adp, aname, avcp, acred, opflag, wantparent);
130 mp_afs_create(ndp, attrs)
131 struct nameidata *ndp;
135 register struct vcache *adp = VTOAFS(ndp->ni_dvp);
136 char *aname = ndp->ni_dent.d_name;
137 enum vcexcl aexcl = NONEXCL; /* XXX - create called properly */
138 int amode = 0; /* XXX - checked in higher level */
139 struct vcache **avcp = (struct vcache **)&(ndp->ni_vp);
140 struct ucred *acred = ndp->ni_cred;
142 code = afs_create(adp, aname, attrs, aexcl,
150 mp_afs_open(avcp, aflags, acred)
151 struct vcache **avcp;
153 struct AFS_UCRED *acred;
157 code = afs_open(avcp, aflags, acred);
162 mp_afs_access(avc, amode, acred)
165 struct AFS_UCRED *acred;
169 code = afs_access(avc, amode, acred);
174 mp_afs_close(avc, flags, cred)
181 code = afs_close(avc, flags, cred);
186 mp_afs_getattr(avc, attrs, acred)
189 struct AFS_UCRED *acred;
193 code = afs_getattr(avc, attrs, acred);
198 mp_afs_setattr(avc, attrs, acred)
201 struct AFS_UCRED *acred;
205 code = afs_setattr(avc, attrs, acred);
210 mp_afs_fsync(avc, fflags, acred, waitfor)
213 struct AFS_UCRED *acred;
218 code = afs_fsync(avc, fflags, acred, waitfor);
224 struct nameidata *ndp;
227 register struct vcache *adp = VTOAFS(ndp->ni_dvp);
228 char *aname = ndp->ni_dent.d_name;
229 struct ucred *acred = ndp->ni_cred;
231 code = afs_remove(adp, aname, acred);
237 mp_afs_link(avc, ndp)
239 struct nameidata *ndp;
242 struct vcache *adp = VTOAFS(ndp->ni_dvp);
243 char *aname = ndp->ni_dent.d_name;
244 struct ucred *acred = ndp->ni_cred;
246 code = afs_link(avc, adp, aname, acred);
252 mp_afs_rename(fndp, tndp)
253 struct nameidata *fndp, *tndp;
256 struct vcache *aodp = VTOAFS(fndp->ni_dvp);
257 char *aname1 = fndp->ni_dent.d_name;
258 struct vcache *andp = VTOAFS(tndp->ni_dvp);
259 char *aname2 = tndp->ni_dent.d_name;
260 struct ucred *acred = tndp->ni_cred;
262 code = afs_rename(aodp, aname1, andp, aname2, acred);
263 AFS_RELE(tndp->ni_dvp);
264 if (tndp->ni_vp != NULL) {
265 AFS_RELE(tndp->ni_vp);
267 AFS_RELE(fndp->ni_dvp);
268 AFS_RELE(fndp->ni_vp);
273 mp_afs_mkdir(ndp, attrs)
274 struct nameidata *ndp;
278 register struct vcache *adp = VTOAFS(ndp->ni_dvp);
279 char *aname = ndp->ni_dent.d_name;
280 register struct vcache **avcp = (struct vcache **)&(ndp->ni_vp);
281 struct ucred *acred = ndp->ni_cred;
283 code = afs_mkdir(adp, aname, attrs, avcp, acred);
290 struct nameidata *ndp;
293 register struct vcache *adp = VTOAFS(ndp->ni_dvp);
294 char *aname = ndp->ni_dent.d_name;
295 struct ucred *acred = ndp->ni_cred;
297 code = afs_rmdir(adp, aname, acred);
299 afs_PutVCache(ndp->ni_vp);
304 mp_afs_symlink(ndp, attrs, atargetName)
305 struct nameidata *ndp;
307 register char *atargetName;
310 register struct vcache *adp = VTOAFS(ndp->ni_dvp);
311 char *aname = ndp->ni_dent.d_name;
312 struct ucred *acred = ndp->ni_cred;
314 code = afs_symlink(adp, aname, attrs, atargetName, acred);
315 AFS_RELE(ndp->ni_dvp);
320 mp_afs_readdir(avc, auio, acred, eofp)
323 struct AFS_UCRED *acred;
328 code = afs_readdir(avc, auio, acred, eofp);
333 mp_afs_readlink(avc, auio, acred)
336 struct AFS_UCRED *acred;
340 code = afs_readlink(avc, auio, acred);
345 mp_afs_lockctl(avc, af, flag, acred, clid, offset)
348 struct AFS_UCRED *acred;
355 code = afs_lockctl(avc, af, flag, acred, clid, offset);
365 code = afs_closex(afd);
370 mp_afs_seek(avc, oldoff, newoff, cred)
372 off_t oldoff, newoff;
382 struct nameidata *ndp;
387 mp_afs_inactive(avc, acred)
388 register struct vcache *avc;
389 struct AFS_UCRED *acred;
392 afs_InactiveVCache(avc, acred);
409 mp_afs_page_read(avc, uio, acred)
415 struct vrequest treq;
418 error = afs_rdwr(avc, uio, UIO_READ, 0, acred);
419 afs_Trace3(afs_iclSetp, CM_TRACE_PAGE_READ, ICL_TYPE_POINTER, avc,
420 ICL_TYPE_INT32, error, ICL_TYPE_INT32, avc->states);
423 } else if ((avc->states & CWired) == 0) {
424 afs_InitReq(&treq, acred);
425 ObtainWriteLock(&avc->lock, 161);
426 afs_Wire(avc, &treq);
427 ReleaseWriteLock(&avc->lock);
434 mp_afs_page_write(avc, uio, acred, pager, offset)
438 memory_object_t pager;
444 error = afs_rdwr(avc, uio, UIO_WRITE, 0, acred);
445 afs_Trace3(afs_iclSetp, CM_TRACE_PAGE_WRITE, ICL_TYPE_POINTER, avc,
446 ICL_TYPE_INT32, error, ICL_TYPE_INT32, avc->states);
456 mp_afs_ubcrdwr(avc, uio, ioflag, cred)
462 register afs_int32 code;
464 afs_int32 fileBase, size, cnt = 0;
466 register afs_int32 tsize;
467 register afs_int32 pageOffset;
469 struct vrequest treq;
470 int rw = uio->uio_rw;
474 afs_int32 save_resid;
480 afs_InitReq(&treq, cred);
481 if (AFS_NFSXLATORREQ(cred) && rw == UIO_READ) {
483 (avc, PRSFS_READ, &treq,
484 CHECK_MODE_BITS | CMB_ALLOW_EXEC_AS_READ)) {
489 afs_Trace4(afs_iclSetp, CM_TRACE_VMRW, ICL_TYPE_POINTER, avc,
490 ICL_TYPE_INT32, (rw == UIO_WRITE ? 1 : 0), ICL_TYPE_LONG,
491 uio->uio_offset, ICL_TYPE_LONG, uio->uio_resid);
492 code = afs_VerifyVCache(avc, &treq);
494 code = afs_CheckCode(code, &treq, 35);
498 if (vType(avc) != VREG) {
500 return EISDIR; /* can't read or write other things */
502 afs_BozonLock(&avc->pvnLock, avc);
503 osi_FlushPages(avc, cred); /* hold bozon lock, but not basic vnode lock */
504 ObtainWriteLock(&avc->lock, 162);
505 /* adjust parameters when appending files */
506 if ((ioflag & IO_APPEND) && uio->uio_rw == UIO_WRITE)
507 uio->uio_offset = avc->m.Length; /* write at EOF position */
508 if (uio->uio_rw == UIO_WRITE) {
509 avc->states |= CDirty;
513 * before starting any I/O, we must ensure that the file is big enough
514 * to hold the results (since afs_putpage will be called to force
517 size = uio->afsio_resid + uio->afsio_offset; /* new file size */
518 if (size > avc->m.Length)
519 avc->m.Length = size; /* file grew */
520 avc->m.Date = osi_Time(); /* Set file date (for ranlib) */
521 if (uio->afsio_resid > PAGE_SIZE)
522 cnt = uio->afsio_resid / PAGE_SIZE;
523 save_resid = uio->afsio_resid;
528 * compute the amount of data to move into this block,
529 * based on uio->afsio_resid.
531 size = uio->afsio_resid; /* transfer size */
532 fileBase = uio->afsio_offset; /* start file position */
533 pageBase = fileBase & ~(PAGE_SIZE - 1); /* file position of the page */
534 pageOffset = fileBase & (PAGE_SIZE - 1); /* start offset within page */
535 tsize = PAGE_SIZE - pageOffset; /* amount left in this page */
537 * we'll read tsize bytes,
538 * but first must make sure tsize isn't too big
541 tsize = size; /* don't read past end of request */
542 eof = 0; /* flag telling us if we hit the EOF on the read */
543 if (uio->uio_rw == UIO_READ) { /* we're doing a read operation */
544 /* don't read past EOF */
545 if (tsize + fileBase > avc->m.Length) {
546 tsize = avc->m.Length - fileBase;
547 eof = 1; /* we did hit the EOF */
549 tsize = 0; /* better safe than sorry */
553 break; /* nothing to transfer, we're done */
555 /* Purge dirty chunks of file if there are too many dirty chunks.
556 * Inside the write loop, we only do this at a chunk boundary.
557 * Clean up partial chunk if necessary at end of loop.
559 if (uio->uio_rw == UIO_WRITE && counter > 0
560 && AFS_CHUNKOFFSET(fileBase) == 0) {
561 code = afs_DoPartialWrite(avc, &treq);
562 avc->states |= CDirty;
570 ReleaseWriteLock(&avc->lock);
574 ubc_lookup(AFSTOV(avc)->v_object, pageBase, PAGE_SIZE, PAGE_SIZE,
575 &page, &flags, NULL);
578 ubc_lookup(AFSTOV(avc)->v_object, pageBase, PAGE_SIZE, PAGE_SIZE,
582 ObtainWriteLock(&avc->lock, 163);
587 if (flags & B_NOCACHE) {
589 * No page found. We should not read the page in if
590 * 1. the write starts on a page edge (ie, pageoffset == 0)
592 * 1. we will fill the page (ie, size == PAGESIZE), or
593 * 2. we are writing past eof
595 if ((uio->uio_rw == UIO_WRITE)
598 && (size == PAGE_SIZE || fileBase >= avc->m.Length)))) {
599 struct vnode *vp = AFSTOV(avc);
600 /* we're doing a write operation past eof; no need to read it */
603 ubc_page_zero(page, 0, PAGE_SIZE);
604 ubc_page_release(page, B_DONE);
607 /* page wasn't cached, read it in. */
611 bp = ubc_bufalloc(page, 1, PAGE_SIZE, 1, B_READ);
614 bp->b_vp = AFSTOV(avc);
615 bp->b_blkno = btodb(pageBase);
616 ReleaseWriteLock(&avc->lock);
617 code = afs_ustrategy(bp, cred); /* do the I/O */
618 ObtainWriteLock(&avc->lock, 164);
624 ubc_page_release(page, 0);
632 data = ubc_load(page, pageOffset, page_size);
634 ReleaseWriteLock(&avc->lock); /* uiomove may page fault */
636 code = uiomove(data + pageOffset, tsize, uio);
637 ubc_unload(page, pageOffset, page_size);
638 if (uio->uio_rw == UIO_WRITE) {
641 /* Mark the page dirty and release it to avoid a deadlock
642 * in ubc_dirty_kluster when more than one process writes
643 * this page at the same time. */
644 toffset = page->pg_offset;
646 ubc_page_release(page, flags);
653 /* We released the page, so we can get a null page
654 * list if another thread calls the strategy routine.
656 pl = ubc_dirty_kluster(AFSTOV(avc)->v_object, NULL, toffset,
657 0, B_WANTED, FALSE, &kpcnt);
659 bp = ubc_bufalloc(pl, 1, PAGE_SIZE, 1, B_WRITE);
661 bp->b_vp = AFSTOV(avc);
662 bp->b_blkno = btodb(pageBase);
664 code = afs_ustrategy(bp, cred); /* do the I/O */
669 ObtainWriteLock(&avc->lock, 415);
675 ubc_page_release(page, flags);
678 ObtainWriteLock(&avc->lock, 165);
680 * If reading at a chunk boundary, start prefetch of next chunk.
682 if (uio->uio_rw == UIO_READ
683 && (counter == 0 || AFS_CHUNKOFFSET(fileBase) == 0)) {
684 tdc = afs_FindDCache(avc, fileBase);
686 if (!(tdc->mflags & DFNextStarted))
687 afs_PrefetchChunk(avc, tdc, cred, &treq);
696 afs_FakeClose(avc, cred);
697 if (uio->uio_rw == UIO_WRITE && code == 0 && (avc->states & CDirty)) {
698 code = afs_DoPartialWrite(avc, &treq);
700 ReleaseWriteLock(&avc->lock);
701 afs_BozonUnlock(&avc->pvnLock, avc);
702 if (DO_FLUSH || (!newpage && (cnt < 10))) {
704 ubc_flush_dirty(AFSTOV(avc)->v_object, flags);
708 ObtainSharedLock(&avc->lock, 409);
711 code = avc->vc_error;
714 /* This is required since we may still have dirty pages after the write.
715 * I could just let close do the right thing, but stat's before the close
716 * return the wrong length.
718 if (code == EDQUOT || code == ENOSPC) {
719 uio->uio_resid = save_resid;
720 UpgradeSToWLock(&avc->lock, 410);
721 osi_ReleaseVM(avc, cred);
722 ConvertWToSLock(&avc->lock);
724 ReleaseSharedLock(&avc->lock);
726 if (!code && (ioflag & IO_SYNC) && (uio->uio_rw == UIO_WRITE)
727 && !AFS_NFSXLATORREQ(cred)) {
728 code = afs_fsync(avc, 0, cred, 0);
731 code = afs_CheckCode(code, &treq, 36);
737 mp_afs_ioctl(struct vnode *vp, int com, caddr_t data, int fflag,
738 struct ucred *cred, int *retval)
744 * Now for some bad news. Since we artificially hold on to vnodes by doing
745 * and extra VNHOLD in afs_NewVCache(), there is no way for us to know
746 * when we need to flush the pages when a program exits. Particularly
747 * if it closes the file after mapping it R/W.
751 mp_afs_mmap(avc, offset, map, addrp, len, prot, maxprot, flags, cred)
752 register struct vcache *avc;
762 struct vp_mmap_args args;
763 register struct vp_mmap_args *ap = &args;
764 struct vnode *vp = AFSTOV(avc);
766 struct vrequest treq;
768 extern kern_return_t u_vp_create();
772 afs_InitReq(&treq, cred);
773 code = afs_VerifyVCache(avc, &treq);
775 code = afs_CheckCode(code, &treq, 37);
779 afs_BozonLock(&avc->pvnLock, avc);
780 osi_FlushPages(avc, cred); /* ensure old pages are gone */
781 afs_BozonUnlock(&avc->pvnLock, avc);
782 ObtainWriteLock(&avc->lock, 166);
783 avc->states |= CMAPPED;
784 ReleaseWriteLock(&avc->lock);
785 ap->a_offset = offset;
788 ap->a_prot = prot, ap->a_maxprot = maxprot;
791 code = u_vp_create(map, vp->v_object, (vm_offset_t) ap);
793 code = afs_CheckCode(code, &treq, 38);
800 mp_afs_getpage(vop, offset, len, protp, pl, plsz,
814 struct vm_policy *policy;
822 register afs_int32 code;
823 struct vrequest treq;
825 int i, pages = (len + PAGE_SIZE - 1) >> page_shift;
829 struct vcache *avc = VTOAFS(vop->vu_vp);
831 /* first, obtain the proper lock for the VM system */
834 afs_InitReq(&treq, cred);
835 code = afs_VerifyVCache(avc, &treq);
838 code = afs_CheckCode(code, &treq, 39); /* failed to get it */
843 /* clean all dirty pages for this vnode */
845 ubc_flush_dirty(vop, 0);
848 afs_BozonLock(&avc->pvnLock, avc);
849 ObtainWriteLock(&avc->lock, 167);
850 afs_Trace4(afs_iclSetp, CM_TRACE_PAGEIN, ICL_TYPE_POINTER, avc,
851 ICL_TYPE_LONG, offset, ICL_TYPE_LONG, len, ICL_TYPE_INT32,
853 for (i = 0; i < pages; i++) {
855 off = offset + PAGE_SIZE * i;
859 ReleaseWriteLock(&avc->lock);
863 ubc_lookup(AFSTOV(avc)->v_object, off, PAGE_SIZE, PAGE_SIZE,
864 pagep, &flags, NULL);
867 ubc_lookup(AFSTOV(avc)->v_object, off, PAGE_SIZE, PAGE_SIZE,
871 ObtainWriteLock(&avc->lock, 168);
875 if (flags & B_NOCACHE) { /* if (page) */
876 if ((rw & B_WRITE) && (offset + len >= avc->m.Length)) {
877 struct vnode *vp = AFSTOV(avc);
878 /* we're doing a write operation past eof; no need to read it */
880 ubc_page_zero(*pagep, 0, PAGE_SIZE);
881 ubc_page_release(*pagep, B_DONE);
884 /* page wasn't cached, read it in. */
888 bp = ubc_bufalloc(*pagep, 1, PAGE_SIZE, 1, B_READ);
891 bp->b_vp = AFSTOV(avc);
892 bp->b_blkno = btodb(off);
893 ReleaseWriteLock(&avc->lock);
894 code = afs_ustrategy(bp, cred); /* do the I/O */
895 ObtainWriteLock(&avc->lock, 169);
901 ubc_page_release(pl[i], 0);
907 if ((rw & B_READ) == 0) {
910 ubc_page_dirty(pl[i], 0);
912 ubc_page_dirty(pl[i]);
916 if (protp && (flags & B_DIRTY) == 0) {
917 protp[i] = VM_PROT_WRITE;
922 pl[i] = VM_PAGE_NULL;
923 ReleaseWriteLock(&avc->lock);
924 afs_BozonUnlock(&avc->pvnLock, avc);
925 afs_Trace3(afs_iclSetp, CM_TRACE_PAGEINDONE, ICL_TYPE_INT32, code,
926 ICL_TYPE_POINTER, *pagep, ICL_TYPE_INT32, flags);
927 code = afs_CheckCode(code, &treq, 40);
934 mp_afs_putpage(vop, pl, pcnt, flags, cred)
941 register afs_int32 code = 0;
942 struct vnode *vp = vop->vu_vp;
943 struct vcache *avc = VTOAFS(vp);
947 afs_Trace4(afs_iclSetp, CM_TRACE_PAGEOUT, ICL_TYPE_POINTER, avc,
948 ICL_TYPE_INT32, pcnt, ICL_TYPE_INT32, vp->v_flag,
949 ICL_TYPE_INT32, flags);
953 if (vp->v_flag & VXLOCK) {
955 for (i = 0; i < pcnt; i++) {
956 ubc_page_release(pl[i], B_DONE | B_DIRTY);
957 pl[i] = VM_PAGE_NULL;
966 /* first, obtain the proper lock for the VM system */
967 afs_BozonLock(&avc->pvnLock, avc);
968 ObtainWriteLock(&avc->lock, 170);
969 for (i = 0; i < pcnt; i++) {
970 vm_page_t page = pl[i];
975 bp = ubc_bufalloc(page, 1, PAGE_SIZE, 1, B_WRITE);
978 bp->b_vp = AFSTOV(avc);
979 bp->b_blkno = btodb(page->pg_offset);
980 ReleaseWriteLock(&avc->lock);
981 code = afs_ustrategy(bp, cred); /* do the I/O */
982 ObtainWriteLock(&avc->lock, 171);
989 pl[i] = VM_PAGE_NULL;
993 ReleaseWriteLock(&avc->lock);
994 afs_BozonUnlock(&avc->pvnLock, avc);
995 afs_Trace2(afs_iclSetp, CM_TRACE_PAGEOUTDONE, ICL_TYPE_INT32, code,
996 ICL_TYPE_INT32, avc->m.Length);
1003 mp_afs_swap(avc, swapop, argp)
1005 vp_swap_op_t swapop;
1012 mp_afs_syncdata(avc, flag, offset, length, cred)
1019 /* NFS V3 makes this call, ignore it. We'll sync the data in afs_fsync. */
1020 if (AFS_NFSXLATORREQ(cred))
1026 /* a freelist of one */
1027 struct buf *afs_bread_freebp = 0;
1030 * Only rfs_read calls this, and it only looks at bp->b_un.b_addr.
1031 * Thus we can use fake bufs (ie not from the real buffer pool).
1033 mp_afs_bread(vp, lbn, bpp, cred)
1039 int offset, fsbsize, error;
1045 AFS_STATCNT(afs_bread);
1046 fsbsize = vp->v_vfsp->vfs_bsize;
1047 offset = lbn * fsbsize;
1048 if (afs_bread_freebp) {
1049 bp = afs_bread_freebp;
1050 afs_bread_freebp = 0;
1052 bp = (struct buf *)AFS_KALLOC(sizeof(*bp));
1053 bp->b_un.b_addr = (caddr_t) AFS_KALLOC(fsbsize);
1056 iov.iov_base = bp->b_un.b_addr;
1057 iov.iov_len = fsbsize;
1058 uio.afsio_iov = &iov;
1059 uio.afsio_iovcnt = 1;
1060 uio.afsio_seg = AFS_UIOSYS;
1061 uio.afsio_offset = offset;
1062 uio.afsio_resid = fsbsize;
1064 error = afs_read(VTOAFS(vp), &uio, cred, lbn, bpp, 0);
1066 afs_bread_freebp = bp;
1071 afs_bread_freebp = bp;
1073 *(struct buf **)&bp->b_vp = bp; /* mark as fake */
1081 mp_afs_brelse(vp, bp)
1086 AFS_STATCNT(afs_brelse);
1087 if ((struct buf *)bp->b_vp != bp) { /* not fake */
1089 } else if (afs_bread_freebp) {
1090 AFS_KFREE(bp->b_un.b_addr, vp->v_vfsp->vfs_bsize);
1091 AFS_KFREE(bp, sizeof(*bp));
1093 afs_bread_freebp = bp;
1099 mp_afs_bmap(avc, abn, anvp, anbn)
1100 register struct vcache *avc;
1101 afs_int32 abn, *anbn;
1102 struct vcache **anvp;
1105 AFS_STATCNT(afs_bmap);
1109 *anbn = abn * (8192 / DEV_BSIZE); /* in 512 byte units */
1116 mp_afs_strategy(abp)
1117 register struct buf *abp;
1119 register afs_int32 code;
1122 AFS_STATCNT(afs_strategy);
1123 code = afs_osi_MapStrategy(afs_ustrategy, abp);
1129 mp_afs_refer(vm_ubc_object_t vop)
1135 mp_afs_release(vm_ubc_object_t vop)
1141 mp_afs_write_check(vm_ubc_object_t vop, vm_page_t pp)
1146 #ifdef AFS_DUX50_ENV
1148 mp_afs_objtovp(vm_ubc_object_t vop, struct vnode **vp)
1155 mp_afs_setpgstamp(vm_page_t pp, unsigned int tick)
1157 pp->pg_stamp = tick;
1163 struct vfs_ubcops afs_ubcops = {
1164 mp_afs_refer, /* refer vnode */
1165 mp_afs_release, /* release vnode */
1166 mp_afs_getpage, /* get page */
1167 mp_afs_putpage, /* put page */
1168 mp_afs_write_check, /* check writablity */
1169 #ifdef AFS_DUX50_ENV
1170 mp_afs_objtovp, /* get vnode pointer */
1171 mp_afs_setpgstamp /* set page stamp */
1177 * Cover function for lookup name using OSF equivalent, namei()
1179 * Note, the result vnode (ni_vp) in the namei data structure is remains
1180 * locked after return.
1182 lookupname(namep, seg, follow, dvpp, cvpp)
1183 char *namep; /* path name */
1184 int seg; /* address space containing name */
1185 int follow; /* follow symbolic links */
1186 struct vnode **dvpp; /* result, containing parent vnode */
1187 struct vnode **cvpp; /* result, containing final component vnode */
1189 /* Should I use free-bee in u-area? */
1190 struct nameidata *ndp = &u.u_nd;
1193 ndp->ni_nameiop = ((follow) ? (LOOKUP | FOLLOW) : (LOOKUP));
1194 ndp->ni_segflg = seg;
1195 ndp->ni_dirp = namep;
1198 *dvpp = ndp->ni_dvp;