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