Beispiel #1
0
int
affs_unlink(struct inode *dir, struct dentry *dentry)
{
	int			 retval;
	struct buffer_head	*bh;
	unsigned long		 ino;
	struct inode		*inode;

	pr_debug("AFFS: unlink(dir=%ld,\"%.*s\")\n",dir->i_ino,
		 (int)dentry->d_name.len,dentry->d_name.name);

	retval  = -ENOENT;
	if (!(bh = affs_find_entry(dir,dentry,&ino)))
		goto unlink_done;

	inode  = dentry->d_inode;

	if ((retval = affs_remove_header(bh,inode)) < 0)
		goto unlink_done;
	
	inode->i_nlink = retval;
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	dir->i_version = ++event;
	mark_inode_dirty(inode);
	d_delete(dentry);
	mark_inode_dirty(dir);
	retval = 0;

unlink_done:
	affs_brelse(bh);
	return retval;
}
Beispiel #2
0
int
affs_rmdir(struct inode *dir, struct dentry *dentry)
{
	pr_debug("%s(dir=%lu, %lu \"%pd\")\n", __func__, dir->i_ino,
		 dentry->d_inode->i_ino, dentry);

	return affs_remove_header(dentry);
}
int
affs_rmdir(struct inode *dir, struct dentry *dentry)
{
	pr_debug("AFFS: rmdir(dir=%u, \"%.*s\")\n", (u32)dir->i_ino,
		 (int)dentry->d_name.len, dentry->d_name.name);

	return affs_remove_header(dentry);
}
Beispiel #4
0
int
affs_unlink(struct inode *dir, struct dentry *dentry)
{
	pr_debug("AFFS: unlink(dir=%d, %lu \"%.*s\")\n", (u32)dir->i_ino,
		 dentry->d_inode->i_ino,
		 (int)dentry->d_name.len, dentry->d_name.name);

	return affs_remove_header(dentry);
}
Beispiel #5
0
int
affs_rename(struct inode *old_dir, struct dentry *old_dentry,
	    struct inode *new_dir, struct dentry *new_dentry)
{
	struct super_block *sb = old_dir->i_sb;
	struct buffer_head *bh = NULL;
	int retval;

	pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
		 old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);

	retval = affs_check_name(new_dentry->d_name.name,
				 new_dentry->d_name.len,
				 affs_nofilenametruncate(old_dentry));

	if (retval)
		return retval;

	/* Unlink destination if it already exists */
	if (new_dentry->d_inode) {
		retval = affs_remove_header(new_dentry);
		if (retval)
			return retval;
	}

	bh = affs_bread(sb, old_dentry->d_inode->i_ino);
	if (!bh)
		return -EIO;

	/* Remove header from its parent directory. */
	affs_lock_dir(old_dir);
	retval = affs_remove_hash(old_dir, bh);
	affs_unlock_dir(old_dir);
	if (retval)
		goto done;

	/* And insert it into the new directory with the new name. */
	affs_copy_name(AFFS_TAIL(sb, bh)->name, new_dentry);
	affs_fix_checksum(sb, bh);
	affs_lock_dir(new_dir);
	retval = affs_insert_hash(new_dir, bh);
	affs_unlock_dir(new_dir);
	/* TODO: move it back to old_dir, if error? */

done:
	mark_buffer_dirty_inode(bh, retval ? old_dir : new_dir);
	affs_brelse(bh);
	return retval;
}
Beispiel #6
0
int
affs_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct inode		*inode = dentry->d_inode;
	int			 retval;
	unsigned long		 ino;
	struct buffer_head	*bh;

	pr_debug("AFFS: rmdir(dir=%lu,\"%.*s\")\n",dir->i_ino,
		 (int)dentry->d_name.len,dentry->d_name.name);

	retval = -ENOENT;
	if (!(bh = affs_find_entry(dir,dentry,&ino)))
		goto rmdir_done;

	/*
	 * Make sure the directory is empty and the dentry isn't busy.
	 */
	retval = -ENOTEMPTY;
	if (!empty_dir(bh,AFFS_I2HSIZE(inode)))
		goto rmdir_done;
	retval = -EBUSY;
	if (!list_empty(&dentry->d_hash))
		goto rmdir_done;

	if ((retval = affs_remove_header(bh,inode)) < 0)
		goto rmdir_done;
	
	inode->i_nlink = retval;
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	retval         = 0;
	dir->i_version = ++event;
	mark_inode_dirty(dir);
	mark_inode_dirty(inode);
	d_delete(dentry);

rmdir_done:
	affs_brelse(bh);
	return retval;
}
Beispiel #7
0
int
affs_rename(struct inode *old_dir, struct dentry *old_dentry,
	    struct inode *new_dir, struct dentry *new_dentry)
{
	struct inode		*old_inode = old_dentry->d_inode;
	struct inode		*new_inode = new_dentry->d_inode;
	struct buffer_head	*old_bh;
	struct buffer_head	*new_bh;
	unsigned long		 old_ino;
	unsigned long		 new_ino;
	int			 retval;

	pr_debug("AFFS: rename(old=%lu,\"%*s\" (inode=%p) to new=%lu,\"%*s\" (inode=%p))\n",
		 old_dir->i_ino,old_dentry->d_name.len,old_dentry->d_name.name,old_inode,
		 new_dir->i_ino,new_dentry->d_name.len,new_dentry->d_name.name,new_inode);
	
	if ((retval = affs_check_name(new_dentry->d_name.name,new_dentry->d_name.len)))
		goto out;

	new_bh = NULL;
	retval = -ENOENT;
	old_bh = affs_find_entry(old_dir,old_dentry,&old_ino);
	if (!old_bh)
		goto end_rename;

	new_bh = affs_find_entry(new_dir,new_dentry,&new_ino);
	if (new_bh && !new_inode) {
		affs_error(old_inode->i_sb,"affs_rename",
			   "No inode for entry found (key=%lu)\n",new_ino);
		goto end_rename;
	}
	if (S_ISDIR(old_inode->i_mode)) {
		if (new_inode) {
			retval = -ENOTEMPTY;
			if (!empty_dir(new_bh,AFFS_I2HSIZE(new_inode)))
				goto end_rename;
		}

		retval = -ENOENT;
		if (affs_parent_ino(old_inode) != old_dir->i_ino)
			goto end_rename;
	}
	/* Unlink destination if it already exists */
	if (new_inode) {
		if ((retval = affs_remove_header(new_bh,new_dir)) < 0)
			goto end_rename;
		new_inode->i_nlink = retval;
		mark_inode_dirty(new_inode);
		if (new_inode->i_ino == new_ino)
			new_inode->i_nlink = 0;
	}
	/* Remove header from its parent directory. */
	if ((retval = affs_remove_hash(old_bh,old_dir)))
		goto end_rename;
	/* And insert it into the new directory with the new name. */
	affs_copy_name(FILE_END(old_bh->b_data,old_inode)->file_name,new_dentry->d_name.name);
	if ((retval = affs_insert_hash(new_dir->i_ino,old_bh,new_dir)))
		goto end_rename;
	affs_fix_checksum(AFFS_I2BSIZE(new_dir),old_bh->b_data,5);

	new_dir->i_ctime   = new_dir->i_mtime = old_dir->i_ctime
			   = old_dir->i_mtime = CURRENT_TIME;
	new_dir->i_version = ++event;
	old_dir->i_version = ++event;
	retval             = 0;
	mark_inode_dirty(new_dir);
	mark_inode_dirty(old_dir);
	mark_buffer_dirty(old_bh,1);
	
end_rename:
	affs_brelse(old_bh);
	affs_brelse(new_bh);
out:
	return retval;
}