if (len <= PAGESIZE)
code =
- afs_GetOnePage(vp,
-#if !defined(AFS_SUN56_ENV)
- (u_int)
-#endif
- off, len, protp, pl, plsz, seg, addr, rw, acred);
+ afs_GetOnePage(vp, off, len, protp, pl, plsz, seg, addr, rw, acred);
else {
+ struct multiPage_range range;
struct vcache *vcp = VTOAFS(vp);
+
+ /* We've been asked to get more than one page. We must return all
+ * requested pages at once, all of them locked, which means all of
+ * these dcache entries cannot be kicked out of the cache before we
+ * return (since their pages cannot be invalidated).
+ *
+ * afs_GetOnePage will be called multiple times by pvn_getpages in
+ * order to get all of the requested pages. One of the later
+ * afs_GetOnePage calls may need to evict some cache entries in order
+ * to perform its read. If we try to kick out one of the entries an
+ * earlier afs_GetOnePage call used, we will deadlock since we have
+ * the page locked. So, to tell afs_GetDownD that it should skip over
+ * any entries we've read in due to this afs_getpage call, record the
+ * offset and length in avc->multiPage.
+ *
+ * Ideally we would just set something in each dcache as we get it,
+ * but that is rather difficult, since pvn_getpages doesn't let us
+ * retain any information between calls to afs_GetOnePage. So instead
+ * just record the offset and length, and let afs_GetDownD calculate
+ * which dcache entries should be skipped. */
+
+ range.off = off;
+ range.len = len;
+
ObtainWriteLock(&vcp->vlock, 548);
- vcp->multiPage++;
+ QAdd(&vcp->multiPage, &range.q);
ReleaseWriteLock(&vcp->vlock);
- afs_BozonLock(&vcp->pvnLock, vcp);
code =
- pvn_getpages(afs_GetOnePage, vp,
-#if !defined(AFS_SUN56_ENV)
- (u_int)
-#endif
- off, len, protp, pl, plsz, seg, addr, rw, acred);
- afs_BozonUnlock(&vcp->pvnLock, vcp);
+ pvn_getpages(afs_GetOnePage, vp, off, len, protp, pl, plsz, seg, addr, rw, acred);
ObtainWriteLock(&vcp->vlock, 549);
- vcp->multiPage--;
+ QRemove(&range.q);
ReleaseWriteLock(&vcp->vlock);
}
AFS_GUNLOCK();
/* Return all the pages from [off..off+len) in file */
int
-#if defined(AFS_SUN56_ENV)
afs_GetOnePage(struct vnode *vp, u_offset_t off, u_int alen, u_int *protp,
struct page *pl[], u_int plsz, struct seg *seg, caddr_t addr,
enum seg_rw rw, afs_ucred_t *acred)
-#else
-afs_GetOnePage(struct vnode *vp, u_int off, u_int alen, u_int *protp,
- struct page *pl[], u_int plsz, struct seg *seg, caddr_t addr,
- enum seg_rw rw, afs_ucred_t *acred)
-#endif
{
struct page *page;
afs_int32 code = 0;
return afs_CheckCode(code, &treq, 44); /* failed to get it */
}
- afs_BozonLock(&avc->pvnLock, avc);
ObtainReadLock(&avc->lock);
afs_Trace4(afs_iclSetp, CM_TRACE_PAGEIN, ICL_TYPE_POINTER, (afs_int32) vp,
if (avc->activeV) {
ReleaseReadLock(&avc->lock);
ReleaseWriteLock(&avc->vlock);
- afs_BozonUnlock(&avc->pvnLock, avc);
afs_PutDCache(tdc);
/* Check activeV again, it may have been turned off
* while we were waiting for a lock in afs_PutDCache */
|| !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) {
ReleaseReadLock(&tdc->lock);
ReleaseReadLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
afs_PutDCache(tdc);
goto retry;
}
/* if we make it here, we can't find the page in memory. Do a real disk read
* from the cache to get the data */
Code |= 0x200; /* XXX */
-#if defined(AFS_SUN54_ENV)
/* use PG_EXCL because we know the page does not exist already. If it
* actually does exist, we have somehow raced between lookup and create.
* As of 4/98, that shouldn't be possible, but we'll be defensive here
* in case someone tries to relax all the serialization of read and write
* operations with harmless things like stat. */
-#if defined(AFS_SUN58_ENV)
page =
page_create_va(vp, toffset, PAGESIZE, PG_WAIT | PG_EXCL, seg,
addr);
-#else
- page =
- page_create_va(vp, toffset, PAGESIZE, PG_WAIT | PG_EXCL,
- seg->s_as, addr);
-#endif
-#else
- page = page_create(vp, toffset, PAGESIZE, PG_WAIT);
-#endif
if (!page) {
continue;
}
buf = pageio_setup(page, PAGESIZE, vp, B_READ); /* allocate a buf structure */
buf->b_edev = 0;
buf->b_dev = 0;
-#if defined(AFS_SUN56_ENV)
buf->b_lblkno = lbtodb(toffset);
-#else
- buf->b_blkno = btodb(toffset);
-#endif
bp_mapin(buf); /* map it in to our address space */
AFS_GLOCK();
nextpage:
/* put page in array and continue */
/* The p_selock must be downgraded to a shared lock after the page is read */
-#if defined(AFS_SUN56_ENV)
- if ((rw != S_CREATE) && !(PAGE_SHARED(page)))
-#else
- if ((rw != S_CREATE) && !(se_shared_assert(&page->p_selock)))
-#endif
- {
+ if ((rw != S_CREATE) && !(PAGE_SHARED(page))) {
page_downgrade(page);
}
pl[slot++] = page;
}
afs_indexFlags[tdc->index] |= IFAnyPages;
ReleaseWriteLock(&afs_xdcache);
- afs_BozonUnlock(&avc->pvnLock, avc);
afs_PutDCache(tdc);
afs_Trace3(afs_iclSetp, CM_TRACE_PAGEINDONE, ICL_TYPE_LONG, code,
ICL_TYPE_LONG, (int)page, ICL_TYPE_LONG, Code);
if (page)
pvn_read_done(page, B_ERROR);
ReleaseReadLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
ReleaseReadLock(&tdc->lock);
afs_PutDCache(tdc);
return code;
struct vcache *avc;
struct page *pages;
afs_int32 code = 0;
-#if defined(AFS_SUN58_ENV)
size_t tlen;
-#else
- afs_int32 tlen;
-#endif
afs_offs_t endPos;
afs_int32 NPages = 0;
-#if defined(AFS_SUN56_ENV)
u_offset_t toff = off;
-#else
- int toff = (int)off;
-#endif
int didWriteLock;
AFS_STATCNT(afs_putpage);
(afs_int32) vp, ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(off),
ICL_TYPE_INT32, (afs_int32) len, ICL_TYPE_LONG, (int)flags);
avc = VTOAFS(vp);
- afs_BozonLock(&avc->pvnLock, avc);
ObtainSharedLock(&avc->lock, 247);
didWriteLock = 0;
}
AFS_GUNLOCK();
-#if defined(AFS_SUN56_ENV)
code = pvn_vplist_dirty(vp, toff, afs_putapage, flags, cred);
-#else
- code = pvn_vplist_dirty(vp, (u_int) off, afs_putapage, flags, cred);
-#endif
AFS_GLOCK();
}
ReleaseWriteLock(&avc->lock);
else
ReleaseSharedLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
afs_Trace2(afs_iclSetp, CM_TRACE_PAGEOUTDONE, ICL_TYPE_LONG, code,
ICL_TYPE_LONG, NPages);
AFS_GUNLOCK();
int
-#if defined(AFS_SUN58_ENV)
afs_putapage(struct vnode *vp, struct page *pages, u_offset_t * offp,
size_t * lenp, int flags, afs_ucred_t *credp)
-#elif defined(AFS_SUN56_ENV)
-afs_putapage(struct vnode *vp, struct page *pages, u_offset_t * offp,
- u_int * lenp, int flags, afs_ucred_t *credp)
-#else
-afs_putapage(struct vnode *vp, struct page *pages, u_int * offp,
- u_int * lenp, int flags, afs_ucred_t *credp)
-#endif
{
struct buf *tbuf;
struct vcache *avc = VTOAFS(vp);
return (ENOMEM);
tbuf->b_dev = 0;
-#if defined(AFS_SUN56_ENV)
tbuf->b_lblkno = lbtodb(pages->p_offset);
-#else
- tbuf->b_blkno = btodb(pages->p_offset);
-#endif
bp_mapin(tbuf);
AFS_GLOCK();
afs_Trace4(afs_iclSetp, CM_TRACE_PAGEOUTONE, ICL_TYPE_LONG, avc,
if (code)
return afs_CheckCode(code, &treq, 45);
- afs_BozonLock(&avc->pvnLock, avc);
- osi_FlushPages(avc, acred); /* hold bozon lock, but not basic vnode lock */
+ osi_FlushPages(avc, acred);
ObtainWriteLock(&avc->lock, 250);
/* adjust parameters when appending files */
if ((ioflag & IO_APPEND) && arw == UIO_WRITE) {
-#if defined(AFS_SUN56_ENV)
auio->uio_loffset = avc->f.m.Length; /* write at EOF position */
-#else
- auio->uio_offset = avc->f.m.Length; /* write at EOF position */
-#endif
}
if (auio->afsio_offset < 0 || (auio->afsio_offset + auio->uio_resid) < 0) {
ReleaseWriteLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
return EINVAL;
}
#ifndef AFS_64BIT_CLIENT
/* file is larger than 2GB */
if (AfsLargeFileSize(auio->uio_offset, auio->uio_resid)) {
ReleaseWriteLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
return EFBIG;
}
#endif
didFakeOpen = 0; /* keep track of open so we can do close */
if (arw == UIO_WRITE) {
/* do ulimit processing; shrink resid or fail */
-#if defined(AFS_SUN56_ENV)
if (auio->uio_loffset + auio->afsio_resid > auio->uio_llimit) {
if (auio->uio_loffset >= auio->uio_llimit) {
ReleaseWriteLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
return EFBIG;
} else {
/* track # of bytes we should write, but won't because of
extraResid -= auio->uio_resid;
}
}
-#else
-#ifdef AFS_SUN52_ENV
- if (auio->afsio_offset + auio->afsio_resid > auio->uio_limit) {
- if (auio->afsio_offset >= auio->uio_limit) {
- ReleaseWriteLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
- return EFBIG;
- } else {
- /* track # of bytes we should write, but won't because of
- * ulimit; we must add this into the final resid value
- * so caller knows we punted some data.
- */
- extraResid = auio->uio_resid;
- auio->uio_resid = auio->uio_limit - auio->afsio_offset;
- extraResid -= auio->uio_resid;
- }
- }
-#endif
-#endif /* SUN56 */
mode = S_WRITE; /* segment map-in mode */
afs_FakeOpen(avc); /* do this for writes, so data gets put back
* when we want it to be put back */
(avc, PRSFS_READ, &treq,
CHECK_MODE_BITS | CMB_ALLOW_EXEC_AS_READ)) {
ReleaseWriteLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
return EACCES;
}
}
}
ReleaseWriteLock(&avc->lock); /* uiomove may page fault */
AFS_GUNLOCK();
-#if defined(AFS_SUN56_ENV)
data = segmap_getmap(segkmap, AFSTOV(avc), (u_offset_t) pageBase);
raddr = (caddr_t) (((uintptr_t) data + pageOffset) & PAGEMASK);
-#else
- data = segmap_getmap(segkmap, AFSTOV(avc), pageBase);
- raddr = (caddr_t) (((u_int) data + pageOffset) & PAGEMASK);
-#endif
rsize =
(((u_int) data + pageOffset + tsize + PAGEOFFSET) & PAGEMASK) -
(u_int) raddr;
code = avc->vc_error;
}
ReleaseWriteLock(&avc->lock);
- afs_BozonUnlock(&avc->pvnLock, avc);
if (!code) {
-#ifdef AFS_SUN53_ENV
if ((ioflag & FSYNC) && (arw == UIO_WRITE)
&& !AFS_NFSXLATORREQ(acred))
code = afs_fsync(avc, 0, acred);
-#else
- if ((ioflag & IO_SYNC) && (arw == UIO_WRITE)
- && !AFS_NFSXLATORREQ(acred))
- code = afs_fsync(avc, acred);
-#endif
}
-#ifdef AFS_SUN52_ENV
/*
* If things worked, add in as remaining in request any bytes
* we didn't write due to file size ulimit.
*/
if (code == 0 && extraResid > 0)
auio->uio_resid += extraResid;
-#endif
return afs_CheckCode(code, &treq, 46);
}
if (code) {
goto out;
}
- afs_BozonLock(&avc->pvnLock, avc);
osi_FlushPages(avc, cred); /* ensure old pages are gone */
avc->f.states |= CMAPPED; /* flag cleared at afs_inactive */
- afs_BozonUnlock(&avc->pvnLock, avc);
AFS_GUNLOCK();
as_rangelock(as);
if ((flags & MAP_FIXED) == 0) {
-#if defined(AFS_SUN57_ENV)
map_addr(addr, len, off, 1, flags);
-#elif defined(AFS_SUN56_ENV)
- map_addr(addr, len, off, 1);
-#else
- map_addr(addr, len, (off_t) off, 1);
-#endif
if (*addr == NULL) {
as_rangeunlock(as);
code = ENOMEM;
#ifdef AFS_SUN59_ENV
afs_frlock(struct vnode *vnp, int cmd, struct flock64 *ap, int flag,
offset_t off, struct flk_callback *flkcb, afs_ucred_t *credp)
-#elif defined(AFS_SUN56_ENV)
-afs_frlock(struct vnode *vnp, int cmd, struct flock64 *ap, int flag,
- offset_t off, afs_ucred_t *credp)
#else
-afs_frlock(struct vnode *vnp, int cmd, struct flock *ap, int flag,
+afs_frlock(struct vnode *vnp, int cmd, struct flock64 *ap, int flag,
offset_t off, afs_ucred_t *credp)
#endif
{
#endif
if ((cmd == F_GETLK) || (cmd == F_O_GETLK) || (cmd == F_SETLK)
|| (cmd == F_SETLKW)) {
-#ifdef AFS_SUN53_ENV
ap->l_pid = ttoproc(curthread)->p_pid;
ap->l_sysid = 0;
-#else
- ap->l_pid = ttoproc(curthread)->p_epid;
- ap->l_sysid = ttoproc(curthread)->p_sysid;
-#endif
AFS_GUNLOCK();
-#ifdef AFS_SUN56_ENV
code = convoff(vnp, ap, 0, off);
-#else
- code = convoff(vnp, ap, 0, (off_t) off);
-#endif
if (code)
return code;
AFS_GLOCK();
int
-#if defined(AFS_SUN56_ENV)
afs_space(struct vnode *vnp, int cmd, struct flock64 *ap, int flag,
offset_t off, afs_ucred_t *credp)
-#else
-afs_space(struct vnode *vnp, int cmd, struct flock *ap, int flag,
- offset_t off, afs_ucred_t *credp)
-#endif
{
afs_int32 code = EINVAL;
struct vattr vattr;
if ((cmd == F_FREESP)
-#ifdef AFS_SUN56_ENV
&& ((code = convoff(vnp, ap, 0, off)) == 0)) {
-#else
- && ((code = convoff(vnp, ap, 0, (off_t) off)) == 0)) {
-#endif
AFS_GLOCK();
if (!ap->l_len) {
vattr.va_mask = AT_SIZE;
return EINVAL;
}
-#ifdef AFS_SUN54_ENV
#ifdef AFS_SUN511_ENV
extern void
afs_dispose(struct vnode *vp, struct page *p, int fl, int dn, struct cred *cr, struct caller_context_t *ct)
return fs_fab_acl(vp, vsecattr, flag, creds);
}
#endif
-#endif
#ifdef AFS_GLOBAL_SUNLOCK
extern int gafs_open(struct vcache **avcp, afs_int32 aflags,
extern int gafs_mkdir(struct vcache *adp, char *aname,
struct vattr *attrs, struct vcache **avcp,
afs_ucred_t *acred);
-extern int
-#ifdef AFS_SUN53_ENV
-gafs_fsync(struct vcache *avc, int flag, afs_ucred_t *acred);
-#else
-gafs_fsync(struct vcache *avc, afs_ucred_t *acred);
-#endif
+extern int gafs_fsync(struct vcache *avc, int flag, afs_ucred_t *acred);
extern int gafs_readlink(struct vcache *avc, struct uio *auio,
afs_ucred_t *acred);
extern int gafs_readdir(struct vcache *avc, struct uio *auio,
afs_pathconf,
afs_pageio,
afs_dumpctl,
-#ifdef AFS_SUN54_ENV
afs_dispose,
afs_setsecattr,
afs_getsecattr,
-#endif
-#if defined(AFS_SUN56_ENV)
fs_shrlock,
-#endif
};
struct vnodeops *afs_ops = &Afs_vnodeops;
#endif
(void) afs_lookup(andp, aname2, &avcp, NULL, 0, NULL, acred);
if (avcp) {
struct vnode *vp = AFSTOV(avcp), *pvp = AFSTOV(andp);
-
+
+# ifdef HAVE_VN_RENAMEPATH
+ vn_renamepath(pvp, vp, aname2, strlen(aname2));
+# else
mutex_enter(&vp->v_lock);
if (vp->v_path != NULL) {
kmem_free(vp->v_path, strlen(vp->v_path) + 1);
}
mutex_exit(&vp->v_lock);
vn_setpath(afs_globalVp, pvp, vp, aname2, strlen(aname2));
+# endif /* !HAVE_VN_RENAMEPATH */
AFS_RELE(avcp);
}
}
int
-#ifdef AFS_SUN53_ENV
gafs_fsync(struct vcache *avc, int flag, afs_ucred_t *acred)
-#else
-gafs_fsync(struct vcache *avc, afs_ucred_t *acred)
-#endif
{
int code;
AFS_GLOCK();
-#ifdef AFS_SUN53_ENV
code = afs_fsync(avc, flag, acred);
-#else
- code = afs_fsync(avc, acred);
-#endif
AFS_GUNLOCK();
return (code);
}
}
mutex_exit(&vp->v_lock);
+#ifndef AFS_SUN511_ENV
/*
* Solaris calls VOP_OPEN on exec, but doesn't call VOP_CLOSE when
* the executable exits. So we clean up the open count here.
*/
if (avc->opens > 0 && avc->mvstat == 0 && !(avc->f.states & CCore))
avc->opens = avc->execsOrWriters = 0;
+#endif
afs_InactiveVCache(avc, acred);
-#ifdef AFS_SUN58_ENV
AFS_GUNLOCK();
/* VFS_RELE must be called outside of GLOCK, since it can potentially
* call afs_freevfs, which acquires GLOCK */
VFS_RELE(afs_globalVFS);
AFS_GLOCK();
-#endif
return 0;
}