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