The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/gnu/fs/reiserfs/reiserfs_inode.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright 2000 Hans Reiser
    3  * See README for licensing and copyright details
    4  * 
    5  * Ported to FreeBSD by Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
    6  * 
    7  * $FreeBSD$
    8  */
    9 
   10 #include <gnu/fs/reiserfs/reiserfs_fs.h>
   11 
   12 static b_strategy_t reiserfs_bufstrategy;
   13 
   14 /*
   15  * Buffer operations for ReiserFS vnodes.
   16  * We punt on VOP_BMAP, so we need to do strategy on the file's vnode
   17  * rather than the underlying device's.
   18  */
   19 static struct buf_ops reiserfs_vnbufops = {
   20         .bop_name       = "ReiserFS",
   21         .bop_strategy   = reiserfs_bufstrategy,
   22 };
   23 
   24 /* Default io size devuned in super.c */
   25 extern int reiserfs_default_io_size;
   26 void inode_set_bytes(struct reiserfs_node *ip, off_t bytes);
   27 
   28 /* Args for the create parameter of reiserfs_get_block */
   29 #define GET_BLOCK_NO_CREATE     0  /* Don't create new blocks or convert
   30                                       tails */
   31 #define GET_BLOCK_CREATE        1  /* Add anything you need to find block */
   32 #define GET_BLOCK_NO_HOLE       2  /* Return ENOENT for file holes */
   33 #define GET_BLOCK_READ_DIRECT   4  /* Read the tail if indirect item not
   34                                       found */
   35 #define GET_BLOCK_NO_ISEM       8  /* i_sem is not held, don't preallocate */
   36 #define GET_BLOCK_NO_DANGLE     16 /* Don't leave any transactions running */
   37 
   38 /* -------------------------------------------------------------------
   39  * vnode operations
   40  * -------------------------------------------------------------------*/
   41 
   42 int
   43 reiserfs_read(struct vop_read_args *ap)
   44 {
   45         struct uio *uio;
   46         struct vnode *vp;
   47         struct reiserfs_node *ip;
   48         struct reiserfs_sb_info *sbi;
   49 
   50         int error;
   51         long size;
   52         daddr_t lbn;
   53         off_t bytesinfile, offset;
   54 
   55         uio = ap->a_uio;
   56         vp  = ap->a_vp;
   57         ip  = VTOI(vp);
   58         sbi = ip->i_reiserfs;
   59 
   60         size = sbi->s_blocksize;
   61 
   62         for (error = 0; uio->uio_resid > 0;) {
   63                 if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0)
   64                         break;
   65 
   66                 /* Compute the logical block number and its offset */
   67                 lbn    = uio->uio_offset / size;
   68                 offset = uio->uio_offset % size;
   69                 reiserfs_log(LOG_DEBUG, "logical block number: %ju\n",
   70                     (intmax_t)lbn);
   71                 reiserfs_log(LOG_DEBUG, "block offset:         %ju\n",
   72                     (intmax_t)offset);
   73 
   74                 /* Read file blocks */
   75                 reiserfs_log(LOG_DEBUG, "reiserfs_get_block(%ju)\n",
   76                     (intmax_t)lbn);
   77                 if ((error = reiserfs_get_block(ip, lbn, offset, uio)) != 0) {
   78                         reiserfs_log(LOG_DEBUG,
   79                             "reiserfs_get_block returned the error %d\n",
   80                             error);
   81                         break;
   82                 }
   83         }
   84 
   85         return (error);
   86 }
   87 
   88 static void
   89 reiserfs_bufstrategy(struct bufobj *bo, struct buf *bp)
   90 {
   91         struct vnode *vp;
   92         int rc;
   93 
   94         vp = bo->bo_private;
   95         KASSERT(bo == &vp->v_bufobj, ("BO/VP mismatch: vp %p bo %p != %p",
   96             vp, &vp->v_bufobj, bo));
   97         rc = VOP_STRATEGY(vp, bp);
   98         KASSERT(rc == 0, ("ReiserFS VOP_STRATEGY failed: bp=%p, "
   99             "vp=%p, rc=%d", bp, vp, rc));
  100 }
  101 
  102 int
  103 reiserfs_inactive(struct vop_inactive_args *ap)
  104 {
  105         int error;
  106         struct vnode *vp;
  107         struct thread *td;
  108         struct reiserfs_node *ip;
  109 
  110         error = 0;
  111         vp = ap->a_vp;
  112         td = ap->a_td;
  113         ip = VTOI(vp);
  114 
  115         reiserfs_log(LOG_DEBUG, "deactivating inode used %d times\n",
  116             vp->v_usecount);
  117 
  118 #if 0
  119         /* Ignore inodes related to stale file handles. */
  120         if (ip->i_mode == 0)
  121                 goto out;
  122 
  123 out:
  124 #endif
  125 
  126         /*
  127          * If we are done with the inode, reclaim it so that it can be reused
  128          * immediately.
  129          */
  130         if (ip->i_mode == 0) {
  131                 reiserfs_log(LOG_DEBUG, "recyling\n");
  132                 vrecycle(vp, td);
  133         }
  134 
  135         return (error);
  136 }
  137 
  138 int
  139 reiserfs_reclaim(struct vop_reclaim_args *ap)
  140 {
  141         struct reiserfs_node *ip;
  142         struct vnode *vp;
  143 
  144         vp = ap->a_vp;
  145 
  146         reiserfs_log(LOG_DEBUG, "reclaiming inode used %d times\n",
  147             vp->v_usecount);
  148         ip = VTOI(vp);
  149 
  150         /* XXX Update this node (write to the disk) */
  151 
  152         /* Remove the inode from its hash chain. */
  153         vfs_hash_remove(vp);
  154 
  155         reiserfs_log(LOG_DEBUG, "free private data\n");
  156         free(vp->v_data, M_REISERFSNODE);
  157         vp->v_data = NULL;
  158         vnode_destroy_vobject(vp);
  159 
  160         return (0);
  161 }
  162 
  163 /* -------------------------------------------------------------------
  164  * Functions from linux/fs/reiserfs/inode.c
  165  * -------------------------------------------------------------------*/
  166 
  167 static void
  168 _make_cpu_key(struct cpu_key *key, int version,
  169     uint32_t dirid, uint32_t objectid, off_t offset, int type, int length)
  170 {
  171 
  172         key->version = version;
  173 
  174         key->on_disk_key.k_dir_id   = dirid;
  175         key->on_disk_key.k_objectid = objectid;
  176         set_cpu_key_k_offset(key, offset);
  177         set_cpu_key_k_type(key, type);
  178         key->key_length = length;
  179 }
  180 
  181 /*
  182  * Take base of inode_key (it comes from inode always) (dirid, objectid)
  183  * and version from an inode, set offset and type of key
  184  */
  185 void
  186 make_cpu_key(struct cpu_key *key, struct reiserfs_node *ip, off_t offset,
  187     int type, int length)
  188 {
  189 
  190         _make_cpu_key(key, get_inode_item_key_version(ip),
  191             le32toh(INODE_PKEY(ip)->k_dir_id),
  192             le32toh(INODE_PKEY(ip)->k_objectid),
  193             offset, type, length);
  194 }
  195 
  196 int
  197 reiserfs_get_block(struct reiserfs_node *ip, long block, off_t offset,
  198     struct uio *uio)
  199 {
  200         caddr_t blk = NULL, p;
  201         struct cpu_key key;
  202         /* unsigned long offset; */
  203         INITIALIZE_PATH(path);
  204         struct buf *bp, *blk_bp;
  205         struct item_head *ih;
  206         struct reiserfs_sb_info *sbi;
  207         int blocknr, chars, done = 0, ret = 0, args = 0;
  208 
  209         sbi = ip->i_reiserfs;
  210 
  211         /* Prepare the key to look for the 'block'-th block of file */
  212         reiserfs_log(LOG_DEBUG, "prepare cpu key\n");
  213         make_cpu_key(&key, ip, (off_t)block * sbi->s_blocksize + 1, TYPE_ANY, 3);
  214 
  215         /* research: */
  216         reiserfs_log(LOG_DEBUG, "search for position\n");
  217         if (search_for_position_by_key(sbi, &key, &path) != POSITION_FOUND) {
  218                 reiserfs_log(LOG_DEBUG, "position not found\n");
  219                 pathrelse(&path);
  220 #if 0
  221                 if (blk)
  222                         kunmap(bh_result->b_page);
  223 #endif
  224                 /*
  225                  * We do not return ENOENT if there is a hole but page is
  226                  * uptodate, because it means that there is some MMAPED data
  227                  * associated with it that is yet to be written to disk.
  228                  */
  229                 if ((args & GET_BLOCK_NO_HOLE)/* &&
  230                     !PageUptodate(bh_result->b_page)*/)
  231                         return (ENOENT);
  232                 return (0);
  233         }
  234         reiserfs_log(LOG_DEBUG, "position found\n");
  235 
  236         bp = get_last_bp(&path);
  237         ih = get_ih(&path);
  238 
  239         if (is_indirect_le_ih(ih)) {
  240                 off_t xfersize;
  241                 uint32_t *ind_item = (uint32_t *)B_I_PITEM(bp, ih);
  242 
  243                 reiserfs_log(LOG_DEBUG, "item is INDIRECT\n");
  244 
  245                 blocknr = get_block_num(ind_item, path.pos_in_item);
  246                 reiserfs_log(LOG_DEBUG, "block number: %d "
  247                     "(ind_item=%p, pos_in_item=%u)\n",
  248                     blocknr, ind_item, path.pos_in_item);
  249 
  250                 xfersize = MIN(sbi->s_blocksize - offset,
  251                     ip->i_size - uio->uio_offset);
  252                 xfersize = MIN(xfersize, uio->uio_resid);
  253 
  254                 if (blocknr) {
  255                         ret = bread(sbi->s_devvp,
  256                             blocknr * btodb(sbi->s_blocksize),
  257                             sbi->s_blocksize, NOCRED, &blk_bp);
  258                         reiserfs_log(LOG_DEBUG, "xfersize: %ju\n",
  259                             (intmax_t)xfersize);
  260                         ret = uiomove(blk_bp->b_data + offset, xfersize, uio);
  261                         brelse(blk_bp);
  262                 } else {
  263                         /*
  264                          * We do not return ENOENT if there is a hole but
  265                          * page is uptodate, because it means That there
  266                          * is some MMAPED data associated with it that
  267                          * is yet to be written to disk.
  268                          */
  269                         if ((args & GET_BLOCK_NO_HOLE)/* &&
  270                             !PageUptodate(bh_result->b_page)*/)
  271                                 ret = (ENOENT);
  272 
  273                         /* Skip this hole */
  274                         uio->uio_resid  -= xfersize;
  275                         uio->uio_offset += xfersize;
  276                 }
  277 
  278                 pathrelse(&path);
  279                 return (ret);
  280         }
  281 
  282         reiserfs_log(LOG_DEBUG, "item should be DIRECT\n");
  283 
  284 #if 0
  285         /* Requested data are in direct item(s) */
  286         if (!(args & GET_BLOCK_READ_DIRECT)) {
  287                 /*
  288                  * We are called by bmap. FIXME: we can not map block of
  289                  * file when it is stored in direct item(s)
  290                  */
  291                 pathrelse(&path);
  292 #if 0
  293                 if (blk)
  294                         kunmap(bh_result->b_page);
  295 #endif
  296                 return (ENOENT);
  297         }
  298 #endif
  299 
  300 #if 0
  301         /*
  302          * If we've got a direct item, and the buffer or page was uptodate, we
  303          * don't want to pull data off disk again. Skip to the end, where we
  304          * map the buffer and return
  305          */
  306         if (buffer_uptodate(bh_result)) {
  307                 goto finished;
  308         } else
  309                 /*
  310                  * grab_tail_page can trigger calls to reiserfs_get_block
  311                  * on up to date pages without any buffers. If the page
  312                  * is up to date, we don't want read old data off disk.
  313                  * Set the up to date bit on the buffer instead and jump
  314                  * to the end
  315                  */
  316                 if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
  317                         set_buffer_uptodate(bh_result);
  318                         goto finished;
  319                 }
  320 #endif
  321 
  322 #if 0
  323         /* Read file tail into part of page */
  324         offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1);
  325         fs_gen = get_generation(ip->i_reiserfs);
  326         copy_item_head(&tmp_ih, ih);
  327 #endif
  328 
  329 #if 0
  330         /*
  331          * We only want to kmap if we are reading the tail into the page. this
  332          * is not the common case, so we don't kmap until we are sure we need
  333          * to. But, this means the item might move if kmap schedules
  334          */
  335         if (!blk) {
  336                 blk = (char *)kmap(bh_result->b_page);
  337                 if (fs_changed (fs_gen, sbi) && item_moved(&tmp_ih, &path))
  338                         goto research;
  339         }
  340         blk += offset;
  341         memset(blk, 0, sbi->s_blocksize);
  342 #endif
  343         if (!blk) {
  344                 reiserfs_log(LOG_DEBUG, "allocating buffer\n");
  345                 blk = malloc(ip->i_size, M_REISERFSNODE, M_WAITOK | M_ZERO);
  346                 if (!blk)
  347                         return (ENOMEM);
  348         }
  349         /* p += offset; */
  350 
  351         p = blk;
  352         do {
  353                 if (!is_direct_le_ih(ih)) {
  354                         reiserfs_log(LOG_ERR, "BUG\n");
  355                         return (ENOENT); /* XXX Wrong error code */
  356                 }
  357 
  358                 /*
  359                  * Make sure we don't read more bytes than actually exist
  360                  * in the file. This can happen in odd cases where i_size
  361                  * isn't correct, and when direct item padding results in
  362                  * a few extra bytes at the end of the direct item
  363                  */
  364                 if ((le_ih_k_offset(ih) + path.pos_in_item) > ip->i_size)
  365                         break;
  366 
  367                 if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > ip->i_size) {
  368                         chars = ip->i_size - (le_ih_k_offset(ih) - 1) -
  369                             path.pos_in_item;
  370                         done  = 1;
  371                 } else {
  372                         chars = ih_item_len(ih) - path.pos_in_item;
  373                 }
  374                 reiserfs_log(LOG_DEBUG, "copying %d bytes\n", chars);
  375                 memcpy(p, B_I_PITEM(bp, ih) + path.pos_in_item, chars);
  376                 if (done) {
  377                         reiserfs_log(LOG_DEBUG, "copy done\n");
  378                         break;
  379                 }
  380 
  381                 p += chars;
  382 
  383                 if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bp) - 1))
  384                         /*
  385                          * We done, if read direct item is not the last
  386                          * item of node
  387                          * FIXME: we could try to check right delimiting
  388                          * key to see whether direct item continues in
  389                          * the right neighbor or rely on i_size
  390                          */
  391                         break;
  392 
  393                 /* Update key to look for the next piece */
  394                 set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + chars);
  395                 if (search_for_position_by_key(sbi, &key, &path) !=
  396                     POSITION_FOUND)
  397                         /*
  398                          * We read something from tail, even if now we got
  399                          * IO_ERROR
  400                          */
  401                         break;
  402 
  403                 bp = get_last_bp(&path);
  404                 ih = get_ih(&path);
  405         } while (1);
  406 
  407         /* finished: */
  408         pathrelse(&path);
  409         /*
  410          * This buffer has valid data, but isn't valid for io. mapping it to
  411          * block #0 tells the rest of reiserfs it just has a tail in it
  412          */
  413         ret = uiomove(blk, ip->i_size, uio);
  414         free(blk, M_REISERFSNODE);
  415         return (ret);
  416 }
  417 
  418 /*
  419  * Compute real number of used bytes by file
  420  * Following three functions can go away when we'll have enough space in
  421  * stat item
  422  */
  423 static int
  424 real_space_diff(struct reiserfs_node *ip, int sd_size)
  425 {
  426         int bytes;
  427         off_t blocksize = ip->i_reiserfs->s_blocksize;
  428 
  429         if (S_ISLNK(ip->i_mode) || S_ISDIR(ip->i_mode))
  430                 return (sd_size);
  431 
  432         /* End of file is also in full block with indirect reference, so round
  433          * up to the next block.
  434          *
  435          * There is just no way to know if the tail is actually packed on the
  436          * file, so we have to assume it isn't. When we pack the tail, we add
  437          * 4 bytes to pretend there really is an unformatted node pointer. */
  438         bytes = ((ip->i_size + (blocksize - 1)) >>
  439             ip->i_reiserfs->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
  440 
  441         return (bytes);
  442 }
  443 
  444 static inline off_t
  445 to_real_used_space(struct reiserfs_node *ip, unsigned long blocks, int sd_size)
  446 {
  447 
  448         if (S_ISLNK(ip->i_mode) || S_ISDIR(ip->i_mode)) {
  449                 return ip->i_size + (off_t)(real_space_diff(ip, sd_size));
  450         }
  451 
  452         return ((off_t)real_space_diff(ip, sd_size)) + (((off_t)blocks) << 9);
  453 }
  454 
  455 void
  456 inode_set_bytes(struct reiserfs_node *ip, off_t bytes)
  457 {
  458 
  459         ip->i_blocks = bytes >> 9;
  460         ip->i_bytes  = bytes & 511;
  461 }
  462 
  463 /* Called by read_locked_inode */
  464 static void
  465 init_inode(struct reiserfs_node *ip, struct path *path)
  466 {
  467         struct buf *bp;
  468         struct item_head *ih;
  469         uint32_t rdev;
  470 
  471         bp = PATH_PLAST_BUFFER(path);
  472         ih = PATH_PITEM_HEAD(path);
  473 
  474         reiserfs_log(LOG_DEBUG, "copy the key (objectid=%d, dirid=%d)\n",
  475             ih->ih_key.k_objectid, ih->ih_key.k_dir_id);
  476         copy_key(INODE_PKEY(ip), &(ih->ih_key));
  477         /* ip->i_blksize = reiserfs_default_io_size; */
  478 
  479         reiserfs_log(LOG_DEBUG, "reset some inode structure members\n");
  480         REISERFS_I(ip)->i_flags = 0;
  481 #if 0
  482         REISERFS_I(ip)->i_prealloc_block = 0;
  483         REISERFS_I(ip)->i_prealloc_count = 0;
  484         REISERFS_I(ip)->i_trans_id = 0;
  485         REISERFS_I(ip)->i_jl = NULL;
  486         REISERFS_I(ip)->i_acl_access = NULL;
  487         REISERFS_I(ip)->i_acl_default = NULL;
  488 #endif
  489 
  490         if (stat_data_v1(ih)) {
  491                 reiserfs_log(LOG_DEBUG, "reiserfs/init_inode: stat data v1\n");
  492                 struct stat_data_v1 *sd;
  493                 unsigned long blocks;
  494 
  495                 sd = (struct stat_data_v1 *)B_I_PITEM(bp, ih);
  496                 
  497                 reiserfs_log(LOG_DEBUG,
  498                     "reiserfs/init_inode: filling more members\n");
  499                 set_inode_item_key_version(ip, KEY_FORMAT_3_5);
  500                 set_inode_sd_version(ip, STAT_DATA_V1);
  501                 ip->i_mode          = sd_v1_mode(sd);
  502                 ip->i_nlink         = sd_v1_nlink(sd);
  503                 ip->i_uid           = sd_v1_uid(sd);
  504                 ip->i_gid           = sd_v1_gid(sd);
  505                 ip->i_size          = sd_v1_size(sd);
  506                 ip->i_atime.tv_sec  = sd_v1_atime(sd);
  507                 ip->i_mtime.tv_sec  = sd_v1_mtime(sd);
  508                 ip->i_ctime.tv_sec  = sd_v1_ctime(sd);
  509                 ip->i_atime.tv_nsec = 0;
  510                 ip->i_ctime.tv_nsec = 0;
  511                 ip->i_mtime.tv_nsec = 0;
  512 
  513                 reiserfs_log(LOG_DEBUG, "  mode  = %08x\n", ip->i_mode);
  514                 reiserfs_log(LOG_DEBUG, "  nlink = %d\n", ip->i_nlink);
  515                 reiserfs_log(LOG_DEBUG, "  owner = %d:%d\n", ip->i_uid,
  516                     ip->i_gid);
  517                 reiserfs_log(LOG_DEBUG, "  size  = %ju\n",
  518                     (intmax_t)ip->i_size);
  519                 reiserfs_log(LOG_DEBUG, "  atime = %jd\n",
  520                     (intmax_t)ip->i_atime.tv_sec);
  521                 reiserfs_log(LOG_DEBUG, "  mtime = %jd\n",
  522                     (intmax_t)ip->i_mtime.tv_sec);
  523                 reiserfs_log(LOG_DEBUG, "  ctime = %jd\n",
  524                     (intmax_t)ip->i_ctime.tv_sec);
  525 
  526                 ip->i_blocks     = sd_v1_blocks(sd);
  527                 ip->i_generation = le32toh(INODE_PKEY(ip)->k_dir_id);
  528                 blocks = (ip->i_size + 511) >> 9;
  529                 blocks = _ROUND_UP(blocks, ip->i_reiserfs->s_blocksize >> 9);
  530                 if (ip->i_blocks > blocks) {
  531                         /*
  532                          * There was a bug in <= 3.5.23 when i_blocks could
  533                          * take negative values. Starting from 3.5.17 this
  534                          * value could even be stored in stat data. For such
  535                          * files we set i_blocks based on file size. Just 2
  536                          * notes: this can be wrong for sparce files. On-disk
  537                          * value will be only updated if file's inode will
  538                          * ever change.
  539                          */
  540                         ip->i_blocks = blocks;
  541                 }
  542 
  543                 rdev = sd_v1_rdev(sd);
  544                 REISERFS_I(ip)->i_first_direct_byte =
  545                     sd_v1_first_direct_byte(sd);
  546 
  547                 /*
  548                  * An early bug in the quota code can give us an odd number
  549                  * for the block count. This is incorrect, fix it here.
  550                  */
  551                 if (ip->i_blocks & 1) {
  552                         ip->i_blocks++ ;
  553                 }
  554                 inode_set_bytes(ip, to_real_used_space(ip, ip->i_blocks,
  555                     SD_V1_SIZE));
  556 
  557                 /*
  558                  * nopack is initially zero for v1 objects. For v2 objects,
  559                  * nopack is initialised from sd_attrs
  560                  */
  561                 REISERFS_I(ip)->i_flags &= ~i_nopack_mask;
  562                 reiserfs_log(LOG_DEBUG, "...done\n");
  563         } else {
  564                 reiserfs_log(LOG_DEBUG, "stat data v2\n");
  565                 /*
  566                  * New stat data found, but object may have old items
  567                  * (directories and symlinks)
  568                  */
  569                 struct stat_data *sd = (struct stat_data *)B_I_PITEM(bp, ih);
  570 
  571                 reiserfs_log(LOG_DEBUG, "filling more members\n");
  572                 ip->i_mode          = sd_v2_mode(sd);
  573                 ip->i_nlink         = sd_v2_nlink(sd);
  574                 ip->i_uid           = sd_v2_uid(sd);
  575                 ip->i_size          = sd_v2_size(sd);
  576                 ip->i_gid           = sd_v2_gid(sd);
  577                 ip->i_mtime.tv_sec  = sd_v2_mtime(sd);
  578                 ip->i_atime.tv_sec  = sd_v2_atime(sd);
  579                 ip->i_ctime.tv_sec  = sd_v2_ctime(sd);
  580                 ip->i_ctime.tv_nsec = 0;
  581                 ip->i_mtime.tv_nsec = 0;
  582                 ip->i_atime.tv_nsec = 0;
  583 
  584                 reiserfs_log(LOG_DEBUG, "  mode  = %08x\n", ip->i_mode);
  585                 reiserfs_log(LOG_DEBUG, "  nlink = %d\n", ip->i_nlink);
  586                 reiserfs_log(LOG_DEBUG, "  owner = %d:%d\n", ip->i_uid,
  587                     ip->i_gid);
  588                 reiserfs_log(LOG_DEBUG, "  size  = %ju\n",
  589                     (intmax_t)ip->i_size);
  590                 reiserfs_log(LOG_DEBUG, "  atime = %jd\n",
  591                     (intmax_t)ip->i_atime.tv_sec);
  592                 reiserfs_log(LOG_DEBUG, "  mtime = %jd\n",
  593                     (intmax_t)ip->i_mtime.tv_sec);
  594                 reiserfs_log(LOG_DEBUG, "  ctime = %jd\n",
  595                     (intmax_t)ip->i_ctime.tv_sec);
  596 
  597                 ip->i_blocks = sd_v2_blocks(sd);
  598                 rdev         = sd_v2_rdev(sd);
  599                 reiserfs_log(LOG_DEBUG, "  blocks = %u\n", ip->i_blocks);
  600 
  601                 if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
  602                         ip->i_generation = le32toh(INODE_PKEY(ip)->k_dir_id);
  603                 else
  604                         ip->i_generation = sd_v2_generation(sd);
  605 
  606                 if (S_ISDIR(ip->i_mode) || S_ISLNK(ip->i_mode))
  607                         set_inode_item_key_version(ip, KEY_FORMAT_3_5);
  608                 else
  609                         set_inode_item_key_version(ip, KEY_FORMAT_3_6);
  610 
  611                 REISERFS_I(ip)->i_first_direct_byte = 0;
  612                 set_inode_sd_version(ip, STAT_DATA_V2);
  613                 inode_set_bytes(ip, to_real_used_space(ip, ip->i_blocks,
  614                     SD_V2_SIZE));
  615 
  616                 /*
  617                  * Read persistent inode attributes from sd and initalise
  618                  * generic inode flags from them
  619                  */
  620                 REISERFS_I(ip)->i_attrs = sd_v2_attrs(sd);
  621                 sd_attrs_to_i_attrs(sd_v2_attrs(sd), ip);
  622                 reiserfs_log(LOG_DEBUG, "...done\n");
  623         }
  624 
  625         pathrelse(path);
  626         if (S_ISREG(ip->i_mode)) {
  627                 reiserfs_log(LOG_DEBUG, "this inode is a regular file\n");
  628                 //ip->i_op = &reiserfs_file_ip_operations;
  629                 //ip->i_fop = &reiserfs_file_operations;
  630                 //ip->i_mapping->a_ops = &reiserfs_address_space_operations ;
  631         } else if (S_ISDIR(ip->i_mode)) {
  632                 reiserfs_log(LOG_DEBUG, "this inode is a directory\n");
  633                 //ip->i_op = &reiserfs_dir_ip_operations;
  634                 //ip->i_fop = &reiserfs_dir_operations;
  635         } else if (S_ISLNK(ip->i_mode)) {
  636                 reiserfs_log(LOG_DEBUG, "this inode is a symlink\n");
  637                 //ip->i_op = &reiserfs_symlink_ip_operations;
  638                 //ip->i_mapping->a_ops = &reiserfs_address_space_operations;
  639         } else {
  640                 reiserfs_log(LOG_DEBUG, "this inode is something unknown in "
  641                     "this universe\n");
  642                 ip->i_blocks = 0;
  643                 //ip->i_op = &reiserfs_special_ip_operations;
  644                 //init_special_ip(ip, ip->i_mode, new_decode_dev(rdev));
  645         }
  646 }
  647 
  648 /*
  649  * reiserfs_read_locked_inode is called to read the inode off disk, and
  650  * it does a make_bad_inode when things go wrong. But, we need to make
  651  * sure and clear the key in the private portion of the inode, otherwise
  652  * a corresponding iput might try to delete whatever object the inode
  653  * last represented.
  654  */
  655 static void
  656 reiserfs_make_bad_inode(struct reiserfs_node *ip) {
  657 
  658         memset(INODE_PKEY(ip), 0, KEY_SIZE);
  659         //make_bad_inode(inode);
  660 }
  661 
  662 void
  663 reiserfs_read_locked_inode(struct reiserfs_node *ip,
  664     struct reiserfs_iget_args *args)
  665 {
  666         INITIALIZE_PATH(path_to_sd);
  667         struct cpu_key key;
  668         unsigned long dirino;
  669         int retval;
  670 
  671         dirino = args->dirid;
  672 
  673         /*
  674          * Set version 1, version 2 could be used too, because stat data
  675          * key is the same in both versions
  676          */
  677         key.version = KEY_FORMAT_3_5;
  678         key.on_disk_key.k_dir_id = dirino;
  679         key.on_disk_key.k_objectid = ip->i_number;
  680         key.on_disk_key.u.k_offset_v1.k_offset = SD_OFFSET;
  681         key.on_disk_key.u.k_offset_v1.k_uniqueness = SD_UNIQUENESS;
  682 
  683         /* Look for the object's stat data */
  684         retval = search_item(ip->i_reiserfs, &key, &path_to_sd);
  685         if (retval == IO_ERROR) {
  686                 reiserfs_log(LOG_ERR,
  687                     "I/O failure occured trying to find stat"
  688                     "data %u/%u\n",
  689                     key.on_disk_key.k_dir_id, key.on_disk_key.k_objectid);
  690                 reiserfs_make_bad_inode(ip);
  691                 return;
  692         }
  693         if (retval != ITEM_FOUND) {
  694                 /*
  695                  * A stale NFS handle can trigger this without it being
  696                  * an error
  697                  */
  698                 reiserfs_log(LOG_ERR,
  699                     "item not found (objectid=%u, dirid=%u)\n",
  700                     key.on_disk_key.k_objectid, key.on_disk_key.k_dir_id);
  701                 pathrelse(&path_to_sd);
  702                 reiserfs_make_bad_inode(ip);
  703                 ip->i_nlink = 0;
  704                 return;
  705         }
  706 
  707         init_inode(ip, &path_to_sd);
  708 
  709         /*
  710          * It is possible that knfsd is trying to access inode of a file
  711          * that is being removed from the disk by some other thread. As
  712          * we update sd on unlink all that is required is to check for
  713          * nlink here. This bug was first found by Sizif when debugging
  714          * SquidNG/Butterfly, forgotten, and found again after Philippe
  715          * Gramoulle <philippe.gramoulle@mmania.com> reproduced it.
  716          * 
  717          * More logical fix would require changes in fs/inode.c:iput() to
  718          * remove inode from hash-table _after_ fs cleaned disk stuff up and
  719          * in iget() to return NULL if I_FREEING inode is found in hash-table.
  720          */
  721         /*
  722          * Currently there is one place where it's ok to meet inode with
  723          * nlink == 0: processing of open-unlinked and half-truncated files
  724          * during mount (fs/reiserfs/super.c:finish_unfinished()).
  725          */
  726         if((ip->i_nlink == 0) &&
  727             !REISERFS_SB(ip->i_reiserfs)->s_is_unlinked_ok ) {
  728                 reiserfs_log(LOG_WARNING, "dead inode read from disk. This is "
  729                     "likely to be race with knfsd. Ignore");
  730                 reiserfs_make_bad_inode(ip);
  731         }
  732 
  733         /* Init inode should be relsing */
  734         reiserfs_check_path(&path_to_sd);
  735 }
  736 
  737 int
  738 reiserfs_iget(
  739     struct mount *mp, const struct cpu_key *key,
  740     struct vnode **vpp, struct thread *td)
  741 {
  742         int error, flags;
  743         struct cdev *dev;
  744         struct vnode *vp;
  745         struct reiserfs_node *ip;
  746         struct reiserfs_mount *rmp;
  747 
  748         struct reiserfs_iget_args args;
  749 
  750         //restart:
  751         /* Check if the inode cache contains it */
  752         // XXX LK_EXCLUSIVE ?
  753         flags = LK_EXCLUSIVE;
  754         error = vfs_hash_get(mp, key->on_disk_key.k_objectid, flags,
  755             td, vpp, NULL, NULL);
  756         if (error || *vpp != NULL)
  757                 return (error);
  758 
  759         rmp = VFSTOREISERFS(mp);
  760         dev = rmp->rm_dev;
  761 
  762         /*
  763          * If this malloc() is performed after the getnewvnode() it might
  764          * block, leaving a vnode with a NULL v_data to be found by
  765          * reiserfs_sync() if a sync happens to fire right then, which
  766          * will cause a panic because reiserfs_sync() blindly dereferences
  767          * vp->v_data (as well it should).
  768          */
  769         reiserfs_log(LOG_DEBUG, "malloc(struct reiserfs_node)\n");
  770         ip = malloc(sizeof(struct reiserfs_node), M_REISERFSNODE,
  771             M_WAITOK | M_ZERO);
  772 
  773         /* Allocate a new vnode/inode. */
  774         reiserfs_log(LOG_DEBUG, "getnewvnode\n");
  775         if ((error =
  776             getnewvnode("reiserfs", mp, &reiserfs_vnodeops, &vp)) != 0) {
  777                 *vpp = NULL;
  778                 free(ip, M_REISERFSNODE);
  779                 reiserfs_log(LOG_DEBUG, "getnewvnode FAILED\n");
  780                 return (error);
  781         }
  782 
  783         args.dirid = key->on_disk_key.k_dir_id;
  784         args.objectid = key->on_disk_key.k_objectid;
  785 
  786         reiserfs_log(LOG_DEBUG, "filling *ip\n");
  787         vp->v_data     = ip;
  788         ip->i_vnode    = vp;
  789         ip->i_dev      = dev;
  790         ip->i_number   = args.objectid;
  791         ip->i_ino      = args.dirid;
  792         ip->i_reiserfs = rmp->rm_reiserfs;
  793 
  794         vp->v_bufobj.bo_ops = &reiserfs_vnbufops;
  795         vp->v_bufobj.bo_private = vp;
  796 
  797         /* If this is the root node, set the VV_ROOT flag */
  798         if (ip->i_number == REISERFS_ROOT_OBJECTID &&
  799             ip->i_ino == REISERFS_ROOT_PARENT_OBJECTID)
  800                 vp->v_vflag |= VV_ROOT;
  801 
  802 #if 0
  803         if (VOP_LOCK(vp, LK_EXCLUSIVE) != 0)
  804                 panic("reiserfs/iget: unexpected lock failure");
  805 
  806         /*
  807          * Exclusively lock the vnode before adding to hash. Note, that we
  808          * must not release nor downgrade the lock (despite flags argument
  809          * says) till it is fully initialized.
  810          */
  811         lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0);
  812 #endif
  813 
  814         lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
  815         error = insmntque(vp, mp);
  816         if (error != 0) {
  817                 free(ip, M_REISERFSNODE);
  818                 *vpp = NULL;
  819                 reiserfs_log(LOG_DEBUG, "insmntque FAILED\n");
  820                 return (error);
  821         }
  822         error = vfs_hash_insert(vp, key->on_disk_key.k_objectid, flags,
  823             td, vpp, NULL, NULL);
  824         if (error || *vpp != NULL)
  825                 return (error);
  826 
  827         /* Read the inode */
  828         reiserfs_log(LOG_DEBUG, "call reiserfs_read_locked_inode ("
  829             "objectid=%d,dirid=%d)\n", args.objectid, args.dirid);
  830         reiserfs_read_locked_inode(ip, &args);
  831 
  832         ip->i_devvp = rmp->rm_devvp;
  833 
  834         switch(vp->v_type = IFTOVT(ip->i_mode)) {
  835         case VBLK:
  836                 reiserfs_log(LOG_DEBUG, "vnode type VBLK\n");
  837                 vp->v_op = &reiserfs_specops;
  838                 break;
  839 #if 0
  840         case VCHR:
  841                 reiserfs_log(LOG_DEBUG, "vnode type VCHR\n");
  842                 vp->v_op = &reiserfs_specops;
  843                 vp = addaliasu(vp, ip->i_rdev);
  844                 ip->i_vnode = vp;
  845                 break;
  846         case VFIFO:
  847                 reiserfs_log(LOG_DEBUG, "vnode type VFIFO\n");
  848                 vp->v_op = reiserfs_fifoop_p;
  849                 break;
  850 #endif
  851         default:
  852                 break;
  853         }
  854 
  855         *vpp = vp;
  856         return (0);
  857 }
  858 
  859 void
  860 sd_attrs_to_i_attrs(uint16_t sd_attrs, struct reiserfs_node *ip)
  861 {
  862 
  863         if (reiserfs_attrs(ip->i_reiserfs)) {
  864 #if 0
  865                 if (sd_attrs & REISERFS_SYNC_FL)
  866                         ip->i_flags |= S_SYNC;
  867                 else
  868                         ip->i_flags &= ~S_SYNC;
  869 #endif
  870                 if (sd_attrs & REISERFS_IMMUTABLE_FL)
  871                         ip->i_flags |= IMMUTABLE;
  872                 else
  873                         ip->i_flags &= ~IMMUTABLE;
  874                 if (sd_attrs & REISERFS_APPEND_FL)
  875                         ip->i_flags |= APPEND;
  876                 else
  877                         ip->i_flags &= ~APPEND;
  878 #if 0
  879                 if (sd_attrs & REISERFS_NOATIME_FL)
  880                         ip->i_flags |= S_NOATIME;
  881                 else
  882                         ip->i_flags &= ~S_NOATIME;
  883                 if (sd_attrs & REISERFS_NOTAIL_FL)
  884                         REISERFS_I(ip)->i_flags |= i_nopack_mask;
  885                 else
  886                         REISERFS_I(ip)->i_flags &= ~i_nopack_mask;
  887 #endif
  888         }
  889 }
  890 
  891 void
  892 i_attrs_to_sd_attrs(struct reiserfs_node *ip, uint16_t *sd_attrs)
  893 {
  894 
  895         if (reiserfs_attrs(ip->i_reiserfs)) {
  896 #if 0
  897                 if (ip->i_flags & S_SYNC)
  898                         *sd_attrs |= REISERFS_SYNC_FL;
  899                 else
  900                         *sd_attrs &= ~REISERFS_SYNC_FL;
  901 #endif
  902                 if (ip->i_flags & IMMUTABLE)
  903                         *sd_attrs |= REISERFS_IMMUTABLE_FL;
  904                 else
  905                         *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
  906                 if (ip->i_flags & APPEND)
  907                         *sd_attrs |= REISERFS_APPEND_FL;
  908                 else
  909                         *sd_attrs &= ~REISERFS_APPEND_FL;
  910 #if 0
  911                 if (ip->i_flags & S_NOATIME)
  912                         *sd_attrs |= REISERFS_NOATIME_FL;
  913                 else
  914                         *sd_attrs &= ~REISERFS_NOATIME_FL;
  915                 if (REISERFS_I(ip)->i_flags & i_nopack_mask)
  916                         *sd_attrs |= REISERFS_NOTAIL_FL;
  917                 else
  918                         *sd_attrs &= ~REISERFS_NOTAIL_FL;
  919 #endif
  920         }
  921 }

Cache object: 3f3f87179283f09971b2444d8bc65c53


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.