示例#1
0
文件: inode.c 项目: rohsaini/mkunity
/*
	Load an inode from disk.
*/
void UMSDOS_read_inode(struct inode *inode)
{
	PRINTK (("read inode %x ino = %d ",inode,inode->i_ino));
	msdos_read_inode(inode);
	PRINTK (("ino = %d %d\n",inode->i_ino,inode->i_count));
	if (S_ISDIR(inode->i_mode)
		&& (inode->u.umsdos_i.u.dir_info.creating != 0
			|| inode->u.umsdos_i.u.dir_info.looking != 0
			|| waitqueue_active(&inode->u.umsdos_i.u.dir_info.p))){
		Printk (("read inode %d %d %p\n"
			,inode->u.umsdos_i.u.dir_info.creating
			,inode->u.umsdos_i.u.dir_info.looking
			,inode->u.umsdos_i.u.dir_info.p));
	}
	/* #Specification: Inode / post initialisation
		To completely initialise an inode, we need access to the owner
		directory, so we can locate more info in the EMD file. This is
		not available the first time the inode is access, we use
		a value in the inode to tell if it has been finally initialised.

		At first, we have tried testing i_count but it was causing
		problem. It is possible that two or more process use the
		newly accessed inode. While the first one block during
		the initialisation (probably while reading the EMD file), the
		others believe all is well because i_count > 1. They go banana
		with a broken inode. See umsdos_lookup_patch and umsdos_patch_inode.
	*/
	umsdos_patch_inode(inode,NULL,0);
}
示例#2
0
文件: namei.c 项目: binsys/doc-linux
static int msdos_create_entry(struct inode *dir,char *name,int is_dir,
    struct inode **result)
{
	struct buffer_head *bh;
	struct msdos_dir_entry *de;
	int res,ino;

	if ((res = msdos_scan(dir,NULL,&bh,&de,&ino)) < 0) {
		if (dir->i_ino == MSDOS_ROOT_INO) return -ENOSPC;
		if ((res = msdos_add_cluster(dir)) < 0) return res;
		if ((res = msdos_scan(dir,NULL,&bh,&de,&ino)) < 0) return res;
	}
	memcpy(de->name,name,MSDOS_NAME);
	de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
	de->start = 0;
	date_unix2dos(CURRENT_TIME,&de->time,&de->date);
	de->size = 0;
	bh->b_dirt = 1;
	if (*result = iget(dir->i_dev,ino)) msdos_read_inode(*result);
	brelse(bh);
	if (!*result) return -EIO;
	(*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime =
	    CURRENT_TIME;
	(*result)->i_dirt = 1;
	return 0;
}
示例#3
0
文件: namei.c 项目: binsys/doc-linux
static int rename_same_dir(struct inode *old_dir,char *old_name,
    struct inode *new_dir,char *new_name,struct buffer_head *old_bh,
    struct msdos_dir_entry *old_de,int old_ino)
{
	struct buffer_head *new_bh;
	struct msdos_dir_entry *new_de;
	struct inode *new_inode,*old_inode;
	int new_ino;
	int exists;

	if (!strncmp(old_name,new_name,MSDOS_NAME)) return 0;
	exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino) >= 0;
	if (*(unsigned char *) old_de->name == DELETED_FLAG) {
		if (exists) brelse(new_bh);
		return -ENOENT;
	}
	if (exists) {
		if (!(new_inode = iget(new_dir->i_dev,new_ino))) {
			brelse(new_bh);
			return -EIO;
		}
		if (S_ISDIR(new_inode->i_mode)) {
			iput(new_inode);
			brelse(new_bh);
			return -EPERM;
		}
		new_inode->i_nlink = 0;
		MSDOS_I(new_inode)->i_busy = 1;
		new_inode->i_dirt = 1;
		new_de->name[0] = DELETED_FLAG;
		new_bh->b_dirt = 1;
		iput(new_inode);
		brelse(new_bh);
	}
	memcpy(old_de->name,new_name,MSDOS_NAME);
	old_bh->b_dirt = 1;
	if (MSDOS_SB(old_dir->i_sb)->conversion == 'a') /* update binary info */
		if (old_inode = iget(old_dir->i_dev,old_ino)) {
			msdos_read_inode(old_inode);
			iput(old_inode);
		}
	return 0;
}
示例#4
0
文件: namei.c 项目: binsys/doc-linux
static int rename_diff_dir(struct inode *old_dir,char *old_name,
    struct inode *new_dir,char *new_name,struct buffer_head *old_bh,
    struct msdos_dir_entry *old_de,int old_ino)
{
	struct buffer_head *new_bh,*free_bh,*dotdot_bh;
	struct msdos_dir_entry *new_de,*free_de,*dotdot_de;
	struct inode *old_inode,*new_inode,*free_inode,*dotdot_inode,*walk;
	int new_ino,free_ino,dotdot_ino;
	int error,exists,ino;

	if (old_dir->i_dev != new_dir->i_dev) return -EINVAL;
	if (old_ino == new_dir->i_ino) return -EINVAL;
	if (!(walk = iget(new_dir->i_dev,new_dir->i_ino))) return -EIO;
	while (walk->i_ino != MSDOS_ROOT_INO) {
		ino = msdos_parent_ino(walk,1);
		iput(walk);
		if (ino < 0) return ino;
		if (ino == old_ino) return -EINVAL;
		if (!(walk = iget(new_dir->i_dev,ino))) return -EIO;
	}
	iput(walk);
	if ((error = msdos_scan(new_dir,NULL,&free_bh,&free_de,&free_ino)) < 0)
	    return error;
	exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino)
	    >= 0;
	if (!(old_inode = iget(old_dir->i_dev,old_ino))) {
		brelse(free_bh);
		if (exists) brelse(new_bh);
		return -EIO;
	}
	if (*(unsigned char *) old_de->name == DELETED_FLAG) {
		iput(old_inode);
		brelse(free_bh);
		if (exists) brelse(new_bh);
		return -ENOENT;
	}
	new_inode = NULL; /* to make GCC happy */
	if (exists) {
		if (!(new_inode = iget(new_dir->i_dev,new_ino))) {
			iput(old_inode);
			brelse(new_bh);
			return -EIO;
		}
		if (S_ISDIR(new_inode->i_mode)) {
			iput(new_inode);
			iput(old_inode);
			brelse(new_bh);
			return -EPERM;
		}
		new_inode->i_nlink = 0;
		MSDOS_I(new_inode)->i_busy = 1;
		new_inode->i_dirt = 1;
		new_de->name[0] = DELETED_FLAG;
		new_bh->b_dirt = 1;
	}
	memcpy(free_de,old_de,sizeof(struct msdos_dir_entry));
	memcpy(free_de->name,new_name,MSDOS_NAME);
	if (!(free_inode = iget(new_dir->i_dev,free_ino))) {
		free_de->name[0] = DELETED_FLAG;
/*  Don't mark free_bh as dirty. Both states are supposed to be equivalent. */
		brelse(free_bh);
		if (exists) {
			iput(new_inode);
			brelse(new_bh);
		}
		return -EIO;
	}
	msdos_read_inode(free_inode);
	MSDOS_I(old_inode)->i_busy = 1;
	cache_inval_inode(old_inode);
	old_inode->i_dirt = 1;
	old_de->name[0] = DELETED_FLAG;
	old_bh->b_dirt = 1;
	free_bh->b_dirt = 1;
	if (!exists) iput(free_inode);
	else {
		MSDOS_I(new_inode)->i_depend = free_inode;
		MSDOS_I(free_inode)->i_old = new_inode;
		/* free_inode is put when putting new_inode */
		iput(new_inode);
		brelse(new_bh);
	}
	if (S_ISDIR(old_inode->i_mode)) {
		if ((error = msdos_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
		    &dotdot_de,&dotdot_ino)) < 0) goto rename_done;
		if (!(dotdot_inode = iget(old_inode->i_dev,dotdot_ino))) {
			brelse(dotdot_bh);
			error = -EIO;
			goto rename_done;
		}
		dotdot_de->start = MSDOS_I(dotdot_inode)->i_start =
		    MSDOS_I(new_dir)->i_start;
		dotdot_inode->i_dirt = 1;
		dotdot_bh->b_dirt = 1;
		iput(dotdot_inode);
		brelse(dotdot_bh);
		old_dir->i_nlink--;
		new_dir->i_nlink++;
		/* no need to mark them dirty */
	}
	error = 0;
rename_done:
	brelse(free_bh);
	iput(old_inode);
	return error;
}