Exemplo n.º 1
0
/***** Unlink a file */
static int msdos_unlink(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = d_inode(dentry);
	struct super_block *sb = inode->i_sb;
	struct fat_slot_info sinfo;
	int err;

	mutex_lock(&MSDOS_SB(sb)->s_lock);
	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (err)
		goto out;

	err = fat_remove_entries(dir, &sinfo);	/* and releases bh */
	if (err)
		goto out;
	clear_nlink(inode);
	inode->i_ctime = current_time(inode);
	fat_detach(inode);
out:
	mutex_unlock(&MSDOS_SB(sb)->s_lock);
	if (!err)
		err = fat_flush_inodes(sb, dir, inode);

	return err;
}
Exemplo n.º 2
0
static int msdos_unlink(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	struct super_block *sb= inode->i_sb;
	struct fat_slot_info sinfo;
	int err;

	lock_super(sb);
	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (err)
		goto out;

	err = fat_remove_entries(dir, &sinfo);	/*                 */
	if (err)
		goto out;
	clear_nlink(inode);
	inode->i_ctime = CURRENT_TIME_SEC;
	fat_detach(inode);
out:
	unlock_super(sb);
	if (!err)
		err = fat_flush_inodes(sb, dir, inode);

	return err;
}
/***** Get inode using directory and name */
struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode = NULL;
	struct msdos_dir_entry *de;
	struct buffer_head *bh = NULL;
	int res;
	loff_t ino;
	
	PRINTK (("msdos_lookup\n"));

	dentry->d_op = &msdos_dentry_operations;

	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh,
			&de, &ino);

	if (res == -ENOENT)
		goto add;
	if (res < 0)
		goto out;
	inode = fat_build_inode(sb, de, ino, &res);
	if (res)
		goto out;
add:
	d_add(dentry, inode);
	res = 0;
out:
	if (bh)
		fat_brelse(sb, bh);
	return ERR_PTR(res);
}
/***** Unlink a file */
int msdos_unlink( struct inode *dir, struct dentry *dentry)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode = dentry->d_inode;
	int res;
	loff_t ino;
	struct buffer_head *bh;
	struct msdos_dir_entry *de;

	bh = NULL;
	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len,
			&bh, &de, &ino);
	if (res < 0)
		goto unlink_done;

	de->name[0] = DELETED_FLAG;
	fat_mark_buffer_dirty(sb, bh);
	fat_detach(inode);
	fat_brelse(sb, bh);
	inode->i_nlink = 0;
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	mark_inode_dirty(inode);
	mark_inode_dirty(dir);
	res = 0;
unlink_done:
	return res;
}
Exemplo n.º 5
0
/***** Get inode using directory and name */
struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry, struct nameidata *nd)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode = NULL;
	struct msdos_dir_entry *de;
	struct buffer_head *bh = NULL;
	loff_t i_pos;
	int res;
	
	dentry->d_op = &msdos_dentry_operations;

	lock_kernel();
	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh,
			 &de, &i_pos);
	if (res == -ENOENT)
		goto add;
	if (res < 0)
		goto out;
	inode = fat_build_inode(sb, de, i_pos, &res);
	if (res)
		goto out;
add:
	res = 0;
	dentry = d_splice_alias(inode, dentry);
	if (dentry)
		dentry->d_op = &msdos_dentry_operations;
out:
	brelse(bh);
	unlock_kernel();
	if (!res)
		return dentry;
	return ERR_PTR(res);
}
Exemplo n.º 6
0
/***** Unlink a file */
int msdos_unlink( struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	loff_t i_pos;
	int res;
	struct buffer_head *bh;
	struct msdos_dir_entry *de;

	bh = NULL;
	lock_kernel();
	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len,
			 &bh, &de, &i_pos);
	if (res < 0)
		goto unlink_done;

	de->name[0] = DELETED_FLAG;
	mark_buffer_dirty(bh);
	fat_detach(inode);
	brelse(bh);
	inode->i_nlink = 0;
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	mark_inode_dirty(inode);
	mark_inode_dirty(dir);
	res = 0;
unlink_done:
	unlock_kernel();
	return res;
}
Exemplo n.º 7
0
/***** Remove a directory */
int msdos_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode = dentry->d_inode;
	int res,ino;
	struct buffer_head *bh;
	struct msdos_dir_entry *de;

	bh = NULL;
	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len,
				&bh, &de, &ino);
	if (res < 0)
		goto rmdir_done;
	/*
	 * Check whether the directory is not in use, then check
	 * whether it is empty.
	 */
	res = fat_dir_empty(inode);
	if (res)
		goto rmdir_done;

	de->name[0] = DELETED_FLAG;
	fat_mark_buffer_dirty(sb, bh);
	fat_detach(inode);
	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);
	res = 0;

rmdir_done:
	fat_brelse(sb, bh);
	return res;
}
Exemplo n.º 8
0
/***** Remove a directory */
static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	struct fat_slot_info sinfo;
	int err;

	lock_kernel();
	/*
	 * Check whether the directory is not in use, then check
	 * whether it is empty.
	 */
	err = fat_dir_empty(inode);
	if (err)
		goto out;
	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (err)
		goto out;

	err = fat_remove_entries(dir, &sinfo);	/* and releases bh */
	if (err)
		goto out;
	drop_nlink(dir);

	clear_nlink(inode);
	inode->i_ctime = CURRENT_TIME_SEC;
	fat_detach(inode);
out:
	unlock_kernel();
	if (!err)
		err = fat_flush_inodes(inode->i_sb, dir, inode);

	return err;
}
Exemplo n.º 9
0
int msdos_unlink(struct inode *dir,const char *name,int len)
{
	int res,ino;
	struct buffer_head *bh;
	struct msdos_dir_entry *de;
	struct inode *inode;

	bh = NULL;
	inode = NULL;
	if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0)
		goto unlink_done;
	if (!(inode = iget(dir->i_dev,ino))) {
		res = -ENOENT;
		goto unlink_done;
	}
	if (!S_ISREG(inode->i_mode)) {
		res = -EPERM;
		goto unlink_done;
	}
	inode->i_nlink = 0;
	MSDOS_I(inode)->i_busy = 1;
	inode->i_dirt = 1;
	de->name[0] = DELETED_FLAG;
	bh->b_dirt = 1;
unlink_done:
	brelse(bh);
	iput(inode);
	iput(dir);
	return res;
}
Exemplo n.º 10
0
/***** Remove a directory */
static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode = d_inode(dentry);
	struct fat_slot_info sinfo;
	int err;

	mutex_lock(&MSDOS_SB(sb)->s_lock);
	/*
	 * Check whether the directory is not in use, then check
	 * whether it is empty.
	 */
	err = fat_dir_empty(inode);
	if (err)
		goto out;
	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (err)
		goto out;

	err = fat_remove_entries(dir, &sinfo);	/* and releases bh */
	if (err)
		goto out;
	drop_nlink(dir);

	clear_nlink(inode);
	inode->i_ctime = current_time(inode);
	fat_detach(inode);
out:
	mutex_unlock(&MSDOS_SB(sb)->s_lock);
	if (!err)
		err = fat_flush_inodes(sb, dir, inode);

	return err;
}
Exemplo n.º 11
0
/***** Get inode using directory and name */
static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
				   struct nameidata *nd)
{
	struct super_block *sb = dir->i_sb;
	struct fat_slot_info sinfo;
	struct inode *inode = NULL;
	int res;

	dentry->d_op = &msdos_dentry_operations;

	lock_kernel();
	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (res == -ENOENT)
		goto add;
	if (res < 0)
		goto out;
	inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
	brelse(sinfo.bh);
	if (IS_ERR(inode)) {
		res = PTR_ERR(inode);
		goto out;
	}
add:
	res = 0;
	dentry = d_splice_alias(inode, dentry);
	if (dentry)
		dentry->d_op = &msdos_dentry_operations;
out:
	unlock_kernel();
	if (!res)
		return dentry;
	return ERR_PTR(res);
}
Exemplo n.º 12
0
/***** Get inode using directory and name */
static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
				   struct nameidata *nd)
{
	struct super_block *sb = dir->i_sb;
	struct fat_slot_info sinfo;
	struct inode *inode;
	int err;

	lock_super(sb);

	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (err) {
		if (err == -ENOENT) {
			inode = NULL;
			goto out;
		}
		goto error;
	}

	inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
	brelse(sinfo.bh);
	if (IS_ERR(inode)) {
		err = PTR_ERR(inode);
		goto error;
	}
out:
	unlock_super(sb);
	return d_splice_alias(inode, dentry);

error:
	unlock_super(sb);
	return ERR_PTR(err);
}
Exemplo n.º 13
0
int msdos_lookup(struct inode *dir,const char *name,int len,
    struct inode **result)
{
	int ino,res;
	struct msdos_dir_entry *de;
	struct buffer_head *bh;
	struct inode *next;

	*result = NULL;
	if (!dir) return -ENOENT;
	if (!S_ISDIR(dir->i_mode)) {
		iput(dir);
		return -ENOENT;
	}
	if (len == 1 && get_fs_byte(name) == '.') {
		*result = dir;
		return 0;
	}
	if (len == 2 && get_fs_byte(name) == '.' && get_fs_byte(name+1) == '.')
	    {
		ino = msdos_parent_ino(dir,0);
		iput(dir);
		if (ino < 0) return ino;
		if (!(*result = iget(dir->i_dev,ino))) return -EACCES;
		return 0;
	}
	if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) {
		iput(dir);
		return res;
	}
	if (bh) brelse(bh);
/* printk("lookup: ino=%d\r\n",ino); */
	if (!(*result = iget(dir->i_dev,ino))) {
		iput(dir);
		return -EACCES;
	}
	if (MSDOS_I(*result)->i_busy) { /* mkdir in progress */
		iput(*result);
		iput(dir);
		return -ENOENT;
	}
	while (MSDOS_I(*result)->i_old) {
		next = MSDOS_I(*result)->i_old;
		iput(*result);
		if (!(*result = iget(next->i_dev,next->i_ino)))
			panic("msdos_lookup: Can't happen");
	}
	iput(dir);
	return 0;
}
Exemplo n.º 14
0
int msdos_rmdir(struct inode *dir,const char *name,int len)
{
	int res,ino,pos;
	struct buffer_head *bh,*dbh;
	struct msdos_dir_entry *de,*dde;
	struct inode *inode;

	bh = NULL;
	inode = NULL;
	res = -EINVAL;
	if (get_fs_byte(name) == '.' && (len == 1 || (len == 2 &&
	    get_fs_byte(name+1) == '.'))) goto rmdir_done;
	if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) goto rmdir_done;
	res = -ENOENT;
	if (!(inode = iget(dir->i_dev,ino))) goto rmdir_done;
	res = -ENOTDIR;
	if (!S_ISDIR(inode->i_mode)) goto rmdir_done;
	res = -EBUSY;
	if (dir->i_dev != inode->i_dev || dir == inode) goto rmdir_done;
	if (inode->i_count > 1) goto rmdir_done;
	if (MSDOS_I(inode)->i_start) { /* may be zero in mkdir */
		res = -ENOTEMPTY;
		pos = 0;
		dbh = NULL;
		while (msdos_get_entry(inode,&pos,&dbh,&dde) > -1)
			if (dde->name[0] && ((unsigned char *) dde->name)[0] !=
			    DELETED_FLAG && strncmp(dde->name,MSDOS_DOT,
			    MSDOS_NAME) && strncmp(dde->name,MSDOS_DOTDOT,
			    MSDOS_NAME)) goto rmdir_done;
		if (dbh) brelse(dbh);
	}
	inode->i_nlink = 0;
	dir->i_mtime = CURRENT_TIME;
	dir->i_nlink--;
	inode->i_dirt = dir->i_dirt = 1;
	de->name[0] = DELETED_FLAG;
	bh->b_dirt = 1;
	res = 0;
rmdir_done:
	brelse(bh);
	iput(dir);
	iput(inode);
	return res;
}
Exemplo n.º 15
0
/***** Get inode using directory and name */
static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
				   struct nameidata *nd)
{
	struct super_block *sb = dir->i_sb;
	struct fat_slot_info sinfo;
	struct inode *inode;
	int err;

        char szBuffer[20];
        int len = min((int)dentry->d_name.len, 19);
        memset(szBuffer, 0, 20);
        __memcpy(szBuffer, dentry->d_name.name, len);
        printk (KERN_INFO "myfat: msdos_lookup, dir is %s\n", szBuffer);

	lock_super(sb);

	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (err) {
		if (err == -ENOENT) {
			inode = NULL;
			goto out;
		}
		goto error;
	}

	inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);  // by rzq: hold the reference count
	brelse(sinfo.bh);
	if (IS_ERR(inode)) {
		err = PTR_ERR(inode);
		goto error;
	}
out:
	unlock_super(sb);
	dentry->d_op = &msdos_dentry_operations;
	dentry = d_splice_alias(inode, dentry);
	if (dentry)
		dentry->d_op = &msdos_dentry_operations;
	return dentry;

error:
	unlock_super(sb);
	return ERR_PTR(err);
}
Exemplo n.º 16
0
/***** Unlink a file */
static int msdos_unlink(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	struct fat_slot_info sinfo;
	int err;

	lock_kernel();
	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	if (err)
		goto out;

	err = fat_remove_entries(dir, &sinfo);	/* and releases bh */
	if (err)
		goto out;
	inode->i_nlink = 0;
	inode->i_ctime = CURRENT_TIME_SEC;
	fat_detach(inode);
out:
	unlock_kernel();

	return err;
}
Exemplo n.º 17
0
/***** Remove a directory */
static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	loff_t i_pos;
	int res;
	struct buffer_head *bh;
	struct msdos_dir_entry *de;

	bh = NULL;
	lock_kernel();
	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len,
			 &bh, &de, &i_pos);
	if (res < 0)
		goto rmdir_done;
	/*
	 * Check whether the directory is not in use, then check
	 * whether it is empty.
	 */
	res = fat_dir_empty(inode);
	if (res)
		goto rmdir_done;

	de->name[0] = DELETED_FLAG;
	mark_buffer_dirty(bh);
	fat_detach(inode);
	inode->i_nlink = 0;
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
	dir->i_nlink--;
	mark_inode_dirty(inode);
	mark_inode_dirty(dir);
	res = 0;

rmdir_done:
	brelse(bh);
	unlock_kernel();
	return res;
}
Exemplo n.º 18
0
/***** Get inode using directory and name */
static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
				   unsigned int flags)
{
	struct super_block *sb = dir->i_sb;
	struct fat_slot_info sinfo;
	struct inode *inode;
	int err;

	mutex_lock(&MSDOS_SB(sb)->s_lock);
	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	switch (err) {
	case -ENOENT:
		inode = NULL;
		break;
	case 0:
		inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
		brelse(sinfo.bh);
		break;
	default:
		inode = ERR_PTR(err);
	}
	mutex_unlock(&MSDOS_SB(sb)->s_lock);
	return d_splice_alias(inode, dentry);
}
Exemplo n.º 19
0
static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
				   struct nameidata *nd)
{
	struct super_block *sb = dir->i_sb;
	struct fat_slot_info sinfo;
	struct inode *inode;
	int err;

	lock_super(sb);
	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
	switch (err) {
	case -ENOENT:
		inode = NULL;
		break;
	case 0:
		inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
		brelse(sinfo.bh);
		break;
	default:
		inode = ERR_PTR(err);
	}
	unlock_super(sb);
	return d_splice_alias(inode, dentry);
}