示例#1
0
/**
 * reiser4_release_dir_common - release of struct file_operations
 * @inode: inode of released file
 * @file: file to release
 *
 * Implementation of release method of struct file_operations for typical
 * directory. All it does is freeing of reiser4 specific file data.
*/
int reiser4_release_dir_common(struct inode *inode, struct file *file)
{
	reiser4_context *ctx;

	ctx = reiser4_init_context(inode->i_sb);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);
	reiser4_free_file_fsdata(file);
	reiser4_exit_context(ctx);
	return 0;
}
示例#2
0
/**
 * scan_mgr - commit atoms which are to be committed
 * @super: super block to commit atoms of
 *
 * Commits old atoms.
 */
static int scan_mgr(struct super_block *super)
{
	int ret;
	reiser4_context ctx;

	init_stack_context(&ctx, super);

	ret = commit_some_atoms(&get_super_private(super)->tmgr);

	reiser4_exit_context(&ctx);
	return ret;
}
示例#3
0
static void entd_flush(struct super_block *super, struct wbq *rq)
{
	reiser4_context ctx;

	init_stack_context(&ctx, super);
	ctx.entd = 1;
	ctx.gfp_mask = GFP_NOFS;

	rq->wbc->range_start = page_offset(rq->page);
	rq->wbc->range_end = rq->wbc->range_start +
		(ENTD_CAPTURE_APAGE_BURST << PAGE_CACHE_SHIFT);


	rq->mapping->a_ops->writepages(rq->mapping, rq->wbc);

	if (rq->wbc->nr_to_write > 0) {
		long result;
		struct bdi_writeback *wb;
		struct wb_writeback_work work = {
			.sb		= super,
			.sync_mode	= WB_SYNC_NONE,
			.nr_pages	= LONG_MAX,
			.range_cyclic	= 0,
			.reason		= WB_REASON_TRY_TO_FREE_PAGES,
		};
		rq->wbc->sync_mode = work.sync_mode,
		rq->wbc->range_cyclic = work.range_cyclic,
		rq->wbc->range_start = 0;
		rq->wbc->range_end = LLONG_MAX;
		/*
		 * we don't need to pin superblock for writeback:
		 * this is implicitly pinned by write_page_by_ent
		 * (via igrab), so that shutdown_super() will wait
		 * (on reiser4_put_super) for entd completion.
		 */
		wb = &rq->mapping->backing_dev_info->wb;

		spin_lock(&wb->list_lock);
		result = generic_writeback_sb_inodes(super,
				             wb,
					     rq->wbc,
					     &work,
					     true);
		spin_unlock(&wb->list_lock);
	}
	rq->wbc->nr_to_write = ENTD_CAPTURE_APAGE_BURST;

	reiser4_writeout(super, rq->wbc);
	context_set_commit_async(&ctx);
	reiser4_exit_context(&ctx);
}
示例#4
0
/* this is common implementation of vfs's fsync method of struct
   file_operations
*/
int reiser4_sync_common(struct file *file, struct dentry *dentry, int datasync)
{
	reiser4_context *ctx;
	int result;

	ctx = reiser4_init_context(dentry->d_inode->i_sb);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);
	result = txnmgr_force_commit_all(dentry->d_inode->i_sb, 0);

	context_set_commit_async(ctx);
	reiser4_exit_context(ctx);
	return result;
}
示例#5
0
/*
 * common sync method for regular files.
 *
 * We are trying to be smart here. Instead of committing all atoms (original
 * solution), we scan dirty pages of this file and commit all atoms they are
 * part of.
 *
 * Situation is complicated by anonymous pages: i.e., extent-less pages
 * dirtied through mmap. Fortunately sys_fsync() first calls
 * filemap_fdatawrite() that will ultimately call reiser4_writepages(), insert
 * all missing extents and capture anonymous pages.
 */
int reiser4_sync_file_common(struct file *file,
			     struct dentry *dentry, int datasync)
{
	reiser4_context *ctx;
	txn_atom *atom;
	reiser4_block_nr reserve;

	ctx = reiser4_init_context(dentry->d_inode->i_sb);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);

	reserve = estimate_update_common(dentry->d_inode);
	if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) {
		reiser4_exit_context(ctx);
		return RETERR(-ENOSPC);
	}
	write_sd_by_inode_common(dentry->d_inode);

	atom = get_current_atom_locked();
	spin_lock_txnh(ctx->trans);
	force_commit_atom(ctx->trans);
	reiser4_exit_context(ctx);
	return 0;
}
示例#6
0
static struct dentry *reiser4_fh_to_dentry(struct super_block *sb,
					   struct fid *fid,
					   int fh_len, int fh_type)
{
	reiser4_context *ctx;
	struct dentry *d;

	assert("edward-1536",
	       fh_type == FH_WITH_PARENT || fh_type == FH_WITHOUT_PARENT);

	ctx = reiser4_init_context(sb);
	if (IS_ERR(ctx))
		return (struct dentry *)ctx;

	d = reiser4_decode_fh(sb, (char *)fid->raw);

	reiser4_exit_context(ctx);
	return d;
}
示例#7
0
static struct dentry *reiser4_fh_to_parent(struct super_block *sb,
					   struct fid *fid,
					   int fh_len, int fh_type)
{
	char * addr;
	struct dentry * d;
	reiser4_context *ctx;
	file_plugin *fplug;

	if (fh_type == FH_WITHOUT_PARENT)
		return NULL;
	assert("edward-1537", fh_type == FH_WITH_PARENT);

	ctx = reiser4_init_context(sb);
	if (IS_ERR(ctx))
		return (struct dentry *)ctx;
	addr = (char *)fid->raw;
	/* extract 2-bytes file plugin id */
	fplug = file_plugin_by_disk_id(reiser4_get_tree(sb), (d16 *)addr);
	if (fplug == NULL) {
		d = ERR_PTR(RETERR(-EINVAL));
		goto exit;
	}
	addr += sizeof(d16);
	/* skip previously encoded object */
	addr = fplug->wire.read(addr, NULL /* skip */);
	if (IS_ERR(addr)) {
		d = (struct dentry *)addr;
		goto exit;
	}
	/* @extract and decode parent object */
	d = reiser4_decode_fh(sb, addr);
 exit:
	reiser4_exit_context(ctx);
	return d;
}
示例#8
0
/**
 * process_cursors - do action on each cursor attached to inode
 * @inode:
 * @act: action to do
 *
 * Finds all cursors of @inode in reiser4's super block radix tree of cursors
 * and performs action specified by @act on each of cursors.
 */
static void process_cursors(struct inode *inode, enum cursor_action act)
{
	oid_t oid;
	dir_cursor *start;
	struct list_head *head;
	reiser4_context *ctx;
	struct d_cursor_info *info;

	/* this can be called by
	 *
	 * kswapd->...->prune_icache->..reiser4_destroy_inode
	 *
	 * without reiser4_context
	 */
	ctx = reiser4_init_context(inode->i_sb);
	if (IS_ERR(ctx)) {
		warning("vs-23", "failed to init context");
		return;
	}

	assert("nikita-3558", inode != NULL);

	info = d_info(inode);
	oid = get_inode_oid(inode);
	spin_lock_inode(inode);
	head = get_readdir_list(inode);
	spin_lock(&d_lock);
	/* find any cursor for this oid: reference to it is hanging of radix
	 * tree */
	start = lookup(info, (unsigned long)oid);
	if (start != NULL) {
		dir_cursor *scan;
		reiser4_file_fsdata *fsdata;

		/* process circular list of cursors for this oid */
		scan = start;
		do {
			dir_cursor *next;

			next = list_entry(scan->list.next, dir_cursor, list);
			fsdata = scan->fsdata;
			assert("nikita-3557", fsdata != NULL);
			if (scan->key.oid == oid) {
				switch (act) {
				case CURSOR_DISPOSE:
					list_del_init(&fsdata->dir.linkage);
					break;
				case CURSOR_LOAD:
					list_add(&fsdata->dir.linkage, head);
					break;
				case CURSOR_KILL:
					kill_cursor(scan);
					break;
				}
			}
			if (scan == next)
				/* last cursor was just killed */
				break;
			scan = next;
		} while (scan != start);
	}
	spin_unlock(&d_lock);
	/* check that we killed 'em all */
	assert("nikita-3568",
	       ergo(act == CURSOR_KILL,
		    list_empty_careful(get_readdir_list(inode))));
	assert("nikita-3569",
	       ergo(act == CURSOR_KILL, lookup(info, oid) == NULL));
	spin_unlock_inode(inode);
	reiser4_exit_context(ctx);
}