]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/gnu/fs/reiserfs/reiserfs_vfsops.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / gnu / fs / reiserfs / reiserfs_vfsops.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 <jspedron@club-internet.fr>
6  * 
7  * $FreeBSD$
8  */
9
10 #include <gnu/fs/reiserfs/reiserfs_fs.h>
11
12 const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
13 const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
14 const char reiserfs_jr_magic_string[]  = REISER2FS_JR_SUPER_MAGIC_STRING;
15
16 /*
17  * Default recommended I/O size is 128k. There might be broken
18  * applications that are confused by this. Use nolargeio mount option to
19  * get usual i/o size = PAGE_SIZE.
20  */
21 int reiserfs_default_io_size = 128 * 1024;
22
23 static vfs_cmount_t     reiserfs_cmount;
24 static vfs_fhtovp_t     reiserfs_fhtovp;
25 static vfs_mount_t      reiserfs_mount;
26 static vfs_root_t       reiserfs_root;
27 static vfs_statfs_t     reiserfs_statfs;
28 static vfs_unmount_t    reiserfs_unmount;
29
30 static int      reiserfs_mountfs(struct vnode *devvp, struct mount *mp,
31                     struct thread *td);
32 static void     load_bitmap_info_data(struct reiserfs_sb_info *sbi,
33                     struct reiserfs_bitmap_info *bi);
34 static int      read_bitmaps(struct reiserfs_mount *rmp);
35 static int      read_old_bitmaps(struct reiserfs_mount *rmp);
36 static int      read_super_block(struct reiserfs_mount *rmp, int offset);
37 static hashf_t  hash_function(struct reiserfs_mount *rmp);
38
39 static int      get_root_node(struct reiserfs_mount *rmp,
40                     struct reiserfs_node **root);
41 uint32_t        find_hash_out(struct reiserfs_mount *rmp);
42
43 MALLOC_DEFINE(M_REISERFSMNT, "reiserfs_mount", "ReiserFS mount structure");
44 MALLOC_DEFINE(M_REISERFSPATH, "reiserfs_path", "ReiserFS path structure");
45 MALLOC_DEFINE(M_REISERFSNODE, "reiserfs_node", "ReiserFS vnode private part");
46
47 /* -------------------------------------------------------------------
48  * VFS operations
49  * -------------------------------------------------------------------*/
50
51 static int
52 reiserfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
53 {
54         struct reiserfs_args args;
55         int error;
56
57         error = copyin(data, &args, sizeof(args));
58         if (error)
59                 return (error);
60
61         ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
62         ma = mount_arg(ma, "export", &args.export, sizeof args.export);
63
64         error = kernel_mount(ma, flags);
65
66         return (error);
67 }
68
69 /*
70  * Mount system call
71  */
72 static int
73 reiserfs_mount(struct mount *mp, struct thread *td)
74 {
75         size_t size;
76         int error, len;
77         mode_t accessmode;
78         char *path, *fspec;
79         struct vnode *devvp;
80         struct vfsoptlist *opts;
81         struct reiserfs_mount *rmp;
82         struct reiserfs_sb_info *sbi;
83         struct nameidata nd, *ndp = &nd;
84
85         if (!(mp->mnt_flag & MNT_RDONLY))
86                 return EROFS;
87
88         /* Get the new options passed to mount */
89         opts = mp->mnt_optnew;
90
91         /* `fspath' contains the mount point (eg. /mnt/linux); REQUIRED */
92         vfs_getopt(opts, "fspath", (void **)&path, NULL);
93         reiserfs_log(LOG_INFO, "mount point is `%s'\n", path);
94
95         /* `from' contains the device name (eg. /dev/ad0s1); REQUIRED */
96         fspec = NULL;
97         error = vfs_getopt(opts, "from", (void **)&fspec, &len);
98         if (!error && fspec[len - 1] != '\0')
99                 return (EINVAL);
100         reiserfs_log(LOG_INFO, "device is `%s'\n", fspec);
101
102         /* Handle MNT_UPDATE (mp->mnt_flag) */
103         if (mp->mnt_flag & MNT_UPDATE) {
104                 /* For now, only NFS export is supported. */
105                 if (vfs_flagopt(opts, "export", NULL, 0))
106                         return (0);
107         }
108
109         /* Not an update, or updating the name: look up the name
110          * and verify that it refers to a sensible disk device. */
111         if (fspec == NULL)
112                 return (EINVAL);
113
114         NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td);
115         if ((error = namei(ndp)) != 0)
116                 return (error);
117         NDFREE(ndp, NDF_ONLY_PNBUF);
118         devvp = ndp->ni_vp;
119
120         if (!vn_isdisk(devvp, &error)) {
121                 vput(devvp);
122                 return (error);
123         }
124
125         /* If mount by non-root, then verify that user has necessary
126          * permissions on the device. */
127         accessmode = VREAD;
128         if ((mp->mnt_flag & MNT_RDONLY) == 0)
129                 accessmode |= VWRITE;
130         error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td);
131         if (error)
132                 error = priv_check(td, PRIV_VFS_MOUNT_PERM);
133         if (error) {
134                 vput(devvp);
135                 return (error);
136         }
137
138         if ((mp->mnt_flag & MNT_UPDATE) == 0) {
139                 error = reiserfs_mountfs(devvp, mp, td);
140         } else {
141                 /* TODO Handle MNT_UPDATE */
142                 vput(devvp);
143                 return (EOPNOTSUPP);
144         }
145
146         if (error) {
147                 vrele(devvp);
148                 return (error);
149         }
150
151         rmp = VFSTOREISERFS(mp);
152         sbi = rmp->rm_reiserfs;
153
154         /*
155          * Note that this strncpy() is ok because of a check at the start
156          * of reiserfs_mount().
157          */
158         reiserfs_log(LOG_DEBUG, "prepare statfs data\n");
159         (void)copystr(fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
160         bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
161         (void)reiserfs_statfs(mp, &mp->mnt_stat, td);
162
163         reiserfs_log(LOG_DEBUG, "done\n");
164         return (0);
165 }
166
167 /*
168  * Unmount system call
169  */
170 static int
171 reiserfs_unmount(struct mount *mp, int mntflags, struct thread *td)
172 {
173         int error, flags = 0;
174         struct reiserfs_mount *rmp;
175         struct reiserfs_sb_info *sbi;
176
177         reiserfs_log(LOG_DEBUG, "get private data\n");
178         rmp = VFSTOREISERFS(mp);
179         sbi = rmp->rm_reiserfs;
180
181         /* Flangs handling */
182         reiserfs_log(LOG_DEBUG, "handle mntflags\n");
183         if (mntflags & MNT_FORCE)
184                 flags |= FORCECLOSE;
185
186         /* Flush files -> vflush */
187         reiserfs_log(LOG_DEBUG, "flush vnodes\n");
188         if ((error = vflush(mp, 0, flags, td)))
189                 return (error);
190
191         /* XXX Super block update */
192
193         if (sbi) {
194                 if (SB_AP_BITMAP(sbi)) {
195                         int i;
196                         reiserfs_log(LOG_DEBUG,
197                             "release bitmap buffers (total: %d)\n",
198                             SB_BMAP_NR(sbi));
199                         for (i = 0; i < SB_BMAP_NR(sbi); i++) {
200                                 if (SB_AP_BITMAP(sbi)[i].bp_data) {
201                                         free(SB_AP_BITMAP(sbi)[i].bp_data,
202                                             M_REISERFSMNT);
203                                         SB_AP_BITMAP(sbi)[i].bp_data = NULL;
204                                 }
205                         }
206
207                         reiserfs_log(LOG_DEBUG, "free bitmaps structure\n");
208                         free(SB_AP_BITMAP(sbi), M_REISERFSMNT);
209                         SB_AP_BITMAP(sbi) = NULL;
210                 }
211
212                 if (sbi->s_rs) {
213                         reiserfs_log(LOG_DEBUG, "free super block data\n");
214                         free(sbi->s_rs, M_REISERFSMNT);
215                         sbi->s_rs = NULL;
216                 }
217         }
218
219         reiserfs_log(LOG_DEBUG, "close device\n");
220 #if defined(si_mountpoint)
221         rmp->rm_devvp->v_rdev->si_mountpoint = NULL;
222 #endif
223
224         DROP_GIANT();
225         g_topology_lock();
226         g_wither_geom_close(rmp->rm_cp->geom, ENXIO);
227         g_topology_unlock();
228         PICKUP_GIANT();
229         vrele(rmp->rm_devvp);
230
231         if (sbi) {
232                 reiserfs_log(LOG_DEBUG, "free sbi\n");
233                 free(sbi, M_REISERFSMNT);
234                 sbi = rmp->rm_reiserfs = NULL;
235         }
236         if (rmp) {
237                 reiserfs_log(LOG_DEBUG, "free rmp\n");
238                 free(rmp, M_REISERFSMNT);
239                 rmp = NULL;
240         }
241
242         mp->mnt_data  = (qaddr_t)0;
243         MNT_ILOCK(mp);
244         mp->mnt_flag &= ~MNT_LOCAL;
245         MNT_IUNLOCK(mp);
246
247         reiserfs_log(LOG_DEBUG, "done\n");
248         return (error);
249 }
250
251 /*
252  * Return the root of a filesystem.
253  */ 
254 static int
255 reiserfs_root(struct mount *mp, int flags, struct vnode **vpp,
256     struct thread *td)
257 {
258         int error;
259         struct vnode *vp;
260         struct cpu_key rootkey;
261
262         rootkey.on_disk_key.k_dir_id = REISERFS_ROOT_PARENT_OBJECTID;
263         rootkey.on_disk_key.k_objectid = REISERFS_ROOT_OBJECTID;
264
265         error = reiserfs_iget(mp, &rootkey, &vp, td);
266
267         if (error == 0)
268                 *vpp = vp;
269         return (error);
270 }
271
272 /*
273  * The statfs syscall
274  */
275 static int
276 reiserfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
277 {
278         struct reiserfs_mount *rmp;
279         struct reiserfs_sb_info *sbi;
280         struct reiserfs_super_block *rs;
281
282         reiserfs_log(LOG_DEBUG, "get private data\n");
283         rmp = VFSTOREISERFS(mp);
284         sbi = rmp->rm_reiserfs;
285         rs  = sbi->s_rs;
286
287         reiserfs_log(LOG_DEBUG, "fill statfs structure\n");
288         sbp->f_bsize  = sbi->s_blocksize;
289         sbp->f_iosize = sbp->f_bsize;
290         sbp->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
291         sbp->f_bfree  = sb_free_blocks(rs);
292         sbp->f_bavail = sbp->f_bfree;
293         sbp->f_files  = 0;
294         sbp->f_ffree  = 0;
295         reiserfs_log(LOG_DEBUG, "  block size   = %ju\n",
296             (intmax_t)sbp->f_bsize);
297         reiserfs_log(LOG_DEBUG, "  IO size      = %ju\n",
298             (intmax_t)sbp->f_iosize);
299         reiserfs_log(LOG_DEBUG, "  block count  = %ju\n",
300             (intmax_t)sbp->f_blocks);
301         reiserfs_log(LOG_DEBUG, "  free blocks  = %ju\n",
302             (intmax_t)sbp->f_bfree);
303         reiserfs_log(LOG_DEBUG, "  avail blocks = %ju\n",
304             (intmax_t)sbp->f_bavail);
305         reiserfs_log(LOG_DEBUG, "...done\n");
306
307         if (sbp != &mp->mnt_stat) {
308                 reiserfs_log(LOG_DEBUG, "copying monut point info\n");
309                 sbp->f_type = mp->mnt_vfc->vfc_typenum;
310                 bcopy((caddr_t)mp->mnt_stat.f_mntonname,
311                     (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
312                 bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
313                     (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
314                 reiserfs_log(LOG_DEBUG, "  mount from: %s\n",
315                     sbp->f_mntfromname);
316                 reiserfs_log(LOG_DEBUG, "  mount on:   %s\n",
317                     sbp->f_mntonname);
318                 reiserfs_log(LOG_DEBUG, "...done\n");
319         }
320
321         return (0);
322 }
323
324 /*
325  * File handle to vnode
326  *
327  * Have to be really careful about stale file handles:
328  * - check that the inode key is valid
329  * - call ffs_vget() to get the locked inode
330  * - check for an unallocated inode (i_mode == 0)
331  * - check that the given client host has export rights and return
332  *   those rights via. exflagsp and credanonp
333  */
334 static int
335 reiserfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
336 {
337         int error;
338         struct rfid *rfhp;
339         struct vnode *nvp;
340         struct cpu_key key;
341         struct reiserfs_node *ip;
342         struct reiserfs_sb_info *sbi;
343         struct thread *td = curthread;
344
345         rfhp = (struct rfid *)fhp;
346         sbi  = VFSTOREISERFS(mp)->rm_reiserfs;
347
348         /* Check that the key is valid */
349         if (rfhp->rfid_dirid < REISERFS_ROOT_PARENT_OBJECTID &&
350             rfhp->rfid_objectid < REISERFS_ROOT_OBJECTID)
351                 return (ESTALE);
352
353         reiserfs_log(LOG_DEBUG,
354             "file handle key is (dirid=%d, objectid=%d)\n",
355             rfhp->rfid_dirid, rfhp->rfid_objectid);
356         key.on_disk_key.k_dir_id   = rfhp->rfid_dirid;
357         key.on_disk_key.k_objectid = rfhp->rfid_objectid;
358
359         reiserfs_log(LOG_DEBUG, "read this inode\n");
360         error = reiserfs_iget(mp, &key, &nvp, td);
361         if (error) {
362                 *vpp = NULLVP;
363                 return (error);
364         }
365
366         reiserfs_log(LOG_DEBUG, "check validity\n");
367         ip = VTOI(nvp);
368         if (ip->i_mode == 0 || ip->i_generation != rfhp->rfid_gen) {
369                 vput(nvp);
370                 *vpp = NULLVP;
371                 return (ESTALE);
372         }
373
374         reiserfs_log(LOG_DEBUG, "return it\n");
375         *vpp = nvp;
376         return (0);
377 }
378
379 /* -------------------------------------------------------------------
380  * Functions for the journal
381  * -------------------------------------------------------------------*/
382
383 int
384 is_reiserfs_3_5(struct reiserfs_super_block *rs)
385 {
386
387         return (!strncmp(rs->s_v1.s_magic, reiserfs_3_5_magic_string,
388             strlen(reiserfs_3_5_magic_string)));
389 }
390
391 int
392 is_reiserfs_3_6(struct reiserfs_super_block *rs)
393 {
394
395         return (!strncmp(rs->s_v1.s_magic, reiserfs_3_6_magic_string,
396             strlen(reiserfs_3_6_magic_string)));
397 }
398
399 int
400 is_reiserfs_jr(struct reiserfs_super_block *rs)
401 {
402
403         return (!strncmp(rs->s_v1.s_magic, reiserfs_jr_magic_string,
404             strlen(reiserfs_jr_magic_string)));
405 }
406
407 static int
408 is_any_reiserfs_magic_string(struct reiserfs_super_block *rs)
409 {
410
411         return ((is_reiserfs_3_5(rs) || is_reiserfs_3_6(rs) ||
412             is_reiserfs_jr(rs)));
413 }
414
415 /* -------------------------------------------------------------------
416  * Internal functions
417  * -------------------------------------------------------------------*/
418
419 /*
420  * Common code for mount and mountroot
421  */ 
422 static int
423 reiserfs_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td)
424 {
425         int error, old_format = 0;
426         struct reiserfs_mount *rmp;
427         struct reiserfs_sb_info *sbi;
428         struct reiserfs_super_block *rs;
429         struct cdev *dev = devvp->v_rdev;
430
431 #if (__FreeBSD_version >= 600000)
432         struct g_consumer *cp;
433         struct bufobj *bo;
434 #endif
435
436         //ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
437
438 #if (__FreeBSD_version < 600000)
439         /*
440          * Disallow multiple mounts of the same device.
441          * Disallow mounting of a device that is currently in use
442          * (except for root, which might share swap device for miniroot).
443          * Flush out any old buffers remaining from a previous use.
444          */
445         if ((error = vfs_mountedon(devvp)) != 0)
446                 return (error);
447         if (vcount(devvp) > 1)
448                 return (EBUSY);
449
450         error = vinvalbuf(devvp, V_SAVE, td->td_ucred, td, 0, 0);
451         if (error) {
452                 VOP_UNLOCK(devvp, 0, td);
453                 return (error);
454         }
455
456         /*
457          * Open the device in read-only, 'cause we don't support write
458          * for now
459          */
460         error = VOP_OPEN(devvp, FREAD, FSCRED, td, NULL);
461         VOP_UNLOCK(devvp, 0, td);
462         if (error)
463                 return (error);
464 #else
465         DROP_GIANT();
466         g_topology_lock();
467         error = g_vfs_open(devvp, &cp, "reiserfs", /* read-only */ 0);
468         g_topology_unlock();
469         PICKUP_GIANT();
470         VOP_UNLOCK(devvp, 0, td);
471         if (error)
472                 return (error);
473
474         bo = &devvp->v_bufobj;
475         bo->bo_private = cp;
476         bo->bo_ops = g_vfs_bufops;
477 #endif
478
479         if (devvp->v_rdev->si_iosize_max != 0)
480                 mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
481         if (mp->mnt_iosize_max > MAXPHYS)
482                 mp->mnt_iosize_max = MAXPHYS;
483
484         rmp = NULL;
485         sbi = NULL;
486
487         /* rmp contains any information about this specific mount */
488         rmp = malloc(sizeof *rmp, M_REISERFSMNT, M_WAITOK | M_ZERO);
489         if (!rmp) {
490                 error = (ENOMEM);
491                 goto out;
492         }
493         sbi = malloc(sizeof *sbi, M_REISERFSMNT, M_WAITOK | M_ZERO);
494         if (!sbi) {
495                 error = (ENOMEM);
496                 goto out;
497         }
498         rmp->rm_reiserfs = sbi;
499         rmp->rm_mountp   = mp;
500         rmp->rm_devvp    = devvp;
501         rmp->rm_dev      = dev;
502 #if (__FreeBSD_version >= 600000)
503         rmp->rm_bo       = &devvp->v_bufobj;
504         rmp->rm_cp       = cp;
505 #endif
506
507         /* Set default values for options: non-aggressive tails */
508         REISERFS_SB(sbi)->s_mount_opt = (1 << REISERFS_SMALLTAIL);
509         REISERFS_SB(sbi)->s_rd_only   = 1;
510         REISERFS_SB(sbi)->s_devvp     = devvp;
511
512         /* Read the super block */
513         if ((error = read_super_block(rmp, REISERFS_OLD_DISK_OFFSET)) == 0) {
514                 /* The read process succeeded, it's an old format */
515                 old_format = 1;
516         } else if ((error = read_super_block(rmp, REISERFS_DISK_OFFSET)) != 0) {
517                 reiserfs_log(LOG_ERR, "can not find a ReiserFS filesystem\n");
518                 goto out;
519         }
520
521         rs = SB_DISK_SUPER_BLOCK(sbi);
522
523         /*
524          * Let's do basic sanity check to verify that underlying device is
525          * not smaller than the filesystem. If the check fails then abort and
526          * scream, because bad stuff will happen otherwise.
527          */
528 #if 0
529         if (s->s_bdev && s->s_bdev->bd_inode &&
530             i_size_read(s->s_bdev->bd_inode) <
531             sb_block_count(rs) * sb_blocksize(rs)) {
532                 reiserfs_log(LOG_ERR,
533                     "reiserfs: filesystem cannot be mounted because it is "
534                     "bigger than the device.\n");
535                 reiserfs_log(LOG_ERR, "reiserfs: you may need to run fsck "
536                     "rr may be you forgot to reboot after fdisk when it "
537                     "told you to.\n");
538                 goto out;
539         }
540 #endif
541
542         /*
543          * XXX This is from the original Linux code, but why affecting 2 values
544          * to the same variable?
545          */
546         sbi->s_mount_state = SB_REISERFS_STATE(sbi);
547         sbi->s_mount_state = REISERFS_VALID_FS;
548
549         if ((error = (old_format ?
550             read_old_bitmaps(rmp) : read_bitmaps(rmp)))) {
551                 reiserfs_log(LOG_ERR, "unable to read bitmap\n");
552                 goto out;
553         }
554
555         /* Make data=ordered the default */
556         if (!reiserfs_data_log(sbi) && !reiserfs_data_ordered(sbi) &&
557             !reiserfs_data_writeback(sbi)) {
558                 REISERFS_SB(sbi)->s_mount_opt |= (1 << REISERFS_DATA_ORDERED);
559         }
560
561         if (reiserfs_data_log(sbi)) {
562                 reiserfs_log(LOG_INFO, "using journaled data mode\n");
563         } else if (reiserfs_data_ordered(sbi)) {
564                 reiserfs_log(LOG_INFO, "using ordered data mode\n");
565         } else {
566                 reiserfs_log(LOG_INFO, "using writeback data mode\n");
567         }
568
569         /* TODO Not yet supported */
570 #if 0
571         if(journal_init(sbi, jdev_name, old_format, commit_max_age)) {
572                 reiserfs_log(LOG_ERR, "unable to initialize journal space\n");
573                 goto out;
574         } else {
575                 jinit_done = 1 ; /* once this is set, journal_release must
576                                     be called if we error out of the mount */
577         }
578
579         if (reread_meta_blocks(sbi)) {
580                 reiserfs_log(LOG_ERR,
581                     "unable to reread meta blocks after journal init\n");
582                 goto out;
583         }
584 #endif
585
586         /* Define and initialize hash function */
587         sbi->s_hash_function = hash_function(rmp);
588
589         if (sbi->s_hash_function == NULL) {
590                 reiserfs_log(LOG_ERR, "couldn't determined hash function\n");
591                 error = (EINVAL);
592                 goto out;
593         }
594
595         if (is_reiserfs_3_5(rs) ||
596             (is_reiserfs_jr(rs) && SB_VERSION(sbi) == REISERFS_VERSION_1))
597                 bit_set(&(sbi->s_properties), REISERFS_3_5);
598         else
599                 bit_set(&(sbi->s_properties), REISERFS_3_6);
600
601         mp->mnt_data = (qaddr_t)rmp;
602         mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
603         mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
604         MNT_ILOCK(mp);
605         mp->mnt_flag |= MNT_LOCAL;
606         MNT_IUNLOCK(mp);
607 #if defined(si_mountpoint)
608         devvp->v_rdev->si_mountpoint = mp;
609 #endif
610
611         return (0);
612
613 out:
614         reiserfs_log(LOG_INFO, "*** error during mount ***\n");
615         if (sbi) {
616                 if (SB_AP_BITMAP(sbi)) {
617                         int i;
618                         for (i = 0; i < SB_BMAP_NR(sbi); i++) {
619                                 if (!SB_AP_BITMAP(sbi)[i].bp_data)
620                                         break;
621                                 free(SB_AP_BITMAP(sbi)[i].bp_data, M_REISERFSMNT);
622                         }
623                         free(SB_AP_BITMAP(sbi), M_REISERFSMNT);
624                 }
625
626                 if (sbi->s_rs) {
627                         free(sbi->s_rs, M_REISERFSMNT);
628                         sbi->s_rs = NULL;
629                 }
630         }
631
632 #if (__FreeBSD_version < 600000)
633         (void)VOP_CLOSE(devvp, FREAD, NOCRED, td);
634 #else
635         if (cp != NULL) {
636                 DROP_GIANT();
637                 g_topology_lock();
638                 g_wither_geom_close(cp->geom, ENXIO);
639                 g_topology_unlock();
640                 PICKUP_GIANT();
641         }
642 #endif
643
644         if (sbi)
645                 free(sbi, M_REISERFSMNT);
646         if (rmp)
647                 free(rmp, M_REISERFSMNT);
648         return (error);
649 }
650
651 /*
652  * Read the super block
653  */
654 static int
655 read_super_block(struct reiserfs_mount *rmp, int offset)
656 {
657         struct buf *bp;
658         int error, bits;
659         struct reiserfs_super_block *rs;
660         struct reiserfs_sb_info *sbi;
661         uint16_t fs_blocksize;
662
663         if (offset == REISERFS_OLD_DISK_OFFSET) {
664                 reiserfs_log(LOG_DEBUG,
665                     "reiserfs/super: read old format super block\n");
666         } else {
667                 reiserfs_log(LOG_DEBUG,
668                     "reiserfs/super: read new format super block\n");
669         }
670
671         /* Read the super block */
672         if ((error = bread(rmp->rm_devvp, offset * btodb(REISERFS_BSIZE),
673             REISERFS_BSIZE, NOCRED, &bp)) != 0) {
674                 reiserfs_log(LOG_ERR, "can't read device\n");
675                 return (error);
676         }
677
678         /* Get it from the buffer data */
679         rs = (struct reiserfs_super_block *)bp->b_data;
680         if (!is_any_reiserfs_magic_string(rs)) {
681                 brelse(bp);
682                 return (EINVAL);
683         }
684
685         fs_blocksize = sb_blocksize(rs);
686         brelse(bp);
687         bp = NULL;
688
689         if (fs_blocksize <= 0) {
690                 reiserfs_log(LOG_ERR, "unexpected null block size");
691                 return (EINVAL);
692         }
693
694         /* Read the super block (for double check)
695          * We can't read the same blkno with a different size: it causes
696          * panic() if INVARIANTS is set. So we keep REISERFS_BSIZE */
697         if ((error = bread(rmp->rm_devvp,
698             offset * REISERFS_BSIZE / fs_blocksize * btodb(fs_blocksize),
699             REISERFS_BSIZE, NOCRED, &bp)) != 0) {
700                 reiserfs_log(LOG_ERR, "can't reread the super block\n");
701                 return (error);
702         }
703
704         rs = (struct reiserfs_super_block *)bp->b_data;
705         if (sb_blocksize(rs) != fs_blocksize) {
706                 reiserfs_log(LOG_ERR, "unexpected block size "
707                     "(found=%u, expected=%u)\n",
708                     sb_blocksize(rs), fs_blocksize);
709                 brelse(bp);
710                 return (EINVAL);
711         }
712
713         reiserfs_log(LOG_DEBUG, "magic: `%s'\n", rs->s_v1.s_magic);
714         reiserfs_log(LOG_DEBUG, "label: `%s'\n", rs->s_label);
715         reiserfs_log(LOG_DEBUG, "block size:     %6d\n", sb_blocksize(rs));
716         reiserfs_log(LOG_DEBUG, "block count:    %6u\n",
717             rs->s_v1.s_block_count);
718         reiserfs_log(LOG_DEBUG, "bitmaps number: %6u\n",
719             rs->s_v1.s_bmap_nr);
720
721         if (rs->s_v1.s_root_block == -1) {
722                 log(LOG_ERR,
723                     "reiserfs: Unfinished reiserfsck --rebuild-tree run "
724                     "detected. Please\n"
725                     "run reiserfsck --rebuild-tree and wait for a "
726                     "completion. If that\n"
727                     "fails, get newer reiserfsprogs package");
728                 brelse(bp);
729                 return (EINVAL);
730         }
731
732         sbi = rmp->rm_reiserfs;
733         sbi->s_blocksize = fs_blocksize;
734
735         for (bits = 9, fs_blocksize >>= 9; fs_blocksize >>= 1; bits++)
736                 ;
737         sbi->s_blocksize_bits = bits;
738
739         /* Copy the buffer and release it */
740         sbi->s_rs = malloc(sizeof *rs, M_REISERFSMNT, M_WAITOK | M_ZERO);
741         if (!sbi->s_rs) {
742                 reiserfs_log(LOG_ERR, "can not read the super block\n");
743                 brelse(bp);
744                 return (ENOMEM);
745         }
746         bcopy(rs, sbi->s_rs, sizeof(struct reiserfs_super_block));
747         brelse(bp);
748
749         if (is_reiserfs_jr(rs)) {
750                 if (sb_version(rs) == REISERFS_VERSION_2)
751                         reiserfs_log(LOG_INFO, "found reiserfs format \"3.6\""
752                             " with non-standard journal");
753                 else if (sb_version(rs) == REISERFS_VERSION_1)
754                         reiserfs_log(LOG_INFO, "found reiserfs format \"3.5\""
755                             " with non-standard journal");
756                 else {
757                         reiserfs_log(LOG_ERR, "found unknown "
758                             "format \"%u\" of reiserfs with non-standard magic",
759                             sb_version(rs));
760                         return (EINVAL);
761                 }
762         } else {
763                 /*
764                  * s_version of standard format may contain incorrect
765                  * information, so we just look at the magic string
766                  */
767                 reiserfs_log(LOG_INFO,
768                     "found reiserfs format \"%s\" with standard journal\n",
769                     is_reiserfs_3_5(rs) ? "3.5" : "3.6");
770         }
771
772         return (0);
773 }
774
775 /*
776  * load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure
777  * from disk.
778  * @sbi - superblock info for this filesystem
779  * @bi  - the bitmap info to be loaded. Requires that bi->bp is valid.
780  *
781  * This routine counts how many free bits there are, finding the first
782  * zero as a side effect. Could also be implemented as a loop of
783  * test_bit() calls, or a loop of find_first_zero_bit() calls. This
784  * implementation is similar to find_first_zero_bit(), but doesn't
785  * return after it finds the first bit. Should only be called on fs
786  * mount, but should be fairly efficient anyways.
787  *
788  * bi->first_zero_hint is considered unset if it == 0, since the bitmap
789  * itself will invariably occupt block 0 represented in the bitmap. The
790  * only exception to this is when free_count also == 0, since there will
791  * be no free blocks at all.
792  */
793 static void
794 load_bitmap_info_data(struct reiserfs_sb_info *sbi,
795     struct reiserfs_bitmap_info *bi)
796 {
797         unsigned long *cur;
798
799         cur = (unsigned long *)bi->bp_data;
800         while ((char *)cur < (bi->bp_data + sbi->s_blocksize)) {
801                 /*
802                  * No need to scan if all 0's or all 1's.
803                  * Since we're only counting 0's, we can simply ignore
804                  * all 1's
805                  */
806                 if (*cur == 0) {
807                         if (bi->first_zero_hint == 0) {
808                                 bi->first_zero_hint =
809                                     ((char *)cur - bi->bp_data) << 3;
810                         }
811                         bi->free_count += sizeof(unsigned long) * 8;
812                 } else if (*cur != ~0L) {
813                         int b;
814
815                         for (b = 0; b < sizeof(unsigned long) * 8; b++) {
816                                 if (!reiserfs_test_le_bit(b, cur)) {
817                                         bi->free_count++;
818                                         if (bi->first_zero_hint == 0)
819                                                 bi->first_zero_hint =
820                                                     (((char *)cur -
821                                                       bi->bp_data) << 3) + b;
822                                 }
823                         }
824                 }
825                 cur++;
826         }
827 }
828
829 /*
830  * Read the bitmaps
831  */
832 static int
833 read_bitmaps(struct reiserfs_mount *rmp)
834 {
835         int i, bmap_nr;
836         struct buf *bp = NULL;
837         struct reiserfs_sb_info *sbi = rmp->rm_reiserfs;
838
839         /* Allocate memory for the table of bitmaps */
840         SB_AP_BITMAP(sbi) =
841             malloc(sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(sbi),
842                 M_REISERFSMNT, M_WAITOK | M_ZERO);
843         if (!SB_AP_BITMAP(sbi))
844                 return (ENOMEM);
845
846         /* Read all the bitmaps */
847         for (i = 0,
848             bmap_nr = (REISERFS_DISK_OFFSET_IN_BYTES / sbi->s_blocksize + 1) *
849             btodb(sbi->s_blocksize);
850             i < SB_BMAP_NR(sbi); i++, bmap_nr = sbi->s_blocksize * 8 * i) {
851                 SB_AP_BITMAP(sbi)[i].bp_data = malloc(sbi->s_blocksize,
852                     M_REISERFSMNT, M_WAITOK | M_ZERO);
853                 if (!SB_AP_BITMAP(sbi)[i].bp_data)
854                         return (ENOMEM);
855                 bread(rmp->rm_devvp, bmap_nr, sbi->s_blocksize, NOCRED, &bp);
856                 bcopy(bp->b_data, SB_AP_BITMAP(sbi)[i].bp_data,
857                     sbi->s_blocksize);
858                 brelse(bp);
859                 bp = NULL;
860
861                 /*if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh))
862                         ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh);*/
863         }
864
865         for (i = 0; i < SB_BMAP_NR(sbi); i++) {
866                 /*if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
867                   reiserfs_warning(s,"sh-2029: reiserfs read_bitmaps: "
868                   "bitmap block (#%lu) reading failed",
869                   SB_AP_BITMAP(s)[i].bh->b_blocknr);
870                   for (i = 0; i < SB_BMAP_NR(s); i++)
871                   brelse(SB_AP_BITMAP(s)[i].bh);
872                   vfree(SB_AP_BITMAP(s));
873                   SB_AP_BITMAP(s) = NULL;
874                   return 1;
875                   }*/
876                 load_bitmap_info_data(sbi, SB_AP_BITMAP(sbi) + i);
877                 reiserfs_log(LOG_DEBUG,
878                     "%d free blocks (starting at block %ld)\n",
879                     SB_AP_BITMAP(sbi)[i].free_count,
880                     (long)SB_AP_BITMAP(sbi)[i].first_zero_hint);
881         }
882
883         return (0);
884 }
885
886 // TODO Not supported
887 static int
888 read_old_bitmaps(struct reiserfs_mount *rmp)
889 {
890
891         return (EOPNOTSUPP);
892 #if 0
893         int i;
894         struct reiserfs_sb_info *sbi = rmp->rm_reiserfs;
895         struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(sbi);
896
897         /* First of bitmap blocks */
898         int bmp1 = (REISERFS_OLD_DISK_OFFSET / sbi->s_blocksize) *
899             btodb(sbi->s_blocksize);
900
901         /* Read true bitmap */
902         SB_AP_BITMAP(sbi) =
903             malloc(sizeof (struct reiserfs_buffer_info *) * sb_bmap_nr(rs),
904                 M_REISERFSMNT, M_WAITOK | M_ZERO);
905         if (!SB_AP_BITMAP(sbi))
906                 return 1;
907
908         for (i = 0; i < sb_bmap_nr(rs); i ++) {
909                 SB_AP_BITMAP(sbi)[i].bp = getblk(rmp->rm_devvp,
910                     (bmp1 + i) * btodb(sbi->s_blocksize), sbi->s_blocksize, 0, 0, 0);
911                 if (!SB_AP_BITMAP(sbi)[i].bp)
912                         return 1;
913                 load_bitmap_info_data(sbi, SB_AP_BITMAP(sbi) + i);
914         }
915
916         return 0;
917 #endif
918 }
919
920 /* -------------------------------------------------------------------
921  * Hash detection stuff
922  * -------------------------------------------------------------------*/
923
924 static int
925 get_root_node(struct reiserfs_mount *rmp, struct reiserfs_node **root)
926 {
927         struct reiserfs_node *ip;
928         struct reiserfs_iget_args args;
929
930         /* Allocate the node structure */
931         reiserfs_log(LOG_DEBUG, "malloc(struct reiserfs_node)\n");
932         MALLOC(ip, struct reiserfs_node *, sizeof(struct reiserfs_node),
933             M_REISERFSNODE, M_WAITOK | M_ZERO);
934
935         /* Fill the structure */
936         reiserfs_log(LOG_DEBUG, "filling *ip\n");
937         ip->i_dev      = rmp->rm_dev;
938         ip->i_number   = REISERFS_ROOT_OBJECTID;
939         ip->i_ino      = REISERFS_ROOT_PARENT_OBJECTID;
940         ip->i_reiserfs = rmp->rm_reiserfs;
941
942         /* Read the inode */
943         args.objectid = ip->i_number;
944         args.dirid    = ip->i_ino;
945         reiserfs_log(LOG_DEBUG, "call reiserfs_read_locked_inode("
946             "objectid=%d,dirid=%d)\n", args.objectid, args.dirid);
947         reiserfs_read_locked_inode(ip, &args);
948
949         ip->i_devvp = rmp->rm_devvp;
950         //XXX VREF(ip->i_devvp); Is it necessary ?
951
952         *root = ip;
953         return (0);
954 }
955
956 /*
957  * If root directory is empty - we set default - Yura's - hash and warn
958  * about it.
959  * FIXME: we look for only one name in a directory. If tea and yura both
960  * have the same value - we ask user to send report to the mailing list
961  */
962 uint32_t find_hash_out(struct reiserfs_mount *rmp)
963 {
964         int retval;
965         struct cpu_key key;
966         INITIALIZE_PATH(path);
967         struct reiserfs_node *ip;
968         struct reiserfs_sb_info *sbi;
969         struct reiserfs_dir_entry de;
970         uint32_t hash = DEFAULT_HASH;
971
972         get_root_node(rmp, &ip);
973         if (!ip)
974                 return (UNSET_HASH);
975
976         sbi = rmp->rm_reiserfs;
977
978         do {
979                 uint32_t teahash, r5hash, yurahash;
980
981                 reiserfs_log(LOG_DEBUG, "make_cpu_key\n");
982                 make_cpu_key(&key, ip, ~0, TYPE_DIRENTRY, 3);
983                 reiserfs_log(LOG_DEBUG, "search_by_entry_key for "
984                     "key(objectid=%d,dirid=%d)\n",
985                     key.on_disk_key.k_objectid, key.on_disk_key.k_dir_id);
986                 retval = search_by_entry_key(sbi, &key, &path, &de);
987                 if (retval == IO_ERROR) {
988                         pathrelse(&path);
989                         return (UNSET_HASH);
990                 }
991                 if (retval == NAME_NOT_FOUND)
992                         de.de_entry_num--;
993
994                 reiserfs_log(LOG_DEBUG, "name found\n");
995
996                 set_de_name_and_namelen(&de);
997
998                 if (deh_offset(&(de.de_deh[de.de_entry_num])) == DOT_DOT_OFFSET) {
999                         /* Allow override in this case */
1000                         if (reiserfs_rupasov_hash(sbi)) {
1001                                 hash = YURA_HASH;
1002                         }
1003                         reiserfs_log(LOG_DEBUG,
1004                             "FS seems to be empty, autodetect "
1005                             "is using the default hash");
1006                         break;
1007                 }
1008
1009                 r5hash   = GET_HASH_VALUE(r5_hash(de.de_name, de.de_namelen));
1010                 teahash  = GET_HASH_VALUE(keyed_hash(de.de_name,
1011                     de.de_namelen));
1012                 yurahash = GET_HASH_VALUE(yura_hash(de.de_name, de.de_namelen));
1013                 if (((teahash == r5hash) &&
1014                     (GET_HASH_VALUE(
1015                      deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash)) ||
1016                     ((teahash == yurahash) &&
1017                      (yurahash ==
1018                       GET_HASH_VALUE(
1019                       deh_offset(&(de.de_deh[de.de_entry_num]))))) ||
1020                     ((r5hash == yurahash) &&
1021                      (yurahash ==
1022                       GET_HASH_VALUE(
1023                       deh_offset(&(de.de_deh[de.de_entry_num])))))) {
1024                         reiserfs_log(LOG_ERR,
1025                             "unable to automatically detect hash "
1026                             "function. Please mount with -o "
1027                             "hash={tea,rupasov,r5}");
1028                         hash = UNSET_HASH;
1029                         break;
1030                 }
1031
1032                 if (GET_HASH_VALUE(
1033                     deh_offset(&(de.de_deh[de.de_entry_num]))) == yurahash) {
1034                         reiserfs_log(LOG_DEBUG, "detected YURA hash\n");
1035                         hash = YURA_HASH;
1036                 } else if (GET_HASH_VALUE(
1037                     deh_offset(&(de.de_deh[de.de_entry_num]))) == teahash) {
1038                         reiserfs_log(LOG_DEBUG, "detected TEA hash\n");
1039                         hash = TEA_HASH;
1040                 } else if (GET_HASH_VALUE(
1041                     deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) {
1042                         reiserfs_log(LOG_DEBUG, "detected R5 hash\n");
1043                         hash = R5_HASH;
1044                 } else {
1045                         reiserfs_log(LOG_WARNING, "unrecognised hash function");
1046                         hash = UNSET_HASH;
1047                 }
1048         } while (0);
1049
1050         pathrelse(&path);
1051         return (hash);
1052 }
1053
1054 /* Finds out which hash names are sorted with */
1055 static int
1056 what_hash(struct reiserfs_mount *rmp)
1057 {
1058         uint32_t code;
1059         struct reiserfs_sb_info *sbi = rmp->rm_reiserfs;
1060
1061         find_hash_out(rmp);
1062         code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(sbi));
1063
1064         /*
1065          * reiserfs_hash_detect() == true if any of the hash mount options
1066          * were used. We must check them to make sure the user isn't using a
1067          * bad hash value
1068          */
1069         if (code == UNSET_HASH || reiserfs_hash_detect(sbi))
1070                 code = find_hash_out(rmp);
1071
1072         if (code != UNSET_HASH && reiserfs_hash_detect(sbi)) {
1073                 /*
1074                  * Detection has found the hash, and we must check against
1075                  * the mount options
1076                  */
1077                 if (reiserfs_rupasov_hash(sbi) && code != YURA_HASH) {
1078                         reiserfs_log(LOG_ERR, "error, %s hash detected, "
1079                             "unable to force rupasov hash",
1080                             reiserfs_hashname(code));
1081                         code = UNSET_HASH;
1082                 } else if (reiserfs_tea_hash(sbi) && code != TEA_HASH) {
1083                         reiserfs_log(LOG_ERR, "error, %s hash detected, "
1084                             "unable to force tea hash",
1085                             reiserfs_hashname(code));
1086                         code = UNSET_HASH;
1087                 } else if (reiserfs_r5_hash(sbi) && code != R5_HASH) {
1088                         reiserfs_log(LOG_ERR, "error, %s hash detected, "
1089                             "unable to force r5 hash",
1090                             reiserfs_hashname(code));
1091                         code = UNSET_HASH;
1092                 }
1093         } else {
1094                 /*
1095                  * Find_hash_out was not called or could not determine
1096                  * the hash
1097                  */
1098                 if (reiserfs_rupasov_hash(sbi)) {
1099                         code = YURA_HASH;
1100                 } else if (reiserfs_tea_hash(sbi)) {
1101                         code = TEA_HASH;
1102                 } else if (reiserfs_r5_hash(sbi)) {
1103                         code = R5_HASH;
1104                 }
1105         }
1106
1107         /* TODO Not supported yet */
1108 #if 0
1109         /* If we are mounted RW, and we have a new valid hash code, update
1110          * the super */
1111         if (code != UNSET_HASH &&
1112             !(s->s_flags & MS_RDONLY) &&
1113             code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) {
1114                 set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code);
1115         }
1116 #endif
1117
1118         return (code);
1119 }
1120
1121 /* Return pointer to appropriate function */
1122 static hashf_t
1123 hash_function(struct reiserfs_mount *rmp)
1124 {
1125
1126         switch (what_hash(rmp)) {
1127         case TEA_HASH:
1128                 reiserfs_log(LOG_INFO, "using tea hash to sort names\n");
1129                 return (keyed_hash);
1130         case YURA_HASH:
1131                 reiserfs_log(LOG_INFO, "using rupasov hash to sort names\n");
1132                 return (yura_hash);
1133         case R5_HASH:
1134                 reiserfs_log(LOG_INFO, "using r5 hash to sort names\n");
1135                 return (r5_hash);
1136         }
1137
1138         return (NULL);
1139 }
1140
1141 /* -------------------------------------------------------------------
1142  * VFS registration
1143  * -------------------------------------------------------------------*/
1144
1145 static struct vfsops reiser_vfsops = {
1146         .vfs_cmount     = reiserfs_cmount,
1147         .vfs_mount      = reiserfs_mount,
1148         .vfs_unmount    = reiserfs_unmount,
1149         //.vfs_checkexp = reiserfs_checkexp,
1150         //.vfs_extattrctl = reiserfs_extattrctl,
1151         .vfs_fhtovp     = reiserfs_fhtovp,
1152         //.vfs_quotactl = reiserfs_quotactl,
1153         .vfs_root       = reiserfs_root,
1154         //.vfs_start    = reiserfs_start,
1155         .vfs_statfs     = reiserfs_statfs,
1156         //.vfs_sync     = reiserfs_sync,
1157         //.vfs_vget     = reiserfs_vget,
1158 };
1159
1160 VFS_SET(reiser_vfsops, reiserfs, VFCF_READONLY);