Пример #1
0
/*
 * Called by iput() when the inode reference count reached zero
 * and the inode is not hashed anywhere.  Used to clear anything
 * that needs to be, before the inode is completely destroyed and put
 * on the inode free list.
 */
STATIC void
mini_fo_clear_inode(inode_t *inode)
{
	/*
	 * Decrement a reference to a hidden_inode, which was incremented
	 * by our read_inode when it was created initially.
	 */

	/* release the wol_list */
	if(S_ISDIR(inode->i_mode)) {
		__meta_put_lists(inode);
	}

	/* mk: fan out fun */
	if(itohi(inode))
		iput(itohi(inode));
	if(itohi2(inode))
		iput(itohi2(inode));

	// XXX: why this assertion fails?
	// because it doesn't like us
	// ASSERT((inode->i_state & I_DIRTY) == 0);
	kfree(itopd(inode));
	__itopd(inode) = NULL;
}
Пример #2
0
STATIC void
mini_fo_read_inode(inode_t *inode)
{
	static struct address_space_operations mini_fo_empty_aops;

	__itopd(inode) = kmalloc(sizeof(struct mini_fo_inode_info), GFP_KERNEL);
	if (!itopd(inode)) {
		printk("<0>%s:%s:%d: No kernel memory!\n", __FILE__, __FUNCTION__, __LINE__);
		ASSERT(NULL);
	}
	itohi(inode) = NULL;
	itohi2(inode) = NULL;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
	inode->i_version++;
#else
	inode->i_version = ++event;	/* increment inode version */
#endif
	inode->i_op = &mini_fo_main_iops;
	inode->i_fop = &mini_fo_main_fops;
#if 0
	/*
	 * XXX: To export a file system via NFS, it has to have the
	 * FS_REQUIRES_DEV flag, so turn it on.  But should we inherit it from
	 * the lower file system, or can we allow our file system to be exported
	 * even if the lower one cannot be natively exported.
	 */
	inode->i_sb->s_type->fs_flags |= FS_REQUIRES_DEV;
	/*
	 * OK, the above was a hack, which is now turned off because it may
	 * cause a panic/oops on some systems.  The correct way to export a
	 * "nodev" filesystem is via using nfs-utils > 1.0 and the "fsid=" export
	 * parameter, which requires 2.4.20 or later.
	 */
#endif
	/* I don't think ->a_ops is ever allowed to be NULL */
	inode->i_mapping->a_ops = &mini_fo_empty_aops;
}
Пример #3
0
int create_sto_reg_file(dentry_t *dentry, int mode)
#endif
{
	int err = 0;
	inode_t *dir;
	dentry_t *hidden_sto_dentry;
	dentry_t *hidden_sto_dir_dentry;

	if(exists_in_storage(dentry)) {
		printk(KERN_CRIT "mini_fo: create_sto_file: wrong type or state.\n");
		err = -EINVAL;
		goto out;
	}
	err = get_neg_sto_dentry(dentry);

	if (err) {
		printk(KERN_CRIT "mini_fo: create_sto_file: ERROR getting neg. sto dentry.\n");
		goto out;
	}

	dir = dentry->d_parent->d_inode;
	hidden_sto_dentry = dtohd2(dentry);

	/* lock parent */
	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);

	err = PTR_ERR(hidden_sto_dir_dentry);
        if (IS_ERR(hidden_sto_dir_dentry))
                goto out;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
	err = vfs_create(hidden_sto_dir_dentry->d_inode,
			 hidden_sto_dentry,
			 mode, nd);
#else
	err = vfs_create(hidden_sto_dir_dentry->d_inode,
			 hidden_sto_dentry,
			 mode);
#endif
        if(err) {
		printk(KERN_CRIT "mini_fo: create_sto_file: ERROR creating sto file.\n");
                goto out_lock;
	}

	if(!dtohd2(dentry)->d_inode) {
		printk(KERN_CRIT "mini_fo: create_sto_file: ERROR creating sto file [2].\n");
                err = -EINVAL;
                goto out_lock;
        }

        /* interpose the new inode */
        if(dtost(dentry) == DELETED) {
                dtost(dentry) = DEL_REWRITTEN;
                err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
                if(err)
                        goto out_lock;
        }
        else if(dtost(dentry) == NON_EXISTANT) {
                dtost(dentry) = CREATED;
                err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
                if(err)
                        goto out_lock;
        }
        else if(dtost(dentry) == UNMODIFIED) {
                dtost(dentry) = MODIFIED;
                /* interpose on new inode */
                if(itohi2(dentry->d_inode) != NULL) {
                        printk(KERN_CRIT "mini_fo: create_sto_file: invalid inode detected.\n");
                        err = -EINVAL;
                        goto out_lock;
                }
                itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
	}
	fist_copy_attr_timesizes(dentry->d_parent->d_inode,
				 hidden_sto_dir_dentry->d_inode);

 out_lock:
        dput(hidden_sto_dir_dentry);
 out:
	return err;
}
Пример #4
0
int create_sto_nod(dentry_t *dentry, int mode, int dev)
#endif
{
	int err = 0;
	inode_t *dir;
	dentry_t *hidden_sto_dentry;
	dentry_t *hidden_sto_dir_dentry;

	if(exists_in_storage(dentry)) {
		err = -EEXIST;
		goto out;
	}
	err = get_neg_sto_dentry(dentry);

	if (err) {
                printk(KERN_CRIT "mini_fo: create_sto_nod: ERROR getting neg. sto dentry.\n");
                goto out;
        }

	dir = dentry->d_parent->d_inode;
	hidden_sto_dentry = dtohd2(dentry);

	/* lock parent */
	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);

	err = PTR_ERR(hidden_sto_dir_dentry);
	if (IS_ERR(hidden_sto_dir_dentry))
		goto out;

	err = vfs_mknod(hidden_sto_dir_dentry->d_inode, hidden_sto_dentry, mode, dev);
	if(err)
		goto out_lock;

	if(!dtohd2(dentry)->d_inode) {
		printk(KERN_CRIT "mini_fo: create_sto_nod: creating storage inode failed [1].\n");
		err = -EINVAL; /* return something indicating failure */
		goto out_lock;
	}

	/* interpose the new inode */
	if(dtost(dentry) == DELETED) {
		dtost(dentry) = DEL_REWRITTEN;
		err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
		if(err)
			goto out_lock;
	}
	else if(dtost(dentry) == NON_EXISTANT) {
		dtost(dentry) = CREATED;
		err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
		if(err)
			goto out_lock;
	}
	else if(dtost(dentry) == UNMODIFIED) {
		dtost(dentry) = MODIFIED;
		/* interpose on new inode */
		if(itohi2(dentry->d_inode) != NULL) {
			printk(KERN_CRIT "mini_fo: create_sto_nod: error, invalid inode detected.\n");
			err = -EINVAL;
			goto out_lock;
		}
		itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
	}

	fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode);

 out_lock:
	dput(hidden_sto_dir_dentry);
 out:
	return err;
}
Пример #5
0
/* create the sto dir, setup states */
int create_sto_dir(dentry_t *dentry, int mode)
{
	int err = 0;
	inode_t *dir;
	dentry_t *hidden_sto_dentry;
        dentry_t *hidden_sto_dir_dentry;

	/* had to take the "!S_ISDIR(mode))" check out, because it failed */
	if(exists_in_storage(dentry)) {
                printk(KERN_CRIT "mini_fo: create_sto_dir: wrong type or state.\\
n");
                err = -EINVAL;
                goto out;
        }

	err = get_neg_sto_dentry(dentry);
	if(err) {
		err = -EINVAL;
		goto out;
	}

	dir = dentry->d_parent->d_inode;
	hidden_sto_dentry = dtohd2(dentry);

	/* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */
	hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent);

	err = PTR_ERR(hidden_sto_dir_dentry);
	if (IS_ERR(hidden_sto_dir_dentry))
		goto out;

	err = vfs_mkdir(hidden_sto_dir_dentry->d_inode,
			hidden_sto_dentry,
			mode);
	if(err) {
		printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir.\n");
		goto out_lock;
	}

	if(!dtohd2(dentry)->d_inode) {
		printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir [2].\n");
		err = -EINVAL;
		goto out_lock;
	}

	/* interpose the new inode */
	if(dtost(dentry) == DELETED) {
		dtost(dentry) = DEL_REWRITTEN;
		err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0);
		if(err)
			goto out_lock;
	}
	else if(dtopd(dentry)->state == NON_EXISTANT) {
		dtopd(dentry)->state = CREATED;
		err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0);
		if(err)
			goto out_lock;
	}
	else if(dtopd(dentry)->state == UNMODIFIED) {
		dtopd(dentry)->state = MODIFIED;
		/* interpose on new inode */
		if(itohi2(dentry->d_inode) != NULL) {
			printk(KERN_CRIT "mini_fo:  create_sto_dir: ERROR, invalid inode detected.\n");
			err = -EINVAL;
			goto out_lock;
		}
		itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode);
	}

	fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode);

	/* initalize the wol list */
	itopd(dentry->d_inode)->deleted_list_size = -1;
	itopd(dentry->d_inode)->renamed_list_size = -1;
	meta_build_lists(dentry);


 out_lock:
	/* was: unlock_dir(hidden_sto_dir_dentry); */
	dput(hidden_sto_dir_dentry);
 out:
	return err;
}