示例#1
0
文件: aging.c 项目: yeonsh/Amoeba
void
gs_init_ttl()
{
    register Inodenum	i;
#ifndef AGE_IN_INODE
    Res_size		numbytes;

    numbytes = Superblock.s_numinodes;
    CEILING_BLKSZ(numbytes);
    Inode_local_ttl = (unsigned char *) a_alloc(A_CACHE_MEM, numbytes);
    Inode_global_ttl = (unsigned char *) a_alloc(A_CACHE_MEM, numbytes);
    if (Inode_local_ttl == 0 || Inode_global_ttl == 0)
        bpanic("Insufficient memory for ttl structures.");
#endif

    if ( init_done ) return ;

    dbmessage(28,("Init_ttl starts..."));

    p_ttl_updates = ttl_updates ;
    mu_init(&update_mutex) ;
    sema_init(&can_age,0) ;
    sema_init(&awaiting_accept,0);

    refuse_age=1 ; refusing_member= -1 ; delay_threshold= HARD_THRESHOLD ;

    /* Initially set all lifetimes to unknown */
    for (i = 1; i < Superblock.s_numinodes; i++)
    {
	    INIT_LOCAL_TTL(i) ; INIT_GLOBAL_TTL(i) ;
    }
    init_done= 1;
    dbmessage(28,("Init_ttl finishes"));
}
示例#2
0
文件: array.c 项目: semenovf/cwt
CwtArray* a_allocz (int sizeof_item, size_t capacity)
{
	CwtArray *a;
	a = a_alloc(sizeof_item, capacity);
	a_bzero(a);
	return a;
}
示例#3
0
文件: array.c 项目: semenovf/cwt
static CwtArray* a_clone (CwtArray *a)
{
	if (a) {
		CwtArray *clone;
		clone = a_alloc(a->sizeof_item, a->capacity);
		a_copy(clone, a, 0, 0, a->capacity);
		return clone;
	}

	return NULL;
}
示例#4
0
文件: inode.c 项目: yeonsh/Amoeba
static disk_addr
in_alloc()
{
    Res_size		numbytes;
    disk_addr		inodeblks;

    /*
     * We allocate space at the beginning of the cache memory for the in-core
     * inode table.
     *  NOTE WELL:	The cache memory must be properly aligned so that
     *			write_inode works properly.  Therefore we round
     *			up to blocksize.
     */

    numbytes = Superblock.s_numinodes * sizeof (Inode);
    /* Round up to blocksize */
    numbytes += Blksizemin1;
    numbytes &= ~Blksizemin1;
    inodeblks = numbytes >> Superblock.s_blksize;
    Inode_table = (Inode *) a_alloc(A_CACHE_MEM, numbytes);

    numbytes = Superblock.s_numinodes*sizeof(peer_bits);
    CEILING_BLKSZ(numbytes);
    Inode_reptab = (peer_bits *) a_alloc(A_CACHE_MEM, numbytes);
    memset((_VOIDSTAR)Inode_reptab,0,(size_t)numbytes);

    numbytes = Superblock.s_numinodes * sizeof (mutex);
    CEILING_BLKSZ(numbytes);
    typed_lock_init() ;

    if (Inode_table == 0 )
	bpanic("Insufficient memory for inode table cache.");

    Limit = Inode_table + Superblock.s_numinodes;
    Last_free = 0;

    return inodeblks ;
}
示例#5
0
DH_FILE * dh_open(char path[])
{
 DH_FILE * dh_file = NULL;
 FILE_ENTRY * fptr;
 char filename[MAX_PATHNAME_LEN+1];
 char pathname[MAX_PATHNAME_LEN+1];
 short int i;
 char * p;
 struct DH_HEADER header;
 struct DH_AK_HEADER ak_header;
 char * ibuff = NULL;
 short int file_id = -1;
 OSFILE fu = INVALID_FILE_HANDLE;      /* Primary subfile */
 OSFILE ofu = INVALID_FILE_HANDLE;     /* Overflow subfile */
 int bytes;
 unsigned long int ak_map;
 short int no_of_subfiles;
 short int no_of_aks;
 bool read_only = FALSE;
 DESCRIPTOR * descr;
 int n;
 int subfile;
 long int ak_node_num;
 OBJECT_HEADER * obj;
 struct stat statbuf;
 unsigned long int device = 0;
 unsigned long int inode = 0;

 dh_err = 0;
 process.os_error = 0;

 /* Validate file name */

 p = strrchr(path, DS);          /* Find final directory separator */
 if (p == NULL) p = path;
 if ((*p == '\0')                  /* Null name in last component */
    || !fullpath(filename, path))  /* Unable to map to absolute pathname */
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }

 /* Check if this file is already open to this process */

 if (stat(filename, &statbuf) != 0)
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }
 device = statbuf.st_dev;
 inode = statbuf.st_ino;

 for (dh_file = dh_file_head; dh_file != NULL; dh_file = dh_file->next_file)
  {
   fptr = FPtr(dh_file->file_id);
   if ((device == 0) && (inode == 0))  /* Compare by name */
    {
     if (strcmp((char *)(fptr->pathname), filename) != 0) continue;
    }
   else
    {
     if ((fptr->device != device) || (fptr->inode != inode)) continue;
    }

   /* Found a match */

   if (fptr->ref_ct < 0)   /* Already open for exclusive access */
    {
     dh_err = DHE_EXCLUSIVE;
     goto exit_dh_open;
    }

   dh_file->open_count++;
   goto exit_dh_open;
  }

 /* Open primary subfile */

 sprintf(pathname, "%s%c~0", filename, DS);
 if (access(pathname, 2)) read_only = TRUE;

 fu = dio_open(pathname, (read_only)?DIO_READ:DIO_UPDATE);
 if (!ValidFileHandle(fu))
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }

 /* Validate primary subfile header */

 if (Read(fu, (char *)(&header), DH_HEADER_SIZE) < 0)
  {
   dh_err = DHE_READ_ERROR;
   process.os_error = OSError;
   goto exit_dh_open;
  }

 switch(header.magic)
  {
   case DH_PRIMARY:
      if (header.hash)
       {
        dh_err = DHE_HASH_TYPE;
        goto exit_dh_open;
       }
      break;
   default:
      dh_err = DHE_PSFH_FAULT;
      goto exit_dh_open;
  }

 if ((header.flags & DHF_TRUSTED)    /* Access requires trusted status */
    && (!(process.program.flags & HDR_IS_TRUSTED)))
  {
   dh_err = DHE_TRUSTED;
   goto exit_dh_open;
  }

 /* !!FILE_VERSION!! */
 if (header.file_version > DH_VERSION)
  {
   dh_err = DHE_VERSION;
   goto exit_dh_open;
  }

 /* Check if this file may contain a record id longer than the maximum
    we can support.  The longest_id element of the DH_PARAMS structure
    is set to the length of the longest id written to the file.  This
    record may not be there anymore.  QMFix will sort this out.         */

 if ((header.file_version > 0)
    && (header.params.longest_id > sysseg->maxidlen))
  {
   dh_err = DHE_ID_LEN;
   goto exit_dh_open;
  }

 /* Open overflow subfile */

 sprintf(pathname, "%s%c~1", filename, DS);
 if (access(pathname, 2)) read_only = TRUE;

 ofu = dio_open(pathname, (read_only)?DIO_READ:DIO_UPDATE);
 if (!ValidFileHandle(ofu))
  {
   dh_err = DHE_FILE_NOT_FOUND;
   goto exit_dh_open;
  }

 /* Allocate new DH_FILE structure
    AKs use subfile numbers from AK_BASE_SUBFILE upwards, based on position
    in the AK map. Because AKs can be deleted, there may be gaps in the
    numbering. At this stage, simply find the highest used AK number so that
    we know how big the data structures need to be. We will go through the
    map again once we have created the AK data array.                                          */

 no_of_aks = 0;
 for(i = 0, ak_map = header.ak_map; i < MAX_INDICES; i++, ak_map = ak_map >> 1)
  {
   if (ak_map & 1) no_of_aks = i + 1;  /* Not really  -  There may be gaps */
  }
 no_of_subfiles = AK_BASE_SUBFILE + no_of_aks;

 bytes = sizeof(struct DH_FILE)
         + (sizeof(struct SUBFILE_INFO) * (no_of_subfiles - 1));
 dh_file = (DH_FILE *)k_alloc(9,bytes);
 if (dh_file == NULL)
  {
   dh_err = DHE_OPEN_NO_MEMORY;
   goto exit_dh_open;
  }

 for (i = 0; i < no_of_subfiles; i++) dh_file->sf[i].fu = INVALID_FILE_HANDLE;

 dh_file->file_version = header.file_version;
 dh_file->header_bytes = DHHeaderSize(header.file_version, header.group_size);
 dh_file->ak_header_bytes = AKHeaderSize(header.file_version);
 dh_file->group_size = header.group_size;

 dh_file->no_of_subfiles = no_of_subfiles;
 dh_file->open_count = 1;
 dh_file->flags = 0;
 dh_file->ak_map = header.ak_map;
 dh_file->trigger_name = NULL;
 dh_file->trigger = NULL;
 dh_file->trigger_modes = 0;

 if (read_only) dh_file->flags |= DHF_RDONLY;        /* Read only */



 if (header.akpath[0] == '\0') dh_file->akpath = NULL;
 else
  {
   dh_file->akpath = (char *)k_alloc(106, strlen(header.akpath) + 1);
   strcpy(dh_file->akpath, header.akpath);
  }

 /* Transfer file units into DH_FILE structure so that we do not have
    to open them again on the first access.                           */

 dh_set_subfile(dh_file, PRIMARY_SUBFILE, fu);
 fu = INVALID_FILE_HANDLE;

 dh_set_subfile(dh_file, OVERFLOW_SUBFILE, ofu);
 ofu = INVALID_FILE_HANDLE;

 /* Load trigger function, if any */

 if (header.trigger_name[0] != '\0')
  {
   dh_file->trigger_name = (char *)k_alloc(69,strlen(header.trigger_name) + 1); /* 0259 */
   strcpy(dh_file->trigger_name, header.trigger_name);

   /* Attempt to snap link to trigger function */

   obj = (OBJECT_HEADER *)load_object(header.trigger_name, FALSE);
   if (obj != NULL) obj->ext_hdr.prog.refs += 1;
   dh_file->trigger = (u_char *)obj;
   dh_file->flags |= DHF_TRIGGER;
 
   /* Copy the trigger mode flags. If this file pre-dates the introduction
      of these flags, the byte will be zero. Set the defaults to be as they
      were for old versions of the system.                                 */

   if (header.trigger_modes) dh_file->trigger_modes = header.trigger_modes;
   else dh_file->trigger_modes = TRG_PRE_WRITE | TRG_PRE_DELETE;
  }

 /* Now process any AK indices */

 if (no_of_aks)      /* Has AK indices */
  {
   dh_file->flags |= DHF_AK;

   /* Set up AK data matrix */

   dh_file->ak_data = a_alloc(no_of_aks, AKD_COLS, TRUE);

   for(i = 0, ak_map = header.ak_map; i < no_of_aks; i++, ak_map = ak_map >> 1)
    {
     /* AK field name - Set as null string for now, filled in for used
        entries after we have validated the subfile.                    */

     descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_NAME);
     InitDescr(descr, STRING);
     descr->data.str.saddr = NULL;
   
     if (ak_map & 1)
      {
       /* Open AK subfile and validate header */

       subfile = i + AK_BASE_SUBFILE;
       if (!dh_open_subfile(dh_file, filename, subfile, FALSE))
        {
         dh_err = DHE_AK_NOT_FOUND;
         goto exit_dh_open;
        }

       if (!dh_read_group(dh_file, subfile, 0, (char *)(&ak_header),
            DH_AK_HEADER_SIZE))
        {
         dh_err = DHE_AK_HDR_READ_ERROR;
         process.os_error = OSError;
         goto exit_dh_open;
        }

       if (ak_header.magic != DH_INDEX)
        {
         dh_err = DHE_AK_HDR_FAULT;
         goto exit_dh_open;
        }

       /* Cross-check the index subfile with the primary data subfile */

       if (header.creation_timestamp != ak_header.data_creation_timestamp)
        {
         dh_err = DHE_AK_CROSS_CHECK;
         goto exit_dh_open;
        }

       /* Fill in AK name */

       ts_init(&(descr->data.str.saddr), strlen(ak_header.ak_name));
       ts_copy_c_string(ak_header.ak_name);
       (void)ts_terminate();

       /* Field number */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_FNO);
       InitDescr(descr, INTEGER);
       descr->data.value = ak_header.fno;

       /* Flags */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_FLGS);
       InitDescr(descr, INTEGER);
       descr->data.value = ak_header.flags;

       /* I-type code */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_OBJ);
       InitDescr(descr, STRING);
       descr->data.str.saddr = NULL;
       ts_init(&(descr->data.str.saddr), ak_header.itype_len);

       ak_node_num = GetAKFwdLink(dh_file, ak_header.itype_ptr);
       if (ak_node_num != 0)   /* Long expression */
        {
         /* Fetch I-type from separate node */

         ibuff = (char *)k_alloc(53, DH_AK_NODE_SIZE);
         do {
             if (!dh_read_group(dh_file, subfile, ak_node_num, ibuff,
                  DH_AK_NODE_SIZE))
              {
               goto exit_dh_open;
              }

             n = ((DH_ITYPE_NODE *)ibuff)->used_bytes - offsetof(DH_ITYPE_NODE, data);
             ts_copy((char *)(((DH_ITYPE_NODE *)ibuff)->data), n);
             ak_node_num = GetAKFwdLink(dh_file, ((DH_ITYPE_NODE *)ibuff)->next);
            } while(ak_node_num);
        }
       else
        {
         ts_copy((char *)ak_header.itype, ak_header.itype_len);
        }
       (void)ts_terminate();

       descr->data.str.saddr = s_make_contiguous(descr->data.str.saddr, NULL);

       /* Collation map name */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_MAPNAME);
       InitDescr(descr, STRING);
       k_put_c_string(ak_header.collation_map_name, descr);

       /* Collation map (contiguous string) */

       descr = Element(dh_file->ak_data, (i * AKD_COLS) + AKD_MAP);
       if (ak_header.collation_map_name[0] == '\0')
        {
         InitDescr(descr, STRING);
         descr->data.str.saddr = NULL;
        }
       else
        {
         k_put_string(ak_header.collation_map, 256, descr);
        }
      }
    }
  }
 else
  {
示例#6
0
文件: inode.c 项目: yeonsh/Amoeba
void
inode_init()
{
    register Inode *	ip;
    register Inode *	lim;
    Res_size		numbytes;
    Inodenum		i;
    disk_addr		inodeblks;

    /*
     * We allocate space at the beginning of the cache memory for the in-core
     * inode table.
     *  NOTE WELL:	The cache memory must be properly aligned so that
     *			write_inode works properly.  Therefore we round
     *			up to blocksize.
     */

    numbytes = Superblock.s_numinodes * sizeof (Inode);
    /* Round up to blocksize */
    numbytes += Blksizemin1;
    numbytes &= ~Blksizemin1;
    inodeblks = numbytes >> Superblock.s_blksize;

    Inode_table = (Inode *) a_alloc(A_CACHE_MEM, numbytes);

    numbytes = Superblock.s_numinodes * sizeof (mutex);
    CEILING_BLKSZ(numbytes);
    Inode_lock = (mutex *) a_alloc(A_CACHE_MEM, numbytes);
    if (Inode_table == 0 || Inode_lock == 0)
	bpanic("Insufficient memory for inode table cache.");

    /* Initialize the locks to free */
    for (i = 0; i < Superblock.s_numinodes; i++)
	mu_init(Inode_lock + i);

#if !defined(USER_LEVEL) && !defined(NDEBUG)

    numbytes = sizeof (struct thread *) * Superblock.s_numinodes;
    CEILING_BLKSZ(numbytes);
    ILKCHK = (struct thread **) a_alloc(A_CACHE_MEM, numbytes);
    if (ILKCHK == 0)
	bpanic("Insufficient memory for inode cross-check table.");
    (void) memset((_VOIDSTAR) ILKCHK, 0, (size_t) numbytes);

#endif

    read_inodetab(inodeblks);

    lim = Limit = Inode_table + Superblock.s_numinodes;
    Last_free = 0;

    /*
     * Go through the inodes and mark those that are allocated (in use).
     * Remember the first free inode.
     */
    for (ip = Inode_table + 1; ip < lim; ip++)
    {
	/*
	 * Files with the intent flag still on were never written to disk
	 * so mark them as empty.
	 */
	if (ip->i_flags & I_INTENT)
	    ip->i_lifetime = 0;

	if (ip->i_lifetime != 0)
	    ip->i_flags = I_ALLOCED;
	else
	    ip->i_flags = 0;
	if (Last_free == 0 && ip->i_flags == 0)
	    Last_free = ip;
    }

    /*
     * See if there are any inodes.
     * If not then we still need to have last_free pointing at the inode table!
     */
    if (Last_free == 0)
    {
	Last_free = Inode_table + 1;
	bwarn("no free inodes!\n");
	return;
    }
}