/***** Make a directory */
int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
{
	struct super_block *sb = dir->i_sb;
	struct buffer_head *bh;
	struct msdos_dir_entry *de;
	struct inode *inode;
	int res,is_hid;
	char msdos_name[MSDOS_NAME];
	loff_t ino;

	res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
				msdos_name, &MSDOS_SB(sb)->options);
	if (res < 0)
		return res;
	is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
	/* foo vs .foo situation */
	if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0)
		goto out_exist;

	res = msdos_add_entry(dir, msdos_name, &bh, &de, &ino, 1, is_hid);
	if (res)
		goto out_unlock;
	inode = fat_build_inode(dir->i_sb, de, ino, &res);
	if (!inode) {
		fat_brelse(sb, bh);
		goto out_unlock;
	}
	res = 0;

	dir->i_nlink++;
	inode->i_nlink = 2; /* no need to mark them dirty */

	res = fat_new_dir(inode, dir, 0);
	if (res)
		goto mkdir_error;

	fat_brelse(sb, bh);
	d_instantiate(dentry, inode);
	res = 0;

out_unlock:
	return res;

mkdir_error:
	printk(KERN_WARNING "msdos_mkdir: error=%d, attempting cleanup\n", res);
	inode->i_nlink = 0;
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	dir->i_nlink--;
	mark_inode_dirty(inode);
	mark_inode_dirty(dir);
	de->name[0] = DELETED_FLAG;
	fat_mark_buffer_dirty(sb, bh);
	fat_brelse(sb, bh);
	fat_detach(inode);
	iput(inode);
	goto out_unlock;

out_exist:
	fat_brelse(sb, bh);
	res = -EINVAL;
	goto out_unlock;
}
예제 #2
0
파일: namei.c 프로젝트: xricson/knoppix
/***** Make a directory */
int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
{
	struct super_block *sb = dir->i_sb;
	struct buffer_head *bh;
	struct msdos_dir_entry *de;
	struct inode *inode;
	int res,is_hid;
	unsigned char msdos_name[MSDOS_NAME];
	loff_t i_pos;

	lock_kernel();
	res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
				msdos_name, &MSDOS_SB(sb)->options);
	if (res < 0) {
		unlock_kernel();
		return res;
	}
	is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
	/* foo vs .foo situation */
	if (fat_scan(dir, msdos_name, &bh, &de, &i_pos) >= 0)
		goto out_exist;

	res = msdos_add_entry(dir, msdos_name, &bh, &de, &i_pos, 1, is_hid);
	if (res)
		goto out_unlock;
	inode = fat_build_inode(dir->i_sb, de, i_pos, &res);
	if (!inode) {
		brelse(bh);
		goto out_unlock;
	}
	res = 0;

	dir->i_nlink++;
	inode->i_nlink = 2; /* no need to mark them dirty */

	res = fat_new_dir(inode, dir, 0);
	if (res)
		goto mkdir_error;

	brelse(bh);
	d_instantiate(dentry, inode);
	res = 0;

out_unlock:
	unlock_kernel();
	return res;

mkdir_error:
	inode->i_nlink = 0;
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	dir->i_nlink--;
	mark_inode_dirty(inode);
	mark_inode_dirty(dir);
	de->name[0] = DELETED_FLAG;
	mark_buffer_dirty(bh);
	brelse(bh);
	fat_detach(inode);
	iput(inode);
	goto out_unlock;

out_exist:
	brelse(bh);
	res = -EINVAL;
	goto out_unlock;
}