/** * 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; }
/** * 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; }
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); }
/* 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; }
/* * 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; }
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; }
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; }
/** * 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); }