disconnected-flush-before-shadowing-20090119
authorSimon Wilkinson <sxw@inf.ed.ac.uk>
Mon, 19 Jan 2009 18:47:52 +0000 (18:47 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 19 Jan 2009 18:47:52 +0000 (18:47 +0000)
LICENSE IPL10
FIXES 124149

make
touch a
fs discon offline
rm -f a
fs discon online
work

src/afs/afs_buffer.c
src/afs/afs_dcache.c
src/afs/afs_disconnected.c
src/afs/afs_prototypes.h

index 66b203f..e3b2a84 100644 (file)
@@ -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);
index 90b3c4b..0ecb739 100644 (file)
@@ -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) {
index 5579a07..e52c3f6 100644 (file)
@@ -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;
     }
index 9f41478..f1aee38 100644 (file)
@@ -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);