159612Sjasone/*-
259612Sjasone * Copyright 2000 Hans Reiser
359612Sjasone * See README for licensing and copyright details
459612Sjasone *
559612Sjasone * Ported to FreeBSD by Jean-S�bastien P�dron <dumbbell@FreeBSD.org>
659612Sjasone *
759612Sjasone * $FreeBSD$
859612Sjasone */
959612Sjasone
1059612Sjasone#include <gnu/fs/reiserfs/reiserfs_fs.h>
1159612Sjasone
1259612Sjasonestatic b_strategy_t reiserfs_bufstrategy;
1359612Sjasone
1459612Sjasone/*
1559612Sjasone * Buffer operations for ReiserFS vnodes.
1659612Sjasone * We punt on VOP_BMAP, so we need to do strategy on the file's vnode
1759612Sjasone * rather than the underlying device's.
1859612Sjasone */
1959612Sjasonestatic struct buf_ops reiserfs_vnbufops = {
2059612Sjasone	.bop_name	= "ReiserFS",
2159612Sjasone	.bop_strategy	= reiserfs_bufstrategy,
2259612Sjasone};
2359612Sjasone
2459612Sjasone/* Default io size devuned in super.c */
2559612Sjasoneextern int reiserfs_default_io_size;
2659612Sjasonevoid inode_set_bytes(struct reiserfs_node *ip, off_t bytes);
2759612Sjasone
2859612Sjasone/* Args for the create parameter of reiserfs_get_block */
2959612Sjasone#define GET_BLOCK_NO_CREATE	0  /* Don't create new blocks or convert
3059612Sjasone				      tails */
3159612Sjasone#define GET_BLOCK_CREATE	1  /* Add anything you need to find block */
3259612Sjasone#define GET_BLOCK_NO_HOLE	2  /* Return ENOENT for file holes */
3359612Sjasone#define GET_BLOCK_READ_DIRECT	4  /* Read the tail if indirect item not
3459612Sjasone				      found */
3559612Sjasone#define GET_BLOCK_NO_ISEM	8  /* i_sem is not held, don't preallocate */
3659612Sjasone#define GET_BLOCK_NO_DANGLE	16 /* Don't leave any transactions running */
3759612Sjasone
3859612Sjasone/* -------------------------------------------------------------------
3959612Sjasone * vnode operations
4059612Sjasone * -------------------------------------------------------------------*/
4159612Sjasone
4259612Sjasoneint
4359612Sjasonereiserfs_read(struct vop_read_args *ap)
4459612Sjasone{
4559612Sjasone	struct uio *uio;
4659612Sjasone	struct vnode *vp;
4759612Sjasone	struct reiserfs_node *ip;
4859612Sjasone	struct reiserfs_sb_info *sbi;
4959612Sjasone
5059612Sjasone	int error;
5159612Sjasone	long size;
5259612Sjasone	daddr_t lbn;
5359612Sjasone	off_t bytesinfile, offset;
5459612Sjasone
5559612Sjasone	uio = ap->a_uio;
5659612Sjasone	vp  = ap->a_vp;
5759612Sjasone	ip  = VTOI(vp);
5859612Sjasone	sbi = ip->i_reiserfs;
5959612Sjasone
6059612Sjasone	size = sbi->s_blocksize;
6159612Sjasone
6281975Skris	for (error = 0; uio->uio_resid > 0;) {
6381975Skris		if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0)
6481975Skris			break;
6559612Sjasone
6659612Sjasone		/* Compute the logical block number and its offset */
6759612Sjasone		lbn    = uio->uio_offset / size;
6859612Sjasone		offset = uio->uio_offset % size;
6959612Sjasone		reiserfs_log(LOG_DEBUG, "logical block number: %ju\n",
7059612Sjasone		    (intmax_t)lbn);
7159612Sjasone		reiserfs_log(LOG_DEBUG, "block offset:         %ju\n",
7259612Sjasone		    (intmax_t)offset);
7359612Sjasone
7459612Sjasone		/* Read file blocks */
7559612Sjasone		reiserfs_log(LOG_DEBUG, "reiserfs_get_block(%ju)\n",
7659612Sjasone		    (intmax_t)lbn);
7759612Sjasone		if ((error = reiserfs_get_block(ip, lbn, offset, uio)) != 0) {
7859612Sjasone			reiserfs_log(LOG_DEBUG,
7959612Sjasone			    "reiserfs_get_block returned the error %d\n",
8059612Sjasone			    error);
8159612Sjasone			break;
8259612Sjasone		}
8359612Sjasone	}
8459612Sjasone
8559612Sjasone	return (error);
8659612Sjasone}
8759612Sjasone
8859612Sjasonestatic void
8959612Sjasonereiserfs_bufstrategy(struct bufobj *bo, struct buf *bp)
9059612Sjasone{
9159612Sjasone	struct vnode *vp;
9259612Sjasone	int rc;
9359612Sjasone
9459612Sjasone	vp = bo->bo_private;
9559612Sjasone	KASSERT(bo == &vp->v_bufobj, ("BO/VP mismatch: vp %p bo %p != %p",
9659612Sjasone	    vp, &vp->v_bufobj, bo));
9759612Sjasone	rc = VOP_STRATEGY(vp, bp);
9859612Sjasone	KASSERT(rc == 0, ("ReiserFS VOP_STRATEGY failed: bp=%p, "
9959612Sjasone	    "vp=%p, rc=%d", bp, vp, rc));
10059612Sjasone}
10159612Sjasone
10259612Sjasoneint
10359612Sjasonereiserfs_inactive(struct vop_inactive_args *ap)
10459612Sjasone{
10559612Sjasone	int error;
10659612Sjasone	struct vnode *vp;
10759612Sjasone	struct thread *td;
10859612Sjasone	struct reiserfs_node *ip;
10959612Sjasone
11059612Sjasone	error = 0;
11159612Sjasone	vp = ap->a_vp;
11259612Sjasone	td = ap->a_td;
11359612Sjasone	ip = VTOI(vp);
11459612Sjasone
11559612Sjasone	reiserfs_log(LOG_DEBUG, "deactivating inode used %d times\n",
11659612Sjasone	    vp->v_usecount);
11759612Sjasone
11859612Sjasone#if 0
11959612Sjasone	/* Ignore inodes related to stale file handles. */
12059612Sjasone	if (ip->i_mode == 0)
12159612Sjasone		goto out;
12259612Sjasone
12359612Sjasoneout:
12459612Sjasone#endif
12559612Sjasone
12659612Sjasone	/*
12759612Sjasone	 * If we are done with the inode, reclaim it so that it can be reused
12859612Sjasone	 * immediately.
12959612Sjasone	 */
13059612Sjasone	if (ip->i_mode == 0) {
13159612Sjasone		reiserfs_log(LOG_DEBUG, "recyling\n");
13259612Sjasone		vrecycle(vp, td);
13359612Sjasone	}
13459612Sjasone
13559612Sjasone	return (error);
13659612Sjasone}
13759612Sjasone
13859612Sjasoneint
13959612Sjasonereiserfs_reclaim(struct vop_reclaim_args *ap)
14059612Sjasone{
14159612Sjasone	struct reiserfs_node *ip;
14259612Sjasone	struct vnode *vp;
14359612Sjasone
14459612Sjasone	vp = ap->a_vp;
14559612Sjasone
14659612Sjasone	reiserfs_log(LOG_DEBUG, "reclaiming inode used %d times\n",
14759612Sjasone	    vp->v_usecount);
14859612Sjasone	ip = VTOI(vp);
14959612Sjasone
15059612Sjasone	/* XXX Update this node (write to the disk) */
15159612Sjasone
15259612Sjasone	/* Remove the inode from its hash chain. */
15359612Sjasone	vfs_hash_remove(vp);
15459612Sjasone
15559612Sjasone	reiserfs_log(LOG_DEBUG, "free private data\n");
15659612Sjasone	free(vp->v_data, M_REISERFSNODE);
15759612Sjasone	vp->v_data = NULL;
15859612Sjasone	vnode_destroy_vobject(vp);
15959612Sjasone
16059612Sjasone	return (0);
16159612Sjasone}
16259612Sjasone
16359612Sjasone/* -------------------------------------------------------------------
16459612Sjasone * Functions from linux/fs/reiserfs/inode.c
16559612Sjasone * -------------------------------------------------------------------*/
16659612Sjasone
16759612Sjasonestatic void
16899239Sdeischen_make_cpu_key(struct cpu_key *key, int version,
16959612Sjasone    uint32_t dirid, uint32_t objectid, off_t offset, int type, int length)
17059612Sjasone{
17159612Sjasone
17259612Sjasone	key->version = version;
17359612Sjasone
17459612Sjasone	key->on_disk_key.k_dir_id   = dirid;
17559612Sjasone	key->on_disk_key.k_objectid = objectid;
17659612Sjasone	set_cpu_key_k_offset(key, offset);
17759612Sjasone	set_cpu_key_k_type(key, type);
17859612Sjasone	key->key_length = length;
17959612Sjasone}
18059612Sjasone
18159612Sjasone/*
18259612Sjasone * Take base of inode_key (it comes from inode always) (dirid, objectid)
18359612Sjasone * and version from an inode, set offset and type of key
18459612Sjasone */
18559612Sjasonevoid
18659612Sjasonemake_cpu_key(struct cpu_key *key, struct reiserfs_node *ip, off_t offset,
18759612Sjasone    int type, int length)
18859612Sjasone{
18959612Sjasone
19059612Sjasone	_make_cpu_key(key, get_inode_item_key_version(ip),
19159612Sjasone	    le32toh(INODE_PKEY(ip)->k_dir_id),
19259612Sjasone	    le32toh(INODE_PKEY(ip)->k_objectid),
19359612Sjasone	    offset, type, length);
19459612Sjasone}
19559612Sjasone
19659612Sjasoneint
19759612Sjasonereiserfs_get_block(struct reiserfs_node *ip, long block, off_t offset,
19859612Sjasone    struct uio *uio)
19959612Sjasone{
20059612Sjasone	caddr_t blk = NULL, p;
20159612Sjasone	struct cpu_key key;
20259612Sjasone	/* unsigned long offset; */
20359612Sjasone	INITIALIZE_PATH(path);
20459612Sjasone	struct buf *bp, *blk_bp;
20559612Sjasone	struct item_head *ih;
20659612Sjasone	struct reiserfs_sb_info *sbi;
20759612Sjasone	int blocknr, chars, done = 0, ret = 0, args = 0;
20859612Sjasone
20959612Sjasone	sbi = ip->i_reiserfs;
21059612Sjasone
21159612Sjasone	/* Prepare the key to look for the 'block'-th block of file */
21259612Sjasone	reiserfs_log(LOG_DEBUG, "prepare cpu key\n");
21359612Sjasone	make_cpu_key(&key, ip, (off_t)block * sbi->s_blocksize + 1, TYPE_ANY, 3);
21459612Sjasone
21559612Sjasone	/* research: */
21659612Sjasone	reiserfs_log(LOG_DEBUG, "search for position\n");
21759612Sjasone	if (search_for_position_by_key(sbi, &key, &path) != POSITION_FOUND) {
21859612Sjasone		reiserfs_log(LOG_DEBUG, "position not found\n");
21959612Sjasone		pathrelse(&path);
22059612Sjasone#if 0
22159612Sjasone		if (blk)
22259612Sjasone			kunmap(bh_result->b_page);
22359612Sjasone#endif
22459612Sjasone		/*
22559612Sjasone		 * We do not return ENOENT if there is a hole but page is
22659612Sjasone		 * uptodate, because it means that there is some MMAPED data
22759612Sjasone		 * associated with it that is yet to be written to disk.
22859612Sjasone		 */
22959612Sjasone		if ((args & GET_BLOCK_NO_HOLE)/* &&
23059612Sjasone		    !PageUptodate(bh_result->b_page)*/)
23159612Sjasone			return (ENOENT);
23259612Sjasone		return (0);
23359612Sjasone	}
23459612Sjasone	reiserfs_log(LOG_DEBUG, "position found\n");
23559612Sjasone
23659612Sjasone	bp = get_last_bp(&path);
23759612Sjasone	ih = get_ih(&path);
23859612Sjasone
23959612Sjasone	if (is_indirect_le_ih(ih)) {
24059612Sjasone		off_t xfersize;
24159612Sjasone		uint32_t *ind_item = (uint32_t *)B_I_PITEM(bp, ih);
24259612Sjasone
24359612Sjasone		reiserfs_log(LOG_DEBUG, "item is INDIRECT\n");
24459612Sjasone
24559612Sjasone		blocknr = get_block_num(ind_item, path.pos_in_item);
24659612Sjasone		reiserfs_log(LOG_DEBUG, "block number: %d "
24759612Sjasone		    "(ind_item=%p, pos_in_item=%u)\n",
24859612Sjasone		    blocknr, ind_item, path.pos_in_item);
24959612Sjasone
25059612Sjasone		xfersize = MIN(sbi->s_blocksize - offset,
25159612Sjasone		    ip->i_size - uio->uio_offset);
25259612Sjasone		xfersize = MIN(xfersize, uio->uio_resid);
25359612Sjasone
25459612Sjasone		if (blocknr) {
25559612Sjasone			ret = bread(sbi->s_devvp,
25659612Sjasone			    blocknr * btodb(sbi->s_blocksize),
25759612Sjasone			    sbi->s_blocksize, NOCRED, &blk_bp);
25859612Sjasone			reiserfs_log(LOG_DEBUG, "xfersize: %ju\n",
25959612Sjasone			    (intmax_t)xfersize);
26059612Sjasone			ret = uiomove(blk_bp->b_data + offset, xfersize, uio);
26159612Sjasone			brelse(blk_bp);
26259612Sjasone		} else {
26359612Sjasone			/*
26459612Sjasone			 * We do not return ENOENT if there is a hole but
26559612Sjasone			 * page is uptodate, because it means That there
26659612Sjasone			 * is some MMAPED data associated with it that
26759612Sjasone			 * is yet to be written to disk.
26859612Sjasone			 */
26959612Sjasone			if ((args & GET_BLOCK_NO_HOLE)/* &&
27059612Sjasone			    !PageUptodate(bh_result->b_page)*/)
27159612Sjasone				ret = (ENOENT);
27259612Sjasone
27359612Sjasone			/* Skip this hole */
27459612Sjasone			uio->uio_resid  -= xfersize;
27559612Sjasone			uio->uio_offset += xfersize;
27659612Sjasone		}
27759612Sjasone
27859612Sjasone		pathrelse(&path);
27959612Sjasone		return (ret);
28059612Sjasone	}
28159612Sjasone
28259612Sjasone	reiserfs_log(LOG_DEBUG, "item should be DIRECT\n");
28359612Sjasone
28459612Sjasone#if 0
28559612Sjasone	/* Requested data are in direct item(s) */
28659612Sjasone	if (!(args & GET_BLOCK_READ_DIRECT)) {
28759612Sjasone		/*
28859612Sjasone		 * We are called by bmap. FIXME: we can not map block of
28959612Sjasone		 * file when it is stored in direct item(s)
29059612Sjasone		 */
29159612Sjasone		pathrelse(&path);
29259612Sjasone#if 0
29359612Sjasone		if (blk)
29459612Sjasone			kunmap(bh_result->b_page);
29559612Sjasone#endif
29659612Sjasone		return (ENOENT);
29759612Sjasone	}
29859612Sjasone#endif
29959612Sjasone
30059612Sjasone#if 0
30159612Sjasone	/*
30259612Sjasone	 * If we've got a direct item, and the buffer or page was uptodate, we
30359612Sjasone	 * don't want to pull data off disk again. Skip to the end, where we
30459612Sjasone	 * map the buffer and return
30559612Sjasone	 */
30659612Sjasone	if (buffer_uptodate(bh_result)) {
30759612Sjasone		goto finished;
30859612Sjasone	} else
30959612Sjasone		/*
31059612Sjasone		 * grab_tail_page can trigger calls to reiserfs_get_block
31159612Sjasone		 * on up to date pages without any buffers. If the page
31259612Sjasone		 * is up to date, we don't want read old data off disk.
31359612Sjasone		 * Set the up to date bit on the buffer instead and jump
31459612Sjasone		 * to the end
31559612Sjasone		 */
31659612Sjasone		if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
31759612Sjasone			set_buffer_uptodate(bh_result);
31859612Sjasone			goto finished;
31959612Sjasone		}
32059612Sjasone#endif
32159612Sjasone
32259612Sjasone#if 0
32359612Sjasone	/* Read file tail into part of page */
32459612Sjasone	offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1);
32559612Sjasone	fs_gen = get_generation(ip->i_reiserfs);
32659612Sjasone	copy_item_head(&tmp_ih, ih);
32759612Sjasone#endif
32859612Sjasone
32959612Sjasone#if 0
33059612Sjasone	/*
33159612Sjasone	 * We only want to kmap if we are reading the tail into the page. this
33259612Sjasone	 * is not the common case, so we don't kmap until we are sure we need
33359612Sjasone	 * to. But, this means the item might move if kmap schedules
33459612Sjasone	 */
33559612Sjasone	if (!blk) {
33659612Sjasone		blk = (char *)kmap(bh_result->b_page);
33759612Sjasone		if (fs_changed (fs_gen, sbi) && item_moved(&tmp_ih, &path))
33859612Sjasone			goto research;
33959612Sjasone	}
34059612Sjasone	blk += offset;
34159612Sjasone	memset(blk, 0, sbi->s_blocksize);
34259612Sjasone#endif
34359612Sjasone	if (!blk) {
34459612Sjasone		reiserfs_log(LOG_DEBUG, "allocating buffer\n");
34559612Sjasone		blk = malloc(ip->i_size, M_REISERFSNODE, M_WAITOK | M_ZERO);
34659612Sjasone		if (!blk)
34759612Sjasone			return (ENOMEM);
34859612Sjasone	}
34959612Sjasone	/* p += offset; */
35059612Sjasone
35159612Sjasone	p = blk;
35259612Sjasone	do {
35359612Sjasone		if (!is_direct_le_ih(ih)) {
35459612Sjasone			reiserfs_log(LOG_ERR, "BUG\n");
35559612Sjasone			return (ENOENT); /* XXX Wrong error code */
35659612Sjasone		}
35799239Sdeischen
35859612Sjasone		/*
35959612Sjasone		 * Make sure we don't read more bytes than actually exist
36059612Sjasone		 * in the file. This can happen in odd cases where i_size
36159612Sjasone		 * isn't correct, and when direct item padding results in
36259612Sjasone		 * a few extra bytes at the end of the direct item
36359612Sjasone		 */
36459612Sjasone		if ((le_ih_k_offset(ih) + path.pos_in_item) > ip->i_size)
36559612Sjasone			break;
36659612Sjasone
36759612Sjasone		if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > ip->i_size) {
36859612Sjasone			chars = ip->i_size - (le_ih_k_offset(ih) - 1) -
36959612Sjasone			    path.pos_in_item;
37059612Sjasone			done  = 1;
37159612Sjasone		} else {
37259612Sjasone			chars = ih_item_len(ih) - path.pos_in_item;
37359612Sjasone		}
37459612Sjasone		reiserfs_log(LOG_DEBUG, "copying %d bytes\n", chars);
37559612Sjasone		memcpy(p, B_I_PITEM(bp, ih) + path.pos_in_item, chars);
37659612Sjasone		if (done) {
37759612Sjasone			reiserfs_log(LOG_DEBUG, "copy done\n");
37859612Sjasone			break;
37959612Sjasone		}
38059612Sjasone
38159612Sjasone		p += chars;
38259612Sjasone
38359612Sjasone		if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bp) - 1))
38459612Sjasone			/*
38559612Sjasone			 * We done, if read direct item is not the last
38659612Sjasone			 * item of node
38759612Sjasone			 * FIXME: we could try to check right delimiting
38859612Sjasone			 * key to see whether direct item continues in
38959612Sjasone			 * the right neighbor or rely on i_size
39059612Sjasone			 */
39159612Sjasone			break;
39259612Sjasone
39359612Sjasone		/* Update key to look for the next piece */
39459612Sjasone		set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + chars);
39559612Sjasone		if (search_for_position_by_key(sbi, &key, &path) !=
39659612Sjasone		    POSITION_FOUND)
39759612Sjasone			/*
39859612Sjasone			 * We read something from tail, even if now we got
39959612Sjasone			 * IO_ERROR
40059612Sjasone			 */
40159612Sjasone			break;
40259612Sjasone
40359612Sjasone		bp = get_last_bp(&path);
40459612Sjasone		ih = get_ih(&path);
40559612Sjasone	} while (1);
40659612Sjasone
40759612Sjasone	/* finished: */
40859612Sjasone	pathrelse(&path);
40959612Sjasone	/*
41059612Sjasone	 * This buffer has valid data, but isn't valid for io. mapping it to
41159612Sjasone	 * block #0 tells the rest of reiserfs it just has a tail in it
41259612Sjasone	 */
41359612Sjasone	ret = uiomove(blk, ip->i_size, uio);
41459612Sjasone	free(blk, M_REISERFSNODE);
41559612Sjasone	return (ret);
41659612Sjasone}
41759612Sjasone
41859612Sjasone/*
41959612Sjasone * Compute real number of used bytes by file
42059612Sjasone * Following three functions can go away when we'll have enough space in
42159612Sjasone * stat item
42259612Sjasone */
42359612Sjasonestatic int
42459612Sjasonereal_space_diff(struct reiserfs_node *ip, int sd_size)
42559612Sjasone{
42659612Sjasone	int bytes;
42759612Sjasone	off_t blocksize = ip->i_reiserfs->s_blocksize;
42859612Sjasone
42959612Sjasone	if (S_ISLNK(ip->i_mode) || S_ISDIR(ip->i_mode))
43059612Sjasone		return (sd_size);
43159612Sjasone
43259612Sjasone	/* End of file is also in full block with indirect reference, so round
43359612Sjasone	 * up to the next block.
43459612Sjasone	 *
43559612Sjasone	 * There is just no way to know if the tail is actually packed on the
43659612Sjasone	 * file, so we have to assume it isn't. When we pack the tail, we add
43759612Sjasone	 * 4 bytes to pretend there really is an unformatted node pointer. */
43859612Sjasone	bytes = ((ip->i_size + (blocksize - 1)) >>
43959612Sjasone	    ip->i_reiserfs->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
44059612Sjasone
44159612Sjasone	return (bytes);
44259612Sjasone}
44359612Sjasone
44459612Sjasonestatic inline off_t
44559612Sjasoneto_real_used_space(struct reiserfs_node *ip, unsigned long blocks, int sd_size)
44659612Sjasone{
44759612Sjasone
44859612Sjasone	if (S_ISLNK(ip->i_mode) || S_ISDIR(ip->i_mode)) {
44959612Sjasone		return ip->i_size + (off_t)(real_space_diff(ip, sd_size));
45059612Sjasone	}
45159612Sjasone
45259612Sjasone	return ((off_t)real_space_diff(ip, sd_size)) + (((off_t)blocks) << 9);
45359612Sjasone}
45459612Sjasone
45559612Sjasonevoid
45659612Sjasoneinode_set_bytes(struct reiserfs_node *ip, off_t bytes)
45759612Sjasone{
45859612Sjasone
45959612Sjasone	ip->i_blocks = bytes >> 9;
46059612Sjasone	ip->i_bytes  = bytes & 511;
46159612Sjasone}
46259612Sjasone
46359612Sjasone/* Called by read_locked_inode */
46459612Sjasonestatic void
46559612Sjasoneinit_inode(struct reiserfs_node *ip, struct path *path)
46659612Sjasone{
46759612Sjasone	struct buf *bp;
46859612Sjasone	struct item_head *ih;
46959612Sjasone	uint32_t rdev;
47059612Sjasone
47159612Sjasone	bp = PATH_PLAST_BUFFER(path);
47259612Sjasone	ih = PATH_PITEM_HEAD(path);
47359612Sjasone
47459612Sjasone	reiserfs_log(LOG_DEBUG, "copy the key (objectid=%d, dirid=%d)\n",
47559612Sjasone	    ih->ih_key.k_objectid, ih->ih_key.k_dir_id);
47659612Sjasone	copy_key(INODE_PKEY(ip), &(ih->ih_key));
47759612Sjasone	/* ip->i_blksize = reiserfs_default_io_size; */
47859612Sjasone
47959612Sjasone	reiserfs_log(LOG_DEBUG, "reset some inode structure members\n");
48059612Sjasone	REISERFS_I(ip)->i_flags = 0;
48159612Sjasone#if 0
48259612Sjasone	REISERFS_I(ip)->i_prealloc_block = 0;
48359612Sjasone	REISERFS_I(ip)->i_prealloc_count = 0;
48459612Sjasone	REISERFS_I(ip)->i_trans_id = 0;
48559612Sjasone	REISERFS_I(ip)->i_jl = NULL;
48659612Sjasone	REISERFS_I(ip)->i_acl_access = NULL;
48759612Sjasone	REISERFS_I(ip)->i_acl_default = NULL;
48859612Sjasone#endif
48959612Sjasone
49059612Sjasone	if (stat_data_v1(ih)) {
49159612Sjasone		reiserfs_log(LOG_DEBUG, "reiserfs/init_inode: stat data v1\n");
49259612Sjasone		struct stat_data_v1 *sd;
49359612Sjasone		unsigned long blocks;
49459612Sjasone
49559612Sjasone		sd = (struct stat_data_v1 *)B_I_PITEM(bp, ih);
49659612Sjasone
49759612Sjasone		reiserfs_log(LOG_DEBUG,
49859612Sjasone		    "reiserfs/init_inode: filling more members\n");
49959612Sjasone		set_inode_item_key_version(ip, KEY_FORMAT_3_5);
50059612Sjasone		set_inode_sd_version(ip, STAT_DATA_V1);
50159612Sjasone		ip->i_mode          = sd_v1_mode(sd);
50259612Sjasone		ip->i_nlink         = sd_v1_nlink(sd);
50359612Sjasone		ip->i_uid           = sd_v1_uid(sd);
50459612Sjasone		ip->i_gid           = sd_v1_gid(sd);
50559612Sjasone		ip->i_size          = sd_v1_size(sd);
50659612Sjasone		ip->i_atime.tv_sec  = sd_v1_atime(sd);
50759612Sjasone		ip->i_mtime.tv_sec  = sd_v1_mtime(sd);
50859612Sjasone		ip->i_ctime.tv_sec  = sd_v1_ctime(sd);
50959612Sjasone		ip->i_atime.tv_nsec = 0;
51059612Sjasone		ip->i_ctime.tv_nsec = 0;
51159612Sjasone		ip->i_mtime.tv_nsec = 0;
51259612Sjasone
51359612Sjasone		reiserfs_log(LOG_DEBUG, "  mode  = %08x\n", ip->i_mode);
51459612Sjasone		reiserfs_log(LOG_DEBUG, "  nlink = %d\n", ip->i_nlink);
51559612Sjasone		reiserfs_log(LOG_DEBUG, "  owner = %d:%d\n", ip->i_uid,
51659612Sjasone		    ip->i_gid);
51759612Sjasone		reiserfs_log(LOG_DEBUG, "  size  = %ju\n",
51859612Sjasone		    (intmax_t)ip->i_size);
51959612Sjasone		reiserfs_log(LOG_DEBUG, "  atime = %jd\n",
52059612Sjasone		    (intmax_t)ip->i_atime.tv_sec);
52159612Sjasone		reiserfs_log(LOG_DEBUG, "  mtime = %jd\n",
52259612Sjasone		    (intmax_t)ip->i_mtime.tv_sec);
52359612Sjasone		reiserfs_log(LOG_DEBUG, "  ctime = %jd\n",
52459612Sjasone		    (intmax_t)ip->i_ctime.tv_sec);
52559612Sjasone
52659612Sjasone		ip->i_blocks     = sd_v1_blocks(sd);
52759612Sjasone		ip->i_generation = le32toh(INODE_PKEY(ip)->k_dir_id);
52859612Sjasone		blocks = (ip->i_size + 511) >> 9;
52959612Sjasone		blocks = _ROUND_UP(blocks, ip->i_reiserfs->s_blocksize >> 9);
53059612Sjasone		if (ip->i_blocks > blocks) {
53159612Sjasone			/*
53259612Sjasone			 * There was a bug in <= 3.5.23 when i_blocks could
53359612Sjasone			 * take negative values. Starting from 3.5.17 this
53459612Sjasone			 * value could even be stored in stat data. For such
53559612Sjasone			 * files we set i_blocks based on file size. Just 2
53659612Sjasone			 * notes: this can be wrong for sparce files. On-disk
53759612Sjasone			 * value will be only updated if file's inode will
53859612Sjasone			 * ever change.
53959612Sjasone			 */
54059612Sjasone			ip->i_blocks = blocks;
54159612Sjasone		}
54259612Sjasone
54359612Sjasone		rdev = sd_v1_rdev(sd);
54459612Sjasone		REISERFS_I(ip)->i_first_direct_byte =
54559612Sjasone		    sd_v1_first_direct_byte(sd);
54659612Sjasone
54759612Sjasone		/*
54859612Sjasone		 * An early bug in the quota code can give us an odd number
54959612Sjasone		 * for the block count. This is incorrect, fix it here.
55059612Sjasone		 */
55159612Sjasone		if (ip->i_blocks & 1) {
55259612Sjasone			ip->i_blocks++ ;
55359612Sjasone		}
55459612Sjasone		inode_set_bytes(ip, to_real_used_space(ip, ip->i_blocks,
55559612Sjasone		    SD_V1_SIZE));
55659612Sjasone
55759612Sjasone		/*
55859612Sjasone		 * nopack is initially zero for v1 objects. For v2 objects,
55959612Sjasone		 * nopack is initialised from sd_attrs
56059612Sjasone		 */
56159612Sjasone		REISERFS_I(ip)->i_flags &= ~i_nopack_mask;
56259612Sjasone		reiserfs_log(LOG_DEBUG, "...done\n");
56359612Sjasone	} else {
56459612Sjasone		reiserfs_log(LOG_DEBUG, "stat data v2\n");
56559612Sjasone		/*
56659612Sjasone		 * New stat data found, but object may have old items
56759612Sjasone		 * (directories and symlinks)
56859612Sjasone		 */
56959612Sjasone		struct stat_data *sd = (struct stat_data *)B_I_PITEM(bp, ih);
57059612Sjasone
57159612Sjasone		reiserfs_log(LOG_DEBUG, "filling more members\n");
57259612Sjasone		ip->i_mode          = sd_v2_mode(sd);
57359612Sjasone		ip->i_nlink         = sd_v2_nlink(sd);
57459612Sjasone		ip->i_uid           = sd_v2_uid(sd);
57559612Sjasone		ip->i_size          = sd_v2_size(sd);
57659612Sjasone		ip->i_gid           = sd_v2_gid(sd);
57759612Sjasone		ip->i_mtime.tv_sec  = sd_v2_mtime(sd);
57859612Sjasone		ip->i_atime.tv_sec  = sd_v2_atime(sd);
57959612Sjasone		ip->i_ctime.tv_sec  = sd_v2_ctime(sd);
58059612Sjasone		ip->i_ctime.tv_nsec = 0;
58159612Sjasone		ip->i_mtime.tv_nsec = 0;
58259612Sjasone		ip->i_atime.tv_nsec = 0;
58359612Sjasone
58459612Sjasone		reiserfs_log(LOG_DEBUG, "  mode  = %08x\n", ip->i_mode);
58559612Sjasone		reiserfs_log(LOG_DEBUG, "  nlink = %d\n", ip->i_nlink);
58659612Sjasone		reiserfs_log(LOG_DEBUG, "  owner = %d:%d\n", ip->i_uid,
58759612Sjasone		    ip->i_gid);
58859612Sjasone		reiserfs_log(LOG_DEBUG, "  size  = %ju\n",
58959612Sjasone		    (intmax_t)ip->i_size);
59059612Sjasone		reiserfs_log(LOG_DEBUG, "  atime = %jd\n",
59159612Sjasone		    (intmax_t)ip->i_atime.tv_sec);
59259612Sjasone		reiserfs_log(LOG_DEBUG, "  mtime = %jd\n",
59359612Sjasone		    (intmax_t)ip->i_mtime.tv_sec);
59459612Sjasone		reiserfs_log(LOG_DEBUG, "  ctime = %jd\n",
59559612Sjasone		    (intmax_t)ip->i_ctime.tv_sec);
59659612Sjasone
59759612Sjasone		ip->i_blocks = sd_v2_blocks(sd);
59859612Sjasone		rdev         = sd_v2_rdev(sd);
59959612Sjasone		reiserfs_log(LOG_DEBUG, "  blocks = %u\n", ip->i_blocks);
60059612Sjasone
60159612Sjasone		if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
60259612Sjasone			ip->i_generation = le32toh(INODE_PKEY(ip)->k_dir_id);
60359612Sjasone		else
60459612Sjasone			ip->i_generation = sd_v2_generation(sd);
60559612Sjasone
60659612Sjasone		if (S_ISDIR(ip->i_mode) || S_ISLNK(ip->i_mode))
60759612Sjasone			set_inode_item_key_version(ip, KEY_FORMAT_3_5);
60859612Sjasone		else
60959612Sjasone			set_inode_item_key_version(ip, KEY_FORMAT_3_6);
61059612Sjasone
61159612Sjasone		REISERFS_I(ip)->i_first_direct_byte = 0;
61259612Sjasone		set_inode_sd_version(ip, STAT_DATA_V2);
61359612Sjasone		inode_set_bytes(ip, to_real_used_space(ip, ip->i_blocks,
61459612Sjasone		    SD_V2_SIZE));
61559612Sjasone
61659612Sjasone		/*
61759612Sjasone		 * Read persistent inode attributes from sd and initalise
61859612Sjasone		 * generic inode flags from them
61959612Sjasone		 */
62059612Sjasone		REISERFS_I(ip)->i_attrs = sd_v2_attrs(sd);
62159612Sjasone		sd_attrs_to_i_attrs(sd_v2_attrs(sd), ip);
62259612Sjasone		reiserfs_log(LOG_DEBUG, "...done\n");
62359612Sjasone	}
62459612Sjasone
62559612Sjasone	pathrelse(path);
62659612Sjasone	if (S_ISREG(ip->i_mode)) {
62759612Sjasone		reiserfs_log(LOG_DEBUG, "this inode is a regular file\n");
62859612Sjasone		//ip->i_op = &reiserfs_file_ip_operations;
62959612Sjasone		//ip->i_fop = &reiserfs_file_operations;
63059612Sjasone		//ip->i_mapping->a_ops = &reiserfs_address_space_operations ;
63159612Sjasone	} else if (S_ISDIR(ip->i_mode)) {
63259612Sjasone		reiserfs_log(LOG_DEBUG, "this inode is a directory\n");
63359612Sjasone		//ip->i_op = &reiserfs_dir_ip_operations;
63459612Sjasone		//ip->i_fop = &reiserfs_dir_operations;
63559612Sjasone	} else if (S_ISLNK(ip->i_mode)) {
63659612Sjasone		reiserfs_log(LOG_DEBUG, "this inode is a symlink\n");
63759612Sjasone		//ip->i_op = &reiserfs_symlink_ip_operations;
63859612Sjasone		//ip->i_mapping->a_ops = &reiserfs_address_space_operations;
63959612Sjasone	} else {
64059612Sjasone		reiserfs_log(LOG_DEBUG, "this inode is something unknown in "
64159612Sjasone		    "this universe\n");
64259612Sjasone		ip->i_blocks = 0;
64359612Sjasone		//ip->i_op = &reiserfs_special_ip_operations;
64459612Sjasone		//init_special_ip(ip, ip->i_mode, new_decode_dev(rdev));
64559612Sjasone	}
64659612Sjasone}
64759612Sjasone
64859612Sjasone/*
64959612Sjasone * reiserfs_read_locked_inode is called to read the inode off disk, and
65059612Sjasone * it does a make_bad_inode when things go wrong. But, we need to make
65159612Sjasone * sure and clear the key in the private portion of the inode, otherwise
65259612Sjasone * a corresponding iput might try to delete whatever object the inode
65359612Sjasone * last represented.
65459612Sjasone */
65559612Sjasonestatic void
65659612Sjasonereiserfs_make_bad_inode(struct reiserfs_node *ip) {
65759612Sjasone
65859612Sjasone	memset(INODE_PKEY(ip), 0, KEY_SIZE);
65959612Sjasone	//make_bad_inode(inode);
66059612Sjasone}
66159612Sjasone
66259612Sjasonevoid
66359612Sjasonereiserfs_read_locked_inode(struct reiserfs_node *ip,
66459612Sjasone    struct reiserfs_iget_args *args)
66559612Sjasone{
66659612Sjasone	INITIALIZE_PATH(path_to_sd);
66759612Sjasone	struct cpu_key key;
66859612Sjasone	unsigned long dirino;
66959612Sjasone	int retval;
67059612Sjasone
67159612Sjasone	dirino = args->dirid;
67259612Sjasone
67359612Sjasone	/*
67459612Sjasone	 * Set version 1, version 2 could be used too, because stat data
67559612Sjasone	 * key is the same in both versions
67659612Sjasone	 */
67759612Sjasone	key.version = KEY_FORMAT_3_5;
67859612Sjasone	key.on_disk_key.k_dir_id = dirino;
67959612Sjasone	key.on_disk_key.k_objectid = ip->i_number;
68059612Sjasone	key.on_disk_key.u.k_offset_v1.k_offset = SD_OFFSET;
68159612Sjasone	key.on_disk_key.u.k_offset_v1.k_uniqueness = SD_UNIQUENESS;
68259612Sjasone
68359612Sjasone	/* Look for the object's stat data */
68459612Sjasone	retval = search_item(ip->i_reiserfs, &key, &path_to_sd);
68559612Sjasone	if (retval == IO_ERROR) {
68659612Sjasone		reiserfs_log(LOG_ERR,
68759612Sjasone		    "I/O failure occured trying to find stat"
68859612Sjasone		    "data %u/%u\n",
68959612Sjasone		    key.on_disk_key.k_dir_id, key.on_disk_key.k_objectid);
69059612Sjasone		reiserfs_make_bad_inode(ip);
69159612Sjasone		return;
69259612Sjasone	}
69359612Sjasone	if (retval != ITEM_FOUND) {
69459612Sjasone		/*
69559612Sjasone		 * A stale NFS handle can trigger this without it being
69659612Sjasone		 * an error
69759612Sjasone		 */
69859612Sjasone		reiserfs_log(LOG_ERR,
69959612Sjasone		    "item not found (objectid=%u, dirid=%u)\n",
70059612Sjasone		    key.on_disk_key.k_objectid, key.on_disk_key.k_dir_id);
70159612Sjasone		pathrelse(&path_to_sd);
70259612Sjasone		reiserfs_make_bad_inode(ip);
70359612Sjasone		ip->i_nlink = 0;
70459612Sjasone		return;
70559612Sjasone	}
70659612Sjasone
70759612Sjasone	init_inode(ip, &path_to_sd);
70859612Sjasone
70959612Sjasone	/*
71059612Sjasone	 * It is possible that knfsd is trying to access inode of a file
71159612Sjasone	 * that is being removed from the disk by some other thread. As
71259612Sjasone	 * we update sd on unlink all that is required is to check for
71359612Sjasone	 * nlink here. This bug was first found by Sizif when debugging
71459612Sjasone	 * SquidNG/Butterfly, forgotten, and found again after Philippe
71559612Sjasone	 * Gramoulle <philippe.gramoulle@mmania.com> reproduced it.
71659612Sjasone	 *
71759612Sjasone	 * More logical fix would require changes in fs/inode.c:iput() to
71859612Sjasone	 * remove inode from hash-table _after_ fs cleaned disk stuff up and
71959612Sjasone	 * in iget() to return NULL if I_FREEING inode is found in hash-table.
72059612Sjasone	 */
72159612Sjasone	/*
72259612Sjasone	 * Currently there is one place where it's ok to meet inode with
72359612Sjasone	 * nlink == 0: processing of open-unlinked and half-truncated files
72459612Sjasone	 * during mount (fs/reiserfs/super.c:finish_unfinished()).
72559612Sjasone	 */
72659612Sjasone	if((ip->i_nlink == 0) &&
72759612Sjasone	    !REISERFS_SB(ip->i_reiserfs)->s_is_unlinked_ok ) {
72859612Sjasone		reiserfs_log(LOG_WARNING, "dead inode read from disk. This is "
72959612Sjasone		    "likely to be race with knfsd. Ignore");
73059612Sjasone		reiserfs_make_bad_inode(ip);
73159612Sjasone	}
73259612Sjasone
73359612Sjasone	/* Init inode should be relsing */
73459612Sjasone	reiserfs_check_path(&path_to_sd);
73559612Sjasone}
73659612Sjasone
73759612Sjasoneint
73859612Sjasonereiserfs_iget(
73959612Sjasone    struct mount *mp, const struct cpu_key *key,
74059612Sjasone    struct vnode **vpp, struct thread *td)
74159612Sjasone{
74259612Sjasone	int error, flags;
74359612Sjasone	struct cdev *dev;
74459612Sjasone	struct vnode *vp;
74559612Sjasone	struct reiserfs_node *ip;
74659612Sjasone	struct reiserfs_mount *rmp;
74759612Sjasone
74859612Sjasone	struct reiserfs_iget_args args;
74959612Sjasone
75059612Sjasone	//restart:
75159612Sjasone	/* Check if the inode cache contains it */
75259612Sjasone	// XXX LK_EXCLUSIVE ?
75359612Sjasone	flags = LK_EXCLUSIVE;
75459612Sjasone	error = vfs_hash_get(mp, key->on_disk_key.k_objectid, flags,
75559612Sjasone	    td, vpp, NULL, NULL);
75659612Sjasone	if (error || *vpp != NULL)
75759612Sjasone		return (error);
75859612Sjasone
75959612Sjasone	rmp = VFSTOREISERFS(mp);
76059612Sjasone	dev = rmp->rm_dev;
76159612Sjasone
76259612Sjasone	/*
76359612Sjasone	 * If this malloc() is performed after the getnewvnode() it might
76459612Sjasone	 * block, leaving a vnode with a NULL v_data to be found by
76559612Sjasone	 * reiserfs_sync() if a sync happens to fire right then, which
76659612Sjasone	 * will cause a panic because reiserfs_sync() blindly dereferences
76759612Sjasone	 * vp->v_data (as well it should).
76859612Sjasone	 */
76959612Sjasone	reiserfs_log(LOG_DEBUG, "malloc(struct reiserfs_node)\n");
77059612Sjasone	ip = malloc(sizeof(struct reiserfs_node), M_REISERFSNODE,
77159612Sjasone	    M_WAITOK | M_ZERO);
77259612Sjasone
77359612Sjasone	/* Allocate a new vnode/inode. */
77459612Sjasone	reiserfs_log(LOG_DEBUG, "getnewvnode\n");
77559612Sjasone	if ((error =
77659612Sjasone	    getnewvnode("reiserfs", mp, &reiserfs_vnodeops, &vp)) != 0) {
77759612Sjasone		*vpp = NULL;
77859612Sjasone		free(ip, M_REISERFSNODE);
77959612Sjasone		reiserfs_log(LOG_DEBUG, "getnewvnode FAILED\n");
78059612Sjasone		return (error);
78159612Sjasone	}
78259612Sjasone
78359612Sjasone	args.dirid = key->on_disk_key.k_dir_id;
78459612Sjasone	args.objectid = key->on_disk_key.k_objectid;
78559612Sjasone
78659612Sjasone	reiserfs_log(LOG_DEBUG, "filling *ip\n");
78759612Sjasone	vp->v_data     = ip;
78859612Sjasone	ip->i_vnode    = vp;
78959612Sjasone	ip->i_dev      = dev;
79059612Sjasone	ip->i_number   = args.objectid;
79159612Sjasone	ip->i_ino      = args.dirid;
79259612Sjasone	ip->i_reiserfs = rmp->rm_reiserfs;
79359612Sjasone
79459612Sjasone	vp->v_bufobj.bo_ops = &reiserfs_vnbufops;
79559612Sjasone	vp->v_bufobj.bo_private = vp;
79659612Sjasone
79759612Sjasone	/* If this is the root node, set the VV_ROOT flag */
79859612Sjasone	if (ip->i_number == REISERFS_ROOT_OBJECTID &&
79959612Sjasone	    ip->i_ino == REISERFS_ROOT_PARENT_OBJECTID)
80059612Sjasone		vp->v_vflag |= VV_ROOT;
80159612Sjasone
80259612Sjasone#if 0
80359612Sjasone	if (VOP_LOCK(vp, LK_EXCLUSIVE) != 0)
80459612Sjasone		panic("reiserfs/iget: unexpected lock failure");
80559612Sjasone
80659612Sjasone	/*
80759612Sjasone	 * Exclusively lock the vnode before adding to hash. Note, that we
80859612Sjasone	 * must not release nor downgrade the lock (despite flags argument
80959612Sjasone	 * says) till it is fully initialized.
81059612Sjasone	 */
81159612Sjasone	lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0);
81259612Sjasone#endif
81359612Sjasone
81459612Sjasone	lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
81559612Sjasone	error = insmntque(vp, mp);
81659612Sjasone	if (error != 0) {
81759612Sjasone		free(ip, M_REISERFSNODE);
81859612Sjasone		*vpp = NULL;
81959612Sjasone		reiserfs_log(LOG_DEBUG, "insmntque FAILED\n");
82059612Sjasone		return (error);
82159612Sjasone	}
82259612Sjasone	error = vfs_hash_insert(vp, key->on_disk_key.k_objectid, flags,
82359612Sjasone	    td, vpp, NULL, NULL);
82459612Sjasone	if (error || *vpp != NULL)
82559612Sjasone		return (error);
82659612Sjasone
82759612Sjasone	/* Read the inode */
82859612Sjasone	reiserfs_log(LOG_DEBUG, "call reiserfs_read_locked_inode ("
82959612Sjasone	    "objectid=%d,dirid=%d)\n", args.objectid, args.dirid);
83059612Sjasone	reiserfs_read_locked_inode(ip, &args);
83159612Sjasone
83259612Sjasone	ip->i_devvp = rmp->rm_devvp;
83359612Sjasone
83459612Sjasone	switch(vp->v_type = IFTOVT(ip->i_mode)) {
83559612Sjasone	case VBLK:
83659612Sjasone		reiserfs_log(LOG_DEBUG, "vnode type VBLK\n");
83759612Sjasone		vp->v_op = &reiserfs_specops;
83859612Sjasone		break;
83959612Sjasone#if 0
84059612Sjasone	case VCHR:
84159612Sjasone		reiserfs_log(LOG_DEBUG, "vnode type VCHR\n");
84259612Sjasone		vp->v_op = &reiserfs_specops;
84359612Sjasone		vp = addaliasu(vp, ip->i_rdev);
84459612Sjasone		ip->i_vnode = vp;
84559612Sjasone		break;
84659612Sjasone	case VFIFO:
84759612Sjasone		reiserfs_log(LOG_DEBUG, "vnode type VFIFO\n");
84859612Sjasone		vp->v_op = reiserfs_fifoop_p;
84959612Sjasone		break;
85059612Sjasone#endif
85159612Sjasone	default:
85259612Sjasone		break;
85359612Sjasone	}
85459612Sjasone
85559612Sjasone	*vpp = vp;
85659612Sjasone	return (0);
85759612Sjasone}
85859612Sjasone
85959612Sjasonevoid
86059612Sjasonesd_attrs_to_i_attrs(uint16_t sd_attrs, struct reiserfs_node *ip)
86159612Sjasone{
86259612Sjasone
86359612Sjasone	if (reiserfs_attrs(ip->i_reiserfs)) {
86459612Sjasone#if 0
86559612Sjasone		if (sd_attrs & REISERFS_SYNC_FL)
86659612Sjasone			ip->i_flags |= S_SYNC;
86759612Sjasone		else
86859612Sjasone			ip->i_flags &= ~S_SYNC;
86959612Sjasone#endif
87059612Sjasone		if (sd_attrs & REISERFS_IMMUTABLE_FL)
87159612Sjasone			ip->i_flags |= IMMUTABLE;
87259612Sjasone		else
87359612Sjasone			ip->i_flags &= ~IMMUTABLE;
87459612Sjasone		if (sd_attrs & REISERFS_APPEND_FL)
87559612Sjasone			ip->i_flags |= APPEND;
87659612Sjasone		else
87759612Sjasone			ip->i_flags &= ~APPEND;
87859612Sjasone#if 0
87959612Sjasone		if (sd_attrs & REISERFS_NOATIME_FL)
88059612Sjasone			ip->i_flags |= S_NOATIME;
88159612Sjasone		else
88259612Sjasone			ip->i_flags &= ~S_NOATIME;
88359612Sjasone		if (sd_attrs & REISERFS_NOTAIL_FL)
88459612Sjasone			REISERFS_I(ip)->i_flags |= i_nopack_mask;
88559612Sjasone		else
88659612Sjasone			REISERFS_I(ip)->i_flags &= ~i_nopack_mask;
88759612Sjasone#endif
88859612Sjasone	}
88959612Sjasone}
89059612Sjasone
89159612Sjasonevoid
89259612Sjasonei_attrs_to_sd_attrs(struct reiserfs_node *ip, uint16_t *sd_attrs)
89359612Sjasone{
89459612Sjasone
89559612Sjasone	if (reiserfs_attrs(ip->i_reiserfs)) {
89659612Sjasone#if 0
89759612Sjasone		if (ip->i_flags & S_SYNC)
89859612Sjasone			*sd_attrs |= REISERFS_SYNC_FL;
89959612Sjasone		else
90059612Sjasone			*sd_attrs &= ~REISERFS_SYNC_FL;
90159612Sjasone#endif
90259612Sjasone		if (ip->i_flags & IMMUTABLE)
90359612Sjasone			*sd_attrs |= REISERFS_IMMUTABLE_FL;
90459612Sjasone		else
90559612Sjasone			*sd_attrs &= ~REISERFS_IMMUTABLE_FL;
90659612Sjasone		if (ip->i_flags & APPEND)
90759612Sjasone			*sd_attrs |= REISERFS_APPEND_FL;
90859612Sjasone		else
90959612Sjasone			*sd_attrs &= ~REISERFS_APPEND_FL;
91059612Sjasone#if 0
91159612Sjasone		if (ip->i_flags & S_NOATIME)
91259612Sjasone			*sd_attrs |= REISERFS_NOATIME_FL;
91359612Sjasone		else
91459612Sjasone			*sd_attrs &= ~REISERFS_NOATIME_FL;
91559612Sjasone		if (REISERFS_I(ip)->i_flags & i_nopack_mask)
91659612Sjasone			*sd_attrs |= REISERFS_NOTAIL_FL;
91759612Sjasone		else
91859612Sjasone			*sd_attrs &= ~REISERFS_NOTAIL_FL;
91959612Sjasone#endif
92059612Sjasone	}
92159612Sjasone}
92259612Sjasone