Exemple #1
0
struct iso_primary_descriptor * cdfs_get_iso_info(struct super_block *sb, int track_no){
  cd * this_cd = cdfs_info(sb);
  struct buffer_head * bh;
  int block;
  struct iso_primary_descriptor * iso_info = 
	  kmalloc(sizeof(struct iso_primary_descriptor), GFP_KERNEL);

  if (!iso_info) {
    printk("kmalloc failed\n");
    return NULL;
  }

  block = this_cd->track[track_no].start_lba+16;  /* ISO info at sector 16 */
  
  PRINT("Retrieving info for data track %d: block %d\n", 
        track_no, block);

  if (!(bh = bread(sb->s_dev, block, CD_FRAMESIZE))) {
    PRINT("FAILED\n");
    return NULL;
  }

  if (!strncmp(bh->b_data+1,"CD001",5)) {
    memcpy(iso_info, bh->b_data, 
		    sizeof(struct iso_primary_descriptor));   /* ISO session */
  } else {
    kfree(iso_info);
    iso_info=NULL;                                       /* DATA, but no ISO */
  }

  brelse(bh);

  return iso_info;

}
Exemple #2
0
static int cdfs_statfs(struct super_block *sb, struct statfs *buf) {
  cd * this_cd = cdfs_info(sb);
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
static int cdfs_statfs(struct dentry *d, struct kstatfs *buf) {
  cd * this_cd = cdfs_info(d->d_sb);
#else
static int cdfs_statfs(struct super_block *sb, struct kstatfs *buf) {
  cd * this_cd = cdfs_info(sb);
#endif
#endif
  PRINT("rmfs_statfs\n");

  buf->f_type    = CDFS_MAGIC;
  buf->f_bsize   = CD_FRAMESIZE;
  buf->f_blocks  = this_cd->size/CD_FRAMESIZE;
  buf->f_namelen = CDFS_MAXFN;
  buf->f_files   = this_cd->tracks;
  return 0;
}
Exemple #3
0
static int cdfs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
  struct inode *inode = filp->f_dentry->d_inode;
  int i;
  cd * this_cd = cdfs_info(inode->i_sb);

  PRINT("cdfs_readdir ino=%ld f_pos=%u\n", inode->i_ino, (int)filp->f_pos);

  for(i=filp->f_pos; i<T2I(this_cd->tracks); i++) {
    if (filldir(dirent, this_cd->track[i].name, strlen(this_cd->track[i].name), 0, i, DT_UNKNOWN) < 0) 
      return 0;
    filp->f_pos++;
  }
  return 1;
}
Exemple #4
0
static void cdfs_umount(struct super_block *sb) {
  int t;
  cd * this_cd = cdfs_info(sb);

  PRINT("cdfs_umount\n");

  for (t=0; t<=this_cd->tracks; t++)
    if ((this_cd->track[T2I(t)].type == DATA) && this_cd->track[T2I(t)].iso_info)
      kfree(this_cd->track[T2I(t)].iso_info);
  
  // Free & invalidate cache
  kfree(this_cd->cache);
  this_cd->cache_sector = -CACHE_SIZE;

  // Remove /proc entry
  cdfs_proc_cd = NULL; 
  kfree(cdfs_info(sb));

#ifdef OLD_KERNEL
  MOD_DEC_USE_COUNT;
#endif

}
Exemple #5
0
unsigned cdfs_data_bmap(struct super_block * sb, int inode, int block)
{
  int result;
  cd * this_cd = cdfs_info(sb);
  track_info * this_track = &(this_cd->track[inode]);
  int session;
  printk("cddata.c:cdfs_data_bmap():AnyoneUseThis???\n");
  if ((this_track->type == BOOT) || (this_track->type == HFS) || (block<20) || this_cd->single)  
    /* 20 sectors seems to be OK for ISO */ 

    result = this_track->start_lba+block;

  else {
    
    /* ISO past sector 18 */
    result = block;
    
    /* post processing */
    for (session=0; session < this_cd->nr_iso_sessions; session++)
    {
      PRINT("this is sector %d, checking session %d: %d-%d\n", result, session, 
            this_cd->lba_iso_sessions[session].start,
            this_cd->lba_iso_sessions[session].stop);
      if ((this_cd->lba_iso_sessions[session].start<=result)
          && (result<=this_cd->lba_iso_sessions[session].stop)) 
        goto exit;    /* OK, reading from an ISO session */
      if ((this_cd->lba_iso_sessions[session].stop<result)
          && (result<this_cd->lba_iso_sessions[session].start)) {
        result = 0;
        goto exit;    /* not OK, reading between two ISO sessions => we force 0*/
      }
    }

    /* We only get here if we read past the last session => we force 0 */
    result = 0;

  }

 exit: 

  //PRINT("BMAP('%s', block %d) => sector %d\n", this_track->name, block, result);

  return result;
}
Exemple #6
0
void cdfs_check_bootable(struct super_block *sb){
  struct buffer_head * bh1, * bh2, *bh3;
  cd * this_cd = cdfs_info(sb);
  int boottrack;
  int no_bootimage=0;
  int sectionoffset=0;

  
  if (!(bh1 = bread(sb->s_dev, 17, CD_FRAMESIZE)))
    return;                            /* sector 17 is unreadable */
  else
    if (!strncmp(bh1->b_data+7, "EL TORITO", 9)) {      
     

      PRINT("BOOT, catalog at %d\n", *(unsigned int*)(bh1->b_data+71));
      bh2 = bread(sb->s_dev,  *(unsigned int*)(bh1->b_data+71), CD_FRAMESIZE);
      
      PRINT("Catalog:\n\tHeader ID=%d, Platform ID=%d, Developer ID=%s\n", 
             *(unsigned char*)(bh2->b_data), 
	     *(unsigned char*)(bh2->b_data+1), bh2->b_data+4);
      
      do {
	this_cd->tracks++;
        boottrack = this_cd->tracks+2;
		
        PRINT("\tInitial/Default entry: %x Bootable, media: %d\n",
               *(unsigned char*)(bh2->b_data+32+0+sectionoffset),
               *(unsigned char*)(bh2->b_data+32+1+sectionoffset) & 15);
        PRINT("\tSector count: %d, Load LBA: %d\n",
               *(unsigned short*)(bh2->b_data+32+6+sectionoffset),
               *(unsigned int*)(bh2->b_data+32+8+sectionoffset));         
  
        this_cd->track[boottrack].type      = BOOT;
        this_cd->track[boottrack].start_lba = *(unsigned int*)
		(bh2->b_data+32+8+sectionoffset);
        this_cd->track[boottrack].size      = cdfs_bootmedia[
		*(unsigned char*)(bh2->b_data+32+1+sectionoffset) & 15].size;
        if (!this_cd->track[boottrack].size)
            this_cd->track[boottrack].size  = *(unsigned short*)
		    (bh2->b_data+32+6+sectionoffset) * CD_FRAMESIZE ;
        this_cd->track[boottrack].stop_lba = this_cd->track[boottrack].
		start_lba + this_cd->track[boottrack].size/CD_FRAMESIZE -1;
        this_cd->track[boottrack].time      = 0;
        sprintf(this_cd->track[boottrack].name,"boot.image_%d",no_bootimage);
        strncpy(this_cd->track[boottrack].bootID,
			bh2->b_data+4+sectionoffset,24);  /* 27?? */
        this_cd->track[boottrack].bootID[24]=0;     

        /* get first sector from boot image */
        bh3=bread(sb->s_dev, this_cd->track[boottrack].start_lba, CD_FRAMESIZE);
        if ((*(unsigned char*)(bh3->b_data+511)=0xAA) && 
			(*(unsigned char*)(bh3->b_data+512)=0x55)) {
          strcat(this_cd->track[boottrack].bootID, 
			  "\n\tType: x86 boot sector, ");

          if (!strncmp(bh3->b_data+2, "LILO", 4)) 
            strcat(this_cd->track[boottrack].bootID, 
			    "LILO boot/chain loader with ");
          else if (!strncmp(bh3->b_data+495, "LDLINUX", 7)) {
            strncat(this_cd->track[boottrack].bootID, bh3->b_data+495, 12);
            strcat(this_cd->track[boottrack].bootID, " boot loader with ");
          }
        
          if (*(unsigned short*)(bh3->b_data+0x438)==0xEF53)         
            strcat(this_cd->track[boottrack].bootID, 
			    "Linux/i386 ext2 filesystem\n");
          else /* FAT */ 
            strncat(this_cd->track[boottrack].bootID, 
			    bh3->b_data+54, 8);  /* FAT type */
        }

        brelse(bh3);
        if (sectionoffset==0) sectionoffset=0x60;
        sectionoffset=sectionoffset+0x20;
      } while (*(unsigned char*)(bh2->b_data+0x42)>no_bootimage++);
      brelse(bh2); 
    }
    brelse(bh1);
}
Exemple #7
0
static void kcdfsd_process_request(void){
  struct list_head * tmp;
  struct kcdfsd_req * req;
  struct page * page;
  struct inode * inode;
  unsigned request;
  
  while (!list_empty (&kcdfsd_req_list)){
    /* Grab the next entry from the beginning of the list */
    tmp = kcdfsd_req_list.next;
    req = list_entry (tmp, struct kcdfsd_req, req_list);
    list_del (tmp);
    page = req->page;
    inode = req->dentry->d_inode;
    request = req->request_type;
    if (!PageLocked(page))
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12))
      PAGE_BUG(page);
#else
      BUG();
#endif

    switch (request){
      case CDDA_REQUEST:
      case CDDA_RAW_REQUEST:
        {
          cd *this_cd = cdfs_info (inode->i_sb);
          char *p;
          track_info *this_track = &(this_cd->track[inode->i_ino]);
          cdfs_cdda_file_read (inode,
                               p = (char *) kmap (page),
                               1 << PAGE_CACHE_SHIFT,
                               (page->index << PAGE_CACHE_SHIFT) +
                               ((this_track->avi) ? this_track->
                                avi_offset : 0),
                               (request == CDDA_RAW_REQUEST));
          if ((this_track->avi) && (this_track->avi_swab)){
              int k;
              for (k=0; k<(1 << PAGE_CACHE_SHIFT); k+=2){
                  char c;
                  c = p[k];
                  p[k] = p[k + 1];
                  p[k + 1] = c;
                }
            }
        }
        break;
      case CDXA_REQUEST:
        cdfs_copy_from_cdXA(inode->i_sb,
                            inode->i_ino,
                            page->index << PAGE_CACHE_SHIFT,
                            (page->index + 1) << PAGE_CACHE_SHIFT,
                            (char *)kmap(page));
        break;
      case CDDATA_REQUEST:
        cdfs_copy_from_cddata(inode->i_sb,
                              inode->i_ino,
                              page->index << PAGE_CACHE_SHIFT,
                              (page->index + 1) << PAGE_CACHE_SHIFT,
                              (char *)kmap(page));
        break;
      case CDHFS_REQUEST:
        cdfs_copy_from_cdhfs(inode->i_sb,
                             inode->i_ino,
                             page->index << PAGE_CACHE_SHIFT,
                             (page->index + 1) << PAGE_CACHE_SHIFT,
                             (char *)kmap(page));
        break;
    }

    SetPageUptodate (page);
    kunmap (page);
    unlock_page (page);
    kfree (req);
  }
}
Exemple #8
0
int cdfs_copy_from_cd(struct super_block * sb, int inode, unsigned int start, unsigned int stop, char * buf)
{
  int start_sector, start_byte, stop_sector, stop_byte, sector;
  int status=0;
  int bad_sector_no_read=0;
  struct cdrom_read_audio cdda;
  unsigned int read_size=CD_FRAMESIZE_RAW_Q;	//CD_FRAMESIZE_RAW_Q=2352+16=2368
  cd * this_cd = cdfs_info(sb);      
  //unsigned start_lba=this_cd->track[inode].start_lba;
  unsigned start_lba=this_cd->track[inode].start_lba;
  char * temp, * temp2;
  char * temp_start;
  int temp_length;

  start_lba=this_cd->track[inode].start_lba;
  
/* cache */
/*
  char * temp, * temp2;
  char * temp_start;
  int temp_length;
*/

  temp = this_cd->cache;

  start_sector = start/read_size;
  start_byte   = start%read_size;
  stop_sector  = stop/read_size;
  stop_byte    = stop%read_size;

  start_sector += start_lba;
  stop_sector  += start_lba;

  if (!stop_byte)
  {	/* empty frame */
  	stop_sector -= 1;
  	stop_byte    = CD_FRAMESIZE_RAW_Q;	//CD_FRAMESIZE_RAW_Q=2352+16=2368
  }

  cdda.addr_format = CDROM_LBA;	//Using CDROM_LBA format
  cdda.nframes     = CACHE_SIZE;
  cdda.buf         = temp;

  // testen of eindadres>CD
  for (sector=start_sector; sector<=stop_sector; sector++)
  {

    PRINT("cache holds [%d-%d], we want sector=%d\n", this_cd->cache_sector, this_cd->cache_sector+CACHE_SIZE-1,  sector);

    if (!((this_cd->cache_sector<=sector) && (sector<this_cd->cache_sector+CACHE_SIZE)))
    {
      this_cd->cache_sector = cdda.addr.lba = sector;

	if((this_cd->bad_sector<5000000)
	&&((this_cd->bad_sector)<=((unsigned long long)cdda.addr.lba))
	&&(((unsigned long long)cdda.addr.lba)<(this_cd->bad_sector+70)))
		bad_sector_no_read=1;
      if(bad_sector_no_read)
      {
	      	status=-5;
		PRINT("<vcd module> Bad sector %d in ACD fail!!! status=%d bad_sector=%lld\n", cdda.addr.lba, status,this_cd->bad_sector);
		return status;
      }
      else
      {
	  PRINT("<vcd module> Reading sector %d in ACD ST \n",cdda.addr.lba);
          status = cdfs_read_cd(sb, (&cdda), cdda.buf);
      }
	  
      if (status)
      {
		  printk("<vcd module> Reading sector %d in ACD SP fail!!! status=%d\n", cdda.addr.lba, status);
		  this_cd->bad_sector=cdda.addr.lba;
		  return status;
      }
      /*
      else
		  PRINT("<vcd module> Reading sector %d in ACD SP OK status=%d\n", cdda.addr.lba, status);
	*/
    }
    temp2=temp+(sector-this_cd->cache_sector)*CD_FRAMESIZE_RAW_Q;	//CD_FRAMESIZE_RAW_Q=2352+16=2368
    if (sector==start_sector)
    {
		temp_start  = temp2+start_byte;
		if (sector!=stop_sector) 
		{
			temp_length = read_size-start_byte;
		}
		else
		{
			temp_length = stop_byte-start_byte;
		}
    }
    else if (sector==stop_sector)
    {
		temp_start  = temp2;
		temp_length = stop_byte;
    }
    else
    {
		temp_start  = temp2;
		temp_length = read_size;
    }
    memcpy(buf, (char*)temp_start, temp_length);
    buf += temp_length;
  }
  return status;
}
Exemple #9
0
void cdfs_copy_from_cd(struct super_block * sb, int inode, unsigned int start, 
    unsigned int stop, char * buf){
  int start_sector, start_byte, stop_sector, stop_byte, sector;
  int status;
  struct cdrom_read_audio cdda;
  unsigned int read_size=CD_FRAMESIZE_RAW;
  cd * this_cd = cdfs_info(sb);      
  unsigned start_lba=this_cd->track[inode].start_lba;

  /* cache */
  char * temp, * temp2;
  char * temp_start;
  int temp_length;

  PRINT("copy_from_cd(%x, %d, %d, %d, %x)\n", sb, inode, start, stop, buf);

  temp = this_cd->cache;

  start_sector = start/read_size;
  start_byte   = start%read_size;
  stop_sector  = stop/read_size;
  stop_byte    = stop%read_size;

  start_sector += start_lba;
  stop_sector  += start_lba;

  if (!stop_byte) {            /* empty frame */
    stop_sector -= 1;
    stop_byte    = CD_FRAMESIZE_RAW;
  }

  PRINT("%d[%d-%d] -> 0x%x...0x%x  ... (%d,%d),(%d,%d)\n", 
      inode, start, stop, (int)buf, (int)buf+stop-start,
      start_sector,start_byte,stop_sector,stop_byte);

  cdda.addr_format = CDROM_LBA;
  cdda.nframes     = CACHE_SIZE;
  cdda.buf         = temp;

  // testen of eindadres>CD

  for (sector=start_sector; sector<=stop_sector; sector++){

    PRINT("cache holds [%d-%d], we want sector=%d\n", this_cd->cache_sector, this_cd->cache_sector+CACHE_SIZE-1,  sector);

    if (!((this_cd->cache_sector<=sector) && (sector<this_cd->cache_sector+CACHE_SIZE))) { 
      PRINT("reading sector %d from CD\n", sector);
      this_cd->cache_sector = cdda.addr.lba = sector;
      status = cdfs_ioctl(sb, CDROMREADAUDIO, (unsigned long)&cdda);
      if (status) {
	printk("copy_from_cd(%d) ioctl failed: %d\n", cdda.addr.lba, status);
	return;
      }      
    } else {
      PRINT("getting sector %d from cache\n", sector);
    }

    temp2=temp+(sector-this_cd->cache_sector)*CD_FRAMESIZE_RAW;

    if (sector==start_sector) {
      temp_start  = temp2+start_byte;
      if (sector!=stop_sector) 
	temp_length = read_size-start_byte;
      else
	temp_length = stop_byte-start_byte;
    } else if (sector==stop_sector) {
      temp_start  = temp2;
      temp_length = stop_byte;
    } else {
      temp_start  = temp2;
      temp_length = read_size;
    }

    PRINT("memcpy(0x%x, %x, %d)\n",(int)buf, (int)temp_start, temp_length);
    memcpy(buf, (char*)temp_start, temp_length);
    buf += temp_length;

  } 
}
Exemple #10
0
int cdfs_get_hfs_info(struct super_block *sb, unsigned track){
  cd * this_cd = cdfs_info(sb);
  struct buffer_head * bh;
  struct new_pmap * pmapp;
  int thistrack;
  unsigned start_lba=this_cd->track[track].start_lba;

  /* We only check for the first partition. */

  PRINT("Retrieving HFS info: reading frame %d from track %d\n", start_lba, track);

  if (!(bh = bread(sb->s_dev, start_lba+0, CD_FRAMESIZE ))) { /* read 2048 bytes */
    PRINT("FAILED\n");
    return -1;
  }

  pmapp=(struct new_pmap*)(bh->b_data+1024);   /* 3e blok van 512 bytes */

  if ( !strncmp((char*)&(pmapp->pmPartType),"Apple_HFS",9) ) {

    this_cd->tracks++;
    thistrack = this_cd->tracks+2;

    this_cd->track[thistrack].type       = HFS;
    this_cd->track[thistrack].start_lba  = ntohl(*(unsigned*)(pmapp->pmPyPartStart))/4;
    this_cd->track[thistrack].hfs_offset = ntohl(*(unsigned*)(pmapp->pmPyPartStart))-4*this_cd->track[thistrack].start_lba;
    this_cd->track[thistrack].size       = ntohl(*(unsigned*)(pmapp->pmPartBlkCnt))*512;
    this_cd->track[thistrack].stop_lba   = this_cd->track[thistrack].start_lba + this_cd->track[thistrack].size/2048;
    this_cd->track[thistrack].time       = 0;
    strcpy(this_cd->track[thistrack].name,"apple.hfs");
    strcpy(this_cd->track[thistrack].bootID,(char*)&pmapp->pmPartName);
    this_cd->track[thistrack].start_lba  += start_lba;
    this_cd->track[thistrack].stop_lba   += start_lba;

    PRINT("Found HFS: %s, starts at %d (offset=%d), stops at %d\n", &pmapp->pmPartName, 
          this_cd->track[thistrack].start_lba,  
          this_cd->track[thistrack].hfs_offset,
          this_cd->track[thistrack].stop_lba);  
  } else {
    /* try next partition */
    
    pmapp=(struct new_pmap*)(bh->b_data+1024+512);   /* 4e blok van 512 bytes */
    
    if ( !strncmp((char*)&(pmapp->pmPartType),"Apple_HFS",9) ) {
      
      this_cd->tracks++;
      thistrack = this_cd->tracks+2;
      
      this_cd->track[thistrack].type       = HFS;
      this_cd->track[thistrack].start_lba  = ntohl(*(unsigned*)(pmapp->pmPyPartStart))/4;
      this_cd->track[thistrack].hfs_offset = ntohl(*(unsigned*)(pmapp->pmPyPartStart))-4*this_cd->track[thistrack].start_lba;
      this_cd->track[thistrack].size       = ntohl(*(unsigned*)(pmapp->pmPartBlkCnt))*512;
      this_cd->track[thistrack].stop_lba   = this_cd->track[thistrack].start_lba + this_cd->track[thistrack].size/2048;
      this_cd->track[thistrack].time       = 0;
      strcpy(this_cd->track[thistrack].name,"apple.hfs");
      strcpy(this_cd->track[thistrack].bootID,(char*)&pmapp->pmPartName);
      this_cd->track[thistrack].start_lba  += start_lba;
      this_cd->track[thistrack].stop_lba   += start_lba;
      
      PRINT("Found HFS: %s, starts at %d (offset=%d), stops at %d\n", &pmapp->pmPartName, 
            this_cd->track[thistrack].start_lba,  
            this_cd->track[thistrack].hfs_offset,
            this_cd->track[thistrack].stop_lba);  
    }
  }
  
  brelse(bh);
  return 0;
  
}
Exemple #11
0
void cdfs_copy_from_cdhfs(struct super_block * sb, int inode, unsigned int start, 
	 unsigned int stop, char * buf){
  int start_sector, start_byte, stop_sector, stop_byte, sector;
  unsigned int read_size=2048;
  cd * this_cd = cdfs_info(sb);      
  struct buffer_head * bh;
  unsigned start_lba=this_cd->track[inode].start_lba;
  char * temp;
  char * temp_start;
  int temp_length;
  char * buf_ptr;

  PRINT("start_lba=%d\n", start_lba);

  /* recalculate start and stop in bytes from the real start of the CD !! */
  start += start_lba*2048+ this_cd->track[inode].hfs_offset*512;
  stop  += start_lba*2048+ this_cd->track[inode].hfs_offset*512;

  start_sector = start/read_size;
  start_byte   = start - start_sector*read_size;
  stop_sector  = stop/read_size;
  stop_byte    = stop - stop_sector*read_size;

  if (!stop_byte) {
    stop_sector--;
    stop_byte=2048;
  }

  PRINT("%d[%d-%d] -> 0x%x...0x%x  ... (%d,%d),(%d,%d)\n", 
         inode, start, stop, (int)buf, (int)buf+stop-start,
         start_sector,start_byte,stop_sector,stop_byte); 
  
  buf_ptr=buf;
  
  for (sector=start_sector; sector<=stop_sector; sector++){
    
    PRINT("reading sector %d, lba=%d\n", sector, start_lba);
    
    if (!(bh = bread(sb->s_dev, sector, CD_FRAMESIZE))) { /* read 2048 bytes */
      PRINT("FAILED\n");
      return;
    }

    temp = bh->b_data;
    
    if (sector==start_sector) {
      temp_start  = temp+start_byte;
      if (sector!=stop_sector) 
        temp_length = read_size-start_byte;
      else
        temp_length = stop_byte-start_byte;
    } else if (sector==stop_sector) {
      temp_start  = temp;
      temp_length = stop_byte;
    } else {
      temp_start  = temp;
      temp_length = read_size;
    }
    
    PRINT("memcpy(0x%x, %x, %d)\n", (int)buf_ptr, (int)temp_start, temp_length);
    
    memcpy(buf_ptr, (char*)temp_start, temp_length);

    brelse(bh);
    
    buf_ptr+=temp_length;
    
  }
};
Exemple #12
0
static struct dentry * cdfs_lookup(struct inode *dir, struct dentry *dentry){
#else
static struct dentry * cdfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
#endif
  struct inode * inode;
  int i;
  cd * this_cd = cdfs_info(dir->i_sb);

  PRINT("cdfs_lookup %s ino=%ld \n", dentry->d_name.name, dir->i_ino);

  for(i=0; i<T2I(this_cd->tracks); i++)
    if (!(strcmp(this_cd->track[i].name, dentry->d_name.name))) {
        goto found;
    }
  return ERR_PTR(-ENOENT);

/* Use goto and read inode with iget()/cdfs_iget() */
/* Thanks to David Howells for patch and Master class in his mail */
found:
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24)
inode = cdfs_iget(dir->i_sb, i);
if (IS_ERR(inode))
  return ERR_CAST(inode);
#else
  inode = iget(dir->i_sb, i);
  if (!inode)
    return ERR_PTR(-ENOMEM);
#endif
d_add(dentry, inode);
return NULL;
}


/***************************************************************************/

static struct file_operations cdfs_dir_operations = {
  .read     = generic_read_dir,
  .readdir  = cdfs_readdir,
};

static struct inode_operations cdfs_inode_operations = {
  .lookup   = cdfs_lookup
};

/**************************************************************************/


static void cdfs_read_inode(struct inode *i) {
  cd * this_cd = cdfs_info(i->i_sb);

  PRINT("this_cd = 0x%x\n", (unsigned)this_cd);

  PRINT("read inode %ld\n", i->i_ino);
  
  i->i_uid        = this_cd->uid;
  i->i_gid        = this_cd->gid;
  i->i_nlink      = 1;
  i->i_op         = &cdfs_inode_operations;
  i->i_fop        = NULL;
  i->i_data.a_ops = NULL;

  if (i->i_ino <= 2) {                               /* . and .. */
    i->i_size  = 0;                      /* Uuugh ?? */
    i->i_mtime = i->i_atime = i->i_ctime = CURRENT_TIME;
    i->i_mode  = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP |  S_IXGRP | S_IROTH | S_IXOTH;
    i->i_fop   = &cdfs_dir_operations;
  } else {                                          /* file */
    i->i_size  = this_cd->track[i->i_ino].size;
#ifdef OLD_KERNEL
    i->i_mtime = i->i_atime = i->i_ctime = this_cd->track[i->i_ino].time;
#else
    i->i_mtime.tv_sec = i->i_atime.tv_sec = i->i_ctime.tv_sec = this_cd->track[i->i_ino].time;
    i->i_mtime.tv_nsec = i->i_atime.tv_nsec = i->i_ctime.tv_nsec = 0;
#endif
    i->i_mode  = this_cd->mode;
    if ((this_cd->track[i->i_ino].type==DATA) && this_cd->track[i->i_ino].iso_size) {
      i->i_fop          = &cdfs_cddata_file_operations; 
      i->i_data.a_ops   = &cdfs_cddata_aops;
    } else if (this_cd->track[i->i_ino].type==AUDIO) {
      i->i_fop          = &cdfs_cdda_file_operations;
      if (this_cd->raw_audio)
	i->i_data.a_ops   = &cdfs_cdda_raw_aops;
      else
	i->i_data.a_ops   = &cdfs_cdda_aops;
    } else if (this_cd->track[i->i_ino].type==BOOT) {
      i->i_fop          = &cdfs_cddata_file_operations;
      i->i_data.a_ops   = &cdfs_cddata_aops;
    } else if (this_cd->track[i->i_ino].type==HFS) {
      if (this_cd->track[i->i_ino].hfs_offset) {
        i->i_fop        = &cdfs_cdhfs_file_operations; /* Bummer, this partition isn't properly aligned... */
        i->i_data.a_ops = &cdfs_cdhfs_aops;
      } else {
        i->i_fop        = &cdfs_cddata_file_operations;
        i->i_data.a_ops = &cdfs_cddata_aops;
      }
    } else {
      i->i_fop          = &cdfs_cdXA_file_operations;
      i->i_data.a_ops   = &cdfs_cdXA_aops;
    }
  }
}
Exemple #13
0
static struct super_block * cdfs_mount(struct super_block *sb, void *data, int silent){
  kdev_t dev = sb->s_dev;
  int i, j, t;
  struct cdrom_tochdr  hdr;
#else
static int cdfs_fill_super(struct super_block *sb, void *data, int silent){
  int i, t;
#endif
  struct cdrom_tocentry   entry;   
  int no_audio=0, no_data=0;
  cd * this_cd;
  struct inode *retinode;

  PRINT("cdfs_mount\n");

#ifdef OLD_KERNEL
  MOD_INC_USE_COUNT;

  set_blocksize(dev, CD_FRAMESIZE);  // voor bread met ide-cd
#else
  sb_set_blocksize(sb, CD_FRAMESIZE);  // voor bread met ide-cd
#endif

  sb->s_blocksize = CD_FRAMESIZE;
  sb->s_blocksize_bits = 11;

  if (!(this_cd = cdfs_info(sb) = kmalloc(sizeof(cd), GFP_KERNEL))){
#ifdef OLD_KERNEL
    MOD_DEC_USE_COUNT;     
    return NULL;
#else
    return -ENOMEM;
#endif
  }

  this_cd->mode           = MODE;
  this_cd->gid            = GID;
  this_cd->uid            = UID;
  this_cd->single         = FALSE;
  this_cd->raw_audio      = 0;
  this_cd->toc_scsi       = FALSE;

  // Initialize cache for maximum sector size
  if (!(this_cd->cache = kmalloc(CD_FRAMESIZE_RAWER*CACHE_SIZE, GFP_KERNEL))) {
#ifdef OLD_KERNEL
    MOD_DEC_USE_COUNT;
    return NULL;
#else
    kfree(cdfs_info(sb));
    return -ENOMEM;
#endif
  }

  // Cache is still invalid
  this_cd->cache_sector = -CACHE_SIZE;

  cdfs_parse_options((char *) data, this_cd);

  /* Populate CD info with '.' and '..' */
  strcpy(this_cd->track[1].name, ".");  this_cd->track[1].start_lba=0;
  strcpy(this_cd->track[2].name, ".."); this_cd->track[2].start_lba=0;
  this_cd->nr_iso_sessions = 0;
  this_cd->size            = 0;

  if (this_cd->toc_scsi){
    if (cdfs_toc_read_full(sb)){
      printk("TOC read failed\n");
#ifdef OLD_KERNEL
      MOD_DEC_USE_COUNT;
      return NULL;
#else
      goto invalid;
#endif
    }
  } else {
    //if (cdfs_ioctl(sb, CDROMREADTOCHDR, (unsigned long)&hdr)){
    if (cdfs_toc_read(sb)){
      printk("cdfs_toc_read failed\n");
#ifdef OLD_KERNEL
      MOD_DEC_USE_COUNT;
      return NULL;
#else
      goto invalid;
#endif
    }
  }

  PRINT("CD contains %d tracks\n", this_cd->tracks);

  /* Collect track info */
  entry.cdte_format = CDROM_LBA;

  for (t=this_cd->tracks; t>=0; t--) {

    i = T2I(t);
//    j = this_cd->tracks-i;

 //   entry.cdte_track = (t==this_cd->tracks) ? CDROM_LEADOUT : t+1;
 //   PRINT("Read track %d/%d/%d\n", entry.cdte_track, t, i);

 //   if (cdfs_ioctl(sb, CDROMREADTOCENTRY, (unsigned long)&entry)){
   //   printk("ioctl(CDROMREADTOCENTRY) failed\n");
     // MOD_DEC_USE_COUNT;
  //    return NULL;
   // }

 //   this_cd->track[i].start_lba  = entry.cdte_addr.lba;
 //   this_cd->track[i].stop_lba   = this_cd->track[i+1].start_lba - 1;
    this_cd->track[i].track_size = this_cd->track[i+1].start_lba - this_cd->track[i].start_lba;  /* in sectors! */

    PRINT("Start[%d]: %d\n", i, this_cd->track[i].start_lba);

    if (t!=this_cd->tracks) {                 /* all tracks but the LEADOUT */
      if (this_cd->track[i].type==DATA) {
	//int track=i;
	no_data++;
	this_cd->track[i].iso_info  = cdfs_get_iso_info(sb, i);
	if (this_cd->track[i].iso_info) {
	  this_cd->track[i].time      = cdfs_constructtime((char*)&(this_cd->track[i].iso_info->creation_date));
	  this_cd->track[i].iso_size  = cdfs_constructsize((char*)&(this_cd->track[i].iso_info->volume_space_size)) * CD_FRAMESIZE;
	  if (!this_cd->single) this_cd->track[i].iso_size += this_cd->track[i].start_lba * CD_FRAMESIZE;
	  this_cd->track[i].track_size *= CD_FRAMESIZE;
	  this_cd->track[i].size = this_cd->track[i+1].start_lba * CD_FRAMESIZE;
	  sprintf(this_cd->track[i].name, this_cd->single ? DATA_NAME_SINGLE : DATA_NAME_ISO, t+1);
	  this_cd->lba_iso_sessions[this_cd->nr_iso_sessions].start = this_cd->track[i].start_lba;
	  this_cd->lba_iso_sessions[this_cd->nr_iso_sessions].stop  = this_cd->track[i].iso_size/CD_FRAMESIZE;
	  this_cd->nr_iso_sessions++;
	  cdfs_get_hfs_info(sb, i);  // possibly also a HFS
	} else {  // DATA, but no ISO -> either HFS or VideoCD
	  if (cdfs_get_hfs_info(sb, i)==-1){
	    printk("CHECKING VIDEOCD!!\n");
	    cdfs_get_XA_info(sb, i);
	    this_cd->track[i].time       = 0;
	    this_cd->track[i].iso_size   = 0;
	    this_cd->track[i].track_size = (this_cd->track[i].track_size-1) * this_cd->track[i].xa_data_size;
	    this_cd->track[i].size       = this_cd->track[i].track_size;
	    sprintf(this_cd->track[i].name, DATA_NAME_VCD, no_data);
	  } else { // HFS, no ISO, no VideoCD -> remove track
	    this_cd->track[i].iso_info  = NULL;
	    this_cd->track[i].type      = 0;
	  }
	}
      } else {
	no_audio++;
	this_cd->track[i].iso_info    = NULL;
	this_cd->track[i].type        = AUDIO;
	this_cd->track[i].time        = get_seconds();
	this_cd->track[i].iso_size    = 0;
	this_cd->track[i].track_size  = this_cd->track[i].track_size * CD_FRAMESIZE_RAW + ((this_cd->raw_audio==0)?WAV_HEADER_SIZE:0);
	this_cd->track[i].size        = this_cd->track[i].track_size;
	this_cd->track[i].avi         = 0;
	sprintf(this_cd->track[i].name, (this_cd->raw_audio)? RAW_AUDIO_NAME:AUDIO_NAME, t+1);
	if (this_cd->raw_audio) {
	  /* read the first sector. */
	  struct cdrom_read_audio cdda;
	  int status,k,j,prevk=0;
	  char* buf;
	  buf=kmalloc(CD_FRAMESIZE_RAW*2,GFP_KERNEL);
	  if(buf==NULL) {
		printk(FSNAME ": kmalloc failed in root.c !\n");
		return(-ENOMEM);
	  }
	  for (j=0;j<10;j++) {
	    cdda.addr_format = CDROM_LBA;
	    cdda.nframes     = 1;
	    cdda.buf         = buf+CD_FRAMESIZE_RAW;
	    cdda.addr.lba = this_cd->track[i].start_lba+j;
	    status = cdfs_ioctl(sb,CDROMREADAUDIO,(unsigned long)&cdda);
	    if (status) {
	      printk("cdfs_ioctl(CDROMREADAUDIO,%d) ioctl failed: %d\n", cdda.addr.lba, status);
	      goto out;
	    }
	    /* search the first non-zero byte */
	    for (k=0;k<CD_FRAMESIZE_RAW;k++)
	      if (buf[k+CD_FRAMESIZE_RAW]) break;
	    if (k<=CD_FRAMESIZE_RAW-4) break;
	    prevk=k;
	    if (k<CD_FRAMESIZE_RAW)
	      for (k=0;k<CD_FRAMESIZE_RAW;k++)
		buf[k]=buf[k+CD_FRAMESIZE_RAW];
	  }
	  if (j==10) goto out;
	  if ((j!=0)&&(prevk!=CD_FRAMESIZE_RAW)) {
	    k=prevk;
	    j--;
	  }
	  else k+=CD_FRAMESIZE_RAW;
	  this_cd->track[i].avi_offset = j*CD_FRAMESIZE_RAW+k-CD_FRAMESIZE_RAW;
	  if ((buf[k]=='R')&&(buf[k+1]=='I')&&
	      (buf[k+2]=='F')&&(buf[k+3]=='F')) {
	    this_cd->track[i].avi = 1;
	    this_cd->track[i].avi_swab = 0;
	  } else if ((buf[k]=='I')&&(buf[k+1]=='R')&&
	      (buf[k+2]=='F')&&(buf[k+3]=='F')) {
	    this_cd->track[i].avi = 1;
	    this_cd->track[i].avi_swab = 1;
	  }
	  if (this_cd->track[i].avi) {
	    if ((this_cd->track[i].avi_offset&1)!=0) {
	      printk("AVI offset is not even, error\n");
	      this_cd->track[i].avi=0;
	    } else {
	      this_cd->track[i].track_size -= this_cd->track[i].avi_offset;
	      sprintf(this_cd->track[i].name, AVI_AUDIO_NAME, t+1);
	    }
	  }
out:
    kfree(buf);
	}
      }
      // Calculate total CD size
      this_cd->size += this_cd->track[i].track_size;

      PRINT("Track %2d: (%dB)\n", t,  this_cd->track[i].size);

    } // else CDROM_LEADOUT

  }

  PRINT("CD ends at %d\n", this_cd->track[this_cd->tracks].start_lba);


  /* take care to get disc id after the toc has been read. JP, 29-12-2001 */
  this_cd->discid = discid(this_cd);

  ////////////////////////////////

  /* Check if CD is bootable */
  if (this_cd->track[T2I(0)].type==DATA) cdfs_check_bootable(sb);

  /* Check for an HFS partition in the first data track */
  /*if (no_data) {
    i=T2I(0);
    while (i<T2I(this_cd->tracks)) {
      if (this_cd->track[i].type==DATA)
        break;
      i++;
    }
    cdfs_get_hfs_info(sb, i);
  }
  */
  
  PRINT("%d audio tracks and %d data tracks => %dbytes\n", 
        no_audio, no_data, this_cd->size);
  
  sb->s_magic  = CDFS_MAGIC;
  sb->s_flags |= MS_RDONLY;
  sb->s_op     = &cdfs_ops;
  /* always get inode status */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24)
  retinode=cdfs_iget(sb, 0);
#else
  retinode=iget(sb, 0);
#endif
  if ( IS_ERR(retinode) )
    return PTR_ERR(retinode);

  PRINT("retinode = %ld\n", retinode->i_ino);

  sb->s_root   = d_alloc_root(retinode);

  cdfs_proc_cd = this_cd;

#ifdef OLD_KERNEL
  return sb;
#else
  return 0;

invalid:
  kfree(this_cd->cache);
  kfree(cdfs_info(sb));
  return -EINVAL;
#endif
}
Exemple #14
0
void cdfs_copy_from_cddata(struct super_block * sb, int inode, unsigned int start,
	unsigned int stop, char * buf){
  int start_sector, start_byte, stop_sector, stop_byte, sector;
  int status;
  cd * this_cd = cdfs_info(sb);
  unsigned int data_size = CD_FRAMESIZE;
  printk("cddata.c:cdfs_copy_from_cddata():AnyoneUseThis???\n");
    
  start_sector = start / data_size;
  start_byte   = start % data_size;
  stop_sector  = stop  / data_size;
  stop_byte    = stop  % data_size;

  if (!stop_byte) {            /* empty frame */
    stop_sector -= 1;
    stop_byte    = CD_FRAMESIZE;
  }
  
  PRINT("%d[%d-%d] -> 0x%x...0x%x  ... (%d,%d),(%d,%d)\n",
        inode, start, stop, (int)buf, (int)buf+stop-start,
        start_sector,start_byte,stop_sector,stop_byte);

  for (sector=start_sector; sector<=stop_sector; sector++) {
    
    unsigned lba = cdfs_data_bmap(sb, inode, sector);
    
    if (!(this_cd->cache_sector == lba))
    {
    	this_cd->cache_sector = lba;
    	if((status = cdfs_read_rawDATA_frame(sb, lba, this_cd->cache)))
    	{
    		printk("copy_from_cddata(%d): ioctl failed: %d\n", lba, status);
    		return;
    	}
    }


    
    {
      char * copy_start;
      int copy_length;
      
      if (sector==start_sector) {
        copy_start  = this_cd->cache+start_byte;
        if (sector!=stop_sector)
          copy_length = data_size-start_byte;
        else
          copy_length = stop_byte-start_byte;
      } else if (sector==stop_sector) {
        copy_start  = this_cd->cache;
        copy_length = stop_byte;
      } else {
        copy_start  = this_cd->cache;
        copy_length = data_size;
      }
      PRINT("memcpy(0x%x, 0x%x, %d)\n", (int)buf, (int)copy_start, copy_length);      
      memcpy(buf, (char*)copy_start, copy_length);
      buf+=copy_length;
    }

  }
}