示例#1
0
static struct inode *__logfs_iget(struct super_block *sb, ino_t ino)
{
	struct inode *inode = iget_locked(sb, ino);
	int err;

	if (!inode)
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW))
		return inode;

	err = logfs_read_inode(inode);
	if (err || inode->i_nlink == 0) {
		/* inode->i_nlink == 0 can be true when called from
		 * block validator */
		/* set i_nlink to 0 to prevent caching */
		clear_nlink(inode);
		logfs_inode(inode)->li_flags |= LOGFS_IF_ZOMBIE;
		iget_failed(inode);
		if (!err)
			err = -ENOENT;
		return ERR_PTR(err);
	}

	logfs_inode_setops(inode);
	unlock_new_inode(inode);
	return inode;
}
static struct inode *__logfs_iget(struct super_block *sb, ino_t ino)
{
	struct inode *inode = iget_locked(sb, ino);
	int err;

	if (!inode)
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW))
		return inode;

	err = logfs_read_inode(inode);
	if (err || inode->i_nlink == 0) {
		
		clear_nlink(inode);
		logfs_inode(inode)->li_flags |= LOGFS_IF_ZOMBIE;
		iget_failed(inode);
		if (!err)
			err = -ENOENT;
		return ERR_PTR(err);
	}

	logfs_inode_setops(inode);
	unlock_new_inode(inode);
	return inode;
}
示例#3
0
static void __logfs_destroy_inode(struct inode *inode)
{
	struct logfs_inode *li = logfs_inode(inode);

	BUG_ON(li->li_block);
	list_del(&li->li_freeing_list);
	call_rcu(&inode->i_rcu, logfs_i_callback);
}
示例#4
0
static void __logfs_destroy_inode(struct inode *inode)
{
	struct logfs_inode *li = logfs_inode(inode);

	BUG_ON(li->li_block);
	list_del(&li->li_freeing_list);
	kmem_cache_free(logfs_inode_cache, li);
}
示例#5
0
static int __logfs_create(struct inode *dir, struct dentry *dentry,
		struct inode *inode, const char *dest, long destlen)
{
	struct logfs_super *super = logfs_super(dir->i_sb);
	struct logfs_inode *li = logfs_inode(inode);
	struct logfs_transaction *ta;
	int ret;

	ta = kzalloc(sizeof(*ta), GFP_KERNEL);
	if (!ta) {
		inode->i_nlink--;
		iput(inode);
		return -ENOMEM;
	}

	ta->state = CREATE_1;
	ta->ino = inode->i_ino;
	mutex_lock(&super->s_dirop_mutex);
	logfs_add_transaction(inode, ta);

	if (dest) {
		/* symlink */
		ret = logfs_inode_write(inode, dest, destlen, 0, WF_LOCK, NULL);
		if (!ret)
			ret = write_inode(inode);
	} else {
		/* creat/mkdir/mknod */
		ret = write_inode(inode);
	}
	if (ret) {
		abort_transaction(inode, ta);
		li->li_flags |= LOGFS_IF_STILLBORN;
		/* FIXME: truncate symlink */
		inode->i_nlink--;
		iput(inode);
		goto out;
	}

	ta->state = CREATE_2;
	logfs_add_transaction(dir, ta);
	ret = logfs_write_dir(dir, dentry, inode);
	/* sync directory */
	if (!ret)
		ret = write_inode(dir);

	if (ret) {
		logfs_del_transaction(dir, ta);
		ta->state = CREATE_2;
		logfs_add_transaction(inode, ta);
		logfs_remove_inode(inode);
		iput(inode);
		goto out;
	}
	d_instantiate(dentry, inode);
out:
	mutex_unlock(&super->s_dirop_mutex);
	return ret;
}
示例#6
0
/* called with inode->i_lock held */
static int logfs_drop_inode(struct inode *inode)
{
	struct logfs_super *super = logfs_super(inode->i_sb);
	struct logfs_inode *li = logfs_inode(inode);

	spin_lock(&logfs_inode_lock);
	list_move(&li->li_freeing_list, &super->s_freeing_list);
	spin_unlock(&logfs_inode_lock);
	return generic_drop_inode(inode);
}
示例#7
0
static void logfs_destroy_inode(struct inode *inode)
{
	struct logfs_inode *li = logfs_inode(inode);

	BUG_ON(list_empty(&li->li_freeing_list));
	spin_lock(&logfs_inode_lock);
	li->li_refcount--;
	if (li->li_refcount == 0)
		__logfs_destroy_inode(inode);
	spin_unlock(&logfs_inode_lock);
}
示例#8
0
static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
	int ret;
	long flags = WF_LOCK;

	/* Can only happen if creat() failed.  Safe to skip. */
	if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN)
		return 0;

	ret = __logfs_write_inode(inode, NULL, flags);
	LOGFS_BUG_ON(ret, inode->i_sb);
	return ret;
}
static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
	int ret;
	long flags = WF_LOCK;

	
	if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN)
		return 0;

	ret = __logfs_write_inode(inode, NULL, flags);
	LOGFS_BUG_ON(ret, inode->i_sb);
	return ret;
}
示例#10
0
struct inode *logfs_new_inode(struct inode *dir, umode_t mode)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode;

	inode = new_inode(sb);
	if (!inode)
		return ERR_PTR(-ENOMEM);

	logfs_init_inode(sb, inode);

	/* inherit parent flags */
	logfs_inode(inode)->li_flags |=
		logfs_inode(dir)->li_flags & LOGFS_FL_INHERITED;

	inode->i_mode = mode;
	logfs_set_ino_generation(sb, inode);

	inode_init_owner(inode, dir, mode);
	logfs_inode_setops(inode);
	insert_inode_hash(inode);

	return inode;
}
static void read_anchor(struct super_block *sb,
		struct logfs_je_anchor *da)
{
	struct logfs_super *super = logfs_super(sb);
	struct inode *inode = super->s_master_inode;
	struct logfs_inode *li = logfs_inode(inode);
	int i;

	super->s_last_ino = be64_to_cpu(da->da_last_ino);
	li->li_flags	= 0;
	li->li_height	= da->da_height;
	i_size_write(inode, be64_to_cpu(da->da_size));
	li->li_used_bytes = be64_to_cpu(da->da_used_bytes);

	for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
		li->li_data[i] = be64_to_cpu(da->da_data[i]);
}
static void account_shadows(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	struct inode *inode = super->s_master_inode;
	struct logfs_inode *li = logfs_inode(inode);
	struct shadow_tree *tree = &super->s_shadow_tree;

	btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
	btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);
	btree_grim_visitor32(&tree->segment_map, 0, NULL);
	tree->no_shadowed_segments = 0;

	if (li->li_block) {
		li->li_block->ops->free_block(sb, li->li_block);
	}
	BUG_ON((s64)li->li_used_bytes < 0);
}
static void *__logfs_write_anchor(struct super_block *sb, void *_da,
		u16 *type, size_t *len)
{
	struct logfs_super *super = logfs_super(sb);
	struct logfs_je_anchor *da = _da;
	struct inode *inode = super->s_master_inode;
	struct logfs_inode *li = logfs_inode(inode);
	int i;

	da->da_height	= li->li_height;
	da->da_last_ino = cpu_to_be64(super->s_last_ino);
	da->da_size	= cpu_to_be64(i_size_read(inode));
	da->da_used_bytes = cpu_to_be64(li->li_used_bytes);
	for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
		da->da_data[i] = cpu_to_be64(li->li_data[i]);
	*type = JE_ANCHOR;
	*len = sizeof(*da);
	return da;
}
示例#14
0
static void logfs_destroy_inode(struct inode *inode)
{
	struct logfs_inode *li = logfs_inode(inode);

	if (inode->i_ino < LOGFS_RESERVED_INOS) {
		/*
		 * The reserved inodes are never destroyed unless we are in
		 * unmont path.
		 */
		__logfs_destroy_meta_inode(inode);
		return;
	}

	BUG_ON(list_empty(&li->li_freeing_list));
	spin_lock(&logfs_inode_lock);
	li->li_refcount--;
	if (li->li_refcount == 0)
		__logfs_destroy_inode(inode);
	spin_unlock(&logfs_inode_lock);
}
示例#15
0
static void account_shadows(struct super_block *sb)
{
	struct logfs_super *super = logfs_super(sb);
	struct inode *inode = super->s_master_inode;
	struct logfs_inode *li = logfs_inode(inode);
	struct shadow_tree *tree = &super->s_shadow_tree;

	btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
	btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);

	if (li->li_block) {
		/*
		 * We never actually use the structure, when attached to the
		 * master inode.  But it is easier to always free it here than
		 * to have checks in several places elsewhere when allocating
		 * it.
		 */
		li->li_block->ops->free_block(sb, li->li_block);
	}
	BUG_ON((s64)li->li_used_bytes < 0);
}
示例#16
0
static void logfs_init_inode(struct super_block *sb, struct inode *inode)
{
	struct logfs_inode *li = logfs_inode(inode);
	int i;

	li->li_flags	= 0;
	li->li_height	= 0;
	li->li_used_bytes = 0;
	li->li_block	= NULL;
	inode->i_uid	= 0;
	inode->i_gid	= 0;
	inode->i_size	= 0;
	inode->i_blocks	= 0;
	inode->i_ctime	= CURRENT_TIME;
	inode->i_mtime	= CURRENT_TIME;
	li->li_refcount = 1;
	INIT_LIST_HEAD(&li->li_freeing_list);

	for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
		li->li_data[i] = 0;

	return;
}
示例#17
0
static void abort_transaction(struct inode *inode, struct logfs_transaction *ta)
{
	if (logfs_inode(inode)->li_block)
		logfs_inode(inode)->li_block->ta = NULL;
	kfree(ta);
}
示例#18
0
static void __logfs_destroy_meta_inode(struct inode *inode)
{
	struct logfs_inode *li = logfs_inode(inode);
	BUG_ON(li->li_block);
	call_rcu(&inode->i_rcu, logfs_i_callback);
}
示例#19
0
static void logfs_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	kmem_cache_free(logfs_inode_cache, logfs_inode(inode));
}
示例#20
0
static void logfs_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	INIT_LIST_HEAD(&inode->i_dentry);
	kmem_cache_free(logfs_inode_cache, logfs_inode(inode));
}