namei-delay-fsync-20060426
authorRainer Toebbicke <rtb@pclella.cern.ch>
Wed, 26 Apr 2006 16:43:17 +0000 (16:43 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 26 Apr 2006 16:43:17 +0000 (16:43 +0000)
FIXES 30632

group fsync calls to speed up operations

src/vol/clone.c
src/vol/ihandle.h
src/vol/namei_ops.c
src/vol/purge.c
src/volser/dumpstuff.c

index 1a02d2d..df4a0f1 100644 (file)
@@ -227,6 +227,12 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
     decRock.vol = V_parentId(rwvp);
 
     /* Read each vnode in the old volume's index file */
+    /* fsyncing the link count file for every inode has a severe 
+       performance penalty, therefore we turn it off temporarily.
+       This assumes we're the only one on that file/volume  -
+       in particular when we force the fsync later!
+    */
+    V_linkHandle(rwvp)->ih_flags|=IH_DELAY_SYNC;
     for (offset = vcp->diskSize;
         STREAM_READ(rwvnode, vcp->diskSize, 1, rwfile) == 1;
         offset += vcp->diskSize) {
@@ -345,6 +351,12 @@ DoCloneIndex(Volume * rwvp, Volume * clvp, VnodeClass class, int reclone)
      * and shouldn't do the idecs.
      */
   error_exit:
+    /* Now take the fsync-bypass away again and force an fsync.
+       Again: assumes we're alone on this file, otherwise we need a lock!
+    */
+    V_linkHandle(rwvp)->ih_flags&=~IH_DELAY_SYNC;
+    IH_CONDSYNC(V_linkHandle(rwvp));
+
     if (rwfile)
        STREAM_CLOSE(rwfile);
     if (clfilein)
index 2aee89d..38d9ab3 100644 (file)
@@ -221,6 +221,7 @@ typedef struct IHandle_s {
 
 /* Flags for the Inode handle */
 #define IH_REALLY_CLOSED               1
+#define IH_DELAY_SYNC                  16
 
 /* Hash function for inode handles */
 #define I_HANDLE_HASH_SIZE     1024    /* power of 2 */
@@ -466,7 +467,7 @@ extern afs_sfsize_t ih_size(int fd);
 #define FDH_WRITE(H, B, S) OS_WRITE((H)->fd_fd, B, S)
 #define FDH_SEEK(H, O, F) OS_SEEK((H)->fd_fd, O, F)
 
-#define FDH_SYNC(H) OS_SYNC((H)->fd_fd)
+#define FDH_SYNC(H) ((H->fd_ih->ih_flags&IH_DELAY_SYNC) ? 0 : OS_SYNC((H)->fd_fd))
 #define FDH_TRUNC(H, L) OS_TRUNC((H)->fd_fd, L)
 #define FDH_SIZE(H) OS_SIZE((H)->fd_fd)
 
index 910b1d0..3bd3fd7 100644 (file)
@@ -572,6 +572,8 @@ namei_icreate(IHandle_t * lh, char *part, int p1, int p2, int p3, int p4)
 
     if (p2 == -1 && p3 == VI_LINKTABLE) {
        /* hack at tmp to setup for set link count call. */
+       memset((void *)&tfd, 0, sizeof(FdHandle_t));    /* minimalistic still, but a little cleaner */
+       tfd.fd_ih = &tmp;
        tfd.fd_fd = fd;
        code = namei_SetLinkCount(&tfd, (Inode) 0, 1, 0);
     }
index 4b13fcf..dd94a27 100644 (file)
@@ -94,7 +94,7 @@ VPurgeVolume(Error * ec, Volume * vp)
     VOL_UNLOCK;
 }
 
-#define MAXOBLITATONCE 200
+#define MAXOBLITATONCE 1000
 /* delete a portion of an index, adjusting offset appropriately.  Returns 0 if
    things work and we should be called again, 1 if success full and done, and -1
    if an error occurred.  It adjusts offset appropriately on 0 or 1 return codes,
@@ -153,10 +153,13 @@ ObliterateRegion(Volume * avp, VnodeClass aclass, StreamHandle_t * afile,
     OS_SYNC(afile->str_fd);
 
     /* finally, do the idec's */
+    V_linkHandle(avp)->ih_flags|=IH_DELAY_SYNC;                /* severe performance penalty */
     for (i = 0; i < iindex; i++) {
        IH_DEC(V_linkHandle(avp), inodes[i], V_parentId(avp));
        DOPOLL;
     }
+    V_linkHandle(avp)->ih_flags&=~IH_DELAY_SYNC;
+    IH_CONDSYNC(V_linkHandle(avp));
 
     /* return the new offset */
     *aoffset = offset;
index 73765d0..9276a97 100644 (file)
@@ -1058,7 +1058,13 @@ RestoreVolume(register struct rx_call *call, Volume * avp, int incremental,
 
     tdelo = delo;
     while (1) {
-       if (ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo)) {
+       int temprc;
+
+       V_linkHandle(avp)->ih_flags |= IH_DELAY_SYNC;   /* Avoid repetitive fdsync()s on linkfile */
+       temprc = ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo);
+       V_linkHandle(avp)->ih_flags &= ~IH_DELAY_SYNC;  /* normal sync behaviour again */
+       IH_CONDSYNC(V_linkHandle(avp));                 /* sync link file */
+       if (temprc) {
            error = VOLSERREAD_DUMPERROR;
            goto clean;
        }