Ejemplo n.º 1
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);
}
Ejemplo n.º 2
0
/*===========================================================================*
 *				fs_readwrite_s				     *
 *===========================================================================*/
PUBLIC int fs_readwrite_s(void)
{
  int r, rw_flag, chunk, block_size, block_spec;
  int partial_cnt, regular, partial_pipe, nrbytes;
  cp_grant_id_t gid;
  off_t position, f_size, bytes_left;
  unsigned int off, cum_io;
  mode_t mode_word;
  int completed, r2 = OK;
  struct inode *rip;
  
  partial_pipe = 0;
  r = OK;
  
  /* Try to get inode according to its index */
  if (fs_m_in.REQ_FD_INODE_INDEX >= 0 && 
          fs_m_in.REQ_FD_INODE_INDEX < NR_INODES &&
          inode[fs_m_in.REQ_FD_INODE_INDEX].i_num == fs_m_in.REQ_FD_INODE_NR) {
      rip = &inode[fs_m_in.REQ_FD_INODE_INDEX];
  }
  else { 
      /* Find the inode referred */
      rip = find_inode(fs_dev, fs_m_in.REQ_FD_INODE_NR);
      if (!rip) {
          printf("FS: unavaliable inode by fs_readwrite(), nr: %d\n", 
                  fs_m_in.REQ_FD_INODE_NR);
          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 */
  block_size = (block_spec ? get_block_size(rip->i_zone[0]) 
      : rip->i_sp->s_block_size);

  f_size = (block_spec ? ULONG_MAX : rip->i_size);
  
  /* Get the values from the request message */ 
  rw_flag = (fs_m_in.m_type == REQ_READ_S ? READING : WRITING);
  gid = fs_m_in.REQ_FD_GID;
  position = fs_m_in.REQ_FD_POS;
  nrbytes = (unsigned) fs_m_in.REQ_FD_NBYTES;
  /*partial_cnt = fs_m_in.REQ_FD_PARTIAL;*/

  /*if (partial_cnt > 0) partial_pipe = 1;*/
  
  rdwt_err = OK;		/* set to EIO if disk error occurs */
  
  if (rw_flag == WRITING && block_spec == 0) {
      /* Check in advance to see if file will grow too big. */
      if (position > 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;
  /* 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 (chunk < 0) chunk = 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_s(rip, cvul64(position), off, chunk, (unsigned) 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 += chunk;	/* position within the file */
  }

  fs_m_out.RES_FD_POS = 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;
	}
  } 
  else {
	if (rip->i_pipe == I_PIPE) {
		if ( position >= rip->i_size) {
			/* Reset pipe pointers. */
			rip->i_size = 0;	/* no data left */
			position = 0;		/* reset reader(s) */
		}
	}
  }

  /* Check to see if read-ahead is called for, and if so, set it up. */
  if (rw_flag == READING && rip->i_seek == NO_SEEK && 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 user-space copying failed, read/write failed. */
  if (r == OK && r2 != OK) {
	r = r2;
  }
  
  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_FD_CUM_IO = cum_io;
  fs_m_out.RES_FD_SIZE = rip->i_size;
  
  return(r);
}
Ejemplo n.º 3
0
/*===========================================================================*
 *				fs_getdents				     *
 *===========================================================================*/
ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
	off_t *posp)
{
	/* Retrieve directory entries.
	 */
	struct fsdriver_dentry fsdentry;
	struct inode *node, *child;
	const char *name;
	off_t pos;
	int r, skip, get_next, indexed;
	static char buf[GETDENTS_BUFSIZ];

	if (*posp >= ULONG_MAX)
		return EIO;

	if ((node = find_inode(ino_nr)) == NULL)
		return EINVAL;

	indexed = node->i_indexed;
	get_next = FALSE;
	child = NULL;

	/* Call the getdents hook, if any, to "refresh" the directory. */
	if (!is_inode_deleted(node) && vtreefs_hooks->getdents_hook != NULL) {
		r = vtreefs_hooks->getdents_hook(node, get_inode_cbdata(node));
		if (r != OK) return r;
	}

	fsdriver_dentry_init(&fsdentry, data, bytes, buf, sizeof(buf));

	do {
		/* Determine which inode and name to use for this entry. */
		pos = (*posp)++;

		if (pos == 0) {
			/* The "." entry. */
			child = node;
			name = ".";
		}
		else if (pos == 1) {
			/* The ".." entry. */
			child = get_parent_inode(node);
			if (child == NULL)
				child = node;
			name = "..";
		}
		else if (pos - 2 < indexed) {
			/* All indexed entries. */
			child = get_inode_by_index(node, pos - 2);

			/* If there is no inode with this particular index,
			 * continue with the next index number.
			 */
			if (child == NULL) continue;

			name = child->i_name;
		}
		else {
			/* All non-indexed entries. */

			/* If this is the first loop iteration, first get to
			 * the non-indexed child identified by the current
			 * position.
			 */
			if (get_next == FALSE) {
				skip = pos - indexed - 2;
				child = get_first_inode(node);

				/* Skip indexed children. */
				while (child != NULL &&
						child->i_index != NO_INDEX)
					child = get_next_inode(child);

				/* Skip to the right position. */
				while (child != NULL && skip-- > 0)
					child = get_next_inode(child);

				get_next = TRUE;
			}
			else {
				child = get_next_inode(child);
			}

			/* No more children? Then stop. */
			if (child == NULL)
				break;

			assert(!is_inode_deleted(child));

			name = child->i_name;
		}

		/* Add the directory entry to the output. */
		r = fsdriver_dentry_add(&fsdentry,
			(ino_t) get_inode_number(child), name, strlen(name),
			IFTODT(child->i_stat.mode));
		if (r < 0)
			return r;
	} while (r > 0);

	return fsdriver_dentry_finish(&fsdentry);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
/*===========================================================================*
 *				do_create				     *
 *===========================================================================*/
PUBLIC int do_create()
{
/* Create a new file.
 */
  char path[PATH_MAX], name[NAME_MAX+1];
  struct inode *parent, *ino;
  struct hgfs_attr attr;
  hgfs_file_t handle;
  int r;

  /* We cannot create files on a read-only file system. */
  if (state.read_only)
	return EROFS;

  /* Get path, name, parent inode and possibly inode for the given path. */
  if ((r = get_name(m_in.REQ_GRANT, m_in.REQ_PATH_LEN, name)) != OK)
	return r;

  if (!strcmp(name, ".") || !strcmp(name, "..")) return EEXIST;

  if ((parent = find_inode(m_in.REQ_INODE_NR)) == NULL)
	return EINVAL;

  if ((r = verify_dentry(parent, name, path, &ino)) != OK)
	return r;

  /* Are we going to need a new inode upon success?
   * Then make sure there is one available before trying anything.
   */
  if (ino == NULL || ino->i_ref > 1 || HAS_CHILDREN(ino)) {
	if (!have_free_inode()) {
		if (ino != NULL)
			put_inode(ino);

		return ENFILE;
	}
  }

  /* Perform the actual create call. */
  r = hgfs_open(path, O_CREAT | O_EXCL | O_RDWR, m_in.REQ_MODE, &handle);

  if (r != OK) {
	/* Let's not try to be too clever with error codes here. If something
	 * is wrong with the directory, we'll find out later anyway.
	 */

	if (ino != NULL)
		put_inode(ino);

	return r;
  }

  /* Get the created file's attributes. */
  attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE;
  r = hgfs_getattr(path, &attr);

  /* If this fails, or returns a directory, we have a problem. This
   * scenario is in fact possible with race conditions.
   * Simulate a close and return a somewhat appropriate error.
   */
  if (r != OK || S_ISDIR(attr.a_mode)) {
	printf("HGFS: lost file after creation!\n");

	hgfs_close(handle);

	if (ino != NULL) {
		del_dentry(ino);

		put_inode(ino);
	}

	return (r == OK) ? EEXIST : r;
  }

  /* We do assume that the HGFS open(O_CREAT|O_EXCL) did its job.
   * If we previousy found an inode, get rid of it now. It's old.
   */
  if (ino != NULL) {
	del_dentry(ino);

	put_inode(ino);
  }

  /* Associate the open file handle with an inode, and reply with its details.
   */
  ino = get_free_inode();

  assert(ino != NULL); /* we checked before whether we had a free one */

  ino->i_file = handle;
  ino->i_flags = I_HANDLE;

  add_dentry(parent, name, ino);

  m_out.RES_INODE_NR = INODE_NR(ino);
  m_out.RES_MODE = get_mode(ino, attr.a_mode);
  m_out.RES_FILE_SIZE_HI = ex64hi(attr.a_size);
  m_out.RES_FILE_SIZE_LO = ex64lo(attr.a_size);
  m_out.RES_UID = opt.uid;
  m_out.RES_GID = opt.gid;
  m_out.RES_DEV = NO_DEV;

  return OK;
}
Ejemplo n.º 7
0
Archivo: read.c Proyecto: Sciumo/minix
/*===========================================================================*
 *				fs_getdents				     *
 *===========================================================================*/
int fs_getdents(void)
{
	/* Retrieve directory entries.
	 */
	struct inode *node, *child = NULL;
	struct dirent *dent;
	char *name;
	size_t len, off, user_off, user_left;
	off_t pos;
	int r, skip, get_next, indexed;
	static char buf[GETDENTS_BUFSIZ];

	if (fs_m_in.REQ_SEEK_POS_HI != 0)
		return EIO;

	if ((node = find_inode(fs_m_in.REQ_INODE_NR)) == NULL)
		return EINVAL;

	off = 0;
	user_off = 0;
	user_left = fs_m_in.REQ_MEM_SIZE;
	indexed = node->i_indexed;
	get_next = FALSE;
	child = NULL;

	/* Call the getdents hook, if any, to "refresh" the directory. */
	if (!is_inode_deleted(node) && vtreefs_hooks->getdents_hook != NULL) {
		r = vtreefs_hooks->getdents_hook(node, get_inode_cbdata(node));
		if (r != OK) return r;
	}

	for (pos = fs_m_in.REQ_SEEK_POS_LO; ; pos++) {
		/* Determine which inode and name to use for this entry. */
		if (pos == 0) {
			/* The "." entry. */
			child = node;
			name = ".";
		}
		else if (pos == 1) {
			/* The ".." entry. */
			child = get_parent_inode(node);
			if (child == NULL)
				child = node;
			name = "..";
		}
		else if (pos - 2 < indexed) {
			/* All indexed entries. */
			child = get_inode_by_index(node, pos - 2);

			/* If there is no inode with this particular index,
			 * continue with the next index number.
			 */
			if (child == NULL) continue;

			name = child->i_name;
		}
		else {
			/* All non-indexed entries. */

			/* If this is the first loop iteration, first get to
			 * the non-indexed child identified by the current
			 * position.
			 */
			if (get_next == FALSE) {
				skip = pos - indexed - 2;
				child = get_first_inode(node);

				/* Skip indexed children. */
				while (child != NULL &&
						child->i_index != NO_INDEX)
					child = get_next_inode(child);

				/* Skip to the right position. */
				while (child != NULL && skip-- > 0)
					child = get_next_inode(child);

				get_next = TRUE;
			}
			else {
				child = get_next_inode(child);
			}

			/* No more children? Then stop. */
			if (child == NULL)
				break;

			assert(!is_inode_deleted(child));

			name = child->i_name;
		}

		len = DWORD_ALIGN(sizeof(struct dirent) + strlen(name));

		/* Is the user buffer too small to store another record? */
		if (user_off + off + len > user_left) {
			/* Is the user buffer too small for even a single
			 * record?
			 */
			if (user_off == 0 && off == 0)
				return EINVAL;

			break;
		}

		/* If our own buffer cannot contain the new record, copy out
		 * first.
		 */
		if (off + len > sizeof(buf)) {
			r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT,
				user_off, (vir_bytes) buf, off, D);
			if (r != OK) return r;

			user_off += off;
			user_left -= off;
			off = 0;
		}

		/* Fill in the actual directory entry. */
		dent = (struct dirent *) &buf[off];
		dent->d_ino = get_inode_number(child);
		dent->d_off = pos;
		dent->d_reclen = len;
		strcpy(dent->d_name, name);

		off += len;
	}

	/* If there is anything left in our own buffer, copy that out now. */
	if (off > 0) {
		r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT,
			user_off, (vir_bytes) buf, off, D);
		if (r != OK)
			return r;

		user_off += off;
	}

	fs_m_out.RES_SEEK_POS_HI = 0;
	fs_m_out.RES_SEEK_POS_LO = pos;
	fs_m_out.RES_NBYTES = user_off;

	return OK;
}
Ejemplo n.º 8
0
Archivo: read.c Proyecto: Sciumo/minix
/*===========================================================================*
 *				do_getdents				     *
 *===========================================================================*/
int do_getdents()
{
/* Retrieve directory entries.
 */
  char name[NAME_MAX+1];
  struct inode *ino, *child;
  struct dirent *dent;
  struct sffs_attr attr;
  size_t len, off, user_off, user_left;
  off_t pos;
  int r;
  /* must be at least sizeof(struct dirent) + NAME_MAX */
  static char buf[BLOCK_SIZE];

  attr.a_mask = SFFS_ATTR_MODE;

  if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL)
	return EINVAL;

  if (m_in.REQ_SEEK_POS_HI != 0) return EINVAL;

  if (!IS_DIR(ino)) return ENOTDIR;

  /* We are going to need at least one free inode to store children in. */
  if (!have_free_inode()) return ENFILE;

  /* If we don't have a directory handle yet, get one now. */
  if ((r = get_handle(ino)) != OK)
	return r;

  off = 0;
  user_off = 0;
  user_left = m_in.REQ_MEM_SIZE;

  /* We use the seek position as file index number. The first position is for
   * the "." entry, the second position is for the ".." entry, and the next
   * position numbers each represent a file in the directory.
   */
  for (pos = m_in.REQ_SEEK_POS_LO; ; pos++) {
	/* Determine which inode and name to use for this entry.
	 * We have no idea whether the host will give us "." and/or "..",
	 * so generate our own and skip those from the host.
	 */
	if (pos == 0) {
		/* Entry for ".". */
		child = ino;

		strcpy(name, ".");

		get_inode(child);
	}
	else if (pos == 1) {
		/* Entry for "..", but only when there is a parent. */
		if (ino->i_parent == NULL)
			continue;

		child = ino->i_parent;

		strcpy(name, "..");

		get_inode(child);
	}
	else {
		/* Any other entry, not being "." or "..". */
		r = sffs_table->t_readdir(ino->i_dir, pos - 2, name,
			sizeof(name), &attr);

		if (r != OK) {
			/* No more entries? Then close the handle and stop. */
			if (r == ENOENT) {
				put_handle(ino);

				break;
			}

			/* FIXME: what if the error is ENAMETOOLONG? */
			return r;
		}

		if (!strcmp(name, ".") || !strcmp(name, ".."))
			continue;

		if ((child = lookup_dentry(ino, name)) == NULL) {
			child = get_free_inode();

			/* We were promised a free inode! */
			assert(child != NULL);

			child->i_flags = MODE_TO_DIRFLAG(attr.a_mode);

			add_dentry(ino, name, child);
		}
	}

	len = DWORD_ALIGN(sizeof(struct dirent) + strlen(name));

	/* Is the user buffer too small to store another record?
	 * Note that we will be rerequesting the same dentry upon a subsequent
	 * getdents call this way, but we really need the name length for this.
	 */
	if (user_off + off + len > user_left) {
		put_inode(child);

		/* Is the user buffer too small for even a single record? */
		if (user_off == 0 && off == 0)
			return EINVAL;

		break;
	}

	/* If our own buffer cannot contain the new record, copy out first. */
	if (off + len > sizeof(buf)) {
		r = sys_safecopyto(m_in.m_source, m_in.REQ_GRANT,
			user_off, (vir_bytes) buf, off, D);

		if (r != OK) {
			put_inode(child);

			return r;
		}

		user_off += off;
		user_left -= off;
		off = 0;
	}

	/* Fill in the actual directory entry. */
	dent = (struct dirent *) &buf[off];
	dent->d_ino = INODE_NR(child);
	dent->d_off = pos;
	dent->d_reclen = len;
	strcpy(dent->d_name, name);

	off += len;

	put_inode(child);
  }

  /* If there is anything left in our own buffer, copy that out now. */
  if (off > 0) {
	r = sys_safecopyto(m_in.m_source, m_in.REQ_GRANT, user_off,
		(vir_bytes) buf, off, D);

	if (r != OK)
		return r;

	user_off += off;
  }

  m_out.RES_SEEK_POS_HI = 0;
  m_out.RES_SEEK_POS_LO = pos;
  m_out.RES_NBYTES = user_off;

  return OK;
}
Ejemplo n.º 9
0
int main(int argc, char **argv) {
    if(argc != 4)
    {
        fprintf(stderr, "Usage: ext2_cp <image file name>  <Absolute path on the disk image> <Absolute on the disk image>\n");
        exit(1);
    }
    int fd = open(argv[1], O_RDWR);
    if (!fd)
    {
        fprintf(stderr, "no file\n" );
        exit(1);
    }

    disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(disk == MAP_FAILED)
    {
        perror("mmap");
        exit(1);
    }

    char *abs_path = argv[2];

    if (abs_path[0] != '/')
    {
        fprintf(stderr,"Not an Absolute Path" );
    }

    char *link_from[100];
    int length=0;
    char *tok = strtok(abs_path, "/");
    while (tok != NULL)
    {
        link_from[length]= tok;
        length++;
        tok = strtok(NULL, "/");
    }

    abs_path = argv[3];

    char *link_to[100];
    int length2=0;
    char *tok2 = strtok(abs_path, "/");
    while (tok2 != NULL)
    {
        link_to[length2]= tok2;
        length2++;
        tok2 = strtok(NULL, "/");
    }

    blockgd = (struct ext2_group_desc *)(disk + 1024 + (EXT2_BLOCK_SIZE));
    inodeTable =  (struct ext2_inode *)(disk + (blockgd->bg_inode_table * (EXT2_BLOCK_SIZE)));


    int inode = 1;
    int i;

    for (i  = 0; i< length-1; i++)
    {
        inode = find_inode(link_from[i], inode);
        if (inode == -1)
        {
            fprintf(stderr, "no such directory\n");
            exit(ENOENT);
        }
    }

    int inode2 = 1;

    for (i  = 0; i< length2-1; i++)
    {
        inode2 = find_inode(link_to[i], inode2);
        if (inode2 == -1)
        {
            fprintf(stderr, "no such directory\n");
            exit(ENOENT);
        }
    }

    struct ext2_inode dirInode = inodeTable[inode];
    int fileInode = -1;

    int shift=0;
    for(i=0; i<dirInode.i_blocks/2; i++) {
        if(fileInode!=-1) {
            break;
        }

        struct ext2_dir_entry_2 *entry;
        if(i>=12) {
            entry = (struct ext2_dir_entry_2 *)(disk + (((unsigned int *)(disk + (inodeTable[inode].i_block[12] -1) * (EXT2_BLOCK_SIZE)))[i-12] -1)*EXT2_BLOCK_SIZE);
        } else {
            entry = (struct ext2_dir_entry_2 *)(disk + inodeTable[inode].i_block[i] * (EXT2_BLOCK_SIZE));
        }

        while (shift < EXT2_BLOCK_SIZE)
        {
            char name[entry->name_len];
            int n;
            for(n= 0; n < entry->name_len; n++)
            {
                name[n]=entry->name[n];
            }
            name[entry->name_len] ='\0';
            if (strcmp(link_from[length - 1], name) == 0)
            {
                if(entry->file_type == 1) {
                    fileInode = entry->inode -1; //  -1 cause position in the inode table
                    break;
                } else {
                    printf("link from is not a file\n");
                    exit(EISDIR);
                }
            }
            else
            {
                shift=shift + entry->rec_len;
                entry = (struct ext2_dir_entry_2 *)(disk + inodeTable[inode].i_block[i] * (EXT2_BLOCK_SIZE)+ shift);
            }
        }
    }

    dirInode = inodeTable[inode2];
    int file2Inode = -1;

    shift = 0;

    for(i=0; i<dirInode.i_blocks/2; i++) {
        if(file2Inode!=-1) {
            break;
        }

        struct ext2_dir_entry_2 *entry;
        if(i>=12) {
            entry = (struct ext2_dir_entry_2 *)(disk + (((unsigned int *)(disk + (inodeTable[inode2].i_block[12] -1) * (EXT2_BLOCK_SIZE)))[i-12] -1)*EXT2_BLOCK_SIZE);
        } else {
            entry = (struct ext2_dir_entry_2 *)(disk + inodeTable[inode2].i_block[i] * (EXT2_BLOCK_SIZE));
        }

        while (shift < EXT2_BLOCK_SIZE)
        {
            char name[entry->name_len];
            int n;
            for(n= 0; n < entry->name_len; n++)
            {
                name[n]=entry->name[n];
            }
            name[entry->name_len] ='\0';
            if (strcmp(link_to[length - 1], name) == 0)
            {
                if(entry->file_type == 1) {
                    file2Inode = entry->inode -1; //  -1 cause position in the inode table
                    break;
                } else {
                    printf("link from is not a file\n");
                    exit(EISDIR);
                }
            }
            else
            {
                shift=shift + entry->rec_len;
                entry = (struct ext2_dir_entry_2 *)(disk + inodeTable[inode2].i_block[i] * (EXT2_BLOCK_SIZE)+ shift);
            }
        }
    }

    printf("file1: %d\n",fileInode);
    printf("file2: %d\n",file2Inode);

    return 0;
}
Ejemplo n.º 10
0
Archivo: read.c Proyecto: Hooman3/minix
/*===========================================================================*
 *				do_getdents				     *
 *===========================================================================*/
ssize_t do_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
	off_t *posp)
{
/* Retrieve directory entries.
 */
  struct fsdriver_dentry fsdentry;
  char name[NAME_MAX+1];
  struct inode *ino, *child;
  struct sffs_attr attr;
  off_t pos;
  int r;
  /* must be at least sizeof(struct dirent) + NAME_MAX */
  static char buf[BLOCK_SIZE];

  if ((ino = find_inode(ino_nr)) == NULL)
	return EINVAL;

  if (!IS_DIR(ino)) return ENOTDIR;

  if (*posp < 0 || *posp >= ULONG_MAX) return EINVAL;

  /* We are going to need at least one free inode to store children in. */
  if (!have_free_inode()) return ENFILE;

  /* If we don't have a directory handle yet, get one now. */
  if ((r = get_handle(ino)) != OK)
	return r;

  fsdriver_dentry_init(&fsdentry, data, bytes, buf, sizeof(buf));

  /* We use the seek position as file index number. The first position is for
   * the "." entry, the second position is for the ".." entry, and the next
   * position numbers each represent a file in the directory.
   */
  do {
	/* Determine which inode and name to use for this entry.
	 * We have no idea whether the host will give us "." and/or "..",
	 * so generate our own and skip those from the host.
	 */
	pos = (*posp)++;

	if (pos == 0) {
		/* Entry for ".". */
		child = ino;

		strcpy(name, ".");

		get_inode(child);
	}
	else if (pos == 1) {
		/* Entry for "..", but only when there is a parent. */
		if (ino->i_parent == NULL)
			continue;

		child = ino->i_parent;

		strcpy(name, "..");

		get_inode(child);
	}
	else {
		/* Any other entry, not being "." or "..". */
		attr.a_mask = SFFS_ATTR_MODE;

		r = sffs_table->t_readdir(ino->i_dir, pos - 2, name,
			sizeof(name), &attr);

		if (r != OK) {
			/* No more entries? Then close the handle and stop. */
			if (r == ENOENT) {
				put_handle(ino);

				break;
			}

			/* FIXME: what if the error is ENAMETOOLONG? */
			return r;
		}

		if (!strcmp(name, ".") || !strcmp(name, ".."))
			continue;

		if ((child = lookup_dentry(ino, name)) == NULL) {
			child = get_free_inode();

			/* We were promised a free inode! */
			assert(child != NULL);

			child->i_flags = MODE_TO_DIRFLAG(attr.a_mode);

			add_dentry(ino, name, child);
		}
	}

	r = fsdriver_dentry_add(&fsdentry, INODE_NR(child), name, strlen(name),
		IS_DIR(child) ? DT_DIR : DT_REG);

	put_inode(child);

	if (r < 0)
		return r;
  } while (r > 0);

  return fsdriver_dentry_finish(&fsdentry);
}
Ejemplo n.º 11
0
/*===========================================================================*
 *				fs_readwrite				     *
 *===========================================================================*/
ssize_t fs_readwrite(ino_t ino_nr, struct fsdriver_data *data, size_t nrbytes,
	off_t position, int call)
{
  int r;
  int regular;
  off_t f_size, bytes_left;
  size_t off, cum_io, block_size, chunk;
  mode_t mode_word;
  int completed;
  struct inode *rip;
  
  r = OK;
  
  /* Find the inode referred */
  if ((rip = find_inode(fs_dev, ino_nr)) == NULL)
	return(EINVAL);

  mode_word = rip->i_mode & I_TYPE;
  regular = (mode_word == I_REGULAR);
  
  /* Determine blocksize */
  block_size = rip->i_sp->s_block_size;
  f_size = rip->i_size;

  lmfs_reset_rdwt_err();

  /* If this is file i/o, check we can write */
  if (call == FSC_WRITE) {
  	  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);
  }

  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 = block_size - off;
	  if (chunk > nrbytes)
		chunk = nrbytes;

	  if (call == FSC_READ) {
		  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, ((u64_t)((unsigned long)position)), off, chunk,
		nrbytes, call, data, cum_io, block_size, &completed);

	  if (r != OK) break;	/* EOF reached */
	  if (lmfs_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 */
  }

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

  rip->i_seek = NO_SEEK;

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

  if (r != OK)
	return r;

  /* 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 (!rip->i_sp->s_rd_only) {
	  if (call == FSC_READ) rip->i_update |= ATIME;
	  if (call == FSC_WRITE) rip->i_update |= CTIME | MTIME;
	  IN_MARKDIRTY(rip);		/* inode is thus now dirty */
  }
  
  return cum_io;
}
Ejemplo n.º 12
0
/*===========================================================================*
 *				fs_readwrite				     *
 *===========================================================================*/
int fs_readwrite(void)
{
  int r, rw_flag;
  block_t b;
  struct buf *bp;
  cp_grant_id_t gid;
  off_t position, f_size;
  unsigned int nrbytes, cum_io;
  mode_t mode_word;
  struct pipe_inode *rip;
  ino_t inumb;

  r = 0;
  cum_io = 0;
  inumb = fs_m_in.REQ_INODE_NR;
  rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
#if 0  
  printk("PFS: going to %s inode %d\n", (rw_flag == READING? "read from": "write to"), inumb);
#endif

  /* Find the inode referred */
  if ((rip = find_inode(inumb)) == NIL_INODE) return(-EINVAL);

  mode_word = rip->i_mode & I_TYPE;
  if (mode_word != I_NAMED_PIPE) return(-EIO);
  f_size = rip->i_size;
  
  /* Get the values from the request message */ 
  rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
  gid = fs_m_in.REQ_GRANT;
  position = fs_m_in.REQ_SEEK_POS_LO;
  nrbytes = (unsigned) fs_m_in.REQ_NBYTES;
  
  if (rw_flag == WRITING) {
	  /* Check in advance to see if file will grow too big. */
	  if (position > PIPE_BUF - nrbytes) return(-EFBIG);
  }

  /* Mark inode in use */
  if ((get_inode(rip->i_dev, rip->i_num)) == NIL_INODE) return(err_code);
  if ((bp = get_block(rip->i_dev, rip->i_num)) == NIL_BUF) return(err_code);

  if (rw_flag == READING) {
	/* Copy a chunk from the block buffer to user space. */
	r = sys_safecopyto(VFS_PROC_NR, gid, 0,
		(vir_bytes) (bp->b_data+position), (phys_bytes) nrbytes, D);
  } else {
	/* Copy a chunk from user space to the block buffer. */
	r = sys_safecopyfrom(VFS_PROC_NR, gid, 0,
		(vir_bytes) (bp->b_data+position), (phys_bytes) nrbytes, D);
  }

  if (r == 0) {
	position += nrbytes; /* Update position */
	cum_io += nrbytes;
  }

  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 (position > f_size) rip->i_size = position;
  } else {
	if(position >= rip->i_size) {
		/* All data in the pipe is read, so reset pipe pointers */
		rip->i_size = 0;	/* no data left */
		position = 0;		/* reset reader(s) */
	}
  }

  bp->b_bytes = position;
  if (rw_flag == READING) rip->i_update |= ATIME;
  if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
  fs_m_out.RES_NBYTES = cum_io;
  put_inode(rip);
  put_block(rip->i_dev, rip->i_num);

  return(r);
}
Ejemplo n.º 13
0
int altera_ci_init(struct altera_ci_config *config, int ci_nr)
{
	struct altera_ci_state *state;
	struct fpga_inode *temp_int = find_inode(config->dev);
	struct fpga_internal *inter = NULL;
	int ret = 0;
	u8 store = 0;

	state = kzalloc(sizeof(struct altera_ci_state), GFP_KERNEL);

	ci_dbg_print("%s\n", __func__);

	if (!state) {
		ret = -ENOMEM;
		goto err;
	}

	if (temp_int != NULL) {
		inter = temp_int->internal;
		(inter->cis_used)++;
		ci_dbg_print("%s: Find Internal Structure!\n", __func__);
	} else {
		inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
		if (!inter) {
			ret = -ENOMEM;
			goto err;
		}

		temp_int = append_internal(inter);
		inter->cis_used = 1;
		inter->dev = config->dev;
		inter->fpga_rw = config->fpga_rw;
		mutex_init(&inter->fpga_mutex);
		inter->strt_wrk = 1;
		ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
	}

	ci_dbg_print("%s: setting state = %p for ci = %d\n", __func__,
						state, ci_nr - 1);
	inter->state[ci_nr - 1] = state;
	state->internal = inter;
	state->nr = ci_nr - 1;

	state->ca.owner = THIS_MODULE;
	state->ca.read_attribute_mem = altera_ci_read_attribute_mem;
	state->ca.write_attribute_mem = altera_ci_write_attribute_mem;
	state->ca.read_cam_control = altera_ci_read_cam_ctl;
	state->ca.write_cam_control = altera_ci_write_cam_ctl;
	state->ca.slot_reset = altera_ci_slot_reset;
	state->ca.slot_shutdown = altera_ci_slot_shutdown;
	state->ca.slot_ts_enable = altera_ci_slot_ts_ctl;
	state->ca.poll_slot_status = altera_poll_ci_slot_status;
	state->ca.data = state;

	ret = dvb_ca_en50221_init(config->adapter,
				   &state->ca,
				   /* flags */ 0,
				   /* n_slots */ 1);
	if (0 != ret)
		goto err;

	altera_hw_filt_init(config, ci_nr);

	if (inter->strt_wrk) {
		INIT_WORK(&inter->work, netup_read_ci_status);
		inter->strt_wrk = 0;
	}

	ci_dbg_print("%s: CI initialized!\n", __func__);

	mutex_lock(&inter->fpga_mutex);

	/* Enable div */
	netup_fpga_op_rw(inter, NETUP_CI_TSA_DIV, 0x0, 0);
	netup_fpga_op_rw(inter, NETUP_CI_TSB_DIV, 0x0, 0);

	/* enable TS out */
	store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
	store |= (3 << 4);
	netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);

	ret = netup_fpga_op_rw(inter, NETUP_CI_REVISION, 0, NETUP_CI_FLG_RD);
	/* enable irq */
	netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0x44, 0);

	mutex_unlock(&inter->fpga_mutex);

	ci_dbg_print("%s: NetUP CI Revision = 0x%x\n", __func__, ret);

	schedule_work(&inter->work);

	return 0;
err:
	ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);

	kfree(state);

	return ret;
}
Ejemplo n.º 14
0
int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
{
	struct netup_hw_pid_filter *pid_filt = NULL;
	struct fpga_inode *temp_int = find_inode(config->dev);
	struct fpga_internal *inter = NULL;
	int ret = 0;

	pid_filt = kzalloc(sizeof(struct netup_hw_pid_filter), GFP_KERNEL);

	ci_dbg_print("%s\n", __func__);

	if (!pid_filt) {
		ret = -ENOMEM;
		goto err;
	}

	if (temp_int != NULL) {
		inter = temp_int->internal;
		(inter->filts_used)++;
		ci_dbg_print("%s: Find Internal Structure!\n", __func__);
	} else {
		inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
		if (!inter) {
			ret = -ENOMEM;
			goto err;
		}

		temp_int = append_internal(inter);
		inter->filts_used = 1;
		inter->dev = config->dev;
		inter->fpga_rw = config->fpga_rw;
		mutex_init(&inter->fpga_mutex);
		inter->strt_wrk = 1;
		ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
	}

	ci_dbg_print("%s: setting hw pid filter = %p for ci = %d\n", __func__,
						pid_filt, hw_filt_nr - 1);
	inter->pid_filt[hw_filt_nr - 1] = pid_filt;
	pid_filt->demux = config->demux;
	pid_filt->internal = inter;
	pid_filt->nr = hw_filt_nr - 1;
	/* store old feed controls */
	pid_filt->start_feed = config->demux->start_feed;
	pid_filt->stop_feed = config->demux->stop_feed;
	/* replace with new feed controls */
	if (hw_filt_nr == 1) {
		pid_filt->demux->start_feed = altera_ci_start_feed_1;
		pid_filt->demux->stop_feed = altera_ci_stop_feed_1;
	} else if (hw_filt_nr == 2) {
		pid_filt->demux->start_feed = altera_ci_start_feed_2;
		pid_filt->demux->stop_feed = altera_ci_stop_feed_2;
	}

	altera_toggle_fullts_streaming(pid_filt, 0, 1);

	return 0;
err:
	ci_dbg_print("%s: Can't init hardware filter: Error %d\n",
		     __func__, ret);

	kfree(pid_filt);

	return ret;
}
Ejemplo n.º 15
0
int main(int argc, char **argv){
	 if(argc != 3) 
    {
        fprintf(stderr, "Usage: ext2_ls <image file name>  <absolute path on the disk>\n");
        exit(1);
    }
    int fd = open(argv[1], O_RDWR);

    disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(disk == MAP_FAILED) 
    {
		perror("mmap");	
		exit(1);
    }
   
    char *abs_path = argv[2];
    
    if (abs_path[0] != '/')
    {
    	fprintf(stderr,"Not an Absolute Path" );
    	exit(1);
    }

    char *dir[100];
    int length=0; 
    char *tok = strtok(abs_path, "/"); 
	while (tok != NULL)
    {
        dir[length]= tok;
        length++;
        tok = strtok(NULL, "/");
    }

    blockgd = (struct ext2_group_desc *)(disk + 1024 + (EXT2_BLOCK_SIZE));
    inodeTable =  (struct ext2_inode *)(disk + (blockgd->bg_inode_table * (EXT2_BLOCK_SIZE)));

    int inode = 1;	
    int i;

    for (i  = 0; i< length-1; i++)
    {	
    	inode = find_inode(dir[i], inode);
    	if (inode == -1)
    	{
    		fprintf(stderr, "no such directory\n");
    		exit(ENOENT);
    	}
    } 

	struct ext2_inode dirInode = inodeTable[inode];
	int fileInode = -1;

	int shift=0;
	for(i=0;i<dirInode.i_blocks/2;i++){
		if(fileInode!=-1){
			break;
		}

		struct ext2_dir_entry_2 *entry;
       if(i>=12){
            entry = (struct ext2_dir_entry_2 *)(disk + (((unsigned int *)(disk + (inodeTable[inode].i_block[12] -1) * (EXT2_BLOCK_SIZE)))[i-12] -1)*EXT2_BLOCK_SIZE);
       }else{
            entry = (struct ext2_dir_entry_2 *)(disk + inodeTable[inode].i_block[i] * (EXT2_BLOCK_SIZE));
       }

		struct ext2_dir_entry_2 *prev;
        while (shift < EXT2_BLOCK_SIZE)
        {
            char name[entry->name_len];
            int n;
            for(n= 0; n < entry->name_len; n++)
            {
                name[n]=entry->name[n];
            }
            name[entry->name_len] ='\0';
            if (entry->file_type == 1 && strcmp(dir[length - 1], name) == 0)
            {
                fileInode = entry->inode -1; //  -1 cause position in the inode table
                if(prev){
                	prev->rec_len += entry->rec_len;
            	}
                break;
            }
            else 
            {
                shift=shift + entry->rec_len; 
                prev = entry;
                entry = (struct ext2_dir_entry_2 *)(disk + inodeTable[inode].i_block[i] * (EXT2_BLOCK_SIZE)+ shift);
            }
        }
	} 

    if(fileInode!=-1){
    	struct ext2_inode fileInodeStruct = inodeTable[fileInode];
    	int j;
    	for(j=0;j<fileInodeStruct.i_blocks/2;j++){
			int blockID;

    		if(j>=12){
    			blockID = (disk + (fileInodeStruct.i_block[12] -1)*EXT2_BLOCK_SIZE)[j-12] -1;
    		}else{
    			blockID = fileInodeStruct.i_block[j] - 1;
    		}

    		unset_bit(blockgd->bg_block_bitmap, blockID);
    	}

    	unset_bit(blockgd->bg_inode_bitmap, fileInode);
    }else{
    	printf("no such file");
    	exit(ENOENT);
    }

    return 0;

}