summaryrefslogtreecommitdiffstats
path: root/sys/gnu/reiserfs/reiserfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/gnu/reiserfs/reiserfs_inode.c')
-rw-r--r--sys/gnu/reiserfs/reiserfs_inode.c926
1 files changed, 0 insertions, 926 deletions
diff --git a/sys/gnu/reiserfs/reiserfs_inode.c b/sys/gnu/reiserfs/reiserfs_inode.c
deleted file mode 100644
index 950bb02..0000000
--- a/sys/gnu/reiserfs/reiserfs_inode.c
+++ /dev/null
@@ -1,926 +0,0 @@
-/*-
- * Copyright 2000 Hans Reiser
- * See README for licensing and copyright details
- *
- * Ported to FreeBSD by Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
- *
- * $FreeBSD$
- */
-
-#include <gnu/reiserfs/reiserfs_fs.h>
-
-static b_strategy_t reiserfs_bufstrategy;
-
-/*
- * Buffer operations for ReiserFS vnodes.
- * We punt on VOP_BMAP, so we need to do strategy on the file's vnode
- * rather than the underlying device's.
- */
-static struct buf_ops reiserfs_vnbufops = {
- .bop_name = "ReiserFS",
- .bop_strategy = reiserfs_bufstrategy,
-};
-
-/* Default io size devuned in super.c */
-extern int reiserfs_default_io_size;
-void inode_set_bytes(struct reiserfs_node *ip, off_t bytes);
-
-/* Args for the create parameter of reiserfs_get_block */
-#define GET_BLOCK_NO_CREATE 0 /* Don't create new blocks or convert
- tails */
-#define GET_BLOCK_CREATE 1 /* Add anything you need to find block */
-#define GET_BLOCK_NO_HOLE 2 /* Return ENOENT for file holes */
-#define GET_BLOCK_READ_DIRECT 4 /* Read the tail if indirect item not
- found */
-#define GET_BLOCK_NO_ISEM 8 /* i_sem is not held, don't preallocate */
-#define GET_BLOCK_NO_DANGLE 16 /* Don't leave any transactions running */
-
-/* -------------------------------------------------------------------
- * vnode operations
- * -------------------------------------------------------------------*/
-
-int
-reiserfs_read(struct vop_read_args *ap)
-{
- struct uio *uio;
- struct vnode *vp;
- struct reiserfs_node *ip;
- struct reiserfs_sb_info *sbi;
-
- int error;
- long size;
- daddr_t lbn;
- off_t bytesinfile, offset;
-
- uio = ap->a_uio;
- vp = ap->a_vp;
- ip = VTOI(vp);
- sbi = ip->i_reiserfs;
-
- size = sbi->s_blocksize;
-
- for (error = 0; uio->uio_resid > 0;) {
- if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0)
- break;
-
- /* Compute the logical block number and its offset */
- lbn = uio->uio_offset / size;
- offset = uio->uio_offset % size;
- reiserfs_log(LOG_DEBUG, "logical block number: %ju\n",
- (intmax_t)lbn);
- reiserfs_log(LOG_DEBUG, "block offset: %ju\n",
- (intmax_t)offset);
-
- /* Read file blocks */
- reiserfs_log(LOG_DEBUG, "reiserfs_get_block(%ju)\n",
- (intmax_t)lbn);
- if ((error = reiserfs_get_block(ip, lbn, offset, uio)) != 0) {
- reiserfs_log(LOG_DEBUG,
- "reiserfs_get_block returned the error %d\n",
- error);
- break;
- }
- }
-
- return (error);
-}
-
-static void
-reiserfs_bufstrategy(struct bufobj *bo, struct buf *bp)
-{
- struct vnode *vp;
- int rc;
-
- vp = bo->bo_private;
- KASSERT(bo == &vp->v_bufobj, ("BO/VP mismatch: vp %p bo %p != %p",
- vp, &vp->v_bufobj, bo));
- rc = VOP_STRATEGY(vp, bp);
- KASSERT(rc == 0, ("ReiserFS VOP_STRATEGY failed: bp=%p, "
- "vp=%p, rc=%d", bp, vp, rc));
-}
-
-int
-reiserfs_inactive(struct vop_inactive_args *ap)
-{
- int error;
- struct vnode *vp;
- struct thread *td;
- struct reiserfs_node *ip;
-
- error = 0;
- vp = ap->a_vp;
- td = ap->a_td;
- ip = VTOI(vp);
-
- reiserfs_log(LOG_DEBUG, "deactivating inode used %d times\n",
- vp->v_usecount);
- if (prtactive && vrefcnt(vp) != 0)
- vprint("ReiserFS/reclaim: pushing active", vp);
-
-#if 0
- /* Ignore inodes related to stale file handles. */
- if (ip->i_mode == 0)
- goto out;
-
-out:
-#endif
-
- /*
- * If we are done with the inode, reclaim it so that it can be reused
- * immediately.
- */
- if (ip->i_mode == 0) {
- reiserfs_log(LOG_DEBUG, "recyling\n");
- vrecycle(vp, td);
- }
-
- return (error);
-}
-
-int
-reiserfs_reclaim(struct vop_reclaim_args *ap)
-{
- struct reiserfs_node *ip;
- struct vnode *vp;
-
- vp = ap->a_vp;
-
- reiserfs_log(LOG_DEBUG, "reclaiming inode used %d times\n",
- vp->v_usecount);
- if (prtactive && vrefcnt(vp) != 0)
- vprint("ReiserFS/reclaim: pushing active", vp);
- ip = VTOI(vp);
-
- /* XXX Update this node (write to the disk) */
-
- /* Remove the inode from its hash chain. */
- vfs_hash_remove(vp);
-
- /* Purge old data structures associated with the inode. */
- if (ip->i_devvp) {
- reiserfs_log(LOG_DEBUG, "releasing device (0x%p)\n",
- ip->i_devvp);
- vrele(ip->i_devvp);
- ip->i_devvp = NULL;
- }
-
- reiserfs_log(LOG_DEBUG, "free private data\n");
- FREE(vp->v_data, M_REISERFSNODE);
- vp->v_data = NULL;
- vnode_destroy_vobject(vp);
-
- return (0);
-}
-
-/* -------------------------------------------------------------------
- * Functions from linux/fs/reiserfs/inode.c
- * -------------------------------------------------------------------*/
-
-static void
-_make_cpu_key(struct cpu_key *key, int version,
- uint32_t dirid, uint32_t objectid, off_t offset, int type, int length)
-{
-
- key->version = version;
-
- key->on_disk_key.k_dir_id = dirid;
- key->on_disk_key.k_objectid = objectid;
- set_cpu_key_k_offset(key, offset);
- set_cpu_key_k_type(key, type);
- key->key_length = length;
-}
-
-/*
- * Take base of inode_key (it comes from inode always) (dirid, objectid)
- * and version from an inode, set offset and type of key
- */
-void
-make_cpu_key(struct cpu_key *key, struct reiserfs_node *ip, off_t offset,
- int type, int length)
-{
-
- _make_cpu_key(key, get_inode_item_key_version(ip),
- le32toh(INODE_PKEY(ip)->k_dir_id),
- le32toh(INODE_PKEY(ip)->k_objectid),
- offset, type, length);
-}
-
-int
-reiserfs_get_block(struct reiserfs_node *ip, long block, off_t offset,
- struct uio *uio)
-{
- caddr_t blk = NULL, p;
- struct cpu_key key;
- /* unsigned long offset; */
- INITIALIZE_PATH(path);
- struct buf *bp, *blk_bp;
- struct item_head *ih;
- struct reiserfs_sb_info *sbi;
- int blocknr, chars, done = 0, ret = 0, args = 0;
-
- sbi = ip->i_reiserfs;
-
- /* Prepare the key to look for the 'block'-th block of file */
- reiserfs_log(LOG_DEBUG, "prepare cpu key\n");
- make_cpu_key(&key, ip, (off_t)block * sbi->s_blocksize + 1, TYPE_ANY, 3);
-
- /* research: */
- reiserfs_log(LOG_DEBUG, "search for position\n");
- if (search_for_position_by_key(sbi, &key, &path) != POSITION_FOUND) {
- reiserfs_log(LOG_DEBUG, "position not found\n");
- pathrelse(&path);
-#if 0
- if (blk)
- kunmap(bh_result->b_page);
-#endif
- /*
- * We do not return ENOENT if there is a hole but page is
- * uptodate, because it means that there is some MMAPED data
- * associated with it that is yet to be written to disk.
- */
- if ((args & GET_BLOCK_NO_HOLE)/* &&
- !PageUptodate(bh_result->b_page)*/)
- return (ENOENT);
- return (0);
- }
- reiserfs_log(LOG_DEBUG, "position found\n");
-
- bp = get_last_bp(&path);
- ih = get_ih(&path);
-
- if (is_indirect_le_ih(ih)) {
- off_t xfersize;
- uint32_t *ind_item = (uint32_t *)B_I_PITEM(bp, ih);
-
- reiserfs_log(LOG_DEBUG, "item is INDIRECT\n");
-
- blocknr = get_block_num(ind_item, path.pos_in_item);
- reiserfs_log(LOG_DEBUG, "block number: %d "
- "(ind_item=%p, pos_in_item=%u)\n",
- blocknr, ind_item, path.pos_in_item);
-
- xfersize = MIN(sbi->s_blocksize - offset,
- ip->i_size - uio->uio_offset);
- xfersize = MIN(xfersize, uio->uio_resid);
-
- if (blocknr) {
- ret = bread(sbi->s_devvp,
- blocknr * btodb(sbi->s_blocksize),
- sbi->s_blocksize, NOCRED, &blk_bp);
- reiserfs_log(LOG_DEBUG, "xfersize: %ju\n",
- (intmax_t)xfersize);
- ret = uiomove(blk_bp->b_data + offset, xfersize, uio);
- brelse(blk_bp);
- } else {
- /*
- * We do not return ENOENT if there is a hole but
- * page is uptodate, because it means That there
- * is some MMAPED data associated with it that
- * is yet to be written to disk.
- */
- if ((args & GET_BLOCK_NO_HOLE)/* &&
- !PageUptodate(bh_result->b_page)*/)
- ret = (ENOENT);
-
- /* Skip this hole */
- uio->uio_resid -= xfersize;
- uio->uio_offset += xfersize;
- }
-
- pathrelse(&path);
- return (ret);
- }
-
- reiserfs_log(LOG_DEBUG, "item should be DIRECT\n");
-
-#if 0
- /* Requested data are in direct item(s) */
- if (!(args & GET_BLOCK_READ_DIRECT)) {
- /*
- * We are called by bmap. FIXME: we can not map block of
- * file when it is stored in direct item(s)
- */
- pathrelse(&path);
-#if 0
- if (blk)
- kunmap(bh_result->b_page);
-#endif
- return (ENOENT);
- }
-#endif
-
-#if 0
- /*
- * If we've got a direct item, and the buffer or page was uptodate, we
- * don't want to pull data off disk again. Skip to the end, where we
- * map the buffer and return
- */
- if (buffer_uptodate(bh_result)) {
- goto finished;
- } else
- /*
- * grab_tail_page can trigger calls to reiserfs_get_block
- * on up to date pages without any buffers. If the page
- * is up to date, we don't want read old data off disk.
- * Set the up to date bit on the buffer instead and jump
- * to the end
- */
- if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
- set_buffer_uptodate(bh_result);
- goto finished;
- }
-#endif
-
-#if 0
- /* Read file tail into part of page */
- offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1);
- fs_gen = get_generation(ip->i_reiserfs);
- copy_item_head(&tmp_ih, ih);
-#endif
-
-#if 0
- /*
- * We only want to kmap if we are reading the tail into the page. this
- * is not the common case, so we don't kmap until we are sure we need
- * to. But, this means the item might move if kmap schedules
- */
- if (!blk) {
- blk = (char *)kmap(bh_result->b_page);
- if (fs_changed (fs_gen, sbi) && item_moved(&tmp_ih, &path))
- goto research;
- }
- blk += offset;
- memset(blk, 0, sbi->s_blocksize);
-#endif
- if (!blk) {
- reiserfs_log(LOG_DEBUG, "allocating buffer\n");
- blk = malloc(ip->i_size, M_REISERFSNODE, M_WAITOK | M_ZERO);
- if (!blk)
- return (ENOMEM);
- }
- /* p += offset; */
-
- p = blk;
- do {
- if (!is_direct_le_ih(ih)) {
- reiserfs_log(LOG_ERR, "BUG\n");
- return (ENOENT); /* XXX Wrong error code */
- }
-
- /*
- * Make sure we don't read more bytes than actually exist
- * in the file. This can happen in odd cases where i_size
- * isn't correct, and when direct item padding results in
- * a few extra bytes at the end of the direct item
- */
- if ((le_ih_k_offset(ih) + path.pos_in_item) > ip->i_size)
- break;
-
- if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > ip->i_size) {
- chars = ip->i_size - (le_ih_k_offset(ih) - 1) -
- path.pos_in_item;
- done = 1;
- } else {
- chars = ih_item_len(ih) - path.pos_in_item;
- }
- reiserfs_log(LOG_DEBUG, "copying %d bytes\n", chars);
- memcpy(p, B_I_PITEM(bp, ih) + path.pos_in_item, chars);
- if (done) {
- reiserfs_log(LOG_DEBUG, "copy done\n");
- break;
- }
-
- p += chars;
-
- if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bp) - 1))
- /*
- * We done, if read direct item is not the last
- * item of node
- * FIXME: we could try to check right delimiting
- * key to see whether direct item continues in
- * the right neighbor or rely on i_size
- */
- break;
-
- /* Update key to look for the next piece */
- set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + chars);
- if (search_for_position_by_key(sbi, &key, &path) !=
- POSITION_FOUND)
- /*
- * We read something from tail, even if now we got
- * IO_ERROR
- */
- break;
-
- bp = get_last_bp(&path);
- ih = get_ih(&path);
- } while (1);
-
- /* finished: */
- pathrelse(&path);
- /*
- * This buffer has valid data, but isn't valid for io. mapping it to
- * block #0 tells the rest of reiserfs it just has a tail in it
- */
- ret = uiomove(blk, ip->i_size, uio);
- free(blk, M_REISERFSNODE);
- return (ret);
-}
-
-/*
- * Compute real number of used bytes by file
- * Following three functions can go away when we'll have enough space in
- * stat item
- */
-static int
-real_space_diff(struct reiserfs_node *ip, int sd_size)
-{
- int bytes;
- off_t blocksize = ip->i_reiserfs->s_blocksize;
-
- if (S_ISLNK(ip->i_mode) || S_ISDIR(ip->i_mode))
- return (sd_size);
-
- /* End of file is also in full block with indirect reference, so round
- * up to the next block.
- *
- * There is just no way to know if the tail is actually packed on the
- * file, so we have to assume it isn't. When we pack the tail, we add
- * 4 bytes to pretend there really is an unformatted node pointer. */
- bytes = ((ip->i_size + (blocksize - 1)) >>
- ip->i_reiserfs->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
-
- return (bytes);
-}
-
-static inline off_t
-to_real_used_space(struct reiserfs_node *ip, unsigned long blocks, int sd_size)
-{
-
- if (S_ISLNK(ip->i_mode) || S_ISDIR(ip->i_mode)) {
- return ip->i_size + (off_t)(real_space_diff(ip, sd_size));
- }
-
- return ((off_t)real_space_diff(ip, sd_size)) + (((off_t)blocks) << 9);
-}
-
-void
-inode_set_bytes(struct reiserfs_node *ip, off_t bytes)
-{
-
- ip->i_blocks = bytes >> 9;
- ip->i_bytes = bytes & 511;
-}
-
-/* Called by read_locked_inode */
-static void
-init_inode(struct reiserfs_node *ip, struct path *path)
-{
- struct buf *bp;
- struct item_head *ih;
- uint32_t rdev;
-
- bp = PATH_PLAST_BUFFER(path);
- ih = PATH_PITEM_HEAD(path);
-
- reiserfs_log(LOG_DEBUG, "copy the key (objectid=%d, dirid=%d)\n",
- ih->ih_key.k_objectid, ih->ih_key.k_dir_id);
- copy_key(INODE_PKEY(ip), &(ih->ih_key));
- /* ip->i_blksize = reiserfs_default_io_size; */
-
- reiserfs_log(LOG_DEBUG, "reset some inode structure members\n");
- REISERFS_I(ip)->i_flags = 0;
-#if 0
- REISERFS_I(ip)->i_prealloc_block = 0;
- REISERFS_I(ip)->i_prealloc_count = 0;
- REISERFS_I(ip)->i_trans_id = 0;
- REISERFS_I(ip)->i_jl = NULL;
- REISERFS_I(ip)->i_acl_access = NULL;
- REISERFS_I(ip)->i_acl_default = NULL;
-#endif
-
- if (stat_data_v1(ih)) {
- reiserfs_log(LOG_DEBUG, "reiserfs/init_inode: stat data v1\n");
- struct stat_data_v1 *sd;
- unsigned long blocks;
-
- sd = (struct stat_data_v1 *)B_I_PITEM(bp, ih);
-
- reiserfs_log(LOG_DEBUG,
- "reiserfs/init_inode: filling more members\n");
- set_inode_item_key_version(ip, KEY_FORMAT_3_5);
- set_inode_sd_version(ip, STAT_DATA_V1);
- ip->i_mode = sd_v1_mode(sd);
- ip->i_nlink = sd_v1_nlink(sd);
- ip->i_uid = sd_v1_uid(sd);
- ip->i_gid = sd_v1_gid(sd);
- ip->i_size = sd_v1_size(sd);
- ip->i_atime.tv_sec = sd_v1_atime(sd);
- ip->i_mtime.tv_sec = sd_v1_mtime(sd);
- ip->i_ctime.tv_sec = sd_v1_ctime(sd);
- ip->i_atime.tv_nsec = 0;
- ip->i_ctime.tv_nsec = 0;
- ip->i_mtime.tv_nsec = 0;
-
- reiserfs_log(LOG_DEBUG, " mode = %08x\n", ip->i_mode);
- reiserfs_log(LOG_DEBUG, " nlink = %d\n", ip->i_nlink);
- reiserfs_log(LOG_DEBUG, " owner = %d:%d\n", ip->i_uid,
- ip->i_gid);
- reiserfs_log(LOG_DEBUG, " size = %ju\n",
- (intmax_t)ip->i_size);
- reiserfs_log(LOG_DEBUG, " atime = %jd\n",
- (intmax_t)ip->i_atime.tv_sec);
- reiserfs_log(LOG_DEBUG, " mtime = %jd\n",
- (intmax_t)ip->i_mtime.tv_sec);
- reiserfs_log(LOG_DEBUG, " ctime = %jd\n",
- (intmax_t)ip->i_ctime.tv_sec);
-
- ip->i_blocks = sd_v1_blocks(sd);
- ip->i_generation = le32toh(INODE_PKEY(ip)->k_dir_id);
- blocks = (ip->i_size + 511) >> 9;
- blocks = _ROUND_UP(blocks, ip->i_reiserfs->s_blocksize >> 9);
- if (ip->i_blocks > blocks) {
- /*
- * There was a bug in <= 3.5.23 when i_blocks could
- * take negative values. Starting from 3.5.17 this
- * value could even be stored in stat data. For such
- * files we set i_blocks based on file size. Just 2
- * notes: this can be wrong for sparce files. On-disk
- * value will be only updated if file's inode will
- * ever change.
- */
- ip->i_blocks = blocks;
- }
-
- rdev = sd_v1_rdev(sd);
- REISERFS_I(ip)->i_first_direct_byte =
- sd_v1_first_direct_byte(sd);
-
- /*
- * An early bug in the quota code can give us an odd number
- * for the block count. This is incorrect, fix it here.
- */
- if (ip->i_blocks & 1) {
- ip->i_blocks++ ;
- }
- inode_set_bytes(ip, to_real_used_space(ip, ip->i_blocks,
- SD_V1_SIZE));
-
- /*
- * nopack is initially zero for v1 objects. For v2 objects,
- * nopack is initialised from sd_attrs
- */
- REISERFS_I(ip)->i_flags &= ~i_nopack_mask;
- reiserfs_log(LOG_DEBUG, "...done\n");
- } else {
- reiserfs_log(LOG_DEBUG, "stat data v2\n");
- /*
- * New stat data found, but object may have old items
- * (directories and symlinks)
- */
- struct stat_data *sd = (struct stat_data *)B_I_PITEM(bp, ih);
-
- reiserfs_log(LOG_DEBUG, "filling more members\n");
- ip->i_mode = sd_v2_mode(sd);
- ip->i_nlink = sd_v2_nlink(sd);
- ip->i_uid = sd_v2_uid(sd);
- ip->i_size = sd_v2_size(sd);
- ip->i_gid = sd_v2_gid(sd);
- ip->i_mtime.tv_sec = sd_v2_mtime(sd);
- ip->i_atime.tv_sec = sd_v2_atime(sd);
- ip->i_ctime.tv_sec = sd_v2_ctime(sd);
- ip->i_ctime.tv_nsec = 0;
- ip->i_mtime.tv_nsec = 0;
- ip->i_atime.tv_nsec = 0;
-
- reiserfs_log(LOG_DEBUG, " mode = %08x\n", ip->i_mode);
- reiserfs_log(LOG_DEBUG, " nlink = %d\n", ip->i_nlink);
- reiserfs_log(LOG_DEBUG, " owner = %d:%d\n", ip->i_uid,
- ip->i_gid);
- reiserfs_log(LOG_DEBUG, " size = %ju\n",
- (intmax_t)ip->i_size);
- reiserfs_log(LOG_DEBUG, " atime = %jd\n",
- (intmax_t)ip->i_atime.tv_sec);
- reiserfs_log(LOG_DEBUG, " mtime = %jd\n",
- (intmax_t)ip->i_mtime.tv_sec);
- reiserfs_log(LOG_DEBUG, " ctime = %jd\n",
- (intmax_t)ip->i_ctime.tv_sec);
-
- ip->i_blocks = sd_v2_blocks(sd);
- rdev = sd_v2_rdev(sd);
- reiserfs_log(LOG_DEBUG, " blocks = %u\n", ip->i_blocks);
-
- if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
- ip->i_generation = le32toh(INODE_PKEY(ip)->k_dir_id);
- else
- ip->i_generation = sd_v2_generation(sd);
-
- if (S_ISDIR(ip->i_mode) || S_ISLNK(ip->i_mode))
- set_inode_item_key_version(ip, KEY_FORMAT_3_5);
- else
- set_inode_item_key_version(ip, KEY_FORMAT_3_6);
-
- REISERFS_I(ip)->i_first_direct_byte = 0;
- set_inode_sd_version(ip, STAT_DATA_V2);
- inode_set_bytes(ip, to_real_used_space(ip, ip->i_blocks,
- SD_V2_SIZE));
-
- /*
- * Read persistent inode attributes from sd and initalise
- * generic inode flags from them
- */
- REISERFS_I(ip)->i_attrs = sd_v2_attrs(sd);
- sd_attrs_to_i_attrs(sd_v2_attrs(sd), ip);
- reiserfs_log(LOG_DEBUG, "...done\n");
- }
-
- pathrelse(path);
- if (S_ISREG(ip->i_mode)) {
- reiserfs_log(LOG_DEBUG, "this inode is a regular file\n");
- //ip->i_op = &reiserfs_file_ip_operations;
- //ip->i_fop = &reiserfs_file_operations;
- //ip->i_mapping->a_ops = &reiserfs_address_space_operations ;
- } else if (S_ISDIR(ip->i_mode)) {
- reiserfs_log(LOG_DEBUG, "this inode is a directory\n");
- //ip->i_op = &reiserfs_dir_ip_operations;
- //ip->i_fop = &reiserfs_dir_operations;
- } else if (S_ISLNK(ip->i_mode)) {
- reiserfs_log(LOG_DEBUG, "this inode is a symlink\n");
- //ip->i_op = &reiserfs_symlink_ip_operations;
- //ip->i_mapping->a_ops = &reiserfs_address_space_operations;
- } else {
- reiserfs_log(LOG_DEBUG, "this inode is something unknown in "
- "this universe\n");
- ip->i_blocks = 0;
- //ip->i_op = &reiserfs_special_ip_operations;
- //init_special_ip(ip, ip->i_mode, new_decode_dev(rdev));
- }
-}
-
-/*
- * reiserfs_read_locked_inode is called to read the inode off disk, and
- * it does a make_bad_inode when things go wrong. But, we need to make
- * sure and clear the key in the private portion of the inode, otherwise
- * a corresponding iput might try to delete whatever object the inode
- * last represented.
- */
-static void
-reiserfs_make_bad_inode(struct reiserfs_node *ip) {
-
- memset(INODE_PKEY(ip), 0, KEY_SIZE);
- //make_bad_inode(inode);
-}
-
-void
-reiserfs_read_locked_inode(struct reiserfs_node *ip,
- struct reiserfs_iget_args *args)
-{
- INITIALIZE_PATH(path_to_sd);
- struct cpu_key key;
- unsigned long dirino;
- int retval;
-
- dirino = args->dirid;
-
- /*
- * Set version 1, version 2 could be used too, because stat data
- * key is the same in both versions
- */
- key.version = KEY_FORMAT_3_5;
- key.on_disk_key.k_dir_id = dirino;
- key.on_disk_key.k_objectid = ip->i_number;
- key.on_disk_key.u.k_offset_v1.k_offset = SD_OFFSET;
- key.on_disk_key.u.k_offset_v1.k_uniqueness = SD_UNIQUENESS;
-
- /* Look for the object's stat data */
- retval = search_item(ip->i_reiserfs, &key, &path_to_sd);
- if (retval == IO_ERROR) {
- reiserfs_log(LOG_ERR,
- "I/O failure occured trying to find stat"
- "data %u/%u\n",
- key.on_disk_key.k_dir_id, key.on_disk_key.k_objectid);
- reiserfs_make_bad_inode(ip);
- return;
- }
- if (retval != ITEM_FOUND) {
- /*
- * A stale NFS handle can trigger this without it being
- * an error
- */
- reiserfs_log(LOG_ERR,
- "item not found (objectid=%u, dirid=%u)\n",
- key.on_disk_key.k_objectid, key.on_disk_key.k_dir_id);
- pathrelse(&path_to_sd);
- reiserfs_make_bad_inode(ip);
- ip->i_nlink = 0;
- return;
- }
-
- init_inode(ip, &path_to_sd);
-
- /*
- * It is possible that knfsd is trying to access inode of a file
- * that is being removed from the disk by some other thread. As
- * we update sd on unlink all that is required is to check for
- * nlink here. This bug was first found by Sizif when debugging
- * SquidNG/Butterfly, forgotten, and found again after Philippe
- * Gramoulle <philippe.gramoulle@mmania.com> reproduced it.
- *
- * More logical fix would require changes in fs/inode.c:iput() to
- * remove inode from hash-table _after_ fs cleaned disk stuff up and
- * in iget() to return NULL if I_FREEING inode is found in hash-table.
- */
- /*
- * Currently there is one place where it's ok to meet inode with
- * nlink == 0: processing of open-unlinked and half-truncated files
- * during mount (fs/reiserfs/super.c:finish_unfinished()).
- */
- if((ip->i_nlink == 0) &&
- !REISERFS_SB(ip->i_reiserfs)->s_is_unlinked_ok ) {
- reiserfs_log(LOG_WARNING, "dead inode read from disk. This is "
- "likely to be race with knfsd. Ignore");
- reiserfs_make_bad_inode(ip);
- }
-
- /* Init inode should be relsing */
- reiserfs_check_path(&path_to_sd);
-}
-
-int
-reiserfs_iget(
- struct mount *mp, const struct cpu_key *key,
- struct vnode **vpp, struct thread *td)
-{
- int error, flags;
- struct cdev *dev;
- struct vnode *vp;
- struct reiserfs_node *ip;
- struct reiserfs_mount *rmp;
-
- struct reiserfs_iget_args args;
-
- //restart:
- /* Check if the inode cache contains it */
- // XXX LK_EXCLUSIVE ?
- flags = LK_EXCLUSIVE;
- error = vfs_hash_get(mp, key->on_disk_key.k_objectid, flags,
- td, vpp, NULL, NULL);
- if (error || *vpp != NULL)
- return (error);
-
- rmp = VFSTOREISERFS(mp);
- dev = rmp->rm_dev;
-
- /*
- * If this MALLOC() is performed after the getnewvnode() it might
- * block, leaving a vnode with a NULL v_data to be found by
- * reiserfs_sync() if a sync happens to fire right then, which
- * will cause a panic because reiserfs_sync() blindly dereferences
- * vp->v_data (as well it should).
- */
- reiserfs_log(LOG_DEBUG, "malloc(struct reiserfs_node)\n");
- ip = malloc(sizeof(struct reiserfs_node), M_REISERFSNODE,
- M_WAITOK | M_ZERO);
-
- /* Allocate a new vnode/inode. */
- reiserfs_log(LOG_DEBUG, "getnewvnode\n");
- if ((error =
- getnewvnode("reiserfs", mp, &reiserfs_vnodeops, &vp)) != 0) {
- *vpp = NULL;
- free(ip, M_REISERFSNODE);
- reiserfs_log(LOG_DEBUG, "getnewvnode FAILED\n");
- return (error);
- }
-
- args.dirid = key->on_disk_key.k_dir_id;
- args.objectid = key->on_disk_key.k_objectid;
-
- reiserfs_log(LOG_DEBUG, "filling *ip\n");
- vp->v_data = ip;
- ip->i_vnode = vp;
- ip->i_dev = dev;
- ip->i_number = args.objectid;
- ip->i_ino = args.dirid;
- ip->i_reiserfs = rmp->rm_reiserfs;
-
- vp->v_bufobj.bo_ops = &reiserfs_vnbufops;
- vp->v_bufobj.bo_private = vp;
-
- /* If this is the root node, set the VV_ROOT flag */
- if (ip->i_number == REISERFS_ROOT_OBJECTID &&
- ip->i_ino == REISERFS_ROOT_PARENT_OBJECTID)
- vp->v_vflag |= VV_ROOT;
-
-#if 0
- if (VOP_LOCK(vp, LK_EXCLUSIVE, td) != 0)
- panic("reiserfs/iget: unexpected lock failure");
-
- /*
- * Exclusively lock the vnode before adding to hash. Note, that we
- * must not release nor downgrade the lock (despite flags argument
- * says) till it is fully initialized.
- */
- lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0, td);
-#endif
-
- error = vfs_hash_insert(vp, key->on_disk_key.k_objectid, flags,
- td, vpp, NULL, NULL);
- if (error || *vpp != NULL)
- return (error);
-
- /* Read the inode */
- reiserfs_log(LOG_DEBUG, "call reiserfs_read_locked_inode ("
- "objectid=%d,dirid=%d)\n", args.objectid, args.dirid);
- reiserfs_read_locked_inode(ip, &args);
-
- ip->i_devvp = rmp->rm_devvp;
- VREF(ip->i_devvp);
-
- switch(vp->v_type = IFTOVT(ip->i_mode)) {
- case VBLK:
- reiserfs_log(LOG_DEBUG, "vnode type VBLK\n");
- vp->v_op = &reiserfs_specops;
- break;
-#if 0
- case VCHR:
- reiserfs_log(LOG_DEBUG, "vnode type VCHR\n");
- vp->v_op = &reiserfs_specops;
- vp = addaliasu(vp, ip->i_rdev);
- ip->i_vnode = vp;
- break;
- case VFIFO:
- reiserfs_log(LOG_DEBUG, "vnode type VFIFO\n");
- vp->v_op = reiserfs_fifoop_p;
- break;
-#endif
- default:
- break;
- }
-
- *vpp = vp;
- return (0);
-}
-
-void
-sd_attrs_to_i_attrs(uint16_t sd_attrs, struct reiserfs_node *ip)
-{
-
- if (reiserfs_attrs(ip->i_reiserfs)) {
-#if 0
- if (sd_attrs & REISERFS_SYNC_FL)
- ip->i_flags |= S_SYNC;
- else
- ip->i_flags &= ~S_SYNC;
-#endif
- if (sd_attrs & REISERFS_IMMUTABLE_FL)
- ip->i_flags |= IMMUTABLE;
- else
- ip->i_flags &= ~IMMUTABLE;
- if (sd_attrs & REISERFS_APPEND_FL)
- ip->i_flags |= APPEND;
- else
- ip->i_flags &= ~APPEND;
-#if 0
- if (sd_attrs & REISERFS_NOATIME_FL)
- ip->i_flags |= S_NOATIME;
- else
- ip->i_flags &= ~S_NOATIME;
- if (sd_attrs & REISERFS_NOTAIL_FL)
- REISERFS_I(ip)->i_flags |= i_nopack_mask;
- else
- REISERFS_I(ip)->i_flags &= ~i_nopack_mask;
-#endif
- }
-}
-
-void
-i_attrs_to_sd_attrs(struct reiserfs_node *ip, uint16_t *sd_attrs)
-{
-
- if (reiserfs_attrs(ip->i_reiserfs)) {
-#if 0
- if (ip->i_flags & S_SYNC)
- *sd_attrs |= REISERFS_SYNC_FL;
- else
- *sd_attrs &= ~REISERFS_SYNC_FL;
-#endif
- if (ip->i_flags & IMMUTABLE)
- *sd_attrs |= REISERFS_IMMUTABLE_FL;
- else
- *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
- if (ip->i_flags & APPEND)
- *sd_attrs |= REISERFS_APPEND_FL;
- else
- *sd_attrs &= ~REISERFS_APPEND_FL;
-#if 0
- if (ip->i_flags & S_NOATIME)
- *sd_attrs |= REISERFS_NOATIME_FL;
- else
- *sd_attrs &= ~REISERFS_NOATIME_FL;
- if (REISERFS_I(ip)->i_flags & i_nopack_mask)
- *sd_attrs |= REISERFS_NOTAIL_FL;
- else
- *sd_attrs &= ~REISERFS_NOTAIL_FL;
-#endif
- }
-}
OpenPOWER on IntegriCloud