Example #1
0
/*===========================================================================*
 *				fs_breadwrite				     *
 *===========================================================================*/
PUBLIC int fs_breadwrite(void)
{
  int r, rw_flag, completed;
  cp_grant_id_t gid;
  u64_t position;
  unsigned int off, cum_io, chunk, block_size;
  size_t nrbytes;
  dev_t target_dev;

  /* Pseudo inode for rw_chunk */
  struct inode rip;
  
  r = OK;

  target_dev = (dev_t) fs_m_in.REQ_DEV2;
  
  /* Get the values from the request message */ 
  rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING);
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  position = make64((unsigned long) fs_m_in.REQ_SEEK_POS_LO,
  		    (unsigned long) fs_m_in.REQ_SEEK_POS_HI);
  nrbytes = (size_t) fs_m_in.REQ_NBYTES;
  
  block_size = get_block_size(target_dev);

  /* Don't block-write to a RO-mounted filesystem. */
  if(superblock.s_dev == target_dev && superblock.s_rd_only)
  	return EROFS;

  rip.i_zone[0] = (zone_t) target_dev;
  rip.i_mode = I_BLOCK_SPECIAL;
  rip.i_size = 0;

  rdwt_err = OK;		/* set to EIO if disk error occurs */
  
  cum_io = 0;
  /* Split the transfer into chunks that don't span two blocks. */
  while (nrbytes > 0) {
	  off = rem64u(position, block_size);	/* offset in blk*/
	  chunk = min(nrbytes, block_size - off);

	  /* Read or write 'chunk' bytes. */
	  r = rw_chunk(&rip, position, off, chunk, nrbytes, rw_flag, gid,
	  	       cum_io, block_size, &completed);

	  if (r != OK) break;	/* EOF reached */
	  if (rdwt_err < 0) break;

	  /* Update counters and pointers. */
	  nrbytes -= chunk;	        /* bytes yet to be read */
	  cum_io += chunk;	        /* bytes read so far */
	  position = add64ul(position, chunk);	/* position within the file */
  }
  
  fs_m_out.RES_SEEK_POS_LO = ex64lo(position); 
  fs_m_out.RES_SEEK_POS_HI = ex64hi(position); 
  
  if (rdwt_err != OK) r = rdwt_err;	/* check for disk error */
  if (rdwt_err == END_OF_FILE) r = OK;

  fs_m_out.RES_NBYTES = cum_io;
  
  return(r);
}
Example #2
0
			/**
			 * The size of a compressed block.
			 * @return Size of a compressed block (4x4) in bytes.
			 */
			inline Uint16 get_block_size() const
			{
				return get_block_size(get_pixel_size());
			}
Example #3
0
/*===========================================================================*
 *				fs_readwrite				     *
 *===========================================================================*/
PUBLIC int fs_readwrite(void)
{
  int r, rw_flag, block_spec;
  int regular;
  cp_grant_id_t gid;
  off_t position, f_size, bytes_left;
  unsigned int off, cum_io, block_size, chunk;
  mode_t mode_word;
  int completed;
  struct inode *rip;
  size_t nrbytes;

  r = OK;

  /* Find the inode referred */
  if ((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
	return(EINVAL);

  mode_word = rip->i_mode & I_TYPE;
  regular = (mode_word == I_REGULAR || mode_word == I_NAMED_PIPE);
  block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0);

  /* Determine blocksize */
  if (block_spec) {
	block_size = get_block_size( (dev_t) rip->i_block[0]);
	f_size = MAX_FILE_POS;
  } else {
	block_size = rip->i_sp->s_block_size;
	f_size = rip->i_size;
	if (f_size < 0) f_size = MAX_FILE_POS;
  }

  /* Get the values from the request message */
  rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
  nrbytes = (size_t) fs_m_in.REQ_NBYTES;

  rdwt_err = OK;                /* set to EIO if disk error occurs */

  if (rw_flag == WRITING && !block_spec) {
	/* Check in advance to see if file will grow too big. */
	if (position > (off_t) (rip->i_sp->s_max_size - nrbytes))
		return(EFBIG);
  }

  cum_io = 0;
  /* Split the transfer into chunks that don't span two blocks. */
  while (nrbytes != 0) {
	off = (unsigned int) (position % block_size);/* offset in blk*/
	chunk = MIN(nrbytes, block_size - off);

	if (rw_flag == READING) {
		bytes_left = f_size - position;
		if (position >= f_size) break;        /* we are beyond EOF */
		if (chunk > bytes_left) chunk = (int) bytes_left;
	}

	/* Read or write 'chunk' bytes. */
	r = rw_chunk(rip, cvul64((unsigned long) position), off, chunk,
		     nrbytes, rw_flag, gid, cum_io, block_size, &completed);

	if (r != OK) break;   /* EOF reached */
	if (rdwt_err < 0) break;

	/* Update counters and pointers. */
	nrbytes -= chunk;     /* bytes yet to be read */
	cum_io += chunk;      /* bytes read so far */
	position += (off_t) chunk;    /* position within the file */
  }

  fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS
                                           has to know this value */

  /* On write, update file size and access time. */
  if (rw_flag == WRITING) {
	if (regular || mode_word == I_DIRECTORY) {
		if (position > f_size) rip->i_size = position;
        }
  }

  /* Check to see if read-ahead is called for, and if so, set it up. */
  if(rw_flag == READING && rip->i_seek == NO_SEEK &&
     (unsigned int) position % block_size == 0 &&
     (regular || mode_word == I_DIRECTORY)) {
	rdahed_inode = rip;
	rdahedpos = position;
  }

  rip->i_seek = NO_SEEK;

  if (rdwt_err != OK) r = rdwt_err;     /* check for disk error */
  if (rdwt_err == END_OF_FILE) r = OK;

  if (r == OK) {
	if (rw_flag == READING) rip->i_update |= ATIME;
	if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
	rip->i_dirt = DIRTY;          /* inode is thus now dirty */
  }

  fs_m_out.RES_NBYTES = cum_io;

  return(r);
}
void InitBLAC(Bsystem *Bsys){

  int i,j;
  int *BLACS_PARAMS;
  static int INIT_FLAG_COMM = 0;

  Bsys->Pmat->info.lenergy.DESC_ivert   = ivector(0,8);
  Bsys->Pmat->info.lenergy.DESC_rhs     = ivector(0,8);
  Bsys->Pmat->info.lenergy.BLACS_PARAMS = ivector(0,14);

  BLACS_PARAMS = Bsys->Pmat->info.lenergy.BLACS_PARAMS;

  BLACS_PARAMS[7] = Bsys->pll->nv_gpsolve;
  BLACS_PARAMS[8] = Bsys->pll->nv_gpsolve;

  /* determinate dimension of grid of CPUs  */
  get_proc_grid(pllinfo[get_active_handle()].nprocs, &i, &j);
  BLACS_PARAMS[3] = i;
  BLACS_PARAMS[4] = j;

  /* determinate size of basic block in global boundary operator */
  BLACS_PARAMS[9]  = get_block_size(BLACS_PARAMS[7], BLACS_PARAMS[3]);
  BLACS_PARAMS[10] = get_block_size(BLACS_PARAMS[8], BLACS_PARAMS[4]);

  if (BLACS_PARAMS[9] < BLACS_PARAMS[10])
     BLACS_PARAMS[10] = BLACS_PARAMS[9];
  else
     BLACS_PARAMS[9] = BLACS_PARAMS[10];

  blacs_gridinit_nektar(BLACS_PARAMS, Bsys->Pmat->info.lenergy.DESC_ivert, Bsys->Pmat->info.lenergy.DESC_rhs);

  /* allocate memory for local partition of ivert */
  /* since we use ScaLAPACK (fortran)- use transpose of  inva_LOC  */

  Bsys->Pmat->info.lenergy.ivert_local  = dmatrix(0,BLACS_PARAMS[12]-1,
                 0,BLACS_PARAMS[11]-1);

  memset(Bsys->Pmat->info.lenergy.ivert_local[0],'\0',BLACS_PARAMS[11]*
   BLACS_PARAMS[12]*sizeof(double));


  Bsys->Pmat->info.lenergy.ivert_ipvt = ivector(0,BLACS_PARAMS[7]-1);

  Bsys->Pmat->info.lenergy.map_row    = ivector(0,BLACS_PARAMS[11]-1);
  get_gather_map(BLACS_PARAMS,'r',Bsys->Pmat->info.lenergy.map_row);

  Bsys->Pmat->info.lenergy.col_displs = ivector(0,BLACS_PARAMS[3]-1);
  Bsys->Pmat->info.lenergy.col_rcvcnt = ivector(0,BLACS_PARAMS[3]-1);
  memset(Bsys->Pmat->info.lenergy.col_displs,'\0',BLACS_PARAMS[3]*sizeof(int));
  memset(Bsys->Pmat->info.lenergy.col_rcvcnt,'\0',BLACS_PARAMS[3]*sizeof(int));

   /* create row and column communicators by splitting */
   /* all processors construct 2D grid */
   if (INIT_FLAG_COMM == 0){
     int info;

     info = MPI_Comm_split(get_MPI_COMM(), BLACS_PARAMS[6], BLACS_PARAMS[5], &MPI_COMM_COLUMN_NEW);
     if (info != MPI_SUCCESS){
       fprintf (stderr, "scatter_topology_nektar: MPI split error\n");
       exit(1);
     }
     info = MPI_Comm_split(get_MPI_COMM(), BLACS_PARAMS[5], BLACS_PARAMS[6], &MPI_COMM_ROW_NEW);
      if (info != MPI_SUCCESS) {
        fprintf (stderr, "scatter_topology_nektar: MPI split error\n");
        exit(1);
     }
     INIT_FLAG_COMM = 1;
   }


  /* summary */
  for (i = 0; i < 13; i++)
     if (pllinfo[get_active_handle()].procid == 0)
       printf(" Ubsys->Gmat->BLACS_PARAMS[%d] = %d \n ",i,Bsys->Pmat->info.lenergy.BLACS_PARAMS[i]);

}
main(int argc, char **argv)
{
	int disk_fd, c;
	char *disk_devname, *ssd_devname, *cachedev;
	sector_t block_size = 0, cache_size = 0;
	sector_t disk_devsize;
	int write_around = 0;
	
	pname = argv[0];
	while ((c = getopt(argc, argv, "fs:b:vr")) != -1) {
		switch (c) {
		case 's':
			cache_size = get_cache_size(optarg);
			break;
		case 'b':
			block_size = get_block_size(optarg);
			/* Block size should be a power of 2 */
                        break;
		case 'v':
			verbose = 1;
                        break;			
		case 'f':
			force = 1;
                        break;
		case 'r':
			write_around = 1;
                        break;
		case '?':
			usage(pname);
		}
	}
	if (optind == argc)
		usage(pname);
	if (block_size == 0)
		block_size = 8;		/* 4KB default blocksize */
	cachedev = argv[optind++];
	if (optind == argc)
		usage(pname);
	ssd_devname = argv[optind++];
	if (optind == argc)
		usage(pname);
	disk_devname = argv[optind];
	disk_fd = open(disk_devname, O_RDONLY);
	if (disk_fd < 0) {
		fprintf(stderr, "%s: Failed to open %s\n", 
			pname, disk_devname);
		exit(1);
	}
	if (ioctl(disk_fd, BLKGETSIZE, &disk_devsize) < 0) {
		fprintf(stderr, "%s: Cannot get disk size %s\n", 
			pname, disk_devname);
		exit(1);				
	}
	printf("cachedev %s, ssd_devname %s, disk_devname %s\n", 
	       cachedev, ssd_devname, disk_devname);
	printf("cache mode %s, block_size %lu, cache_size %lu\n", 
	       ((write_around) ? "WRITE_AROUND" : "WRITE_THRU"), block_size, cache_size);
	sprintf(dmsetup_cmd, "echo 0 %lu flashcache-wt %s %s %d %lu ",
		disk_devsize, disk_devname, ssd_devname, write_around, block_size);
	if (cache_size > 0) {
		char cache_size_str[4096];
		
		sprintf(cache_size_str, "%lu ", cache_size);
		strcat(dmsetup_cmd, cache_size_str);
	}
	/* Go ahead and create the cache.
	 * XXX - Should use the device mapper library for this.
	 */
	strcat(dmsetup_cmd, "| dmsetup create ");
	strcat(dmsetup_cmd, cachedev);
	strcat(dmsetup_cmd, "\n");
	load_module();
	if (verbose)
		fprintf(stderr, "Creating FlashCache_wt Volume : %s", dmsetup_cmd);
	system(dmsetup_cmd);
}
Example #6
0
uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size)
{
    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(pp_buffer);
    NULL_PARAM_CHECK(p_size);

    const uint32_t requested_size = (*p_size);

    VERIFY_REQUESTED_SIZE(requested_size);

    NRF_LOG_DEBUG("[MM]: >> nrf_mem_reserve, size 0x%04lX.\r\n", requested_size);

    MM_MUTEX_LOCK();

    const uint32_t block_cat    = get_block_cat(requested_size, TOTAL_BLOCK_COUNT);
    uint32_t       block_index  = m_block_start[block_cat];
    uint32_t       memory_index = m_block_mem_start[block_cat];
    uint32_t       err_code     = (NRF_ERROR_NO_MEM | MEMORY_MANAGER_ERR_BASE);

    NRF_LOG_DEBUG("[MM]: Start index for the pool = 0x%08lX, total block count 0x%08X\r\n",
                  block_index,
                  TOTAL_BLOCK_COUNT);

    for (; block_index < TOTAL_BLOCK_COUNT; block_index++)
    {
        uint32_t block_size = get_block_size(block_index);

        if (is_block_free(block_index) == true)
        {
            NRF_LOG_DEBUG("[MM]: Reserving block 0x%08lX\r\n", block_index);

            // Search succeeded, found free block.
            err_code     = NRF_SUCCESS;

            // Allocate block.
            block_allocate(block_index);

            (*pp_buffer) = &m_memory[memory_index];
            (*p_size)    = block_size;

#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
            (*p_min_size) = MIN((*p_min_size), requested_size);
            (*p_max_size) = MAX((*p_max_size), requested_size);
#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS

            break;
        }
        memory_index += block_size;
    }
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_DEBUG ("[MM]: Memory reservation result %d, memory %p, size %d!",
                       err_code,
                       (uint32_t)(*pp_buffer),
                       (*p_size));

#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
        nrf_mem_diagnose();
#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
    }

    MM_MUTEX_UNLOCK();

    NRF_LOG_DEBUG("[MM]: << nrf_mem_reserve %p, result 0x%08lX.\r\n",
                  (uint32_t)(*pp_buffer), err_code);

    return err_code;
}
// Return a pointer to a block given its number.
// get_block(fs, 0) == fs;
void * _ref_get_block(void * fs, __u32 block_num) {
    __u32 block_size = get_block_size(fs);
    return fs + (block_num * block_size);
}
Example #8
0
/* start from bootloader_message.slot_suffix[BOOTCTRL_IDX] */
#define BOOTCTRL_IDX				0
#define BOOTCTRL_OFFSET		\
	(u32)(&(((struct bootloader_message *)0)->slot_suffix[BOOTCTRL_IDX]))
#define CRC_DATA_OFFSET		\
	(uint32_t)(&(((struct boot_ctl *)0)->a_slot_meta[0]))

struct slot_meta {
	u8 bootsuc:1;
	u8 tryremain:3;
	u8 priority:4;
};

struct boot_ctl {
	char magic[4]; /* "\0FSL" */
	u32 crc;
	struct slot_meta a_slot_meta[SLOT_NUM];
	u8 recovery_tryremain;
};

static unsigned int g_mmc_id;
static unsigned int g_slot_selected;
static const char *g_slot_suffix[SLOT_NUM] = {"_a", "_b"};

static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);

static int strcmp_l1(const char *s1, const char *s2)
{
	if (!s1 || !s2)
		return -1;
	return strncmp(s1, s2, strlen(s1));
}

void set_mmc_id(unsigned int id)
{
	g_mmc_id = id;
}

static void dump_slotmeta(struct boot_ctl *ptbootctl)
{
	int i;

	if (ptbootctl == NULL)
		return;

	printf("RecoveryTryRemain %d, crc %u\n",
		   ptbootctl->recovery_tryremain, ptbootctl->crc);

	for (i = 0; i < SLOT_NUM; i++) {
		printf("slot %d: pri %d, try %d, suc %d\n", i,
			   ptbootctl->a_slot_meta[i].priority,
				ptbootctl->a_slot_meta[i].tryremain,
				ptbootctl->a_slot_meta[i].bootsuc);
	}

	return;
}

const char *get_slot_suffix(void)
{
	return g_slot_suffix[g_slot_selected];
}

static unsigned int slot_find(struct boot_ctl *ptbootctl)
{
	unsigned int max_pri = 0;
	unsigned int slot = -1;
	int i;

	for (i	= 0; i < SLOT_NUM; i++) {
		struct slot_meta *pslot_meta = &(ptbootctl->a_slot_meta[i]);
		if ((pslot_meta->priority > max_pri) &&
			((pslot_meta->bootsuc > 0) ||
			(pslot_meta->tryremain > 0))) {
			max_pri = pslot_meta->priority;
			slot = i;
			printf("select_slot slot %d\n", slot);
		}
	}

	return slot;
}

static ulong get_block_size(char *ifname, int dev, int part)
{
	block_dev_desc_t *dev_desc = NULL;
	disk_partition_t part_info;

	dev_desc = get_dev(ifname, dev);
	if (dev_desc == NULL) {
		printf("Block device %s %d not supported\n", ifname, dev);
		return 0;
	}

	if (get_partition_info(dev_desc, part, &part_info)) {
		printf("Cannot find partition %d\n", part);
		return 0;
	}

	return part_info.blksz;
}

#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */
static int rw_block(bool bread, char **ppblock,
					uint *pblksize, char *pblock_write)
{
	int ret;
	char *argv[6];
	char addr_str[20];
	char cnt_str[8];
	char devpart_str[8];
	char block_begin_str[8];
	ulong blk_size = 0;
	uint blk_begin = 0;
	uint blk_end = 0;
	uint block_cnt = 0;
	char *p_block = NULL;

	if (bread && ((ppblock == NULL) || (pblksize == NULL)))
		return -1;

	if (!bread && (pblock_write == NULL))
		return -1;

	blk_size = get_block_size("mmc", g_mmc_id,
			CONFIG_ANDROID_MISC_PARTITION_MMC);
	if (blk_size == 0) {
		printf("rw_block, get_block_size return 0\n");
		return -1;
	}

	blk_begin = BOOTCTRL_OFFSET/blk_size;
	blk_end = (BOOTCTRL_OFFSET + sizeof(struct boot_ctl) - 1)/blk_size;
	block_cnt = 1 + (blk_end - blk_begin);

	sprintf(devpart_str, "0x%x:0x%x", g_mmc_id,
		CONFIG_ANDROID_MISC_PARTITION_MMC);
	sprintf(block_begin_str, "0x%x", blk_begin);
	sprintf(cnt_str, "0x%x", block_cnt);

	argv[0] = "rw"; /* not care */
	argv[1] = "mmc";
	argv[2] = devpart_str;
	argv[3] = addr_str;
	argv[4] = block_begin_str;
	argv[5] = cnt_str;

	if (bread) {
		p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt);
		if (NULL == p_block) {
			printf("rw_block, memalign %d bytes failed\n",
			       (int)(blk_size * block_cnt));
			return -1;
		}
		sprintf(addr_str, "0x%x", (unsigned int)p_block);
		ret = do_read(NULL, 0, 6, argv);
		if (ret) {
			free(p_block);
			printf("do_read failed, ret %d\n", ret);
			return -1;
		}

		*ppblock = p_block;
		*pblksize = (uint)blk_size;
	} else {
		sprintf(addr_str, "0x%x", (unsigned int)pblock_write);
		ret = do_write(NULL, 0, 6, argv);
		if (ret) {
			printf("do_write failed, ret %d\n", ret);
			return -1;
		}
	}

	return 0;
}
// Return a pointer to a block given its number.
// get_block(fs, 0) == fs;
void * get_block(void * fs, __u32 block_num) {
  return fs + block_num * get_block_size(fs);
}
Example #10
0
// Return a pointer to a block given its number.
// get_block(fs, 0) == fs;
void * get_block(void * fs, __u32 block_num) {
    return (void *) ((size_t) fs + get_block_size(fs) * block_num);
}
Example #11
0
int main(int argc, char **argv) 
{
  iso_primary_descriptor_type  ipd;
  char *dev = default_dev;
  char vendor[9],model[17],rev[5];
  unsigned char reply[1024];
  char tmpstr[255];
  int replylen=sizeof(reply);
  int trackno = 0;
  int info_only = 0;
  unsigned char *buffer;
  int buffersize = READBLOCKS*BLOCKSIZE;
  int start,stop,imagesize=0,tracksize=0;
  int counter = 0;
  long readsize = 0;
  long imagesize_bytes = 0;
  int drive_block_size, init_bsize;
  int force_mode = 0;
  int scanbus_mode = 0;
  int dump_start, dump_count;
  MD5_CTX *MD5; 
  char digest[16],digest_text[33];
  int md5_mode = 0;
  int opt_index = 0;
  int audio_track = 0;
  int readblocksize = BLOCKSIZE;
  int file_format = AF_FILE_AIFFC;
#ifdef IRIX
  CDPARSER *cdp = CDcreateparser();
  CDFRAME  cdframe;
#endif
  int dev_type;
  int i,c,o;
  int len;
  int start_time,cur_time,kbps;

  if (rcsid); 

  MD5 = malloc(sizeof(MD5_CTX));
  buffer=(unsigned char*)malloc(READBLOCKS*AUDIOBLOCKSIZE);
  if (!buffer || !MD5) die("No memory");

  if (argc<2) die("parameter(s) missing\n"
	          "Try '%s --help' for more information.\n",PRGNAME);

 
  /* parse command line parameters */
  while(1) {
    if ((c=getopt_long(argc,argv,"SMmvhid:",long_options,&opt_index))
	== -1) break;
    switch (c) {
    case 'a':
      file_format=AF_FILE_AIFF;
      break;
    case 'A':
      file_format=AF_FILE_AIFFC;
      break;
    case 'v':
      verbose_mode=1;
      break;
    case 'h':
      p_usage();
      break;
    case 'd':
      dev=strdup(optarg);
      break;
    case 't':
      if (sscanf(optarg,"%d",&trackno)!=1) trackno=0;
      break;
    case 'i':
      info_only=1; 
      break;
    case 'c':
      if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2)
	die("invalid parameters");
      dump_mode=1;
      break;
#ifdef IRIX
    case 'C':
      if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2)
	die("invalid parameters");
      dump_mode=2;
      break;
#endif
    case 'f':
      if (sscanf(optarg,"%d",&force_mode)!=1) die("invalid parameters");
      if (force_mode<1 || force_mode >2) {
	die("invalid parameters");
      }
      break;
    case 'm':
      md5_mode=1;
      break;
    case 'M':
      md5_mode=2;
      break;
    case 's':
      audio_mode=1;
      break;
    case 'S':
      scanbus_mode=1;
      break;
    case 'V':
      printf(PRGNAME " "  VERSION "  " HOST_TYPE
	     "\nCopyright (c) Timo Kokkonen, 1997-1998.\n\n"); 
      exit(0);
      break;

    case '?':
      break;

    default:
      die("error parsing parameters");

    }
  }


  if (!info_only) {
    if (md5_mode==2) outfile=fopen("/dev/null","w");
    else outfile=fopen(argv[optind],"w");
    if (!outfile) {
      if (argv[optind]) die("cannot open output file '%s'",argv[optind]);
      info_only=1;
    }
  }

  printf("readiso(9660) " VERSION "\n");

  /* open the scsi device */
  if (scsi_open(dev)) die("error opening scsi device '%s'",dev); 

  if (scanbus_mode) {
    printf("\n");
    scan_bus();
    exit(0);
  }
  
  memset(reply,0,sizeof(reply));
  if ((dev_type=inquiry(vendor,model,rev))<0) 
    die("error accessing scsi device");

  if (verbose_mode) {
    printf("device:   %s\n",dev);
    printf("Vendor:   %s\nModel:    %s\nRevision: %s\n",vendor,model,rev);
  }

  if ( (dev_type&0x1f) != 0x5 ) {
    die("Device doesn't seem to be a CD-ROM!");
  }

#ifdef IRIX
  if (strcmp(vendor,"TOSHIBA")) {
    warn("NOTE! Audio track reading probably not supported on this device.\n");
  }
#endif

  test_ready();
  if (test_ready()!=0) {
    sleep(2);
    if (test_ready()!=0)  die("device not ready");
  }

  fprintf(stderr,"Initializing...\n");
  if (audio_mode) {
#ifdef IRIX
    audioport=ALopenport("readiso","w",0);
    if (!audioport) {
      warn("Cannot initialize audio.");
      audio_mode=0;
    }
#else
    audio_mode=0;
#endif
  }


#ifdef IRIX
  /* Make sure we get sane underflow exception handling */
  sigfpe_[_UNDERFL].repls = _ZERO;
  handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL);
#endif

  /* set_removable(1); */

#if 0
  replylen=255;
  if (mode_sense10(reply,&replylen)==0) {
    printf("replylen=%d blocks=%d blocklen=%d\n",replylen,
	   V3(&reply[8+1]),V3(&reply[8+5]));
    PRINT_BUF(reply,replylen);
  }
  replylen=255; /* sizeof(reply); */
  if (mode_sense(reply,&replylen)==0) {
    printf("replylen=%d blocks=%d blocklen=%d\n",replylen,
	   V3(&reply[4+1]),V3(&reply[4+5]));
    PRINT_BUF(reply,replylen);
  }
#endif

  if (dump_mode==2) init_bsize=AUDIOBLOCKSIZE;
  else init_bsize=BLOCKSIZE;

  start_stop(0);

  if ( (drive_block_size=get_block_size()) < 0 ) {
    warn("cannot get current block size");
    drive_block_size=init_bsize;
  }

  if (drive_block_size != init_bsize) {
    mode_select(init_bsize,(dump_mode==2?0x82:0x00));
    drive_block_size=get_block_size();
    if (drive_block_size!=init_bsize) warn("cannot set drive block size.");
  }

  start_stop(1);

  if (dump_mode && !info_only) {
#ifdef IRIX
    CDFRAME buf;
    if (dump_mode==2) {
      if (cdp) {
	CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0);
      } else die("No audioparser");
    }
#endif
    fprintf(stderr,"Dumping %d sector(s) starting from LBA=%d\n",
	    dump_count,dump_start);
    for (i=dump_start;i<dump_start+dump_count;i++) {
      len=buffersize;
      read_10(i,1,buffer,&len);
      if (len<init_bsize) break;

#ifdef IRIX
      if (dump_mode==2) {
	memcpy(&buf,buffer,CDDA_BLOCKSIZE);
	CDparseframe(cdp,&buf);
      }
#endif
	
      fwrite(buffer,len,1,outfile); 
      fprintf(stderr,".");
    }
    fprintf(stderr,"\ndone.\n");
    
    goto quit;
  }


  fprintf(stderr,"Reading disc TOC...");
  replylen=sizeof(reply);
  read_toc(reply,&replylen,verbose_mode);
  printf("\n");

  if (trackno==0) { /* try to find first data track */
    for (i=0;i<(reply[3]-reply[2]+1);i++) {
      o=4+i*8;
      if (reply[o+1]&DATA_TRACK) { trackno=i+1; break; }
    }
    if (trackno==0) die("No data track(s) found.");
  }

  fprintf(stderr,"Reading track %d...\n",trackno); 

  if ( (trackno < reply[2]) || (trackno > reply[3]) )
    die("Invalid track specified.");
    
  if ( ((reply[(trackno-1)*8+4+1]&DATA_TRACK)==0) ) {
    fprintf(stderr,"Not a data track.\n");
    mode_select(AUDIOBLOCKSIZE,0x82);
    if (mode_sense(reply,&replylen)!=0) die("cannot get sense data");
    drive_block_size=V3(&reply[9]);
    fprintf(stderr,"Selecting CD-DA mode, output file format: %s\n",
	    file_format==AF_FILE_AIFFC?"AIFFC":"AIFF");
    audio_track=1;
  } else {
    audio_track=0;
  }


  start=V4(&reply[(trackno-1)*8+4+4]);
  stop=V4(&reply[(trackno)*8+4+4]);
  tracksize=abs(stop-start);
  /* if (verbose_mode) printf("Start LBA=%d\nStop  LBA=%d\n",start,stop); */

  len=buffersize;
  read_10(start-0,1,buffer,&len);
  /* PRINT_BUF(buffer,32); */

  
  if (!audio_track) {
    /* read the iso9660 primary descriptor */
    fprintf(stderr,"Reading ISO9660 primary descriptor...\n");
    len=buffersize;
    read_10(start+16,1,buffer,&len);
    if (len<sizeof(ipd)) die("cannot read iso9660 primary descriptor.");
    memcpy(&ipd,buffer,sizeof(ipd));
    
    imagesize=ISONUM(ipd.volume_space_size);
    
    /* we should really check here if we really got a valid primary 
       descriptor or not... */
    if ( (imagesize>(stop-start)) || (imagesize<1) ) {
      fprintf(stderr,"\aInvalid ISO primary descriptor!!!\n");
      if (!info_only) fprintf(stderr,"Copying entire track to image file.\n");
      force_mode=2;
    }
    
    if (force_mode==1) {} /* use size from ISO primary descriptor */
    else if (force_mode==2) imagesize=tracksize; /* use size from TOC */
    else {
      if (  ( (tracksize-imagesize) > MAX_DIFF_ALLOWED ) || 
	    ( imagesize > tracksize )  )   {
	fprintf(stderr,"ISO primary descriptor has suspicious volume size"
		" (%d blocks)\n",imagesize);
	imagesize=tracksize;
	fprintf(stderr,
		"Using track size from TOC record (%d blocks) instead.\n", 
		imagesize);
	fprintf(stderr,
		"(option -f can be used to override this behaviour.)\n");
      }
    }

    imagesize_bytes=imagesize*BLOCKSIZE;
    

    if (verbose_mode||info_only) {
      printf("ISO9660 image info:\n");
      printf("Type:              %02xh\n",ipd.type[0]);  
      ISOGETSTR(tmpstr,ipd.id,5);
      printf("ID:                %s\n",tmpstr);
      printf("Version:           %u\n",ipd.version[0]);
      ISOGETSTR(tmpstr,ipd.system_id,32);
      printf("System id:         %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.volume_id,32);
      printf("Volume id:         %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.volume_set_id,128);
      if (strlen(tmpstr)>0) printf("Volume set id:     %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.publisher_id,128);
      if (strlen(tmpstr)>0) printf("Publisher id:      %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.preparer_id,128);
      if (strlen(tmpstr)>0) printf("Preparer id:       %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.application_id,128);
      if (strlen(tmpstr)>0) printf("Application id:    %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.creation_date);
      printf("Creation date:     %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.modification_date);
      if (!NULLISODATE(ipd.modification_date)) 
	printf("Modification date: %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.expiration_date);
      if (!NULLISODATE(ipd.expiration_date))
	printf("Expiration date:   %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.effective_date);
      if (!NULLISODATE(ipd.effective_date))
	printf("Effective date:    %s\n",tmpstr);
      
      printf("Image size:        %02d:%02d:%02d, %d blocks (%ld bytes)\n",
	      LBA_MIN(ISONUM(ipd.volume_space_size)),
	      LBA_SEC(ISONUM(ipd.volume_space_size)),
	      LBA_FRM(ISONUM(ipd.volume_space_size)),
	      ISONUM(ipd.volume_space_size),
	      (long)ISONUM(ipd.volume_space_size)*BLOCKSIZE
	     );
      printf("Track size:        %02d:%02d:%02d, %d blocks (%ld bytes)\n",
	      LBA_MIN(tracksize),
	      LBA_SEC(tracksize),
	      LBA_FRM(tracksize),
	      tracksize,
	      (long)tracksize*BLOCKSIZE
	     );
    }
  } else { 
#ifdef IRIX
    /* if reading audio track */
    imagesize=tracksize;
    imagesize_bytes=imagesize*CDDA_DATASIZE;
    buffersize = READBLOCKS*AUDIOBLOCKSIZE;
    readblocksize = AUDIOBLOCKSIZE;

    if (cdp) {
      CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0);
    } else die("No audioparser");
    
    fclose(outfile);
    aiffsetup=AFnewfilesetup();
    AFinitrate(aiffsetup,AF_DEFAULT_TRACK,44100.0); /* 44.1 kHz */
    AFinitfilefmt(aiffsetup,file_format);           /* set file format */
    AFinitchannels(aiffsetup,AF_DEFAULT_TRACK,2);   /* stereo */
    AFinitsampfmt(aiffsetup,AF_DEFAULT_TRACK,
		  AF_SAMPFMT_TWOSCOMP,16);          /* 16bit */
    aiffoutfile=AFopenfile(argv[optind],"w",aiffsetup);
    if (!aiffoutfile) die("Cannot open target file (%s).",argv[optind]);
#endif
  }

  /* read the image */

  if (md5_mode) MD5Init(MD5);

  if (!info_only) {
    start_time=(int)time(NULL);
    fprintf(stderr,"Reading %s (%ldMb)...\n",
	    audio_track?"audio track":"ISO9660 image",
	    imagesize_bytes/(1024*1024));

    do {
      len=buffersize;
      if(readsize/readblocksize+READBLOCKS>imagesize) {
	read_10(start+counter,imagesize-readsize/readblocksize,buffer,&len);
      }
      else
	read_10(start+counter,READBLOCKS,buffer,&len);
      if ((counter%(1024*1024/readblocksize))<READBLOCKS) {
	cur_time=(int)time(NULL);
	if ((cur_time-start_time)>0) {
	  kbps=(readsize/1024)/(cur_time-start_time);
	} else {
	  kbps=0;
	}
	
	fprintf(stderr,"%3dM of %dM read. (%d kb/s)         \r",
		counter/512,imagesize/512,kbps);
      }
      counter+=READBLOCKS;
      readsize+=len;
      if (!audio_track) {
	fwrite(buffer,len,1,outfile);
      } else {
#ifdef IRIX
	/* audio track */
	for(i=0;i<(len/CDDA_BLOCKSIZE);i++) {
	  CDparseframe(cdp,(CDFRAME*)&buffer[i*CDDA_BLOCKSIZE]);
	}
#endif
      }
      if (md5_mode) MD5Update(MD5,buffer,(readsize>imagesize_bytes?
				       len-(readsize-imagesize_bytes):len) );
    } while (len==readblocksize*READBLOCKS&&readsize<imagesize*readblocksize);
    
    fprintf(stderr,"\n");
    if (!audio_track) {
      if (readsize > imagesize_bytes) 
	ftruncate(fileno(outfile),imagesize_bytes);
      if (readsize < imagesize_bytes) 
	fprintf(stderr,"Image not complete!\n");
      else fprintf(stderr,"Image complete.\n");
      fclose(outfile);
    } else {
#ifdef IRIX
      AFclosefile(aiffoutfile);
#endif
    }
  }

  if (md5_mode && !info_only) {
    MD5Final((unsigned char*)digest,MD5);
    md2str((unsigned char*)digest,digest_text);
    fprintf(stderr,"MD5 (%s) = %s\n",(md5_mode==2?"'image'":argv[optind]),
	    digest_text);
  }

 quit:
  start_stop(0);
  /* set_removable(1); */

  /* close the scsi device */
  scsi_close();

  return 0;
}
Example #12
0
int
main(int argc, char **argv)
{
	setlocale(LC_ALL, "");
	program_name = argv[0];

	opt_block_size = get_block_size();

	int c;
	while ((c = getopt(argc, argv, "b:c:")) != -1) {
		switch (c) {
		case 'b':
			if (!parse_arg_block_size(optarg))
				usage();
			break;
		case 'c':
			if (!parse_arg_compression(optarg))
				usage();
			break;
		default:
			usage();
		}
	}

	if (argc - optind < 2)
		usage();
	mtbl_output_fname = argv[argc - 1];

	/* open user dso */
	init_dso();

	/* open merger, writer */
	init_mtbl();

	/* open readers */
	const size_t n_readers = argc - 1 - optind;
	struct mtbl_reader *readers[n_readers];
	for (size_t i = 0; i < n_readers; i++) {
		const char *fname = argv[i + optind];
		fprintf(stderr, "%s: opening input file %s\n", program_name, fname);
		readers[i] = mtbl_reader_init(fname, NULL);
		if (readers[i] == NULL) {
			fprintf(stderr, "Error: mtbl_reader_init() failed.\n\n");
			usage();
		}
		mtbl_merger_add_source(merger, mtbl_reader_source(readers[i]));
	}

	/* do merge */
	my_timespec_get(&start_time);
	merge();

	/* cleanup readers */
	for (size_t i = 0; i < n_readers; i++)
		mtbl_reader_destroy(&readers[i]);

	/* call user cleanup */
	if (user_func_free != NULL)
		user_func_free(user_clos);

	print_stats();

	return (EXIT_SUCCESS);
}
Example #13
0
/*
 * cl_update (CUDA version)
 */
static void update_func_cuda(void *descr[], void *arg)
{
    struct block_description *block = arg;
    int workerid = starpu_worker_get_id();
    DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    if (block->bz == 0)
        fprintf(stderr,"!!! DO update_func_cuda z %d CUDA%d !!!\n", block->bz, workerid);
    else
        DEBUG( "!!! DO update_func_cuda z %d CUDA%d !!!\n", block->bz, workerid);
#ifdef STARPU_USE_MPI
    int rank = 0;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    DEBUG( "!!!           RANK %d              !!!\n", rank);
#endif
    DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");

    unsigned block_size_z = get_block_size(block->bz);
    unsigned i;
    update_per_worker[workerid]++;

    struct timeval tv, tv2, diff, delta = {.tv_sec = 0, .tv_usec = get_ticks()*1000};
    gettimeofday(&tv, NULL);
    timersub(&tv, &start, &tv2);
    timersub(&tv2, &last_tick[block->bz], &diff);
    while (timercmp(&diff, &delta, >=)) {
        timeradd(&last_tick[block->bz], &delta, &last_tick[block->bz]);
        timersub(&tv2, &last_tick[block->bz], &diff);
        if (who_runs_what_index[block->bz] < who_runs_what_len)
            who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = -1;
    }

    if (who_runs_what_index[block->bz] < who_runs_what_len)
        who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = global_workerid(workerid);

    /*
     *	Load neighbours' boundaries : TOP
     */

    /* The offset along the z axis is (block_size_z + K) */
    load_subblock_from_buffer_cuda(descr[0], descr[2], block_size_z+K);
    load_subblock_from_buffer_cuda(descr[1], descr[3], block_size_z+K);

    /*
     *	Load neighbours' boundaries : BOTTOM
     */
    load_subblock_from_buffer_cuda(descr[0], descr[4], 0);
    load_subblock_from_buffer_cuda(descr[1], descr[5], 0);

    /*
     *	Stencils ... do the actual work here :) TODO
     */

    for (i=1; i<=K; i++)
    {
        starpu_block_interface_t *oldb = descr[i%2], *newb = descr[(i+1)%2];
        TYPE *old = (void*) oldb->ptr, *new = (void*) newb->ptr;

        /* Shadow data */
        cuda_shadow_host(block->bz, old, oldb->nx, oldb->ny, oldb->nz, oldb->ldy, oldb->ldz, i);

        /* And perform actual computation */
#ifdef LIFE
        cuda_life_update_host(block->bz, old, new, oldb->nx, oldb->ny, oldb->nz, oldb->ldy, oldb->ldz, i);
#else
        cudaMemcpy(new, old, oldb->nx * oldb->ny * oldb->nz * sizeof(*new), cudaMemcpyDeviceToDevice);
#endif /* LIFE */
    }

    cudaError_t cures;
    if ((cures = cudaThreadSynchronize()) != cudaSuccess)
        STARPU_CUDA_REPORT_ERROR(cures);

}
#endif /* STARPU_USE_CUDA */

/*
 * cl_update (CPU version)
 */
static void update_func_cpu(void *descr[], void *arg)
{
    struct block_description *block = arg;
    int workerid = starpu_worker_get_id();
    DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    if (block->bz == 0)
        fprintf(stderr,"!!! DO update_func_cpu z %d CPU%d !!!\n", block->bz, workerid);
    else
        DEBUG( "!!! DO update_func_cpu z %d CPU%d !!!\n", block->bz, workerid);
#ifdef STARPU_USE_MPI
    int rank = 0;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    DEBUG( "!!!           RANK %d            !!!\n", rank);
#endif
    DEBUG( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");

    unsigned block_size_z = get_block_size(block->bz);
    unsigned i;
    update_per_worker[workerid]++;

    struct timeval tv, tv2, diff, delta = {.tv_sec = 0, .tv_usec = get_ticks() * 1000};
    gettimeofday(&tv, NULL);
    timersub(&tv, &start, &tv2);
    timersub(&tv2, &last_tick[block->bz], &diff);
    while (timercmp(&diff, &delta, >=)) {
        timeradd(&last_tick[block->bz], &delta, &last_tick[block->bz]);
        timersub(&tv2, &last_tick[block->bz], &diff);
        if (who_runs_what_index[block->bz] < who_runs_what_len)
            who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = -1;
    }

    if (who_runs_what_index[block->bz] < who_runs_what_len)
        who_runs_what[block->bz + (who_runs_what_index[block->bz]++) * get_nbz()] = global_workerid(workerid);

    /*
     *	Load neighbours' boundaries : TOP
     */

    /* The offset along the z axis is (block_size_z + K) */
    load_subblock_from_buffer_cpu(descr[0], descr[2], block_size_z+K);
    load_subblock_from_buffer_cpu(descr[1], descr[3], block_size_z+K);

    /*
     *	Load neighbours' boundaries : BOTTOM
     */
    load_subblock_from_buffer_cpu(descr[0], descr[4], 0);
    load_subblock_from_buffer_cpu(descr[1], descr[5], 0);

    /*
     *	Stencils ... do the actual work here :) TODO
     */

    for (i=1; i<=K; i++)
    {
        starpu_block_interface_t *oldb = descr[i%2], *newb = descr[(i+1)%2];
        TYPE *old = (void*) oldb->ptr, *new = (void*) newb->ptr;

        /* Shadow data */
        unsigned ldy = oldb->ldy, ldz = oldb->ldz;
        unsigned nx = oldb->nx, ny = oldb->ny, nz = oldb->nz;
        unsigned x, y, z;
        unsigned stepx = 1;
        unsigned stepy = 1;
        unsigned stepz = 1;
        unsigned idx = 0;
        unsigned idy = 0;
        unsigned idz = 0;
        TYPE *ptr = old;

#		include "shadow.h"

        /* And perform actual computation */
#ifdef LIFE
        life_update(block->bz, old, new, oldb->nx, oldb->ny, oldb->nz, oldb->ldy, oldb->ldz, i);
#else
        memcpy(new, old, oldb->nx * oldb->ny * oldb->nz * sizeof(*new));
#endif /* LIFE */
    }
}

/* Performance model and codelet structure */
static struct starpu_perfmodel_t cl_update_model = {
    .type = STARPU_HISTORY_BASED,
    .symbol = "cl_update"
};

starpu_codelet cl_update = {
    .where =
#ifdef STARPU_USE_CUDA
    STARPU_CUDA|
#endif
    STARPU_CPU,
    .cpu_func = update_func_cpu,
#ifdef STARPU_USE_CUDA
    .cuda_func = update_func_cuda,
#endif
    .model = &cl_update_model,
    .nbuffers = 6
};

/*
 * Save the block internal boundaries to give them to our neighbours.
 */

/* CPU version */
static void load_subblock_into_buffer_cpu(starpu_block_interface_t *block,
        starpu_block_interface_t *boundary,
        unsigned firstz)
{
    /* Sanity checks */
    STARPU_ASSERT(block->nx == boundary->nx);
    STARPU_ASSERT(block->ny == boundary->ny);
    STARPU_ASSERT(boundary->nz == K);

    /* NB: this is not fully garanteed ... but it's *very* likely and that
     * makes our life much simpler */
    STARPU_ASSERT(block->ldy == boundary->ldy);
    STARPU_ASSERT(block->ldz == boundary->ldz);

    /* We do a contiguous memory transfer */
    size_t boundary_size = K*block->ldz*block->elemsize;

    unsigned offset = firstz*block->ldz;
    TYPE *block_data = (TYPE *)block->ptr;
    TYPE *boundary_data = (TYPE *)boundary->ptr;
    memcpy(boundary_data, &block_data[offset], boundary_size);
}

/* CUDA version */
#ifdef STARPU_USE_CUDA
static void load_subblock_into_buffer_cuda(starpu_block_interface_t *block,
        starpu_block_interface_t *boundary,
        unsigned firstz)
{
    /* Sanity checks */
    STARPU_ASSERT(block->nx == boundary->nx);
    STARPU_ASSERT(block->ny == boundary->ny);
    STARPU_ASSERT(boundary->nz == K);

    /* NB: this is not fully garanteed ... but it's *very* likely and that
     * makes our life much simpler */
    STARPU_ASSERT(block->ldy == boundary->ldy);
    STARPU_ASSERT(block->ldz == boundary->ldz);

    /* We do a contiguous memory transfer */
    size_t boundary_size = K*block->ldz*block->elemsize;

    unsigned offset = firstz*block->ldz;
    TYPE *block_data = (TYPE *)block->ptr;
    TYPE *boundary_data = (TYPE *)boundary->ptr;
    cudaMemcpy(boundary_data, &block_data[offset], boundary_size, cudaMemcpyDeviceToDevice);
}
#endif /* STARPU_USE_CUDA */

/* Record how many top/bottom saves each worker performed */
unsigned top_per_worker[STARPU_NMAXWORKERS];
unsigned bottom_per_worker[STARPU_NMAXWORKERS];

/* top save, CPU version */
static void dummy_func_top_cpu(void *descr[] __attribute__((unused)), void *arg)
{
    struct block_description *block = arg;
    int workerid = starpu_worker_get_id();
    top_per_worker[workerid]++;

    DEBUG( "DO SAVE Bottom block %d\n", block->bz);

    /* The offset along the z axis is (block_size_z + K)- K */
    unsigned block_size_z = get_block_size(block->bz);

    load_subblock_into_buffer_cpu(descr[0], descr[2], block_size_z);
    load_subblock_into_buffer_cpu(descr[1], descr[3], block_size_z);
}

/* bottom save, CPU version */
static void dummy_func_bottom_cpu(void *descr[] __attribute__((unused)), void *arg)
{
    struct block_description *block = arg;
    int workerid = starpu_worker_get_id();
    bottom_per_worker[workerid]++;

    DEBUG( "DO SAVE Top block %d\n", block->bz);

    load_subblock_into_buffer_cpu(descr[0], descr[2], K);
    load_subblock_into_buffer_cpu(descr[1], descr[3], K);
}

/* top save, CUDA version */
#ifdef STARPU_USE_CUDA
static void dummy_func_top_cuda(void *descr[] __attribute__((unused)), void *arg)
{
    struct block_description *block = arg;
    int workerid = starpu_worker_get_id();
    top_per_worker[workerid]++;

    DEBUG( "DO SAVE Top block %d\n", block->bz);

    /* The offset along the z axis is (block_size_z + K)- K */
    unsigned block_size_z = get_block_size(block->bz);

    load_subblock_into_buffer_cuda(descr[0], descr[2], block_size_z);
    load_subblock_into_buffer_cuda(descr[1], descr[3], block_size_z);
    cudaThreadSynchronize();
}

/* bottom save, CUDA version */
static void dummy_func_bottom_cuda(void *descr[] __attribute__((unused)), void *arg)
{
    struct block_description *block = arg;
    int workerid = starpu_worker_get_id();
    bottom_per_worker[workerid]++;

    DEBUG( "DO SAVE Bottom block %d on CUDA\n", block->bz);

    load_subblock_into_buffer_cuda(descr[0], descr[2], K);
    load_subblock_into_buffer_cuda(descr[1], descr[3], K);
    cudaThreadSynchronize();
}
#endif /* STARPU_USE_CUDA */

/* Performance models and codelet for save */
static struct starpu_perfmodel_t save_cl_bottom_model = {
    .type = STARPU_HISTORY_BASED,
    .symbol = "save_cl_bottom"
};

static struct starpu_perfmodel_t save_cl_top_model = {
    .type = STARPU_HISTORY_BASED,
    .symbol = "save_cl_top"
};

starpu_codelet save_cl_bottom = {
    .where =
#ifdef STARPU_USE_CUDA
    STARPU_CUDA|
#endif
    STARPU_CPU,
    .cpu_func = dummy_func_bottom_cpu,
#ifdef STARPU_USE_CUDA
    .cuda_func = dummy_func_bottom_cuda,
#endif
    .model = &save_cl_bottom_model,
    .nbuffers = 4
};

starpu_codelet save_cl_top = {
    .where =
#ifdef STARPU_USE_CUDA
    STARPU_CUDA|
#endif
    STARPU_CPU,
    .cpu_func = dummy_func_top_cpu,
#ifdef STARPU_USE_CUDA
    .cuda_func = dummy_func_top_cuda,
#endif
    .model = &save_cl_top_model,
    .nbuffers = 4
};
Example #14
0
void oskar_dftw(
        int normalise,
        int num_in,
        double wavenumber,
        const oskar_Mem* weights_in,
        const oskar_Mem* x_in,
        const oskar_Mem* y_in,
        const oskar_Mem* z_in,
        int offset_coord_out,
        int num_out,
        const oskar_Mem* x_out,
        const oskar_Mem* y_out,
        const oskar_Mem* z_out,
        const oskar_Mem* data,
        int offset_out,
        oskar_Mem* output,
        int* status)
{
    if (*status) return;
    const int location = oskar_mem_location(output);
    const int type = oskar_mem_precision(output);
    const int is_dbl = oskar_mem_is_double(output);
    const int is_3d = (z_in != NULL && z_out != NULL);
    const int is_data = (data != NULL);
    const int is_matrix = oskar_mem_is_matrix(output);
    if (!oskar_mem_is_complex(output) || !oskar_mem_is_complex(weights_in) ||
            oskar_mem_is_matrix(weights_in))
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }
    if (oskar_mem_location(weights_in) != location ||
            oskar_mem_location(x_in) != location ||
            oskar_mem_location(y_in) != location ||
            oskar_mem_location(x_out) != location ||
            oskar_mem_location(y_out) != location)
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }
    if (oskar_mem_precision(weights_in) != type ||
            oskar_mem_type(x_in) != type ||
            oskar_mem_type(y_in) != type ||
            oskar_mem_type(x_out) != type ||
            oskar_mem_type(y_out) != type)
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (is_data)
    {
        if (oskar_mem_location(data) != location)
        {
            *status = OSKAR_ERR_LOCATION_MISMATCH;
            return;
        }
        if (!oskar_mem_is_complex(data) ||
                oskar_mem_type(data) != oskar_mem_type(output) ||
                oskar_mem_precision(data) != type)
        {
            *status = OSKAR_ERR_TYPE_MISMATCH;
            return;
        }
    }
    if (is_3d)
    {
        if (oskar_mem_location(z_in) != location ||
                oskar_mem_location(z_out) != location)
        {
            *status = OSKAR_ERR_LOCATION_MISMATCH;
            return;
        }
        if (oskar_mem_type(z_in) != type || oskar_mem_type(z_out) != type)
        {
            *status = OSKAR_ERR_TYPE_MISMATCH;
            return;
        }
    }
    oskar_mem_ensure(output, (size_t) offset_out + num_out, status);
    if (*status) return;
    if (location == OSKAR_CPU)
    {
        if (is_data)
        {
            if (is_matrix)
            {
                if (is_3d)
                {
                    if (is_dbl)
                        dftw_m2m_3d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status),
                                oskar_mem_double_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status),
                                oskar_mem_double_const(z_out, status),
                                oskar_mem_double4c_const(data, status),
                                offset_out,
                                oskar_mem_double4c(output, status), 0);
                    else
                        dftw_m2m_3d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status),
                                oskar_mem_float_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status),
                                oskar_mem_float_const(z_out, status),
                                oskar_mem_float4c_const(data, status),
                                offset_out,
                                oskar_mem_float4c(output, status), 0);
                }
                else
                {
                    if (is_dbl)
                        dftw_m2m_2d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status), 0,
                                oskar_mem_double4c_const(data, status),
                                offset_out,
                                oskar_mem_double4c(output, status), 0);
                    else
                        dftw_m2m_2d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status), 0,
                                oskar_mem_float4c_const(data, status),
                                offset_out,
                                oskar_mem_float4c(output, status), 0);
                }
            }
            else
            {
                if (is_3d)
                {
                    if (is_dbl)
                        dftw_c2c_3d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status),
                                oskar_mem_double_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status),
                                oskar_mem_double_const(z_out, status),
                                oskar_mem_double2_const(data, status),
                                offset_out,
                                oskar_mem_double2(output, status), 0);
                    else
                        dftw_c2c_3d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status),
                                oskar_mem_float_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status),
                                oskar_mem_float_const(z_out, status),
                                oskar_mem_float2_const(data, status),
                                offset_out,
                                oskar_mem_float2(output, status), 0);
                }
                else
                {
                    if (is_dbl)
                        dftw_c2c_2d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status), 0,
                                oskar_mem_double2_const(data, status),
                                offset_out,
                                oskar_mem_double2(output, status), 0);
                    else
                        dftw_c2c_2d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status), 0,
                                oskar_mem_float2_const(data, status),
                                offset_out,
                                oskar_mem_float2(output, status), 0);
                }
            }
        }
        else
        {
            if (is_3d)
            {
                if (is_dbl)
                    dftw_o2c_3d_double(num_in, wavenumber,
                            oskar_mem_double2_const(weights_in, status),
                            oskar_mem_double_const(x_in, status),
                            oskar_mem_double_const(y_in, status),
                            oskar_mem_double_const(z_in, status),
                            offset_coord_out, num_out,
                            oskar_mem_double_const(x_out, status),
                            oskar_mem_double_const(y_out, status),
                            oskar_mem_double_const(z_out, status),
                            0, offset_out,
                            oskar_mem_double2(output, status), 0);
                else
                    dftw_o2c_3d_float(num_in, (float)wavenumber,
                            oskar_mem_float2_const(weights_in, status),
                            oskar_mem_float_const(x_in, status),
                            oskar_mem_float_const(y_in, status),
                            oskar_mem_float_const(z_in, status),
                            offset_coord_out, num_out,
                            oskar_mem_float_const(x_out, status),
                            oskar_mem_float_const(y_out, status),
                            oskar_mem_float_const(z_out, status),
                            0, offset_out,
                            oskar_mem_float2(output, status), 0);
            }
            else
            {
                if (is_dbl)
                    dftw_o2c_2d_double(num_in, wavenumber,
                            oskar_mem_double2_const(weights_in, status),
                            oskar_mem_double_const(x_in, status),
                            oskar_mem_double_const(y_in, status), 0,
                            offset_coord_out, num_out,
                            oskar_mem_double_const(x_out, status),
                            oskar_mem_double_const(y_out, status), 0,
                            0, offset_out,
                            oskar_mem_double2(output, status), 0);
                else
                    dftw_o2c_2d_float(num_in, (float)wavenumber,
                            oskar_mem_float2_const(weights_in, status),
                            oskar_mem_float_const(x_in, status),
                            oskar_mem_float_const(y_in, status), 0,
                            offset_coord_out, num_out,
                            oskar_mem_float_const(x_out, status),
                            oskar_mem_float_const(y_out, status), 0,
                            0, offset_out,
                            oskar_mem_float2(output, status), 0);
            }
        }
    }
    else
    {
        size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
        const void* np = 0;
        const char* k = 0;
        int max_in_chunk;
        float wavenumber_f = (float) wavenumber;

        /* Select the kernel. */
        switch (is_dbl * DBL | is_3d * D3 | is_data * DAT | is_matrix * MAT)
        {
        case D2 | FLT:             k = "dftw_o2c_2d_float";  break;
        case D2 | DBL:             k = "dftw_o2c_2d_double"; break;
        case D3 | FLT:             k = "dftw_o2c_3d_float";  break;
        case D3 | DBL:             k = "dftw_o2c_3d_double"; break;
        case D2 | FLT | DAT:       k = "dftw_c2c_2d_float";  break;
        case D2 | DBL | DAT:       k = "dftw_c2c_2d_double"; break;
        case D3 | FLT | DAT:       k = "dftw_c2c_3d_float";  break;
        case D3 | DBL | DAT:       k = "dftw_c2c_3d_double"; break;
        case D2 | FLT | DAT | MAT: k = "dftw_m2m_2d_float";  break;
        case D2 | DBL | DAT | MAT: k = "dftw_m2m_2d_double"; break;
        case D3 | FLT | DAT | MAT: k = "dftw_m2m_3d_float";  break;
        case D3 | DBL | DAT | MAT: k = "dftw_m2m_3d_double"; break;
        default:
            *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE;
            return;
        }
        if (oskar_device_is_nv(location))
            local_size[0] = (size_t) get_block_size(num_out);
        oskar_device_check_local_size(location, 0, local_size);
        global_size[0] = oskar_device_global_size(
                (size_t) num_out, local_size[0]);

        /* max_in_chunk must be multiple of 16. */
        max_in_chunk = is_3d ? (is_dbl ? 384 : 800) : (is_dbl ? 448 : 896);
        if (is_data && is_3d && !is_dbl) max_in_chunk = 768;
        const size_t element_size = is_dbl ? sizeof(double) : sizeof(float);
        const size_t local_mem_size = max_in_chunk * element_size;
        const size_t arg_size_local[] = {
                2 * local_mem_size, 2 * local_mem_size,
                (is_3d ? local_mem_size : 0)
        };

        /* Set kernel arguments. */
        const oskar_Arg args[] = {
                {INT_SZ, &num_in},
                {is_dbl ? DBL_SZ : FLT_SZ,
                        is_dbl ? (void*)&wavenumber : (void*)&wavenumber_f},
                {PTR_SZ, oskar_mem_buffer_const(weights_in)},
                {PTR_SZ, oskar_mem_buffer_const(x_in)},
                {PTR_SZ, oskar_mem_buffer_const(y_in)},
                {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_in) : &np},
                {INT_SZ, &offset_coord_out},
                {INT_SZ, &num_out},
                {PTR_SZ, oskar_mem_buffer_const(x_out)},
                {PTR_SZ, oskar_mem_buffer_const(y_out)},
                {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_out) : &np},
                {PTR_SZ, is_data ? oskar_mem_buffer_const(data) : &np},
                {INT_SZ, &offset_out},
                {PTR_SZ, oskar_mem_buffer(output)},
                {INT_SZ, &max_in_chunk}
        };
        oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                sizeof(args) / sizeof(oskar_Arg), args,
                sizeof(arg_size_local) / sizeof(size_t), arg_size_local,
                status);
    }
    if (normalise)
        oskar_mem_scale_real(output, 1. / num_in, offset_out, num_out, status);
}
Example #15
0
/*===========================================================================*
 *				fs_readwrite				     *
 *===========================================================================*/
PUBLIC int fs_readwrite(void)
{
  int r, rw_flag, block_spec;
  int regular;
  cp_grant_id_t gid;
  off_t position, f_size, bytes_left;
  unsigned int off, cum_io, block_size, chunk;
  mode_t mode_word;
  int completed;
  struct inode *rip;
  size_t nrbytes;
  
  r = OK;
  
  /* Find the inode referred */
  if ((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
	return(EINVAL);

  mode_word = rip->i_mode & I_TYPE;
  regular = (mode_word == I_REGULAR || mode_word == I_NAMED_PIPE);
  block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0);
  
  /* Determine blocksize */
  if (block_spec) {
	block_size = get_block_size( (dev_t) rip->i_zone[0]);
	f_size = MAX_FILE_POS;
  } else {
  	block_size = rip->i_sp->s_block_size;
  	f_size = rip->i_size;
  }

  /* Get the values from the request message */ 
  rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
  nrbytes = (size_t) fs_m_in.REQ_NBYTES;
  
  rdwt_err = OK;		/* set to EIO if disk error occurs */

  /* If this is file i/o, check we can write */
  if (rw_flag == WRITING && !block_spec) {
  	  if(rip->i_sp->s_rd_only) 
		  return EROFS;

	  /* Check in advance to see if file will grow too big. */
	  if (position > (off_t) (rip->i_sp->s_max_size - nrbytes))
		  return(EFBIG);

	  /* Clear the zone containing present EOF if hole about
	   * to be created.  This is necessary because all unwritten
	   * blocks prior to the EOF must read as zeros.
	   */
	  if(position > f_size) clear_zone(rip, f_size, 0);
  }

  /* If this is block i/o, check we can write */
  if(block_spec && rw_flag == WRITING &&
  	(dev_t) rip->i_zone[0] == superblock.s_dev && superblock.s_rd_only)
		return EROFS;
	      
  cum_io = 0;
  /* Split the transfer into chunks that don't span two blocks. */
  while (nrbytes > 0) {
	  off = ((unsigned int) position) % block_size; /* offset in blk*/
	  chunk = min(nrbytes, block_size - off);

	  if (rw_flag == READING) {
		  bytes_left = f_size - position;
		  if (position >= f_size) break;	/* we are beyond EOF */
		  if (chunk > (unsigned int) bytes_left) chunk = bytes_left;
	  }
	  
	  /* Read or write 'chunk' bytes. */
	  r = rw_chunk(rip, cvul64((unsigned long) position), off, chunk,
	  	       nrbytes, rw_flag, gid, cum_io, block_size, &completed);

	  if (r != OK) break;	/* EOF reached */
	  if (rdwt_err < 0) break;

	  /* Update counters and pointers. */
	  nrbytes -= chunk;	/* bytes yet to be read */
	  cum_io += chunk;	/* bytes read so far */
	  position += (off_t) chunk;	/* position within the file */
  }

  fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS
					   has to know this value */
  
  /* On write, update file size and access time. */
  if (rw_flag == WRITING) {
	  if (regular || mode_word == I_DIRECTORY) {
		  if (position > f_size) rip->i_size = position;
	  }
  } 

  rip->i_seek = NO_SEEK;

  if (rdwt_err != OK) r = rdwt_err;	/* check for disk error */
  if (rdwt_err == END_OF_FILE) r = OK;

  /* even on a ROFS, writing to a device node on it is fine, 
   * just don't update the inode stats for it. And dito for reading.
   */
  if (r == OK && !rip->i_sp->s_rd_only) {
	  if (rw_flag == READING) rip->i_update |= ATIME;
	  if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
	  IN_MARKDIRTY(rip);		/* inode is thus now dirty */
  }
  
  fs_m_out.RES_NBYTES = cum_io;
  
  return(r);
}
Example #16
0
void nbody_engine_cuda_bh_tex::fcompute(const nbcoord_t& t, const memory* _y, memory* _f)
{
	Q_UNUSED(t);
	const smemory*	y = dynamic_cast<const smemory*>(_y);
	smemory*		f = dynamic_cast<smemory*>(_f);

	if(y == NULL)
	{
		qDebug() << "y is not smemory";
		return;
	}

	if(f == NULL)
	{
		qDebug() << "f is not smemory";
		return;
	}

	advise_compute_count();

	size_t					count = m_data->get_count();
	std::vector<nbcoord_t>	host_y(y->size() / sizeof(nbcoord_t));
	std::vector<nbcoord_t>	host_mass(count);

	read_buffer(host_y.data(), y);
	read_buffer(host_mass.data(), m_mass);

	const nbcoord_t*	rx = host_y.data();
	const nbcoord_t*	ry = rx + count;
	const nbcoord_t*	rz = rx + 2 * count;
	const nbcoord_t*	mass = host_mass.data();

	nbody_space_heap	heap;
	heap.build(count, rx, ry, rz, mass, m_distance_to_node_radius_ratio);

	size_t			tree_size = heap.get_radius_sqr().size();

	if(m_dev_indites == NULL)
	{
		m_dev_tree_xyzr = dynamic_cast<smemory*>(create_buffer(tree_size * sizeof(nbcoord_t) * 4));
		m_dev_tree_mass = dynamic_cast<smemory*>(create_buffer(tree_size * sizeof(nbcoord_t)));
		m_dev_indites = dynamic_cast<smemory*>(create_buffer(tree_size * sizeof(int)));
	}

	const nbcoord_t*	dev_y = static_cast<const nbcoord_t*>(y->data());
	nbcoord_t*			dev_f = static_cast<nbcoord_t*>(f->data());
	int*				dev_indites = static_cast<int*>(m_dev_indites->data());

	static_assert(sizeof(vertex4<nbcoord_t>) == sizeof(nbcoord_t) * 4,
				  "sizeof(vertex4) must be equal to sizeof(nbcoord_t)*4");

	std::vector<vertex4<nbcoord_t>>	host_tree_xyzr(tree_size);
	std::vector<int>				host_indites(tree_size);

	#pragma omp parallel for
	for(size_t n = 0; n < tree_size; ++n)
	{
		host_tree_xyzr[n].x = heap.get_mass_center()[n].x;
		host_tree_xyzr[n].y = heap.get_mass_center()[n].y;
		host_tree_xyzr[n].z = heap.get_mass_center()[n].z;
		host_tree_xyzr[n].w = heap.get_radius_sqr()[n];
		host_indites[n] = static_cast<int>(heap.get_body_n()[n]);
	}

	write_buffer(m_dev_tree_xyzr, host_tree_xyzr.data());
	write_buffer(m_dev_tree_mass, heap.get_mass().data());
	write_buffer(m_dev_indites, host_indites.data());

	if(m_tree_layout == etl_heap)
	{
		fcompute_heap_bh_tex(0, static_cast<int>(count), static_cast<int>(tree_size), dev_f,
							 m_dev_tree_xyzr->tex(4), m_dev_tree_mass->tex(),
							 dev_indites, get_block_size());
	}
	else if(m_tree_layout == etl_heap_stackless)
	{
		fcompute_heap_bh_stackless(0, static_cast<int>(count), static_cast<int>(tree_size), dev_f,
								   m_dev_tree_xyzr->tex(4), m_dev_tree_mass->tex(),
								   dev_indites, get_block_size());
	}

	fcompute_xyz(dev_y, dev_f, static_cast<int>(count), get_block_size());
}
Example #17
0
/*===========================================================================*
 *				fs_readwrite				     *
 *===========================================================================*/
PUBLIC int fs_readwrite(void)
{
  int r, rw_flag, block_spec;
  int regular;
  cp_grant_id_t gid;
  off_t position, f_size, bytes_left;
  unsigned int off, cum_io, block_size, chunk;
  mode_t mode_word;
  int completed;
  struct inode *rip;
  size_t nrbytes;
  
  r = OK;
  
  /* Find the inode referred */
  if ((rip = find_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
	return(EINVAL);

  mode_word = rip->i_mode & I_TYPE;
  /* immediate files are regular files too! */
  regular = (mode_word == I_REGULAR || mode_word == I_IMMEDIATE || mode_word == I_NAMED_PIPE);
  block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0);
  
  /* Determine blocksize */
  if (block_spec) {
	block_size = get_block_size( (dev_t) rip->i_zone[0]);
	f_size = MAX_FILE_POS;
  } else {
  	block_size = rip->i_sp->s_block_size;
  	f_size = rip->i_size;
  }

  /* Get the values from the request message */ 
  rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  position = (off_t) fs_m_in.REQ_SEEK_POS_LO;
  nrbytes = (size_t) fs_m_in.REQ_NBYTES;
  
  rdwt_err = OK;		/* set to EIO if disk error occurs */

  if (rw_flag == WRITING && !block_spec && (rip->i_mode & I_TYPE) != I_IMMEDIATE) {
	  /* Check in advance to see if file will grow too big. */
	  if (position > (off_t) (rip->i_sp->s_max_size - nrbytes))
		  return(EFBIG);

	  /* Clear the zone containing present EOF if hole about
	   * to be created.  This is necessary because all unwritten
	   * blocks prior to the EOF must read as zeros.
	   */
	  if(position > f_size) clear_zone(rip, f_size, 0);
  }
  
  cum_io = 0;
	
	if((rip->i_mode & I_TYPE) == I_IMMEDIATE)
	{
    int sanity = 0;
    if(f_size > 40) printf("Immediate file is %d bytes!\n", f_size);
    
    if(rw_flag == WRITING)
    {  
      /* printf("fs_readwrite() WRITING to immediate file\n"); */
        
      /* is the file going to need to be upconverted from immediate to regular? */
      if((f_size + nrbytes) > 40 || position > 40)
      {
        char tmp[40];
        register int i;
        register struct buf *bp;
        
        for(i = 0; i < f_size; i++)
        {
          tmp[i] = *(((char *)rip->i_zone) + i);
        }
        
        /* clear inode since it will now hold pointers rather than data (copied from wipe_inode()) */
        rip->i_size = 0;
        rip->i_update = ATIME | CTIME | MTIME;	/* update all times later */
        rip->i_dirt = DIRTY;
        for (i = 0; i < V2_NR_TZONES; i++) rip->i_zone[i] = NO_ZONE;
        
        /* Writing to a nonexistent block. Create and enter in inode.*/
    		if ((bp = new_block(rip, (off_t) 0)) == NULL)
    			panic("bp not valid in fs_readwrite immediate growth; this can't be happening!");
    		
    		/* copy data to bp->data */
    		for(i = 0; i < f_size; i++)
        {
          bp->b_data[i] = tmp[i];
        }
    		
        bp->b_dirt = DIRTY;
    		
        put_block(bp, PARTIAL_DATA_BLOCK);	
    		
        position += f_size;
        f_size = rip->i_size;
        rip->i_mode = (I_REGULAR | (rip->i_mode & ALL_MODES));
      }
      /* the file will not grow over 40 bytes */
      else
      {
        sanity = 1;
      }
    }
    else
    {
      /* printf("fs_readwrite() READING from immediate file\n"); */
      
      bytes_left = f_size - position;
      /* if the position is past the end of the file, it is already too late... */
      if(bytes_left > 0)
      {
        sanity = 1;
        /* don't read past the EOF, just right up to it */
        if(nrbytes > bytes_left) nrbytes = bytes_left;
      }
    }
    
    if(sanity)
    {
      r = rw_immed(rip, position, nrbytes, rw_flag, gid, cum_io);
      if(r == OK)
      {
        cum_io += nrbytes;
        position += nrbytes;
        /* no more bytes left to read */
        nrbytes = 0;
      }
    }
	}
	
  /* Split the transfer into chunks that don't span two blocks. */
  while (nrbytes > 0) {
	  off = ((unsigned int) position) % block_size; /* offset in blk*/
	  chunk = min(nrbytes, block_size - off);

	  if (rw_flag == READING) {
		  bytes_left = f_size - position;
		  if (position >= f_size) break;	/* we are beyond EOF */
		  if (chunk > (unsigned int) bytes_left) chunk = bytes_left;
	  }
	  
	  /* Read or write 'chunk' bytes. */
	  r = rw_chunk(rip, cvul64((unsigned long) position), off, chunk,
	  	       nrbytes, rw_flag, gid, cum_io, block_size, &completed);

	  if (r != OK) break;	/* EOF reached */
	  if (rdwt_err < 0) break;

	  /* Update counters and pointers. */
	  nrbytes -= chunk;	/* bytes yet to be read */
	  cum_io += chunk;	/* bytes read so far */
	  position += (off_t) chunk;	/* position within the file */
  }

  fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS
					   has to know this value */
  
  /* On write, update file size and access time. */
  if (rw_flag == WRITING) {
	  if (regular || mode_word == I_DIRECTORY) {
		  if (position > f_size) rip->i_size = position;
	  }
  }

  /* Check to see if read-ahead is called for, and if so, set it up. */
  if(rw_flag == READING && rip->i_seek == NO_SEEK &&
     (unsigned int) position % block_size == 0 &&
     (regular || mode_word == I_DIRECTORY)) {
	  rdahed_inode = rip;
	  rdahedpos = position;
  } 

  rip->i_seek = NO_SEEK;

  if (rdwt_err != OK) r = rdwt_err;	/* check for disk error */
  if (rdwt_err == END_OF_FILE) r = OK;

  if (r == OK) {
	  if (rw_flag == READING) rip->i_update |= ATIME;
	  if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
	  rip->i_dirt = DIRTY;		/* inode is thus now dirty */
  }
  
  fs_m_out.RES_NBYTES = cum_io;
  
  return(r);
}
Example #18
0
char disk_io_read(test_results_t* result, int iters, cmd_line_args * cmd_args,
        benchmark_test* bmtest, result_table_t* res_table) {
	FILE *read_fp = NULL;
	long long time_diff;
	int block_size = 0;
	int done, loop, j;
	double clock_accuracy;
	char retry_status = UNACCEPTABLE_DEVIATIONS;
	int sub_iters = DEFAULT_SUBITERS;

	int count = 0;
	char *_read_buf = NULL;
	char print_flag = FALSE;
	struct timespec start_time, end_time;

	block_size = get_block_size();

	assert(block_size> 0);

	clock_accuracy = get_min_exec_time(res_table);

	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "\nTest Report for disk I/O read configuration:\n");

	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "=================================================\n");
	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "\ndisk_io_config: Total number of iterations = %d\n\n", iters);

	done = 0;
	while (!done) {
		int n;
		_read_buf = calloc(1, block_size);

		if (_read_buf == NULL) {
			RTMB_printf(stderr,
			        "calloc() failed in disk_io_read_config()\n");
			abort();
		}

		/*Make sure there is data in the file before attempting a read*/
		setup_file_for_read(block_size * sub_iters, 1);

		for (loop = 0; loop < iters; loop++) {
			open_file_for_read(&read_fp);

			if (get_cur_time(&start_time) == ERROR) {
				abort();
			}

			for (j = 0; j < sub_iters; j++) {
				if ((n = fread(_read_buf, sizeof(char),
				        block_size, read_fp)) != block_size) {
					perror("fwrite:");
					abort();
				}
			}

			if (get_cur_time(&end_time) == ERROR) {
				abort();
			}

			/* Get the time difference of start and end times */
			time_diff = get_time_diff(start_time, end_time);
			RTMB_verbose_printf(stdout, cmd_args, 2,
			        "disk_io_read_config: Difference between end"
				        " and start times = %.3f us\n",
			        MICROSEC(time_diff));

			add_entry(result, time_diff, 0);
			fclose(read_fp);
		}

		if (IS_EXEC_TIME_GRT_THAN_CLK(result, clock_accuracy)) {
			print_flag = TRUE;
			if (check_pass_criteria(result, cmd_args, bmtest, 0)
			        == SUCCESS) {
				/*
				 * test passed,
				 * disk IO rate is determined
				 */
				retry_status = ACCEPTABLE_DEVIATIONS;
				done = 1;
				break;
			} else {
				/*If we have completed, return error*/
				if (++count == bmtest->_threshold) {
					RTMB_printf(stderr,
					        "disk_io_read_config: exceeded"
						        " maximum attempts \n");
					break;
				}

			}
		}

		if (print_flag == TRUE) {
			RTMB_verbose_printf(stdout, cmd_args, 1,
			        "\ndisk_io_read_config: Retrying test");
			RTMB_verbose_printf(stdout, cmd_args, 1,
			        " with bigger work quantum to get"
				        " lesser variance...\n");
		}

		/*
		 * measured times are not accurate enough,
		 * hence retry.
		 */
		free_chain(result, 0);
		sub_iters *= MULTIPLIER_FOR_SUB_ITER;
		free(_read_buf);
	}

	result->opern_amount = block_size * sub_iters;

	return retry_status;
}
Example #19
0
// Return a pointer to a block given its number.
// get_block(fs, 0) == fs;
void * get_block(void * fs, __u32 block_num) {
    return (void*) (char*)fs + block_num*get_block_size(fs); 
} 
Example #20
0
int
main(int argc, char **argv)
{
	int nvram_fd, cache_fd, disk_fd, c;//新增 nvram_fd
	char *disk_devname, *flash_devname, *nvram_devname, *cachedev;//新增 nvram_devname表示nvram缓存路径名字
	struct flash_superblock *sb = (struct flash_superblock *)buf;//flash超级块的对象sb指向buf空间
	struct flash_superblock *nsb = (struct flash_superblock *)nvram_buf;//新增 nb结构体
	sector_t nvram_devsize, cache_devsize, disk_devsize;//新增 nvram_cache_devsize
	sector_t block_size = 0, md_block_size = 0, cache_size = 0, nvram_size = 0;//新增 nvram_size
	sector_t ram_needed;//typedef unsigned long sector_t;
	struct sysinfo i;
	int cache_sectorsize, nvram_sectorsize;//新增 nvram的扇区大小
	int associativity = 512;
	int disk_associativity = 512;
	int ret;
	int cache_mode = -1;
	char *cache_mode_str;
	
	pname = argv[0];
	//flashcache_create -p back flashcache /dev/pma /dev/pmb /dev/loop0
	//flashcache_create [-v] -p back|around|thru [-s cache size] [-b block size] cachedevname flash_devname disk_devname
	while ((c = getopt(argc, argv, "fs:b:d:m:va:p:")) != -1) {
		switch (c) {
		case 's':
			//这个位置以后还可以初始化nvram_size属性
			cache_size = get_cache_size(optarg);//s选项后面跟着的是缓存大小 默认大小,不然就要分别指定两个缓存的大小
			break;
		case 'a':
			associativity = atoi(optarg);//缓存分组大小
			break;
		case 'b':
			block_size = get_block_size(optarg);//缓存块大小  2的n次幂
			/* Block size should be a power of 2 */
                        break;
		case 'd':
			disk_associativity = get_block_size(optarg);//磁盘分组大小
			break;
		case 'm':
			md_block_size = get_block_size(optarg);//元数据块大小
			/* MD block size should be a power of 2 */
                        break;
		case 'v':
			verbose = 1;
                        break;			
		case 'f':
			force = 1;
                        break;
		case 'p':
			if (strcmp(optarg, "back") == 0) {        //默认设置成WB模式
				cache_mode = FLASHCACHE_WRITE_BACK;
				cache_mode_str = "WRITE_BACK";
			} else if ((strcmp(optarg, "thru") == 0) ||
				   (strcmp(optarg, "through") == 0)) {
				cache_mode = FLASHCACHE_WRITE_THROUGH;
				cache_mode_str = "WRITE_THROUGH";
			} else if (strcmp(optarg, "around") == 0) {
				cache_mode = FLASHCACHE_WRITE_AROUND;
				cache_mode_str = "WRITE_AROUND";
			} else
				usage(pname);
                        break;			
		case '?':
			usage(pname);
		}
	}
	if (cache_mode == -1)
		usage(pname);
	if (optind == argc)
		usage(pname);
	if (block_size == 0)
		block_size = 8;		/* 4KB default blocksize */  //缓存块大小默认为8个扇区,4KB
	if (md_block_size == 0)
		md_block_size = 8;	/* 4KB default blocksize */  //元数据块大小也是一样
	//进一步分别获取虚拟设备、flash设备和磁盘设备的名字   如果说参数个数提前用完了optind==argc,则调用usage返回错误信息
	cachedev = argv[optind++];
	if (optind == argc)
		usage(pname);
	//新增 获取nvram的设备路径名
	nvram_devname = argv[optind++];
	if (optind == argc)
		usage(pname);
	flash_devname = argv[optind++];
	if (optind == argc)
		usage(pname);
	disk_devname = argv[optind];
	//新增 对nvram路径名/磁盘分组大小的输出 
	//printf("cachedev %s, nvram_devname %s, flash_devname %s, disk_devname %s cache_mode %s disk_associativity %lu\n", 
	//       cachedev, nvram_devname, flash_devname, disk_devname, cache_mode_str, disk_associativity);
	if (cache_mode == FLASHCACHE_WRITE_BACK)
		printf("FLASHCACHE_WRITE_BACK:block_size %lu, md_block_size %lu, cache_size %lu\n", 
		       block_size, md_block_size, cache_size);
	else
		printf("block_size %lu, cache_size %lu\n", 
		       block_size, cache_size);

	//新增 读取nvram缓存空间的超级块中的数据,并判断nvram中是否已经有数据
	nvram_fd = open(nvram_devname, O_RDONLY);
	if (nvram_fd < 0) {
		fprintf(stderr, "Failed to open %s\n", nvram_devname);
		exit(1);
	}
    lseek(nvram_fd, 0, SEEK_SET);
	if (read(nvram_fd, nvram_buf, 512) < 0) {
		fprintf(stderr, "Cannot read NVRAM superblock %s\n", 
			nvram_devname);
		exit(1);		
	}
	if (nsb->cache_sb_state == CACHE_MD_STATE_DIRTY ||
	    nsb->cache_sb_state == CACHE_MD_STATE_CLEAN ||
	    nsb->cache_sb_state == CACHE_MD_STATE_FASTCLEAN ||
	    nsb->cache_sb_state == CACHE_MD_STATE_UNSTABLE) {
		fprintf(stderr, "%s: Valid Flashcache already exists on %s\n", 
			pname, nvram_devname);
		fprintf(stderr, "%s: Use flashcache_destroy first and then create again %s\n", 
			pname, nvram_devname);
		exit(1);
	}

	//读取flash缓存空间的超级块中的数据
	//指向文件的头部,并从头部开始读取512个字节的数据到buf中  那就应该是超级块只占用一个扇区大小?
	cache_fd = open(flash_devname, O_RDONLY);
	if (cache_fd < 0) {
		fprintf(stderr, "Failed to open %s\n", flash_devname);
		exit(1);
	}
    lseek(cache_fd, 0, SEEK_SET);
	if (read(cache_fd, buf, 512) < 0) {
		fprintf(stderr, "Cannot read Flash superblock %s\n", 
			flash_devname);
		exit(1);		
	}
	//通过flash缓存超级块的clean或者shutdown状态来判断是否已经有缓存数据在flash中
	if (sb->cache_sb_state == CACHE_MD_STATE_DIRTY ||
	    sb->cache_sb_state == CACHE_MD_STATE_CLEAN ||
	    sb->cache_sb_state == CACHE_MD_STATE_FASTCLEAN ||
	    sb->cache_sb_state == CACHE_MD_STATE_UNSTABLE) {
		fprintf(stderr, "%s: Valid Flashcache already exists on %s\n", 
			pname, flash_devname);
		fprintf(stderr, "%s: Use flashcache_destroy first and then create again %s\n", 
			pname, flash_devname);
		exit(1);
	}
	//
	disk_fd = open(disk_devname, O_RDONLY);
	if (disk_fd < 0) {
		fprintf(stderr, "%s: Failed to open %s\n", 
			pname, disk_devname);
		exit(1);
	}

	//新增 获取nvram设备空间大小BLKGETSIZE和物理扇区大小BLKSSZGET
	//并判断nvram缓存数据块大小是否大于nvram物理扇区大小和nvram缓存空间大小是否小于nvram设备大小
	//不过默认cache_size应该为0,所以nvram_size也默认为0
	if (ioctl(nvram_fd, BLKGETSIZE, &nvram_devsize) < 0) {
		fprintf(stderr, "%s: Cannot get nvram size %s\n", 
		pname, nvram_devname);
		exit(1);		
	}
	if (ioctl(nvram_fd, BLKSSZGET, &nvram_sectorsize) < 0) {
		fprintf(stderr, "%s: Cannot get nvram size %s\n", 
			pname, nvram_devname);
		exit(1);		
	}
	if (md_block_size > 0 &&
	    md_block_size * 512 < nvram_sectorsize) {
		fprintf(stderr, "%s: NVRAM device (%s) sector size (%d) cannot be larger than metadata block size (%d) !\n",
		        pname, nvram_devname, nvram_sectorsize, md_block_size * 512);
		exit(1);				
	}
	if (nvram_size && nvram_size > nvram_devsize) {
		fprintf(stderr, "%s: Cache size is larger than nvram size %lu/%lu\n", 
			pname, nvram_size, nvram_devsize);
		exit(1);		
	}

	//获取flash设备的空间大小并写入到cache_devsize中
	if (ioctl(cache_fd, BLKGETSIZE, &cache_devsize) < 0) {
		fprintf(stderr, "%s: Cannot get cache size %s\n", 
			pname, flash_devname);
		exit(1);		
	}
	if (ioctl(disk_fd, BLKGETSIZE, &disk_devsize) < 0) {
		fprintf(stderr, "%s: Cannot get disk size %s\n", 
			pname, disk_devname);
		exit(1);				
	}

	//获取flash设备的物理扇区大小
	if (ioctl(cache_fd, BLKSSZGET, &cache_sectorsize) < 0) {
		fprintf(stderr, "%s: Cannot get cache size %s\n", 
			pname, flash_devname);
		exit(1);		
	}
	//flash设备的物理扇区大小不能大于元数据块的大小   不然元数据块就成了管理flash的最小数据单元了
	if (md_block_size > 0 &&
	    md_block_size * 512 < cache_sectorsize) {
		fprintf(stderr, "%s: SSD device (%s) sector size (%d) cannot be larger than metadata block size (%d) !\n",
		        pname, flash_devname, cache_sectorsize, md_block_size * 512);
		exit(1);				
	}
	//缓存空间大小不能大于flash设备空间大小
	if (cache_size && cache_size > cache_devsize) {
		fprintf(stderr, "%s: Cache size is larger than ssd size %lu/%lu\n", 
			pname, cache_size, cache_devsize);
		exit(1);		
	}

	//新增 输出已获取到的设备信息
	printf("flash:%s缓存大小为%d,设备大小为%d nvram:%s缓存大小为%d,设备大小为%d disk:%s设备大小为%d\n", flash_devname, cache_size, cache_devsize, nvram_devname, nvram_size, nvram_devsize, disk_devname, disk_devsize);

	/* Remind users how much core memory it will take - not always insignificant.
 	 * If it's > 25% of RAM, warn.
         */
 	//如果缓存空间大小没有在参数中赋值,为0,则为设备大小/块大小 *缓存块大小,即整个设备 
 	//新增 nvram_size为0,ram_needed加上nvram设备大小
	if (cache_size == 0 || nvram_size == 0)
		ram_needed = (cache_devsize / block_size) * sizeof(struct cacheblock) + (nvram_devsize / block_size) * sizeof(struct cacheblock);	/* Whole device */
	else
		ram_needed = (cache_size / block_size) * sizeof(struct cacheblock) + (nvram_size / block_size) * sizeof(struct cacheblock);

	sysinfo(&i);
	printf("Flashcache metadata will use %luMB of your %luMB main memory\n",
		ram_needed >> 20, i.totalram >> 20);
	//若是所使用的Flashcache元数据空间占内存空间比例超过1/4则提示     ram_needed不是整个缓存空间的大小吗?为什么说元数据?
	if (!force && ram_needed > (i.totalram * 25 / 100)) {
		fprintf(stderr, "Proportion of main memory needed for flashcache metadata is high.\n");
		fprintf(stderr, "You can reduce this with a smaller cache or a larger blocksize.\n");
		check_sure();
	}
	//printf("输出一次disk_associativity=%lu associativity=%lu\n", disk_associativity, associativity);
	//磁盘分组大小不能大于缓存分组大小
	if (disk_associativity == 0 ||
	    disk_associativity > associativity) {
		fprintf(stderr, "%s: Invalid Disk Associativity %ld\n",
			pname, disk_associativity);
		exit(1);
	}
	//printf("再输出一次disk_associativity=%lu associativity=%lu\n", disk_associativity, associativity);
	//缓存大小也不能大于磁盘大小   
	//新增 加入nvram_size > disk_devsize
	if (!force && (cache_size > disk_devsize || nvram_size > disk_devsize)) {
		fprintf(stderr, "Size of cache volume (%s) || (%s) is larger than disk volume (%s)\n",
			nvram_devname, flash_devname, disk_devname);
		check_sure();
	}
	//新增  先提前输出一遍命令内容  共享cache_mode、block_size、assoc、md_block_size   persistence默认为2,即create
	printf("echo 0 %lu flashcache disk=%s ssd=%s nvram=%s cachedev=%s cachemode=%d 2 blocksize=%lu cachesize=%lu nvramsize=%lu assoc=%d diskassoc=%d md_block_size=%lu"
		" | dmsetup create %s.\n",
		disk_devsize, disk_devname, flash_devname, nvram_devname, cachedev, cache_mode, block_size, 
		cache_size, nvram_size, associativity, disk_associativity, md_block_size,
		cachedev);

	/*
[root@localhost flashcache-3.1.3]# flashcache_create -p back cache1g8g /dev/pma /dev/pmb /dev/loop0
cachedev cache1g8g, nvram_devname /dev/pma, flash_devname /dev/pmb, disk_devname /dev/loop0 cache mode WRITE_BACK
block_size 8, md_block_size 8, cache_size 0
Flashcache metadata will use 58MB of your 64426MB main memory
echo 0 20971520 flashcache /dev/loop0 /dev/pmb /dev/pma cache1g8g 1 2 8 0 0 512 266287972864 8 | dmsetup create cache1g8g
echo 0 20971520 flashcache /dev/loop0 /dev/pmb cachehaha 1 2 8 0 512 140733193388544 8 | dmsetup create cachehaha
	*/
	/*
umount /dev/mapper/cachecache
dmsetup remove cachecache
rmmod flashcache
flashcache_destroy /dev/pmb


make && make install
modprobe pmbd mode="pmbd1,8;hmo50;hms9;pmapY;rdsx1,2;wrsx1,12;"
fdisk -l
losetup /dev/loop0 /home/disk.img 

dd if=/dev/zero of=/root/workspace/disk.img bs=1024k count=131072



make KERNEL_TREE=/usr/src/kernels/2.6.32-504.12.2.el6.x86_64/ && make install
modprobe flashcache
lsmod | grep flashcache
flashcache_create -p back cachecache /dev/pma /dev/pmb /dev/loop0

flashcache_create -p back cachecache /dev/pma /dev/loop0

mkfs.ext3 /dev/mapper/cachecache
mount /dev/mapper/cachecache /home/mount
fio -filename=/home/mount/file.1G -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=1G -numjobs=10 -runtime=1000 -group_reporting -name=mytest 


echo 0 20971520 flashcache disk=/dev/loop0 ssd=/dev/pmb nvram=/dev/pma cachedev=cachecache cachemode=1 2 blocksize=8 cachesize=0 nvramsize=0 assoc=512 diskassoc=512 md_block_size=8 | dmsetup create cachecache
echo 0 20971520 flashcache /dev/loop0 /dev/pmb /dev/pma cachecache 1 2 8 0 0 512 512 8 | dmsetup create cachecache

	*/

	//设计创建设备的命令  先不加入nvram,不然后面需要加上解析参数的部分才能正常运行
	sprintf(dmsetup_cmd, "echo 0 %lu flashcache %s %s %s %s %d 2 %lu %lu %lu %d %lu %lu"
		" | dmsetup create %s",
		disk_devsize, disk_devname, flash_devname, nvram_devname, cachedev, cache_mode, block_size, 
		cache_size, nvram_size, associativity, disk_associativity, md_block_size,
		cachedev);
	printf("dmsetup_cmd:%s\n", dmsetup_cmd);
	/* Go ahead and create the cache.
	 * XXX - Should use the device mapper library for this.
	 */
	
	load_module();//加载flashcache模块
	if (verbose)
		fprintf(stderr, "Creating FlashCache Volume : \"%s\"\n", dmsetup_cmd);
	ret = system(dmsetup_cmd);//执行命令  创建设备
	if (ret) {
		fprintf(stderr, "%s failed\n", dmsetup_cmd);
		exit(1);
	}
	return 0;
}