Example #1
0
int sbull_init(void)
{
    int result, i;

    /*
     * Copy the (static) cfg variables to public prefixed ones to allow
     * snoozing with a debugger.
     */

    sbull_major    = major;
    sbull_devs     = devs;
    sbull_rahead   = rahead;
    sbull_size     = size;
    sbull_blksize  = blksize;
    sbull_hardsect = hardsect;

#ifdef LINUX_20
    /* Hardsect can't be changed :( */
    if (hardsect != 512) {
        printk(KERN_ERR "sbull: can't change hardsect size\n");
        hardsect = sbull_hardsect = 512;
    }
#endif
    /*
     * Register your major, and accept a dynamic number
     */
    result = register_blkdev(sbull_major, "sbull", &sbull_fops);
    if (result < 0) {
        printk(KERN_WARNING "sbull: can't get major %d\n",sbull_major);
        return result;
    }
    if (sbull_major == 0) sbull_major = result; /* dynamic */
    major = sbull_major; /* Use `major' later on to save typing */

    /*
     * Assign the other needed values: request, rahead, size, blksize,
     * hardsect. All the minor devices feature the same value.
     * Note that `sbull' defines all of them to allow testing non-default
     * values. A real device could well avoid setting values in global
     * arrays if it uses the default values.
     */

    read_ahead[major] = sbull_rahead;
    result = -ENOMEM; /* for the possible errors */

    sbull_sizes = kmalloc(sbull_devs * sizeof(int), GFP_KERNEL);
    if (!sbull_sizes)
        goto fail_malloc;
    for (i=0; i < sbull_devs; i++) /* all the same size */
        sbull_sizes[i] = sbull_size;
    blk_size[major]=sbull_sizes;

    sbull_blksizes = kmalloc(sbull_devs * sizeof(int), GFP_KERNEL);
    if (!sbull_blksizes)
        goto fail_malloc;
    for (i=0; i < sbull_devs; i++) /* all the same blocksize */
        sbull_blksizes[i] = sbull_blksize;
    blksize_size[major]=sbull_blksizes;

    sbull_hardsects = kmalloc(sbull_devs * sizeof(int), GFP_KERNEL);
    if (!sbull_hardsects)
        goto fail_malloc;
    for (i=0; i < sbull_devs; i++) /* all the same hardsect */
        sbull_hardsects[i] = sbull_hardsect;
    hardsect_size[major]=sbull_hardsects;

    /* FIXME: max_readahead and max_sectors */
    
    /* 
     * allocate the devices -- we can't have them static, as the number
     * can be specified at load time
     */

    sbull_devices = kmalloc(sbull_devs * sizeof (Sbull_Dev), GFP_KERNEL);
    if (!sbull_devices)
        goto fail_malloc;
    memset(sbull_devices, 0, sbull_devs * sizeof (Sbull_Dev));
    for (i=0; i < sbull_devs; i++) {
        /* data and usage remain zeroed */
        sbull_devices[i].size = 1024 * sbull_size;
        init_timer(&(sbull_devices[i].timer));
        sbull_devices[i].timer.data = (unsigned long)(sbull_devices+i);
        sbull_devices[i].timer.function = sbull_expires;
        spin_lock_init(&sbull_devices[i].lock);
    }

    /*
     * Get the queue set up, and register our (nonexistent) partitions.
     */  
#ifdef SBULL_MULTIQUEUE
    for (i = 0; i < sbull_devs; i++) {
        blk_init_queue(&sbull_devices[i].queue, sbull_request);
        blk_queue_headactive(&sbull_devices[i].queue, 0);
        blk_queue_pluggable(&sbull_devices[i].queue, sbull_plug);
    }
    blk_dev[major].queue = sbull_find_queue;
#else
#  ifdef LINUX_24
    if (noqueue)
    {
        blk_init_queue(BLK_DEFAULT_QUEUE(major), sbull_unused_request);
        blk_queue_make_request(BLK_DEFAULT_QUEUE(major), sbull_make_request);
    }
    else
#  endif /* LINUX_24 */
        blk_init_queue(BLK_DEFAULT_QUEUE(major), sbull_request);
#endif
    /* A no-op in 2.4.0, but all drivers seem to do it anyway */
    for (i = 0; i < sbull_devs; i++)
            register_disk(NULL, MKDEV(major, i), 1, &sbull_fops,
                            sbull_size << 1);

#ifndef SBULL_DEBUG
    EXPORT_NO_SYMBOLS; /* otherwise, leave global symbols visible */
#endif

    printk ("<1>sbull: init complete, %d devs, size %d blks %d hs %d\n",
                    sbull_devs, sbull_size, sbull_blksize, sbull_hardsect);
#ifdef SBULL_MULTIQUEUE
    printk ("<1>sbull: Using multiqueue request\n");
#elif defined(LINUX_24)
    if (noqueue)
            printk (KERN_INFO "sbull: using direct make_request\n");
#endif

#ifdef DO_RAW_INTERFACE
    sbullr_init();
#endif
    return 0; /* succeed */

  fail_malloc:
    read_ahead[major] = 0;
    if (sbull_sizes) kfree(sbull_sizes);
    blk_size[major] = NULL;
    if (sbull_blksizes) kfree(sbull_blksizes);
    blksize_size[major] = NULL;
    if (sbull_hardsects) kfree(sbull_hardsects);
    hardsect_size[major] = NULL;
    if (sbull_devices) kfree(sbull_devices);

    unregister_blkdev(major, "sbull");
    return result;
}
Example #2
0
/*! 
  - structure de données pour le ndev
  - création fichier DEVFS
  - attribution MINOR number
  - init des valeurs des tableaux kernel (cf. blkdev.h)
*/
int smd_add_ndev(servernode_t *sn, 
		 char *nom_device, 
		 char *path_device,
		 int devnb,
		 u64 nb_sectors) {
  int no_ndev;
  ndevice_t *nd;

  PDEBUG("entering. param: sn=%p (name=%s) nom_device=%s "
	 "path_device=%s devnb = %d nb_sectors=%lld\n",
	 sn, 
	 sn->name, 
	 nom_device, 
	 path_device,
	 devnb,
	 nb_sectors);

  // et si le nouveau ndev existe déjà sur ce snode..
  // on met à jour la nouvelle taille si besoin est
  if (new_ndev(sn, nom_device) == FALSE) {
    PDEBUG("ndev '%s' exist => checking if its size has changed\n",
	   nom_device);
    nd = get_ndev_from_name(sn, nom_device);
    if (nd == NULL) {
      PERROR("can't get the nd structure of existing ndev '%s'\n",
	     nom_device);
      return ERROR;
    }
	     
    if (quotient64(nb_sectors*SMD_HARDSECT,1024) != nd->size) {
      // changement de taille
      PDEBUG("size changed: old size = %lld KB, new size = %lld KB\n", 
	     nd->size,
	     quotient64(nb_sectors*SMD_HARDSECT,1024));
      nd->size = quotient64(nb_sectors*SMD_HARDSECT,1024);
      blk_size[SMD_MAJOR_NUMBER][nd->minor] = nd->size;
    }
    return SUCCESS;
  }
     

  no_ndev = unused_elt_indice((void *)sn->ndevs, NBMAX_NDEVS);
  if (no_ndev == NBMAX_NDEVS) {
    PERROR("can't create the new image device because max number "
	   "(= %d) reached for the server node '%s'\n",
	   NBMAX_NDEVS,
	   sn->name);
    return ERROR;
  }
  
  PDEBUG("free elt indice %d of sn->ndevs[] chosen\n", no_ndev);

  nd = vmalloc(sizeof(struct ndevice));
  if (nd == NULL) {
    PERROR("can't allocate memory for new ndev '%s'\n", nom_device);
    return ERROR;
  }

  nd->sn = sn;

  nd->minor = unused_elt_indice((void *)minor2ndev,NBMAX_NDEVS);
  if (nd->minor == NBMAX_NDEVS) {
    PERROR("can't get a minor number for device '%s:%s' "
	   "because max number (= %d) reached \n",
	   nom_device, nd->name,
	   NBMAX_NDEVS);
    return ERROR;
  }
  
  nd->localnb = devnb;
  sscanf(nom_device,"%s", nd->name);
  sscanf(path_device,"%s", nd->rpath);
  sprintf(nd->lpath,"/dev/%s/%s", sn->name, nd->name);
 
	 
  nd->dev_file = 
    devfs_register(sn->dev_rep, nd->name,
		   DEVFS_FL_DEFAULT, 
		   SMD_MAJOR_NUMBER, nd->minor,
		   S_IFBLK | S_IRUSR | S_IWUSR, 
		   &smd_fops, 
		   NULL); 

  PDEBUG("  nd->dev_file = "
	 "devfs_register(sn->dev_rep, nd->name,"
	 "DEVFS_FL_DEFAULT, "
	 "SMD_MAJOR_NUMBER, nd->minor, "
	 "S_IFBLK | S_IRUSR | S_IWUSR," 
	 "&smd_fops," 
	 "NULL) == %p\n",nd->dev_file);

  if (nd->dev_file  == NULL) {
    PERROR("can't create dev_file for ndev '%s:%s'\n",
	   sn->name,
	   nd->name);
    goto error;
  }

  PDEBUG("devfs file '%s' created\n", nd->name);

  nd->nb_io = 0;
  nd->size = quotient64(nb_sectors*SMD_HARDSECT,1024); // en Ko

  // smd_size[no_brique] mise à jour plus tard
  blk_size[SMD_MAJOR_NUMBER][nd->minor] = nd->size;
  blksize_size[SMD_MAJOR_NUMBER][nd->minor] = SMD_BLKSIZE;
  hardsect_size[SMD_MAJOR_NUMBER][nd->minor] = SMD_HARDSECT;
  max_readahead[SMD_MAJOR_NUMBER][nd->minor] = SMD_READAHEAD;
  max_sectors[SMD_MAJOR_NUMBER][nd->minor] = sn->maxsize_req;
  
  // on initialise la queue des requêtes
  blk_init_queue(&nd->queue, smd_request);
  blk_queue_headactive(&nd->queue,0);
  
  PDEBUG("dev queue iniatilized\n");

  minor2ndev[nd->minor] = nd;
  sn->ndevs[no_ndev] = nd;
  PDEBUG("networked device '%s' added\n", nd->name);
  return SUCCESS;

 error:
  vfree(nd);
  return ERROR;

}