kernel - Rejigger mount code to add vfs_flags in struct vfsops
[dragonfly.git] / sys / gnu / vfs / ext2fs / ext2_vfsops.c
1 /*
2  *  modified for EXT2FS support in Lites 1.1
3  *
4  *  Aug 1995, Godmar Back (gback@cs.utah.edu)
5  *  University of Utah, Department of Computer Science
6  */
7 /*
8  * Copyright (c) 1989, 1991, 1993, 1994
9  *      The Regents of the University of California.  All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *      @(#)ffs_vfsops.c        8.8 (Berkeley) 4/18/94
36  *      $FreeBSD: src/sys/gnu/ext2fs/ext2_vfsops.c,v 1.63.2.7 2002/07/01 00:18:51 iedowse Exp $
37  */
38
39 #include "opt_quota.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/nlookup.h>
44 #include <sys/proc.h>
45 #include <sys/priv.h>
46 #include <sys/kernel.h>
47 #include <sys/vnode.h>
48 #include <sys/mount.h>
49 #include <sys/buf.h>
50 #include <sys/conf.h>
51 #include <sys/fcntl.h>
52 #include <sys/diskslice.h>
53 #include <sys/malloc.h>
54 #include <sys/stat.h>
55 #include <vm/vm_zone.h>
56
57 #include <sys/buf2.h>
58 #include <sys/thread2.h>
59
60 #include "quota.h"
61 #include "dinode.h"
62 #include "inode.h"
63 #include "ext2_mount.h"
64 #include "ext2_extern.h"
65
66 #include "fs.h"
67 #include "ext2_fs.h"
68 #include "ext2_fs_sb.h"
69
70 extern struct vop_ops ext2_vnode_vops;
71 extern struct vop_ops ext2_spec_vops;
72 extern struct vop_ops ext2_fifo_vops;
73
74 static int ext2_fhtovp (struct mount *, struct vnode *,
75                                 struct fid *, struct vnode **);
76 static int ext2_flushfiles (struct mount *mp, int flags);
77 static int ext2_mount (struct mount *, char *, caddr_t, struct ucred *);
78 static int ext2_mountfs (struct vnode *, struct mount *, struct ucred *);
79 static int ext2_root(struct mount *, struct vnode **);
80 static int ext2_reload (struct mount *mountp, struct ucred *cred);
81 static int ext2_sbupdate (struct ext2_mount *, int);
82 static int ext2_sync (struct mount *, int);
83 static int ext2_unmount (struct mount *, int);
84 static int ext2_vget (struct mount *, struct vnode *, ino_t, struct vnode **);
85 static int ext2_init(struct vfsconf *);
86 static int ext2_vptofh (struct vnode *, struct fid *);
87
88 static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
89 MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
90
91 static struct vfsops ext2fs_vfsops = {
92         .vfs_flags =            0,
93         .vfs_mount =            ext2_mount,
94         .vfs_unmount =          ext2_unmount,
95         .vfs_root =             ext2_root,      /* root inode via vget */
96         .vfs_quotactl =         ext2_quotactl,  /* quota operations */
97         .vfs_statfs =           ext2_statfs,
98         .vfs_sync =             ext2_sync,
99         .vfs_vget =             ext2_vget,
100         .vfs_fhtovp =           ext2_fhtovp,
101         .vfs_checkexp =         ext2_check_export,
102         .vfs_vptofh =           ext2_vptofh,
103         .vfs_init =             ext2_init,
104         .vfs_uninit =           ext2_uninit
105 };
106
107 VFS_SET(ext2fs_vfsops, ext2fs, 0);
108 MODULE_VERSION(ext2fs, 1);
109
110 static int ext2fs_inode_hash_lock;
111
112 static int      ext2_check_sb_compat (struct ext2_super_block *es,
113                                           cdev_t dev, int ronly);
114 static int      compute_sb_data (struct vnode *devvp,
115                                      struct ext2_super_block *es,
116                                      struct ext2_sb_info *fs);
117
118 static int
119 ext2_root(struct mount *mp, struct vnode **vpp)
120 {
121         struct vnode *nvp;
122         int error;
123
124         error = VFS_VGET(mp, NULL, (ino_t)EXT2_ROOTINO, &nvp);
125         if (error)
126                 return (error);
127         *vpp = nvp;
128         return (0);
129 }
130
131 /*
132  * Do operations associated with quotas
133  */
134 int
135 ext2_quotactl(struct mount *mp, int cmds, uid_t uid, caddr_t arg,
136              struct ucred *cred)
137 {
138 #ifndef QUOTA
139         return (EOPNOTSUPP);
140 #else
141         int cmd, type, error;
142
143         type = cmds & SUBCMDMASK;
144         cmd = cmds >> SUBCMDSHIFT;
145
146         if (uid == -1) {
147                 switch(type) {
148                         case USRQUOTA:
149                                 uid = cred->cr_ruid;
150                                 break;
151                         case GRPQUOTA:
152                                 uid = cred->cr_rgid;
153                                 break;
154                         default:
155                                 return (EINVAL);
156                 }
157         }
158
159         /*
160          * Check permissions.
161          */
162         switch (cmd) {
163
164         case Q_QUOTAON:
165                 error = priv_check_cred(cred, PRIV_UFS_QUOTAON, 0);
166                 break;
167
168         case Q_QUOTAOFF:
169                 error = priv_check_cred(cred, PRIV_UFS_QUOTAOFF, 0);
170                 break;
171
172         case Q_SETQUOTA:
173                 error = priv_check_cred(cred, PRIV_VFS_SETQUOTA, 0);
174                 break;
175
176         case Q_SETUSE:
177                 error = priv_check_cred(cred, PRIV_UFS_SETUSE, 0);
178                 break;
179
180         case Q_GETQUOTA:
181                 if (uid == cred->cr_ruid)
182                         error = 0;
183                 else
184                         error = priv_check_cred(cred, PRIV_VFS_GETQUOTA, 0);
185                 break;
186
187         case Q_SYNC:
188                 error = 0;
189                 break;
190
191         default:
192                 error = EINVAL;
193                 break;
194         }
195
196         if (error)
197                 return (error);
198
199
200         if ((uint)type >= MAXQUOTAS)
201                 return (EINVAL);
202         if (vfs_busy(mp, LK_NOWAIT))
203                 return (0);
204
205         switch (cmd) {
206
207         case Q_QUOTAON:
208                 error = ext2_quotaon(cred, mp, type, arg);
209                 break;
210
211         case Q_QUOTAOFF:
212                 error = ext2_quotaoff(mp, type);
213                 break;
214
215         case Q_SETQUOTA:
216                 error = ext2_setquota(mp, uid, type, arg);
217                 break;
218
219         case Q_SETUSE:
220                 error = ext2_setuse(mp, uid, type, arg);
221                 break;
222
223         case Q_GETQUOTA:
224                 error = ext2_getquota(mp, uid, type, arg);
225                 break;
226
227         case Q_SYNC:
228                 error = ext2_qsync(mp);
229                 break;
230
231         default:
232                 error = EINVAL;
233                 break;
234         }
235         vfs_unbusy(mp);
236         return (error);
237 #endif
238 }
239
240 /*
241  * Initial UFS filesystems, done only once.
242  */
243 static int
244 ext2_init(struct vfsconf *vfsp)
245 {
246         static int done;
247
248         if (done)
249                 return (0);
250         done = 1;
251         ext2_ihashinit();
252 #ifdef QUOTA
253         ext2_dqinit();
254 #endif
255         return (0);
256 }
257
258 /*
259  * VFS Operations.
260  *
261  * mount system call
262  *
263  * Parameters:
264  *      data:   this is actually a (struct ext2_args *)
265  */
266 static int
267 ext2_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
268 {
269         struct vnode *devvp;
270         struct ext2_args args;
271         struct ext2_mount *ump = NULL;
272         struct ext2_sb_info *fs;
273         size_t size;
274         int error, flags;
275         mode_t accessmode;
276         struct nlookupdata nd;
277
278         if ((error = copyin(data, (caddr_t)&args, sizeof (struct ext2_args))) != 0)
279                 return (error);
280
281         /*
282          * If updating, check whether changing from read-only to
283          * read/write; if there is no device name, that's all we do.
284          */
285         if (mp->mnt_flag & MNT_UPDATE) {
286                 ump = VFSTOEXT2(mp);
287                 fs = ump->um_e2fs;
288                 devvp = ump->um_devvp;
289                 error = 0;
290                 if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) {
291                         flags = WRITECLOSE;
292                         if (mp->mnt_flag & MNT_FORCE)
293                                 flags |= FORCECLOSE;
294                         if (vfs_busy(mp, LK_NOWAIT))
295                                 return (EBUSY);
296                         error = ext2_flushfiles(mp, flags);
297                         vfs_unbusy(mp);
298                         if (!error && fs->s_wasvalid) {
299                                 fs->s_es->s_state |= EXT2_VALID_FS;
300                                 ext2_sbupdate(ump, MNT_WAIT);
301                         }
302                         fs->s_rd_only = 1;
303                         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
304                         VOP_OPEN(devvp, FREAD, FSCRED, NULL);
305                         VOP_CLOSE(devvp, FREAD|FWRITE, NULL);
306                         vn_unlock(devvp);
307                 }
308                 if (!error && (mp->mnt_flag & MNT_RELOAD))
309                         error = ext2_reload(mp, cred);
310                 if (error)
311                         return (error);
312                 if (ext2_check_sb_compat(fs->s_es, devvp->v_rdev,
313                     (mp->mnt_kern_flag & MNTK_WANTRDWR) == 0) != 0)
314                         return (EPERM);
315                 if (fs->s_rd_only && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
316                         /*
317                          * If upgrade to read-write by non-root, then verify
318                          * that user has necessary permissions on the device.
319                          */
320                         if (cred->cr_uid != 0) {
321                                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
322                                 error = VOP_EACCESS(devvp, VREAD | VWRITE, cred);
323                                 if (error) {
324                                         vn_unlock(devvp);
325                                         return (error);
326                                 }
327                                 vn_unlock(devvp);
328                         }
329
330                         if ((fs->s_es->s_state & EXT2_VALID_FS) == 0 ||
331                             (fs->s_es->s_state & EXT2_ERROR_FS)) {
332                                 if (mp->mnt_flag & MNT_FORCE) {
333                                         kprintf(
334 "WARNING: %s was not properly dismounted\n",
335                                             fs->fs_fsmnt);
336                                 } else {
337                                         kprintf(
338 "WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
339                                             fs->fs_fsmnt);
340                                         return (EPERM);
341                                 }
342                         }
343                         fs->s_es->s_state &= ~EXT2_VALID_FS;
344                         ext2_sbupdate(ump, MNT_WAIT);
345                         fs->s_rd_only = 0;
346                         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
347                         VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, NULL);
348                         VOP_CLOSE(devvp, FREAD, NULL);
349                         vn_unlock(devvp);
350                 }
351                 if (args.fspec == NULL) {
352                         /*
353                          * Process export requests.
354                          */
355                         return (vfs_export(mp, &ump->um_export, &args.export));
356                 }
357         }
358         /*
359          * Not an update, or updating the name: look up the name
360          * and verify that it refers to a sensible block device.
361          */
362         devvp = NULL;
363         error = nlookup_init(&nd, args.fspec, UIO_USERSPACE, NLC_FOLLOW);
364         if (error == 0)
365                 error = nlookup(&nd);
366         if (error == 0)
367                 error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp);
368         nlookup_done(&nd);
369         if (error)
370                 return (error);
371
372         if (!vn_isdisk(devvp, &error)) {
373                 vrele(devvp);
374                 return (error);
375         }
376
377         /*
378          * If mount by non-root, then verify that user has necessary
379          * permissions on the device.
380          */
381         if (cred->cr_uid != 0) {
382                 accessmode = VREAD;
383                 if ((mp->mnt_flag & MNT_RDONLY) == 0)
384                         accessmode |= VWRITE;
385                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
386                 if ((error = VOP_EACCESS(devvp, accessmode, cred)) != 0) {
387                         vput(devvp);
388                         return (error);
389                 }
390                 vn_unlock(devvp);
391         }
392
393         if ((mp->mnt_flag & MNT_UPDATE) == 0) {
394                 error = ext2_mountfs(devvp, mp, cred);
395         } else {
396                 if (devvp != ump->um_devvp)
397                         error = EINVAL; /* needs translation */
398                 else
399                         vrele(devvp);
400         }
401         if (error) {
402                 vrele(devvp);
403                 return (error);
404         }
405         ump = VFSTOEXT2(mp);
406         fs = ump->um_e2fs;
407         copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
408         bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
409         copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
410         bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
411         ext2_statfs(mp, &mp->mnt_stat, cred);
412         return (0);
413 }
414
415 static int
416 ext2_check_sb_compat(struct ext2_super_block *es, cdev_t dev, int ronly)
417 {
418         if (es->s_magic != EXT2_SUPER_MAGIC) {
419                 kprintf("ext2fs: %s: wrong magic number %#x (expected %#x)\n",
420                     devtoname(dev), es->s_magic, EXT2_SUPER_MAGIC);
421                 return (1);
422         }
423         if (es->s_rev_level > EXT2_GOOD_OLD_REV) {
424                 if (es->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP) {
425                         kprintf(
426 "WARNING: mount of %s denied due to unsupported optional features\n",
427                             devtoname(dev));
428                         return (1);
429                 }
430                 if (!ronly &&
431                     (es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) {
432                         kprintf(
433 "WARNING: R/W mount of %s denied due to unsupported optional features\n",
434                             devtoname(dev));
435                         return (1);
436                 }
437         }
438         return (0);
439 }
440
441 /*
442  * this computes the fields of the  ext2_sb_info structure from the
443  * data in the ext2_super_block structure read in
444  */
445 static int
446 compute_sb_data(struct vnode *devvp, struct ext2_super_block *es,
447                 struct ext2_sb_info *fs)
448 {
449         int db_count, error;
450         int i, j;
451         int logic_sb_block = 1; /* XXX for now */
452
453 #if 1
454 #define V(v)
455 #else
456 #define V(v)  kprintf(#v"= %d\n", fs->v);
457 #endif
458
459         fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
460         V(s_blocksize)
461         fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size;
462         V(s_bshift)
463         fs->s_fsbtodb = es->s_log_block_size + 1;
464         V(s_fsbtodb)
465         fs->s_qbmask = fs->s_blocksize - 1;
466         V(s_bmask)
467         fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es);
468         V(s_blocksize_bits)
469         fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size;
470         V(s_frag_size)
471         if (fs->s_frag_size)
472                 fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size;
473         V(s_frags_per_block)
474         fs->s_blocks_per_group = es->s_blocks_per_group;
475         V(s_blocks_per_group)
476         fs->s_frags_per_group = es->s_frags_per_group;
477         V(s_frags_per_group)
478         fs->s_inodes_per_group = es->s_inodes_per_group;
479         V(s_inodes_per_group)
480         if (es->s_rev_level == EXT2_GOOD_OLD_REV) {
481                 fs->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
482                 fs->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
483         } else {
484                 fs->s_first_ino = es->s_first_ino;
485                 fs->s_inode_size = es->s_inode_size;
486                 /*
487                  * Simple sanity check for superblock inode size value.
488                  */
489                 if (fs->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE ||
490                     fs->s_inode_size > fs->s_blocksize ||
491                     (fs->s_inode_size & (fs->s_inode_size - 1)) != 0) {
492                         kprintf("EXT2-fs: invalid inode size %d\n",
493                         fs->s_inode_size);
494                         return (EIO);
495                 }
496         }
497         V(s_first_ino)
498         V(s_inode_size)
499         fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE(fs);
500         V(s_inodes_per_block)
501         fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block;
502         V(s_itb_per_group)
503         fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc);
504         V(s_desc_per_block)
505         /* s_resuid / s_resgid ? */
506         fs->s_groups_count = (es->s_blocks_count - es->s_first_data_block +
507                               EXT2_BLOCKS_PER_GROUP(fs) - 1) /
508                               EXT2_BLOCKS_PER_GROUP(fs);
509         V(s_groups_count)
510         db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
511                                          EXT2_DESC_PER_BLOCK(fs);
512         fs->s_db_per_group = db_count;
513         V(s_db_per_group)
514
515         fs->s_group_desc = kmalloc(db_count * sizeof (struct buf *),
516                                 M_EXT2MNT, M_WAITOK);
517
518         /* adjust logic_sb_block */
519         if (fs->s_blocksize > SBSIZE)
520                 /*
521                  * Godmar thinks: if the blocksize is greater than 1024,
522                  * then, the superblock is logically part of block zero.
523                  */
524                 logic_sb_block = 0;
525
526         for (i = 0; i < db_count; i++) {
527                 error = bread(devvp, fsbtodoff(fs, logic_sb_block + i + 1),
528                                 fs->s_blocksize, &fs->s_group_desc[i]);
529                 if (error) {
530                         for (j = 0; j < i; j++)
531                                 brelse(fs->s_group_desc[j]);
532                         kfree(fs->s_group_desc, M_EXT2MNT);
533                         kprintf("EXT2-fs: unable to read group descriptors (%d)\n", error);
534                         return EIO;
535                 }
536                 /* Set the B_LOCKED flag on the buffer, then brelse() it */
537                 LCK_BUF(fs->s_group_desc[i])
538         }
539         if (!ext2_check_descriptors(fs)) {
540                 for (j = 0; j < db_count; j++)
541                         ULCK_BUF(fs->s_group_desc[j])
542                 kfree(fs->s_group_desc, M_EXT2MNT);
543                 kprintf("EXT2-fs: (ext2_check_descriptors failure) "
544                         "unable to read group descriptors\n");
545                 return EIO;
546         }
547
548         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
549                 fs->s_inode_bitmap_number[i] = 0;
550                 fs->s_inode_bitmap[i] = NULL;
551                 fs->s_block_bitmap_number[i] = 0;
552                 fs->s_block_bitmap[i] = NULL;
553         }
554         fs->s_loaded_inode_bitmaps = 0;
555         fs->s_loaded_block_bitmaps = 0;
556         return 0;
557 }
558
559 /*
560  * Reload all incore data for a filesystem (used after running fsck on
561  * the root filesystem and finding things to fix). The filesystem must
562  * be mounted read-only.
563  *
564  * Things to do to update the mount:
565  *      1) invalidate all cached meta-data.
566  *      2) re-read superblock from disk.
567  *      3) re-read summary information from disk.
568  *      4) invalidate all inactive vnodes.
569  *      5) invalidate all cached file data.
570  *      6) re-read inode data for all active vnodes.
571  */
572 static int ext2_reload_scan(struct mount *mp, struct vnode *vp, void *rescan);
573
574 struct scaninfo {
575         int rescan;
576         int allerror;
577         int waitfor;
578         struct vnode *devvp;
579         struct ext2_sb_info *fs;
580 };
581
582 static int
583 ext2_reload(struct mount *mountp, struct ucred *cred)
584 {
585         struct vnode *devvp;
586         struct buf *bp;
587         struct ext2_super_block *es;
588         struct ext2_sb_info *fs;
589         int error;
590         struct scaninfo scaninfo;
591
592         if ((mountp->mnt_flag & MNT_RDONLY) == 0)
593                 return (EINVAL);
594         /*
595          * Step 1: invalidate all cached meta-data.
596          */
597         devvp = VFSTOEXT2(mountp)->um_devvp;
598         if (vinvalbuf(devvp, 0, 0, 0))
599                 panic("ext2_reload: dirty1");
600         /*
601          * Step 2: re-read superblock from disk.
602          * constants have been adjusted for ext2
603          */
604         if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0)
605                 return (error);
606         es = (struct ext2_super_block *)bp->b_data;
607         if (ext2_check_sb_compat(es, devvp->v_rdev, 0) != 0) {
608                 brelse(bp);
609                 return (EIO);           /* XXX needs translation */
610         }
611         fs = VFSTOEXT2(mountp)->um_e2fs;
612         bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block));
613
614         if((error = compute_sb_data(devvp, es, fs)) != 0) {
615                 brelse(bp);
616                 return error;
617         }
618 #ifdef UNKLAR
619         if (fs->fs_sbsize < SBSIZE)
620                 bp->b_flags |= B_INVAL;
621 #endif
622         brelse(bp);
623
624         scaninfo.rescan = 1;
625         scaninfo.devvp = devvp;
626         scaninfo.fs = fs;
627         while (error == 0 && scaninfo.rescan) {
628             scaninfo.rescan = 0;
629             error = vmntvnodescan(mountp, VMSC_GETVX,
630                                   NULL, ext2_reload_scan, &scaninfo);
631         }
632         return(error);
633 }
634
635 static int
636 ext2_reload_scan(struct mount *mp, struct vnode *vp, void *data)
637 {
638         struct scaninfo *info = data;
639         struct inode *ip;
640         struct buf *bp;
641         int error;
642
643         /*
644          * Try to recycle
645          */
646         if (vrecycle(vp))
647                 return(0);
648
649         /*
650          * Step 1: invalidate all cached file data.
651          */
652         if (vinvalbuf(vp, 0, 0, 0))
653                 panic("ext2_reload: dirty2");
654         /*
655          * Step 2: re-read inode data for all active vnodes.
656          */
657         ip = VTOI(vp);
658         error = bread(info->devvp,
659                       fsbtodoff(info->fs, ino_to_fsba(info->fs, ip->i_number)),
660                       (int)info->fs->s_blocksize, &bp);
661         if (error)
662                 return (error);
663         ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data +
664             EXT2_INODE_SIZE(info->fs) * ino_to_fsbo(info->fs, ip->i_number)),
665             &ip->i_din);
666         brelse(bp);
667         return(0);
668 }
669
670 /*
671  * Common code for mount and mountroot
672  */
673 static int
674 ext2_mountfs(struct vnode *devvp, struct mount *mp, struct ucred *cred)
675 {
676         struct ext2_mount *ump;
677         struct buf *bp;
678         struct ext2_sb_info *fs;
679         struct ext2_super_block *es;
680         cdev_t dev;
681         int error, i;
682         int ronly;
683
684         /*
685          * Disallow multiple mounts of the same device.
686          * Disallow mounting of a device that is currently in use
687          * (except for root, which might share swap device for miniroot).
688          * Flush out any old buffers remaining from a previous use.
689          */
690         if ((error = vfs_mountedon(devvp)) != 0)
691                 return (error);
692         if (vcount(devvp) > 0)
693                 return (EBUSY);
694         if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)) != 0)
695                 return (error);
696 #ifdef READONLY
697 /* turn on this to force it to be read-only */
698         mp->mnt_flag |= MNT_RDONLY;
699 #endif
700
701         ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
702         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
703         error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, NULL);
704         vn_unlock(devvp);
705         if (error)
706                 return (error);
707         dev = devvp->v_rdev;
708         if (dev->si_iosize_max != 0)
709                 mp->mnt_iosize_max = dev->si_iosize_max;
710         if (mp->mnt_iosize_max > MAXPHYS)
711                 mp->mnt_iosize_max = MAXPHYS;
712
713         bp = NULL;
714         ump = NULL;
715         if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0)
716                 goto out;
717         es = (struct ext2_super_block *)bp->b_data;
718         if (ext2_check_sb_compat(es, dev, ronly) != 0) {
719                 error = EINVAL;         /* XXX needs translation */
720                 goto out;
721         }
722         if ((es->s_state & EXT2_VALID_FS) == 0 ||
723             (es->s_state & EXT2_ERROR_FS)) {
724                 if (ronly || (mp->mnt_flag & MNT_FORCE)) {
725                         kprintf(
726 "WARNING: Filesystem was not properly dismounted\n");
727                 } else {
728                         kprintf(
729 "WARNING: R/W mount denied.  Filesystem is not clean - run fsck\n");
730                         error = EPERM;
731                         goto out;
732                 }
733         }
734         ump = kmalloc(sizeof *ump, M_EXT2MNT, M_WAITOK | M_ZERO);
735         ump->um_malloctype = M_EXT2NODE;
736         ump->um_blkatoff = ext2_blkatoff;
737         ump->um_truncate = ext2_truncate;
738         ump->um_update = ext2_update;
739         ump->um_valloc = ext2_valloc;
740         ump->um_vfree = ext2_vfree;
741         /* I don't know whether this is the right strategy. Note that
742            we dynamically allocate both a ext2_sb_info and a ext2_super_block
743            while Linux keeps the super block in a locked buffer
744          */
745         ump->um_e2fs = kmalloc(sizeof(struct ext2_sb_info),
746                 M_EXT2MNT, M_WAITOK);
747         ump->um_e2fs->s_es = kmalloc(sizeof(struct ext2_super_block),
748                 M_EXT2MNT, M_WAITOK);
749         bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
750         if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
751                 goto out;
752         /*
753          * We don't free the group descriptors allocated by compute_sb_data()
754          * until ext2_unmount().  This is OK since the mount will succeed.
755          */
756         brelse(bp);
757         bp = NULL;
758         fs = ump->um_e2fs;
759         fs->s_rd_only = ronly;  /* ronly is set according to mnt_flags */
760         /* if the fs is not mounted read-only, make sure the super block is
761            always written back on a sync()
762          */
763         fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0;
764         if (ronly == 0) {
765                 fs->s_dirt = 1;         /* mark it modified */
766                 fs->s_es->s_state &= ~EXT2_VALID_FS;    /* set fs invalid */
767         }
768         mp->mnt_data = (qaddr_t)ump;
769         mp->mnt_stat.f_fsid.val[0] = devid_from_dev(dev);
770         mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
771         mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN;
772         mp->mnt_flag |= MNT_LOCAL;
773         ump->um_mountp = mp;
774         ump->um_dev = dev;
775         ump->um_devvp = devvp;
776         /* setting those two parameters allows us to use
777            ext2_bmap w/o changse !
778         */
779         ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
780         ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
781         ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
782         for (i = 0; i < MAXQUOTAS; i++)
783                 ump->um_quotas[i] = NULLVP;
784         dev->si_mountpoint = mp;
785
786         vfs_add_vnodeops(mp, &ext2_vnode_vops, &mp->mnt_vn_norm_ops);
787         vfs_add_vnodeops(mp, &ext2_spec_vops, &mp->mnt_vn_spec_ops);
788         vfs_add_vnodeops(mp, &ext2_fifo_vops, &mp->mnt_vn_fifo_ops);
789
790         if (ronly == 0)
791                 ext2_sbupdate(ump, MNT_WAIT);
792         return (0);
793 out:
794         if (bp)
795                 brelse(bp);
796         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
797         VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NULL);
798         vn_unlock(devvp);
799         if (ump) {
800                 kfree(ump->um_e2fs->s_es, M_EXT2MNT);
801                 kfree(ump->um_e2fs, M_EXT2MNT);
802                 kfree(ump, M_EXT2MNT);
803                 mp->mnt_data = (qaddr_t)0;
804         }
805         return (error);
806 }
807
808 /*
809  * unmount system call
810  */
811 static int
812 ext2_unmount(struct mount *mp, int mntflags)
813 {
814         struct ext2_mount *ump;
815         struct ext2_sb_info *fs;
816         int error, flags, ronly, i;
817
818         flags = 0;
819         if (mntflags & MNT_FORCE) {
820                 if (mp->mnt_flag & MNT_ROOTFS)
821                         return (EINVAL);
822                 flags |= FORCECLOSE;
823         }
824         if ((error = ext2_flushfiles(mp, flags)) != 0)
825                 return (error);
826         ump = VFSTOEXT2(mp);
827         fs = ump->um_e2fs;
828         ronly = fs->s_rd_only;
829         if (ronly == 0) {
830                 if (fs->s_wasvalid)
831                         fs->s_es->s_state |= EXT2_VALID_FS;
832                 ext2_sbupdate(ump, MNT_WAIT);
833         }
834
835         /* release buffers containing group descriptors */
836         for(i = 0; i < fs->s_db_per_group; i++)
837                 ULCK_BUF(fs->s_group_desc[i])
838         kfree(fs->s_group_desc, M_EXT2MNT);
839
840         /* release cached inode/block bitmaps */
841         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
842                 if (fs->s_inode_bitmap[i])
843                         ULCK_BUF(fs->s_inode_bitmap[i])
844
845         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
846                 if (fs->s_block_bitmap[i])
847                         ULCK_BUF(fs->s_block_bitmap[i])
848
849         ump->um_devvp->v_rdev->si_mountpoint = NULL;
850
851         vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
852         error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, NULL);
853         vn_unlock(ump->um_devvp);
854
855         vrele(ump->um_devvp);
856         kfree(fs->s_es, M_EXT2MNT);
857         kfree(fs, M_EXT2MNT);
858         kfree(ump, M_EXT2MNT);
859         mp->mnt_data = (qaddr_t)0;
860         mp->mnt_flag &= ~MNT_LOCAL;
861         return (error);
862 }
863
864 /*
865  * Flush out all the files in a filesystem.
866  */
867 static int
868 ext2_flushfiles(struct mount *mp, int flags)
869 {
870         struct ext2_mount *ump;
871         int error;
872 #ifdef QUOTA
873         int i;
874 #endif
875
876         ump = VFSTOEXT2(mp);
877 #ifdef QUOTA
878         if (mp->mnt_flag & MNT_QUOTA) {
879                 if ((error = vflush(mp, 0, SKIPSYSTEM|flags)) != 0)
880                         return (error);
881                 for (i = 0; i < MAXQUOTAS; i++) {
882                         if (ump->um_quotas[i] == NULLVP)
883                                 continue;
884                         ext2_quotaoff(mp, i);
885                 }
886                 /*
887                  * Here we fall through to vflush again to ensure
888                  * that we have gotten rid of all the system vnodes.
889                  */
890         }
891 #endif
892         error = vflush(mp, 0, flags);
893         return (error);
894 }
895
896 /*
897  * Go through the disk queues to initiate sandbagged IO;
898  * go through the inodes to write those that have been modified;
899  * initiate the writing of the super block if it has been modified.
900  *
901  * Note: we are always called with the filesystem marked `MPBUSY'.
902  */
903
904 static int ext2_sync_scan(struct mount *mp, struct vnode *vp, void *data);
905
906 static int
907 ext2_sync(struct mount *mp, int waitfor)
908 {
909         struct ext2_mount *ump = VFSTOEXT2(mp);
910         struct ext2_sb_info *fs;
911         struct scaninfo scaninfo;
912         int error;
913
914         fs = ump->um_e2fs;
915         if (fs->s_dirt != 0 && fs->s_rd_only != 0) {            /* XXX */
916                 kprintf("fs = %s\n", fs->fs_fsmnt);
917                 panic("ext2_sync: rofs mod");
918         }
919
920         /*
921          * Write back each (modified) inode.
922          */
923         scaninfo.allerror = 0;
924         scaninfo.rescan = 1;
925         scaninfo.waitfor = waitfor;
926         while (scaninfo.rescan) {
927                 scaninfo.rescan = 0;
928                 vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT,
929                               NULL, ext2_sync_scan, &scaninfo);
930         }
931
932         /*
933          * Force stale file system control information to be flushed.
934          */
935         if ((waitfor & MNT_LAZY) == 0) {
936                 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
937                 if ((error = VOP_FSYNC(ump->um_devvp, waitfor, 0)) != 0)
938                         scaninfo.allerror = error;
939                 vn_unlock(ump->um_devvp);
940         }
941 #ifdef QUOTA
942         ext2_qsync(mp);
943 #endif
944         /*
945          * Write back modified superblock.
946          */
947         if (fs->s_dirt != 0) {
948                 fs->s_dirt = 0;
949                 fs->s_es->s_wtime = time_second;
950                 if ((error = ext2_sbupdate(ump, waitfor)) != 0)
951                         scaninfo.allerror = error;
952         }
953         return (scaninfo.allerror);
954 }
955
956 static int
957 ext2_sync_scan(struct mount *mp, struct vnode *vp, void *data)
958 {
959         struct scaninfo *info = data;
960         struct inode *ip;
961         int error;
962
963         ip = VTOI(vp);
964         if (vp->v_type == VNON ||
965             ((ip->i_flag &
966             (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
967             (RB_EMPTY(&vp->v_rbdirty_tree) || (info->waitfor & MNT_LAZY)))) {
968                 return(0);
969         }
970         if ((error = VOP_FSYNC(vp, info->waitfor, 0)) != 0)
971                 info->allerror = error;
972         return(0);
973 }
974
975 /*
976  * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it
977  * in from disk.  If it is in core, wait for the lock bit to clear, then
978  * return the inode locked.  Detection and handling of mount points must be
979  * done by the calling routine.
980  */
981 static int
982 ext2_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
983 {
984         struct ext2_sb_info *fs;
985         struct inode *ip;
986         struct ext2_mount *ump;
987         struct buf *bp;
988         struct vnode *vp;
989         cdev_t dev;
990         int i, error;
991         int used_blocks;
992
993         ump = VFSTOEXT2(mp);
994         dev = ump->um_dev;
995 restart:
996         if ((*vpp = ext2_ihashget(dev, ino)) != NULL)
997                 return (0);
998
999         /*
1000          * Lock out the creation of new entries in the FFS hash table in
1001          * case getnewvnode() or MALLOC() blocks, otherwise a duplicate
1002          * may occur!
1003          */
1004         if (ext2fs_inode_hash_lock) {
1005                 while (ext2fs_inode_hash_lock) {
1006                         ext2fs_inode_hash_lock = -1;
1007                         tsleep(&ext2fs_inode_hash_lock, 0, "e2vget", 0);
1008                 }
1009                 goto restart;
1010         }
1011         ext2fs_inode_hash_lock = 1;
1012
1013         /*
1014          * If this MALLOC() is performed after the getnewvnode()
1015          * it might block, leaving a vnode with a NULL v_data to be
1016          * found by ext2_sync() if a sync happens to fire right then,
1017          * which will cause a panic because ext2_sync() blindly
1018          * dereferences vp->v_data (as well it should).
1019          */
1020         ip = kmalloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK);
1021
1022         /* Allocate a new vnode/inode. */
1023         if ((error = getnewvnode(VT_EXT2FS, mp, &vp, 0, LK_CANRECURSE)) != 0) {
1024                 if (ext2fs_inode_hash_lock < 0)
1025                         wakeup(&ext2fs_inode_hash_lock);
1026                 ext2fs_inode_hash_lock = 0;
1027                 *vpp = NULL;
1028                 kfree(ip, M_EXT2NODE);
1029                 return (error);
1030         }
1031         bzero((caddr_t)ip, sizeof(struct inode));
1032         vp->v_data = ip;
1033         ip->i_vnode = vp;
1034         ip->i_e2fs = fs = ump->um_e2fs;
1035         ip->i_dev = dev;
1036         ip->i_number = ino;
1037 #ifdef QUOTA
1038         for (i = 0; i < MAXQUOTAS; i++)
1039                 ip->i_dquot[i] = NODQUOT;
1040 #endif
1041         /*
1042          * Put it onto its hash chain.  Since our vnode is locked, other
1043          * requests for this inode will block if they arrive while we are
1044          * sleeping waiting for old data structures to be purged or for the
1045          * contents of the disk portion of this inode to be read.
1046          */
1047         ext2_ihashins(ip);
1048
1049         if (ext2fs_inode_hash_lock < 0)
1050                 wakeup(&ext2fs_inode_hash_lock);
1051         ext2fs_inode_hash_lock = 0;
1052
1053         /* Read in the disk contents for the inode, copy into the inode. */
1054 #if 0
1055 kprintf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
1056 #endif
1057         error = bread(ump->um_devvp, fsbtodoff(fs, ino_to_fsba(fs, ino)),
1058                       (int)fs->s_blocksize, &bp);
1059         if (error) {
1060                 /*
1061                  * The inode does not contain anything useful, so it would
1062                  * be misleading to leave it on its hash chain. With mode
1063                  * still zero, it will be unlinked and returned to the free
1064                  * list by vput().
1065                  */
1066                 brelse(bp);
1067                 vx_put(vp);
1068                 *vpp = NULL;
1069                 return (error);
1070         }
1071         /* convert ext2 inode to dinode */
1072         ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
1073                         ino_to_fsbo(fs, ino)), &ip->i_din);
1074         ip->i_block_group = ino_to_cg(fs, ino);
1075         ip->i_next_alloc_block = 0;
1076         ip->i_next_alloc_goal = 0;
1077         ip->i_prealloc_count = 0;
1078         ip->i_prealloc_block = 0;
1079         /* now we want to make sure that block pointers for unused
1080            blocks are zeroed out - ext2_balloc depends on this
1081            although for regular files and directories only
1082         */
1083         if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) {
1084                 used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize;
1085                 for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++)
1086                         ip->i_db[i] = 0;
1087         }
1088 #if 0
1089         ext2_print_inode(ip);
1090 #endif
1091         bqrelse(bp);
1092
1093         /*
1094          * Initialize the vnode from the inode, check for aliases.
1095          * Note that the underlying vnode may have changed.
1096          */
1097         if ((error = ext2_vinit(mp, &vp)) != 0) {
1098                 vx_put(vp);
1099                 *vpp = NULL;
1100                 return (error);
1101         }
1102
1103         /*
1104          * Finish inode initialization now that aliasing has been resolved.
1105          */
1106         ip->i_devvp = ump->um_devvp;
1107         vref(ip->i_devvp);
1108         /*
1109          * Set up a generation number for this inode if it does not
1110          * already have one. This should only happen on old filesystems.
1111          */
1112         if (ip->i_gen == 0) {
1113                 ip->i_gen = krandom() / 2 + 1;
1114                 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
1115                         ip->i_flag |= IN_MODIFIED;
1116         }
1117         /*
1118          * Return the locked and refd vnode.
1119          */
1120         *vpp = vp;
1121         return (0);
1122 }
1123
1124 /*
1125  * File handle to vnode
1126  *
1127  * Have to be really careful about stale file handles:
1128  * - check that the inode number is valid
1129  * - call ext2_vget() to get the locked inode
1130  * - check for an unallocated inode (i_mode == 0)
1131  * - check that the given client host has export rights and return
1132  *   those rights via. exflagsp and credanonp
1133  */
1134 static int
1135 ext2_fhtovp(struct mount *mp, struct vnode *rootvp,
1136             struct fid *fhp, struct vnode **vpp)
1137 {
1138         struct ufid *ufhp;
1139         struct ext2_sb_info *fs;
1140         struct inode *ip;
1141         struct vnode *nvp;
1142         int error;
1143
1144         ufhp = (struct ufid *)fhp;
1145         fs = VFSTOEXT2(mp)->um_e2fs;
1146         if (ufhp->ufid_ino < EXT2_ROOTINO ||
1147             ufhp->ufid_ino > fs->s_groups_count * fs->s_es->s_inodes_per_group)
1148                 return (ESTALE);
1149
1150         error = VFS_VGET(mp, rootvp, ufhp->ufid_ino, &nvp);
1151         if (error) {
1152                 *vpp = NULLVP;
1153                 return (error);
1154         }
1155         ip = VTOI(nvp);
1156         if (ip->i_mode == 0 ||
1157             ip->i_gen != ufhp->ufid_gen ||
1158             (VFSTOEXT2(mp)->um_i_effnlink_valid ? ip->i_effnlink :
1159             ip->i_nlink) <= 0) {
1160                 vput(nvp);
1161                 *vpp = NULLVP;
1162                 return (ESTALE);
1163         }
1164         *vpp = nvp;
1165         return (0);
1166 }
1167
1168 /*
1169  * Vnode pointer to File handle
1170  */
1171 /* ARGSUSED */
1172 static int
1173 ext2_vptofh(struct vnode *vp, struct fid *fhp)
1174 {
1175         struct inode *ip;
1176         struct ufid *ufhp;
1177
1178         ip = VTOI(vp);
1179         ufhp = (struct ufid *)fhp;
1180         ufhp->ufid_len = sizeof(struct ufid);
1181         ufhp->ufid_ino = ip->i_number;
1182         ufhp->ufid_gen = ip->i_gen;
1183         return (0);
1184 }
1185
1186 /*
1187  * This is the generic part of fhtovp called after the underlying
1188  * filesystem has validated the file handle.
1189  *
1190  * Verify that a host should have access to a filesystem.
1191  */
1192 int
1193 ext2_check_export(struct mount *mp, struct sockaddr *nam, int *exflagsp,
1194                  struct ucred **credanonp)
1195 {
1196         struct netcred *np;
1197         struct ext2_mount *ump;
1198
1199         ump = VFSTOEXT2(mp);
1200         /*
1201          * Get the export permission structure for this <mp, client> tuple.
1202          */
1203         np = vfs_export_lookup(mp, &ump->um_export, nam);
1204         if (np == NULL)
1205                 return (EACCES);
1206
1207         *exflagsp = np->netc_exflags;
1208         *credanonp = &np->netc_anon;
1209         return (0);
1210 }
1211
1212 /*
1213  * Write a superblock and associated information back to disk.
1214  */
1215 static int
1216 ext2_sbupdate(struct ext2_mount *mp, int waitfor)
1217 {
1218         struct ext2_sb_info *fs = mp->um_e2fs;
1219         struct ext2_super_block *es = fs->s_es;
1220         struct buf *bp;
1221         int error = 0;
1222 /*
1223 kprintf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
1224 */
1225         bp = getblk(mp->um_devvp, SBOFF, SBSIZE, 0, 0);
1226         bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block));
1227         if (waitfor == MNT_WAIT)
1228                 error = bwrite(bp);
1229         else
1230                 bawrite(bp);
1231
1232         /*
1233          * The buffers for group descriptors, inode bitmaps and block bitmaps
1234          * are not busy at this point and are (hopefully) written by the
1235          * usual sync mechanism. No need to write them here
1236          */
1237
1238         return (error);
1239 }