From e1cc987ea57c03a93dd02164ecb75cd705fc79b3 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Mon, 19 Jan 2009 18:47:52 +0000 Subject: [PATCH] disconnected-flush-before-shadowing-20090119 LICENSE IPL10 FIXES 124149 make touch a fs discon offline rm -f a fs discon online work --- src/afs/afs_buffer.c | 51 ++++++++++++++++++++++++++++++-------- src/afs/afs_dcache.c | 3 +++ src/afs/afs_disconnected.c | 4 ++- src/afs/afs_prototypes.h | 1 + 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/afs/afs_buffer.c b/src/afs/afs_buffer.c index 66b203fbe..e3b2a840c 100644 --- a/src/afs/afs_buffer.c +++ b/src/afs/afs_buffer.c @@ -475,13 +475,52 @@ DZap(struct dcache *adc) MReleaseReadLock(&afs_bufferLock); } +static void +DFlushBuffer(struct buffer *ab) { + struct osi_file *tfile; + +#if defined(LINUX_USE_FH) + tfile = afs_CFileOpen(&ab->fh, ab->fh_type); +#else + tfile = afs_CFileOpen(ab->inode); +#endif + afs_CFileWrite(tfile, ab->page * AFS_BUFFER_PAGESIZE, + ab->data, AFS_BUFFER_PAGESIZE); + ab->dirty = 0; /* Clear the dirty flag */ + afs_CFileClose(tfile); +} + +void +DFlushDCache(struct dcache *adc) +{ + int i; + struct buffer *tb; + + ObtainReadLock(&afs_bufferLock); + + for (i = 0; i <= PHPAGEMASK; i++) + for (tb = phTable[pHash(adc->index, i)]; tb; tb = tb->hashNext) + if (tb->fid == adc->index) { + ObtainWriteLock(&tb->lock, 702); + tb->lockers++; + ReleaseReadLock(&afs_bufferLock); + if (tb->dirty) { + DFlushBuffer(tb); + } + tb->lockers--; + ReleaseWriteLock(&tb->lock); + ObtainReadLock(&afs_bufferLock); + } + + ReleaseReadLock(&afs_bufferLock); +} + void DFlush(void) { /* Flush all the modified buffers. */ register int i; register struct buffer *tb; - struct osi_file *tfile; AFS_STATCNT(DFlush); tb = Buffers; @@ -503,15 +542,7 @@ DFlush(void) * we cannot lock afs_xdcache). In addition, we cannot obtain * a dcache lock while holding the tb->lock of the same file * since that can deadlock with DRead/DNew */ -#if defined(LINUX_USE_FH) - tfile = afs_CFileOpen(&tb->fh, tb->fh_type); -#else - tfile = afs_CFileOpen(tb->inode); -#endif - afs_CFileWrite(tfile, tb->page * AFS_BUFFER_PAGESIZE, - tb->data, AFS_BUFFER_PAGESIZE); - tb->dirty = 0; /* Clear the dirty flag */ - afs_CFileClose(tfile); + DFlushBuffer(tb); } tb->lockers--; MReleaseWriteLock(&tb->lock); diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 90b3c4bea..0ecb739dc 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -3741,6 +3741,9 @@ int afs_MakeShadowDir(struct vcache *avc) ReleaseWriteLock(&afs_xdcache); + /* Make sure and flush dir buffers back into the disk cache */ + DFlushDCache(tdc); + /* Alloc a 4k block. */ data = (char *) afs_osi_Alloc(4096); if (!data) { diff --git a/src/afs/afs_disconnected.c b/src/afs/afs_disconnected.c index 5579a0759..e52c3f606 100644 --- a/src/afs/afs_disconnected.c +++ b/src/afs/afs_disconnected.c @@ -271,10 +271,12 @@ int afs_GetVnodeName(struct vcache *avc, if (tdc) { tnf.fid = &avc->fid; - tnf.name_len = 0; + tnf.name_len = -1; tnf.name = aname; afs_dir_EnumerateDir(tdc, &get_vnode_name_hook, &tnf); afs_PutDCache(tdc); + if (tnf.name_len == -1) + code = ENOENT; } else { code = ENOENT; } diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 9f414787c..f1aee38da 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -30,6 +30,7 @@ extern void DRelease(register struct buffer *bp, int flag); extern int DVOffset(register void *ap); extern void DZap(struct dcache * fid); extern void DFlush(void); +extern void DFlushDCache(struct dcache *); extern void *DNew(register struct dcache * fid, register int page); extern void shutdown_bufferpackage(void); -- 2.39.5