コード例 #1
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int	reiserfs_rename (
			 struct inode * old_dir, struct dentry *old_dentry,
			 struct inode * new_dir, struct dentry *new_dentry
			 )
{
  static struct wait_queue * wait = NULL;
  static int lock = 0;
  int result;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  
  while (lock)
    sleep_on(&wait);
  lock = 1;
  journal_begin(&th, old_dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiesrfs_rename") ;
  /* we are trusting if_in_ram_update_sd to update the transaction 
  ** info in each inode as they get chagned
  */
  result = do_reiserfs_rename (&th, old_dir, old_dentry, new_dir, new_dentry);
  pop_journal_writer(windex) ;
  journal_end(&th, old_dir->i_sb, jbegin_count) ;
  lock = 0;
  wake_up(&wait);
  return result;
}
コード例 #2
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
{
  struct inode *inode = old_dentry->d_inode;
  struct path path_to_entry;
  struct reiserfs_dir_entry de;
  int error;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  
  init_path (&path_to_entry);

  /* object must not be directory */
  if (S_ISDIR(inode->i_mode)) {
    return -EPERM;
  }
  
  /* file has too many links */
  if (inode->i_nlink >= REISERFS_LINK_MAX) {
    return -EMLINK;
  }

  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_link") ;

  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de) == POSITION_FOUND) {
    pathrelse (&path_to_entry);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return -EEXIST;
  }
  
  pathrelse (&path_to_entry);

  /* free preserve list if we should */
/*  maybe_free_preserve_list (dir->i_sb);*/

  /* create new entry */
  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return error;
  }
  inode->i_nlink++;
  inode->i_ctime = CURRENT_TIME;
  if_in_ram_update_sd (&th, inode);
  if_in_ram_update_sd (&th, dir);
  inode->i_count++;
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #3
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
{
  int error;
  struct inode * inode;
  struct reiserfs_dir_entry de;
  int windex ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
  struct reiserfs_transaction_handle th ;
  int err;
	
  if (!dir)
    return -ENOENT;
	
  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  th.t_caller = "create" ;
  windex = push_journal_writer("reiserfs_create") ;
  inode = reiserfs_new_inode (&th, dir, mode, 0, dentry, inode, &err);
  if (!inode) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;
	
  inode->i_op = &reiserfs_file_inode_operations;
  inode->i_mode = mode;

  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }
  if_in_ram_update_sd (&th, dir); 
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #4
0
/*
** We pack the tails of files on file close, not at the time they are written.
** This implies an unnecessary copy of the tail and an unnecessary indirect item
** insertion/balancing, for files that are written in one write.
** It avoids unnecessary tail packings (balances) for files that are written in
** multiple writes and are small enough to have tails.
** 
** file_release is called by the VFS layer when the file is closed.  If
** this is the last open file descriptor, and the file
** small enough to have a tail, and the tail is currently in an
** unformatted node, the tail is converted back into a direct item.
** 
** We use reiserfs_truncate_file to pack the tail, since it already has
** all the conditions coded.  
*/
static int reiserfs_file_release (struct inode * inode, struct file * filp)
{

    struct reiserfs_transaction_handle th ;
    int windex ;

    if (!S_ISREG (inode->i_mode))
	BUG ();

    /* fast out for when nothing needs to be done */
    if ((atomic_read(&inode->i_count) > 1 ||
         !(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) || 
         !tail_has_to_be_packed(inode))       && 
	inode->u.reiserfs_i.i_prealloc_count <= 0) {
	return 0;
    }    
    
    lock_kernel() ;
    down (&inode->i_sem); 
    journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
    reiserfs_update_inode_transaction(inode) ;

#ifdef REISERFS_PREALLOCATE
    reiserfs_discard_prealloc (&th, inode);
#endif
    journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;

    if (atomic_read(&inode->i_count) <= 1 &&
	(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) &&
        tail_has_to_be_packed (inode)) {
	/* if regular file is released by last holder and it has been
	   appended (we append by unformatted node only) or its direct
	   item(s) had to be converted, then it may have to be
	   indirect2direct converted */
	windex = push_journal_writer("file_release") ;
	reiserfs_truncate_file(inode, 0) ;
	pop_journal_writer(windex) ;
    }
    up (&inode->i_sem); 
    unlock_kernel() ;
    return 0;
}
コード例 #5
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname)
{
  struct inode * inode;
  struct path path_to_entry;
  struct reiserfs_dir_entry de;
  int error;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  int err;

  init_path (&path_to_entry);
  if (strlen (symname) + 1 + SD_SIZE > MAX_ITEM_LEN (dir->i_sb->s_blocksize)) {
    return -ENAMETOOLONG;
  }
  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }
 
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_symlink") ;
  inode = reiserfs_new_inode (&th, dir, S_IFLNK, symname, dentry, inode, &err);
  if (inode == 0) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  inode->i_op = &reiserfs_symlink_inode_operations;
  inode->i_size = strlen (symname);
  inode->i_mode = S_IFLNK | 0777;
  if_in_ram_update_sd (&th, inode);

  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de) == POSITION_FOUND) {
    pathrelse (&path_to_entry);
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return -EEXIST;
  }
  pathrelse (&path_to_entry);

  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }
  if_in_ram_update_sd (&th, dir);
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #6
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
{
  int retval;
  struct inode * inode;
  struct reiserfs_dir_entry de;
  struct path path;
  int windex ;
  int call_journal_end = 1 ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 

  init_path (&path);

  retval = -ENOENT;
	
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_unlink") ;
  /* free preserve list if we should */
/*  maybe_free_preserve_list (dir->i_sb);*/
	
  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == POSITION_NOT_FOUND) {
    goto end_unlink;
  }

  inode = dentry->d_inode;

  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  retval = -EPERM;
  if (S_ISDIR (inode->i_mode)) {
    goto end_unlink;
  }
  if ((dir->i_mode & S_ISVTX) && !fsuser() &&
      current->fsuid != inode->i_uid &&
      current->fsuid != dir->i_uid) {
    goto end_unlink;
  }

  retval = -ENOENT;
  if (comp_short_keys ((struct key *)&(de.de_dir_id), INODE_PKEY (inode))) {
    goto end_unlink;
  }
  
  if (!inode->i_nlink) {
    printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
	   kdevname(inode->i_dev), inode->i_ino, inode->i_nlink);
    inode->i_nlink = 1;
  }
  if (reiserfs_cut_from_item (&th, dir, dir->i_sb, &path, &(de.de_entry_num), &(de.de_entry_key), 0, NOTHING_SPECIAL) == 0) {
    retval = -ENOENT;
    goto end_unlink;
  }

  inode->i_nlink--;
  inode->i_ctime = CURRENT_TIME;
  if_in_ram_update_sd (&th, inode);

  dir->i_size -= (de.de_entrylen + DEH_SIZE);
  dir->i_ctime = dir->i_mtime = CURRENT_TIME;
  if_in_ram_update_sd (&th, dir) ;
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  call_journal_end = 0 ;
  d_delete(dentry); 
  retval = 0;

end_unlink:
  pathrelse (&path);
  pop_journal_writer(windex) ;
  if (call_journal_end) 
    journal_end(&th, dir->i_sb, jbegin_count) ;
  return retval;
}
コード例 #7
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
{
  struct inode * inode;
  int retval;
  struct reiserfs_dir_entry de;
  struct path path;
  struct super_block *s ;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 

  init_path (&path);

  retval = -ENOENT;
  de.de_gen_number_bit_string = 0;
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiesrfs_rmdir") ;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == POSITION_NOT_FOUND)
    goto end_rmdir;

  inode = dentry->d_inode;

  /* we don't need call this so early here, I'm just being cautious */
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  retval = rmdir_not_allowed (dir, &de, inode);
  if (retval)
    goto end_rmdir;

  /* free preserve list if we should */
/*  maybe_free_preserve_list (dir->i_sb);*/

  if (!reiserfs_empty_dir (inode))
    retval = -ENOTEMPTY;
  else {
    /* cut entry from dir directory */
    if (reiserfs_cut_from_item (&th, dir, dir->i_sb, &path, &(de.de_entry_num), &(de.de_entry_key), 0, NOTHING_SPECIAL) == 0) {
      retval = -ENOENT;
    }
  }
  if (retval)
    goto end_rmdir;

  if (inode->i_nlink != 2)
    printk ("reiserfs_rmdir: empty directory has nlink != 2 (%d)\n", inode->i_nlink);
  inode->i_nlink = 0;
  inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
  if_in_ram_update_sd (&th, inode);
  dir->i_nlink --;
  dir->i_size -= (DEH_SIZE + de.de_entrylen);
  if_in_ram_update_sd (&th, dir);

  s = dir->i_sb ;
  pop_journal_writer(windex) ;
  journal_end(&th, s, jbegin_count) ;
  d_delete(dentry); /* note, we've moved this after the journal end */
  return 0;
	
end_rmdir:
  /* we must release path, because we did not call reiserfs_cut_from_item, or reiserfs_cut_from_item
     does not release path if operation was not complete */
  pathrelse (&path);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return retval;	
}
コード例 #8
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
{
  int error;
  struct inode * inode;
  struct path path_to_entry;
  struct reiserfs_dir_entry de;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  int err;


  init_path (&path_to_entry);
  if (!dir || !dir->i_sb) {
    return -EINVAL;
  }
  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }

  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_mkdir") ;
  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de) == POSITION_FOUND) {
    pathrelse (&path_to_entry);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput(inode) ;
    return -EEXIST;
  }
  pathrelse (&path_to_entry);
  
  if (dir->i_nlink >= REISERFS_LINK_MAX) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput(inode) ;
    return -EMLINK;
  }
  
  mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
  if (dir->i_mode & S_ISGID)
    mode |= S_ISGID;
  inode = reiserfs_new_inode (&th, dir, mode, 0, dentry, inode, &err);
  if (!inode) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  inode->i_op = &reiserfs_dir_inode_operations;

  /* new inode and stat data are uptodate. Inode is clean. */
  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink = 0;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }

  /* update dir inode, reiserfs_add_entry does not do that */
  dir->i_nlink ++;
  if_in_ram_update_sd (&th, dir);
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}
コード例 #9
0
ファイル: namei.c プロジェクト: chinnyannieb/empeg-hijack
int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
{
  int error;
  struct inode * inode;
  struct path path_to_entry;
  struct reiserfs_dir_entry de;
  int windex ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
  int err;

  if (!dir)
    return -ENOENT;

  init_path (&path_to_entry);

  inode = get_empty_inode() ;
  if (!inode) {
    return -ENOSPC ;
  }
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_mknod") ;
  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de) == POSITION_FOUND) {
    pathrelse ( &path_to_entry);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput(inode) ;
    return -EEXIST;
  }

  pathrelse ( &path_to_entry);

  inode = reiserfs_new_inode (&th, dir, mode, 0, dentry, inode, &err);
  if (!inode) {
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    return err;
  }
  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  inode->i_uid = current->fsuid;
  inode->i_mode = mode;
  inode->i_op = NULL;

  if (S_ISREG(inode->i_mode))
    inode->i_op = &reiserfs_file_inode_operations;
  else if (S_ISDIR(inode->i_mode)) {
    inode->i_op = &reiserfs_dir_inode_operations;
    if (dir->i_mode & S_ISGID)
      inode->i_mode |= S_ISGID;
  }
  else if (S_ISLNK(inode->i_mode))
    inode->i_op = &reiserfs_symlink_inode_operations;
  else if (S_ISCHR(inode->i_mode))
    inode->i_op = &chrdev_inode_operations;
  else if (S_ISBLK(inode->i_mode))
    inode->i_op = &blkdev_inode_operations;
  else if (S_ISFIFO(inode->i_mode))
    init_fifo(inode);
  if (S_ISBLK(mode) || S_ISCHR(mode))
    inode->i_rdev = to_kdev_t(rdev);

  if_in_ram_update_sd (&th, inode);

  error = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, INODE_PKEY (inode), &de, 1);
  if (error) {
    inode->i_nlink--;
    if_in_ram_update_sd (&th, inode);
    pop_journal_writer(windex) ;
    journal_end(&th, dir->i_sb, jbegin_count) ;
    iput (inode);
    return error;
  }
  if_in_ram_update_sd (&th, dir);
  d_instantiate(dentry, inode);
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  return 0;
}