afs-prefer-backup-volumes-on-mountpoints-option-20030808
authorKris Van Hees <aedil-afs@alchar.org>
Fri, 8 Aug 2003 20:55:03 +0000 (20:55 +0000)
committerDerrick Brashear <shadow@dementia.org>
Fri, 8 Aug 2003 20:55:03 +0000 (20:55 +0000)
afsd option (-backuptree) and proc interface code for linux to enable preferring
backup volumes when crossing mountpoints once in a tree of backup volumes.

src/afs/LINUX/osi_sysctl.c
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs.h
src/afs/afs_call.c
src/afs/afs_volume.c
src/afsd/afsd.c
src/config/afs_args.h

index d47868f..1fc7336 100644 (file)
@@ -45,6 +45,10 @@ static ctl_table afs_sysctl_table[] = {
      &afs_rx_deadtime, sizeof(afs_int32), 0644, NULL,
      &proc_dointvec}
     ,
+    {6, "bkVolPref",
+     &afs_bkvolpref, sizeof(afs_int32), 0644, NULL,
+     &proc_dointvec}
+    ,
     {0}
 };
 
index 6aafccd..e9d760a 100644 (file)
@@ -36,6 +36,7 @@ extern struct inode_operations afs_symlink_iops, afs_dir_iops;
 #endif
 
 
+afs_int32 afs_bkvolpref = 0;
 afs_int32 afs_bulkStatsDone;
 static int bulkStatCounter = 0;        /* counter for bulk stat seq. numbers */
 int afs_fakestat_enable = 0;   /* 1: fakestat-all, 2: fakestat-crosscell */
@@ -63,11 +64,11 @@ EvalMountPoint(register struct vcache *avc, struct vcache *advc,
     struct volume *tvp = 0;
     struct VenusFid tfid;
     struct cell *tcell;
-    char *cpos, *volnamep;
-    char type, *buf;
-    afs_int32 prefetchRO;      /* 1=>No  2=>Yes */
-    afs_int32 mtptCell, assocCell, hac = 0;
-    afs_int32 samecell, roname, len;
+    char   *cpos, *volnamep;
+    char   type, *buf;
+    afs_int32  prefetch;          /* 1=>None  2=>RO  3=>BK */
+    afs_int32  mtptCell, assocCell, hac = 0;
+    afs_int32  samecell, roname, len;
 
     AFS_STATCNT(EvalMountPoint);
 #ifdef notdef
@@ -111,28 +112,35 @@ EvalMountPoint(register struct vcache *avc, struct vcache *advc,
                                               && (avc->fid.Cell ==
                                                   assocCell));
 
-    /* Decide whether to prefetch the RO. Also means we want the RO.
-     * If this is a regular mountpoint with a RW volume name and
-     * we cross a cell boundary -or- start from a RO volume, then we will
-     * want to prefetch the RO volume when we get the RW below.
+    /* Decide whether to prefetch the BK, or RO.  Also means we want the BK or
+     * RO.
+     * If this is a regular mountpoint with a RW volume name
+     * - If BK preference is enabled AND we remain within the same cell AND
+     *   start from a BK volume, then we will want to prefetch the BK volume.
+     * - If we cross a cell boundary OR start from a RO volume, then we will
+     *   want to prefetch the RO volume.
      */
-    if ((type == '#') && !roname && (!samecell || (avc->states & CRO))) {
-       prefetchRO = 2;         /* Yes, prefetch the RO */
+    if ((type == '#') && !roname) {
+       if (afs_bkvolpref && samecell && (avc->states & CBackup))
+           prefetch = 3; /* Prefetch the BK */
+       else if (!samecell || (avc->states & CRO))
+           prefetch = 2; /* Prefetch the RO */
+       else
+           prefetch = 1; /* Do not prefetch */
     } else {
-       prefetchRO = 1;         /* No prefetch of the RO */
+       prefetch = 1; /* Do not prefetch */
     }
 
     /* Get the volume struct. Unless this volume name has ".readonly" or
      * ".backup" in it, this will get the volume struct for the RW volume.
      * The RO volume will be prefetched if requested (but not returned).
      */
-    tvp =
-       afs_GetVolumeByName(volnamep, mtptCell, prefetchRO, areq, WRITE_LOCK);
+    tvp = afs_GetVolumeByName(volnamep, mtptCell, prefetch, areq, WRITE_LOCK);
 
     /* If no volume was found in this cell, try the associated linked cell */
     if (!tvp && hac && areq->volumeError) {
-       tvp =
-           afs_GetVolumeByName(volnamep, assocCell, prefetchRO, areq,
+       tvp =
+           afs_GetVolumeByName(volnamep, assocCell, prefetch, areq,
                                WRITE_LOCK);
     }
 
@@ -140,7 +148,7 @@ EvalMountPoint(register struct vcache *avc, struct vcache *advc,
      * doesn't exist? Try adding ".readonly" to volname and look for that.
      * Don't know why we do this. Would have still found it in above call - jpm.
      */
-    if (!tvp && (prefetchRO == 2)) {
+    if (!tvp && (prefetch == 2)) {
        buf = (char *)osi_AllocSmallSpace(strlen(volnamep) + 10);
 
        strcpy(buf, volnamep);
@@ -164,16 +172,26 @@ EvalMountPoint(register struct vcache *avc, struct vcache *advc,
        return ENODEV;
     }
 
-    /* If we want (prefetched) the RO and it exists, then drop the
-     * RW volume and get the RO. Othewise, go with the RW.
+    /* If we want (prefetched) the BK and it exists, then drop the RW volume
+     * and get the BK.
+     * Otherwise, if we want (prefetched0 the RO and it exists, then drop the
+     * RW volume and get the RO.
+     * Otherwise, go with the RW.
      */
-    if ((prefetchRO == 2) && tvp->roVol) {
-       tfid.Fid.Volume = tvp->roVol;   /* remember RO volume */
+    if ((prefetch == 3) && tvp->backVol) {
+       tfid.Fid.Volume = tvp->backVol; /* remember BK volume */
        tfid.Cell = tvp->cell;
        afs_PutVolume(tvp, WRITE_LOCK); /* release old volume */
        tvp = afs_GetVolume(&tfid, areq, WRITE_LOCK);   /* get the new one */
        if (!tvp)
            return ENODEV;      /* oops, can't do it */
+    } else if ((prefetch >= 2) && tvp->roVol) {
+       tfid.Fid.Volume = tvp->roVol;   /* remember RO volume */
+       tfid.Cell = tvp->cell;
+       afs_PutVolume(tvp, WRITE_LOCK); /* release old volume */
+       tvp = afs_GetVolume(&tfid, areq, WRITE_LOCK);   /* get the new one */
+       if (!tvp)
+          return ENODEV;       /* oops, can't do it */
     }
 
     if (avc->mvid == 0)
index 77abf07..2569b00 100644 (file)
@@ -259,6 +259,7 @@ enum { AFS_GCPAGS_NOTCOMPILED = 0, AFS_GCPAGS_OK =
 
 extern afs_int32 afs_gcpags;
 extern afs_int32 afs_gcpags_procsize;
+extern afs_int32 afs_bkvolpref;
 
 struct unixuser {
     struct unixuser *next;     /* next hash pointer */
index 34ff6b3..188a333 100644 (file)
@@ -871,8 +871,12 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
     } else if (parm == AFSOP_SET_FAKESTAT) {
        afs_fakestat_enable = parm2;
        code = 0;
-    } else
-       code = EINVAL;
+    }
+    else if (parm == AFSOP_SET_BACKUPTREE) {
+       afs_bkvolpref = parm2;
+    }
+    else
+      code = EINVAL;
 
   out:
     AFS_GUNLOCK();
index 6020cc4..d78e849 100644 (file)
@@ -688,7 +688,15 @@ afs_NewVolumeByName(char *aname, afs_int32 acell, int agood,
     else
        ve = (char *)tve;
     tv = afs_SetupVolume(0, aname, ve, tcell, agood, type, areq);
-    if ((agood == 2) && tv->roVol) {
+    if ((agood == 3) && tv->backVol) {
+       /*
+        * This means that very soon we'll ask for the BK volume so
+        * we'll prefetch it (well we did already.)
+        */
+       tv1 = afs_SetupVolume(tv->backVol, (char *)0, ve, tcell, 0, type, areq);
+       tv1->refCount--;
+    }
+    if ((agood >= 2) && tv->roVol) {
        /*
         * This means that very soon we'll ask for the RO volume so
         * we'll prefetch it (well we did already.)
index 2fcba11..0f31dc9 100644 (file)
@@ -265,9 +265,10 @@ static int enable_process_stats = 0;       /* enable rx stats */
 #ifdef AFS_AFSDB_ENV
 static int enable_afsdb = 0;   /* enable AFSDB support */
 #endif
-static int enable_dynroot = 0; /* enable dynroot support */
-static int enable_fakestat = 0;        /* enable fakestat support */
-static int enable_nomount = 0; /* do not mount */
+static int enable_dynroot = 0;         /* enable dynroot support */
+static int enable_fakestat = 0;                /* enable fakestat support */
+static int enable_backuptree = 0;      /* enable backup tree support */
+static int enable_nomount = 0;         /* do not mount */
 #ifdef notdef
 static int inodes = 60;                /* VERY conservative, but has to be */
 #endif
@@ -1489,6 +1490,10 @@ mainproc(as, arock)
        /* -nomount */
        enable_nomount = 1;
     }
+    if (as->parms[30].items) {
+       /* -backuptree */
+       enable_backuptree = 1;
+    }
 
     /*
      * Pull out all the configuration info for the workstation's AFS cache and
@@ -1826,6 +1831,14 @@ mainproc(as, arock)
            printf("%s: Error enabling fakestat support.\n", rn);
     }
 
+    if (enable_backuptree) {
+       if (afsd_verbose)
+           printf("%s: Enabling backup tree support in kernel.\n", rn);
+       code = call_syscall(AFSOP_SET_BACKUPTREE, enable_backuptree);
+       if (code)
+           printf("%s: Error enabling backup tree support.\n", rn);
+    }
+
     /*
      * Tell the kernel about each cell in the configuration.
      */
@@ -2151,6 +2164,7 @@ main(argc, argv)
     cmd_AddParm(ts, "-fakestat-all", CMD_FLAG, CMD_OPTIONAL,
                "Enable fakestat support for all mounts");
     cmd_AddParm(ts, "-nomount", CMD_FLAG, CMD_OPTIONAL, "Do not mount AFS");
+    cmd_AddParm(ts, "-backuptree", CMD_FLAG, CMD_OPTIONAL, "Prefer backup volumes for mointpoints in backup volumes");
     return (cmd_Dispatch(argc, argv));
 }
 
index 901e0f6..77892b3 100644 (file)
@@ -45,6 +45,7 @@
 #define        AFSOP_CELLINFO           34     /* set the cellinfo file name */
 #define        AFSOP_SET_THISCELL       35     /* set the primary cell */
 #define AFSOP_BASIC_INIT        36     /* used to be part of START_AFS */
+#define AFSOP_SET_BACKUPTREE    37     /* enable backup tree support */
 
 /* The range 20-30 is reserved for AFS system offsets in the afs_syscall */
 #define        AFSCALL_PIOCTL          20