int DNew(struct dcache *adc, int page, struct DirBuffer *entry) { /* Same as read, only do *not* even try to read the page, since it * probably doesn't exist. */ struct buffer *tb; AFS_STATCNT(DNew); ObtainWriteLock(&afs_bufferLock, 264); if ((tb = afs_newslot(adc, page, NULL)) == 0) { ReleaseWriteLock(&afs_bufferLock); return EIO; } /* extend the chunk, if needed */ /* Do it now, not in DFlush or afs_newslot when the data is written out, * since now our caller has adc->lock writelocked, and we can't acquire * that lock (or even map from a fid to a dcache) in afs_newslot or * DFlush due to lock hierarchy issues */ if ((page + 1) * AFS_BUFFER_PAGESIZE > adc->f.chunkBytes) { afs_AdjustSize(adc, (page + 1) * AFS_BUFFER_PAGESIZE); osi_Assert(afs_WriteDCache(adc, 1) == 0); } ObtainWriteLock(&tb->lock, 265); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; }
int afs_sgidaemon(void) { int s; struct dcache *tdc; if (afs_sgibklock == NULL) { SV_INIT(&afs_sgibksync, "bksync", 0, 0); SV_INIT(&afs_sgibkwait, "bkwait", 0, 0); SPINLOCK_INIT(&afs_sgibklock, "bklock"); } s = SPLOCK(afs_sgibklock); for (;;) { /* wait for something to do */ SP_WAIT(afs_sgibklock, s, &afs_sgibksync, PINOD); osi_Assert(afs_sgibklist); /* XX will probably need to generalize to real list someday */ s = SPLOCK(afs_sgibklock); while (afs_sgibklist) { tdc = afs_sgibklist; afs_sgibklist = NULL; SPUNLOCK(afs_sgibklock, s); AFS_GLOCK(); tdc->dflags &= ~DFEntryMod; osi_Assert(afs_WriteDCache(tdc, 1) == 0); AFS_GUNLOCK(); s = SPLOCK(afs_sgibklock); } /* done all the work - wake everyone up */ while (SV_SIGNAL(&afs_sgibkwait)); } }