"Fossies" - the Fresh Open Source Software Archive

Member "coda-6.9.5/coda-src/partition/partition.c" (26 Jun 2007, 7851 Bytes) of package /linux/misc/old/coda-6.9.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "partition.c" see the Fossies "Dox" file reference documentation.

    1 /* BLURB gpl
    2 
    3                            Coda File System
    4                               Release 6
    5 
    6           Copyright (c) 1987-2003 Carnegie Mellon University
    7                   Additional copyrights listed below
    8 
    9 This  code  is  distributed "AS IS" without warranty of any kind under
   10 the terms of the GNU General Public Licence Version 2, as shown in the
   11 file  LICENSE.  The  technical and financial  contributors to Coda are
   12 listed in the file CREDITS.
   13 
   14                         Additional copyrights
   15                            none currently
   16 
   17 #*/
   18 
   19 #ifdef __cplusplus
   20 extern "C" {
   21 #endif
   22 
   23 #ifdef HAVE_CONFIG_H
   24 #include <config.h>
   25 #endif
   26 
   27 #include <unistd.h>
   28 #include "coda_string.h"
   29 #include <sys/file.h>
   30 #include "coda_flock.h"
   31 #ifdef HAVE_SYS_STATVFS_H
   32 #include <sys/statvfs.h>
   33 #elif defined(HAVE_SYS_STATFS_H)
   34 #include <sys/statfs.h>
   35 #elif defined(HAVE_SYS_VFS_H)
   36 #include <sys/vfs.h>
   37 #elif defined(HAVE_SYS_MOUNT_H)
   38 #include <sys/param.h>
   39 #include <sys/mount.h>
   40 #endif
   41 
   42 #ifdef __cplusplus
   43 }
   44 #endif
   45 
   46 #include <util.h>
   47 #include <lwp/lwp.h>
   48 #include <lwp/lock.h>
   49 #include <util.h>
   50 #include "partition.h"
   51 
   52 static void DP_InitPartition(Partent entry, struct inodeops *operations,
   53            union PartitionData *data, Device devno);
   54 
   55 /* 
   56  * operations on partitions not involving volumes
   57  * this depends on vicetab.h and inodeops.h
   58  */
   59 
   60 struct dllist_head DiskPartitionList;
   61 
   62 static struct inodeops *DP_InodeOpsByType(char *type);
   63 /* InitPartitions reads the vicetab file. For each server partition it finds
   64    on the invoking host it initializes this partition with the correct
   65    method.  When the partition has been initialized successfully, it is
   66    inserted in the DiskPartitionList, a linked list of DiskPartitions.
   67    */
   68 void DP_Init(const char *tabfile, const char *hostname)
   69 {
   70     int rc;
   71     Partent entry;
   72     FILE *tabhandle;
   73     struct inodeops *operations;
   74     union PartitionData *data;
   75     Device  devno, codadev;
   76     char host[MAXHOSTNAMELEN];
   77 
   78     if (!hostname) {
   79     gethostname(host, MAXHOSTNAMELEN);
   80     hostname = host;
   81     }
   82 
   83     codadev = 1;
   84     list_head_init(&DiskPartitionList);
   85 
   86     tabhandle = Partent_set(tabfile, "r");
   87     if ( !tabhandle ) {
   88     eprint("No file vicetab file %s found.\n", tabfile);
   89     CODA_ASSERT(0);
   90     }
   91 
   92     while ( (entry = Partent_get(tabhandle)) ) {
   93         if (!UtilHostEq(hostname, Partent_host(entry))) {
   94         Partent_free(&entry);
   95         continue;
   96     }
   97 
   98     operations = DP_InodeOpsByType(Partent_type(entry));
   99     if ( !operations ) {
  100         eprint("Partition entry %s, %s has unknown type %s.\n",
  101            Partent_host(entry), Partent_dir(entry), 
  102            Partent_type(entry));
  103         CODA_ASSERT(0);
  104     }
  105 
  106     if ( operations->init ) {
  107         rc = operations->init(&data, entry, &devno);
  108         if ( rc != 0 ) {
  109         eprint("Partition entry %s, %s had initialization error.\n");
  110         CODA_ASSERT(0);
  111         }
  112     }
  113 
  114     /* the devno is written to RVM storage in the vnodes - 
  115        whatever scheme for numbering partitions is used should 
  116        take note of this */
  117         DP_InitPartition(entry, operations, data, devno);
  118     codadev++; 
  119     Partent_free(&entry);
  120     }
  121     Partent_end(tabhandle);
  122 
  123     /* log the status */
  124     DP_PrintStats(stdout);
  125 }
  126 
  127 static void
  128 DP_InitPartition(Partent entry, struct inodeops *operations,
  129            union PartitionData *data, Device devno)
  130 {
  131     struct DiskPartition *dp, *pp;
  132     struct dllist_head *tmp;
  133 
  134     /* allocate */
  135     dp = (struct DiskPartition *) malloc(sizeof (struct DiskPartition));
  136     if ( ! dp ) {
  137     eprint("Out of memory\n");
  138     CODA_ASSERT(0);
  139     }
  140     memset(dp, 0, sizeof(struct DiskPartition));
  141     list_head_init(&dp->dp_chain);
  142 
  143     tmp = &DiskPartitionList;
  144     while ((tmp = tmp->next) != &DiskPartitionList) {
  145         pp = list_entry(tmp, struct DiskPartition, dp_chain);
  146         if ( pp->device == devno ) {
  147             eprint("Device %d requested by partition %s used by %s!\n",
  148                devno, Partent_dir(entry), pp->name);
  149             CODA_ASSERT(0);
  150         }
  151     }
  152 
  153     /* Add it to the end.  Preserve order for printing. Check devno. */
  154     list_add(&dp->dp_chain, DiskPartitionList.prev);
  155     /*  fill in the structure */
  156     strncpy(dp->name, Partent_dir(entry), MAXPATHLEN);
  157     dp->device = devno;
  158     dp->ops = operations;
  159     dp->d = data;
  160 
  161     DP_SetUsage(dp);
  162 }
  163 
  164 struct DiskPartition *
  165 DP_Find(Device devno)
  166 {
  167     struct DiskPartition *dp = NULL;
  168     struct dllist_head *tmp;
  169 
  170     tmp = &DiskPartitionList;
  171     while( (tmp = tmp->next) != &DiskPartitionList) {
  172         dp = list_entry(tmp, struct DiskPartition, dp_chain);
  173         if (dp->device == devno)
  174             break;
  175     }
  176     if (dp == NULL) {
  177         SLog(0, "FindPartition Couldn't find partition %d", devno);
  178     }
  179     return dp;  
  180 }
  181 
  182 struct DiskPartition *
  183 DP_Get(char *name)
  184 {
  185     struct DiskPartition *dp = NULL;
  186     struct dllist_head *tmp;
  187 
  188     tmp = &DiskPartitionList;
  189     dp = list_entry(tmp, struct DiskPartition, dp_chain);
  190     
  191     while((dp) && (strcmp(dp->name, name) != 0) &&
  192       ((tmp = tmp->next) != &DiskPartitionList)) {
  193         dp = list_entry(tmp, struct DiskPartition, dp_chain);
  194     }
  195 
  196     if ((strcmp(dp->name,name)) != 0)
  197         dp = NULL;
  198     if (dp == NULL) {
  199     VLog(0, "VGetPartition Couldn't find partition %s", name);
  200     }
  201     return dp;  
  202 }
  203 
  204 
  205 void DP_SetUsage(struct DiskPartition *dp)
  206 {
  207     unsigned long reserved;
  208     int scale, rc;
  209 #if defined(HAVE_SYS_STATVFS_H)
  210     struct statvfs vfsbuf;
  211 
  212     rc = statvfs(dp->name, &vfsbuf);
  213     if ( rc != 0 ) {
  214     eprint("Error in statvfs of %s\n", dp->name);
  215     perror("");
  216     CODA_ASSERT( 0 );
  217     }
  218 #elif defined(HAVE_STATFS)
  219     struct statfs vfsbuf;
  220 
  221     rc = statfs(dp->name, &vfsbuf);
  222     if ( rc != 0 ) {
  223     eprint("Error in statfs of %s\n", dp->name);
  224     perror("");
  225     CODA_ASSERT( 0 );
  226     }
  227 #else
  228 #error "Need statvfs or statfs"
  229 #endif
  230 
  231     /* scale values to # of 512 byte blocks, further fixup is later-on */
  232     reserved = vfsbuf.f_bfree - vfsbuf.f_bavail; /* reserved for s-user */
  233     dp->free = vfsbuf.f_bavail;  /* free blocks for non s-users */
  234     dp->totalUsable = (vfsbuf.f_blocks - reserved);
  235     dp->minFree = 100 * reserved / vfsbuf.f_blocks;
  236 
  237     /* and scale values to the expected 1K per block */
  238     if (vfsbuf.f_bsize < 1024) {
  239     scale = 1024 / vfsbuf.f_bsize;
  240     dp->free /= scale;
  241     dp->totalUsable /= scale;
  242     } else if (vfsbuf.f_bsize > 1024) {
  243     scale = vfsbuf.f_bsize / 1024;
  244     dp->free *= scale;
  245     dp->totalUsable *= scale;
  246     }
  247 }
  248 
  249 void DP_ResetUsage(void)
  250 {
  251     struct DiskPartition *dp;
  252     struct dllist_head *tmp;
  253 
  254     tmp = &DiskPartitionList;
  255     while( (tmp = tmp->next) != &DiskPartitionList) {
  256         dp = list_entry(tmp, struct DiskPartition, dp_chain);
  257         DP_SetUsage(dp);
  258         LWP_DispatchProcess();
  259     }
  260 }
  261 
  262 void 
  263 DP_PrintStats(FILE *fp) 
  264 {
  265     struct DiskPartition *dp;
  266     struct dllist_head *tmp;
  267 
  268     tmp = &DiskPartitionList;
  269     while( (tmp = tmp->next) != &DiskPartitionList) {
  270     dp = list_entry(tmp, struct DiskPartition, dp_chain);
  271     SLog(0, "Partition %s: %uK available (minfree=%u%%), %uK free.",
  272          dp->name, dp->totalUsable, dp->minFree, dp->free);
  273     }
  274 }
  275 
  276 void 
  277 DP_LockPartition(char *name)
  278 {
  279     register struct DiskPartition *dp = DP_Get(name);
  280     CODA_ASSERT(dp != NULL);
  281     if (dp->lock_fd == -1) {
  282     /* Cannot writelock a directory using fcntl, disabling for now --JH */
  283 #if 0
  284     dp->lock_fd = open(dp->name, O_RDONLY, 0);
  285     CODA_ASSERT(dp->lock_fd != -1);
  286     CODA_ASSERT (myflock(dp->lock_fd, MYFLOCK_EX, MYFLOCK_BL) == 0);
  287 #endif
  288     }
  289 }
  290 
  291 void 
  292 DP_UnlockPartition(char *name)
  293 {
  294     register struct DiskPartition *dp = DP_Get(name);
  295     CODA_ASSERT(dp != NULL);
  296     if (dp->lock_fd != -1)
  297     close(dp->lock_fd);
  298     dp->lock_fd = -1;
  299 }
  300 
  301 
  302 static struct inodeops *DP_InodeOpsByType(char *type) 
  303 {
  304   
  305     if ( strcmp(type, "simple") == 0  ) {
  306     return &inodeops_simple;
  307     }
  308 
  309     if( strcmp(type, "ftree") == 0 ) {
  310     return &inodeops_ftree;
  311     }
  312 
  313     if( strcmp(type, "backup") == 0 ) {
  314     return &inodeops_backup;
  315     }
  316 
  317     return NULL;
  318 }