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

Cache object: 6f29293934dc9c30472801bee80861fa


[ 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.