]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - sys/fs/ext2fs/ext2_vfsops.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / sys / fs / 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  * 4. 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$
37  */
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/namei.h>
42 #include <sys/priv.h>
43 #include <sys/proc.h>
44 #include <sys/kernel.h>
45 #include <sys/vnode.h>
46 #include <sys/mount.h>
47 #include <sys/bio.h>
48 #include <sys/buf.h>
49 #include <sys/conf.h>
50 #include <sys/fcntl.h>
51 #include <sys/malloc.h>
52 #include <sys/stat.h>
53 #include <sys/mutex.h>
54
55 #include <geom/geom.h>
56 #include <geom/geom_vfs.h>
57
58 #include <fs/ext2fs/ext2_mount.h>
59 #include <fs/ext2fs/inode.h>
60
61 #include <fs/ext2fs/fs.h>
62 #include <fs/ext2fs/ext2fs.h>
63 #include <fs/ext2fs/ext2_dinode.h>
64 #include <fs/ext2fs/ext2_extern.h>
65
66 static int      ext2_flushfiles(struct mount *mp, int flags, struct thread *td);
67 static int      ext2_mountfs(struct vnode *, struct mount *);
68 static int      ext2_reload(struct mount *mp, struct thread *td);
69 static int      ext2_sbupdate(struct ext2mount *, int);
70 static int      ext2_cgupdate(struct ext2mount *, int);
71 static vfs_unmount_t            ext2_unmount;
72 static vfs_root_t               ext2_root;
73 static vfs_statfs_t             ext2_statfs;
74 static vfs_sync_t               ext2_sync;
75 static vfs_vget_t               ext2_vget;
76 static vfs_fhtovp_t             ext2_fhtovp;
77 static vfs_mount_t              ext2_mount;
78
79 MALLOC_DEFINE(M_EXT2NODE, "ext2_node", "EXT2 vnode private part");
80 static MALLOC_DEFINE(M_EXT2MNT, "ext2_mount", "EXT2 mount structure");
81
82 static struct vfsops ext2fs_vfsops = {
83         .vfs_fhtovp =           ext2_fhtovp,
84         .vfs_mount =            ext2_mount,
85         .vfs_root =             ext2_root,      /* root inode via vget */
86         .vfs_statfs =           ext2_statfs,
87         .vfs_sync =             ext2_sync,
88         .vfs_unmount =          ext2_unmount,
89         .vfs_vget =             ext2_vget,
90 };
91
92 VFS_SET(ext2fs_vfsops, ext2fs, 0);
93
94 static int      ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev,
95                     int ronly);
96 static int      compute_sb_data(struct vnode * devvp,
97                     struct ext2fs * es, struct m_ext2fs * fs);
98
99 static const char *ext2_opts[] = { "acls", "async", "noatime", "noclusterr", 
100     "noclusterw", "noexec", "export", "force", "from", "multilabel",
101     "suiddir", "nosymfollow", "sync", "union", NULL };
102
103 /*
104  * VFS Operations.
105  *
106  * mount system call
107  */
108 static int
109 ext2_mount(struct mount *mp)
110 {
111         struct vfsoptlist *opts;
112         struct vnode *devvp;
113         struct thread *td;
114         struct ext2mount *ump = 0;
115         struct m_ext2fs *fs;
116         struct nameidata nd, *ndp = &nd;
117         accmode_t accmode;
118         char *path, *fspec;
119         int error, flags, len;
120
121         td = curthread;
122         opts = mp->mnt_optnew;
123
124         if (vfs_filteropt(opts, ext2_opts))
125                 return (EINVAL);
126
127         vfs_getopt(opts, "fspath", (void **)&path, NULL);
128         /* Double-check the length of path.. */
129         if (strlen(path) >= MAXMNTLEN - 1)
130                 return (ENAMETOOLONG);
131
132         fspec = NULL;
133         error = vfs_getopt(opts, "from", (void **)&fspec, &len);
134         if (!error && fspec[len - 1] != '\0')
135                 return (EINVAL);
136
137         /*
138          * If updating, check whether changing from read-only to
139          * read/write; if there is no device name, that's all we do.
140          */
141         if (mp->mnt_flag & MNT_UPDATE) {
142                 ump = VFSTOEXT2(mp);
143                 fs = ump->um_e2fs; 
144                 error = 0;
145                 if (fs->e2fs_ronly == 0 &&
146                     vfs_flagopt(opts, "ro", NULL, 0)) {
147                         error = VFS_SYNC(mp, MNT_WAIT);
148                         if (error)
149                                 return (error);
150                         flags = WRITECLOSE;
151                         if (mp->mnt_flag & MNT_FORCE)
152                                 flags |= FORCECLOSE;
153                         error = ext2_flushfiles(mp, flags, td);
154                         if ( error == 0 && fs->e2fs_wasvalid && ext2_cgupdate(ump, MNT_WAIT) == 0) {
155                                 fs->e2fs->e2fs_state |= E2FS_ISCLEAN;
156                                 ext2_sbupdate(ump, MNT_WAIT);
157                         }
158                         fs->e2fs_ronly = 1;
159                         vfs_flagopt(opts, "ro", &mp->mnt_flag, MNT_RDONLY);
160                         DROP_GIANT();
161                         g_topology_lock();
162                         g_access(ump->um_cp, 0, -1, 0);
163                         g_topology_unlock();
164                         PICKUP_GIANT();
165                 }
166                 if (!error && (mp->mnt_flag & MNT_RELOAD))
167                         error = ext2_reload(mp, td);
168                 if (error)
169                         return (error);
170                 devvp = ump->um_devvp;
171                 if (fs->e2fs_ronly && !vfs_flagopt(opts, "ro", NULL, 0)) {
172                         if (ext2_check_sb_compat(fs->e2fs, devvp->v_rdev, 0))
173                                 return (EPERM);
174
175                         /*
176                          * If upgrade to read-write by non-root, then verify
177                          * that user has necessary permissions on the device.
178                          */
179                         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
180                         error = VOP_ACCESS(devvp, VREAD | VWRITE,
181                             td->td_ucred, td);
182                         if (error)
183                                 error = priv_check(td, PRIV_VFS_MOUNT_PERM);
184                         if (error) {
185                                 VOP_UNLOCK(devvp, 0);
186                                 return (error);
187                         }
188                         VOP_UNLOCK(devvp, 0);
189                         DROP_GIANT();
190                         g_topology_lock();
191                         error = g_access(ump->um_cp, 0, 1, 0);
192                         g_topology_unlock();
193                         PICKUP_GIANT();
194                         if (error)
195                                 return (error);
196
197                         if ((fs->e2fs->e2fs_state & E2FS_ISCLEAN) == 0 ||
198                             (fs->e2fs->e2fs_state & E2FS_ERRORS)) {
199                                 if (mp->mnt_flag & MNT_FORCE) {
200                                         printf(
201 "WARNING: %s was not properly dismounted\n", fs->e2fs_fsmnt);
202                                 } else {
203                                         printf(
204 "WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
205                                             fs->e2fs_fsmnt);
206                                         return (EPERM);
207                                 }
208                         }
209                         fs->e2fs->e2fs_state &= ~E2FS_ISCLEAN;
210                         (void)ext2_cgupdate(ump, MNT_WAIT);
211                         fs->e2fs_ronly = 0;
212                         MNT_ILOCK(mp);
213                         mp->mnt_flag &= ~MNT_RDONLY;
214                         MNT_IUNLOCK(mp);
215                 }
216                 if (vfs_flagopt(opts, "export", NULL, 0)) {
217                         /* Process export requests in vfs_mount.c. */
218                         return (error);
219                 }
220         }
221
222         /*
223          * Not an update, or updating the name: look up the name
224          * and verify that it refers to a sensible disk device.
225          */
226         if (fspec == NULL)
227                 return (EINVAL);
228         NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td);
229         if ((error = namei(ndp)) != 0)
230                 return (error);
231         NDFREE(ndp, NDF_ONLY_PNBUF);
232         devvp = ndp->ni_vp;
233
234         if (!vn_isdisk(devvp, &error)) {
235                 vput(devvp);
236                 return (error);
237         }
238
239         /*
240          * If mount by non-root, then verify that user has necessary
241          * permissions on the device.
242          *
243          * XXXRW: VOP_ACCESS() enough?
244          */
245         accmode = VREAD;
246         if ((mp->mnt_flag & MNT_RDONLY) == 0)
247                 accmode |= VWRITE;
248         error = VOP_ACCESS(devvp, accmode, td->td_ucred, td);
249         if (error)
250                 error = priv_check(td, PRIV_VFS_MOUNT_PERM);
251         if (error) {
252                 vput(devvp);
253                 return (error);
254         }
255
256         if ((mp->mnt_flag & MNT_UPDATE) == 0) {
257                 error = ext2_mountfs(devvp, mp);
258         } else {
259                 if (devvp != ump->um_devvp) {
260                         vput(devvp);
261                         return (EINVAL);        /* needs translation */
262                 } else
263                         vput(devvp);
264         }
265         if (error) {
266                 vrele(devvp);
267                 return (error);
268         }
269         ump = VFSTOEXT2(mp);
270         fs = ump->um_e2fs;
271
272         /*
273          * Note that this strncpy() is ok because of a check at the start
274          * of ext2_mount().
275          */
276         strncpy(fs->e2fs_fsmnt, path, MAXMNTLEN);
277         fs->e2fs_fsmnt[MAXMNTLEN - 1] = '\0';
278         vfs_mountedfrom(mp, fspec);
279         return (0);
280 }
281
282 static int
283 ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly)
284 {
285
286         if (es->e2fs_magic != E2FS_MAGIC) {
287                 printf("ext2fs: %s: wrong magic number %#x (expected %#x)\n",
288                     devtoname(dev), es->e2fs_magic, E2FS_MAGIC);
289                 return (1);
290         }
291         if (es->e2fs_rev > E2FS_REV0) {
292                 if (es->e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) {
293                         printf(
294 "WARNING: mount of %s denied due to unsupported optional features\n",
295                             devtoname(dev));
296                         return (1);
297                 }
298                 if (!ronly &&
299                     (es->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP)) {
300                         printf("WARNING: R/W mount of %s denied due to "
301                             "unsupported optional features\n", devtoname(dev));
302                         return (1);
303                 }
304         }
305         return (0);
306 }
307
308 /*
309  * This computes the fields of the  ext2_sb_info structure from the
310  * data in the ext2_super_block structure read in.
311  */
312 static int
313 compute_sb_data(struct vnode *devvp, struct ext2fs *es,
314     struct m_ext2fs *fs)
315 {
316         int db_count, error;
317         int i;
318         int logic_sb_block = 1; /* XXX for now */
319         struct buf *bp;
320
321         fs->e2fs_bsize = EXT2_MIN_BLOCK_SIZE << es->e2fs_log_bsize;
322         fs->e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->e2fs_log_bsize;
323         fs->e2fs_fsbtodb = es->e2fs_log_bsize + 1;
324         fs->e2fs_qbmask = fs->e2fs_bsize - 1;
325         fs->e2fs_blocksize_bits = es->e2fs_log_bsize + 10;
326         fs->e2fs_fsize = EXT2_MIN_FRAG_SIZE << es->e2fs_log_fsize;
327         if (fs->e2fs_fsize)
328                 fs->e2fs_fpb = fs->e2fs_bsize / fs->e2fs_fsize;
329         fs->e2fs_bpg = es->e2fs_bpg;
330         fs->e2fs_fpg = es->e2fs_fpg;
331         fs->e2fs_ipg = es->e2fs_ipg;
332         if (es->e2fs_rev == E2FS_REV0) {
333                 fs->e2fs_first_inode = EXT2_FIRSTINO;
334                 fs->e2fs_isize = E2FS_REV0_INODE_SIZE ;
335         } else {
336                 fs->e2fs_first_inode = es->e2fs_first_ino;
337                 fs->e2fs_isize = es->e2fs_inode_size;
338
339                 /*
340                  * Simple sanity check for superblock inode size value.
341                  */
342                 if (fs->e2fs_isize < E2FS_REV0_INODE_SIZE  ||
343                     fs->e2fs_isize > fs->e2fs_bsize ||
344                     (fs->e2fs_isize & (fs->e2fs_isize - 1)) != 0) {
345                         printf("EXT2-fs: invalid inode size %d\n",
346                             fs->e2fs_isize);
347                         return (EIO);
348                 }
349         }
350         fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs);
351         fs->e2fs_itpg = fs->e2fs_ipg /fs->e2fs_ipb;
352         fs->e2fs_descpb = fs->e2fs_bsize / sizeof (struct ext2_gd);
353         /* s_resuid / s_resgid ? */
354         fs->e2fs_gcount = (es->e2fs_bcount - es->e2fs_first_dblock +
355             EXT2_BLOCKS_PER_GROUP(fs) - 1) / EXT2_BLOCKS_PER_GROUP(fs);
356         db_count = (fs->e2fs_gcount + EXT2_DESC_PER_BLOCK(fs) - 1) /
357             EXT2_DESC_PER_BLOCK(fs);
358         fs->e2fs_gdbcount = db_count;
359         fs->e2fs_gd = malloc(db_count * fs->e2fs_bsize,
360             M_EXT2MNT, M_WAITOK);
361         fs->e2fs_contigdirs = malloc(fs->e2fs_gcount * sizeof(*fs->e2fs_contigdirs), 
362             M_EXT2MNT, M_WAITOK);
363
364         /*
365          * Adjust logic_sb_block.
366          * Godmar thinks: if the blocksize is greater than 1024, then
367          * the superblock is logically part of block zero.
368          */
369         if(fs->e2fs_bsize > SBSIZE)
370                 logic_sb_block = 0;
371         for (i = 0; i < db_count; i++) {
372                 error = bread(devvp ,
373                          fsbtodb(fs, logic_sb_block + i + 1 ),
374                         fs->e2fs_bsize, NOCRED, &bp);
375                 if (error) {
376                         free(fs->e2fs_gd, M_EXT2MNT);
377                         brelse(bp);
378                         return (error);
379                 }
380                 e2fs_cgload((struct ext2_gd *)bp->b_data,
381                     &fs->e2fs_gd[
382                         i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
383                     fs->e2fs_bsize);
384                 brelse(bp);
385                 bp = NULL;
386         }
387         fs->e2fs_total_dir = 0;
388         for (i=0; i < fs->e2fs_gcount; i++){
389                 fs->e2fs_total_dir += fs->e2fs_gd[i].ext2bgd_ndirs;
390                 fs->e2fs_contigdirs[i] = 0;
391         }
392         if (es->e2fs_rev == E2FS_REV0 ||
393             (es->e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGEFILE) == 0)
394                 fs->e2fs_maxfilesize = 0x7fffffff;
395         else
396                 fs->e2fs_maxfilesize = 0x7fffffffffffffff;
397         return (0);
398 }
399
400 /*
401  * Reload all incore data for a filesystem (used after running fsck on
402  * the root filesystem and finding things to fix). The filesystem must
403  * be mounted read-only.
404  *
405  * Things to do to update the mount:
406  *      1) invalidate all cached meta-data.
407  *      2) re-read superblock from disk.
408  *      3) re-read summary information from disk.
409  *      4) invalidate all inactive vnodes.
410  *      5) invalidate all cached file data.
411  *      6) re-read inode data for all active vnodes.
412  * XXX we are missing some steps, in particular # 3, this has to be reviewed.
413  */
414 static int
415 ext2_reload(struct mount *mp, struct thread *td)
416 {
417         struct vnode *vp, *mvp, *devvp;
418         struct inode *ip;
419         struct buf *bp;
420         struct ext2fs *es;
421         struct m_ext2fs *fs;
422         int error;
423
424         if ((mp->mnt_flag & MNT_RDONLY) == 0)
425                 return (EINVAL);
426         /*
427          * Step 1: invalidate all cached meta-data.
428          */
429         devvp = VFSTOEXT2(mp)->um_devvp;
430         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
431         if (vinvalbuf(devvp, 0, 0, 0) != 0)
432                 panic("ext2_reload: dirty1");
433         VOP_UNLOCK(devvp, 0);
434
435         /*
436          * Step 2: re-read superblock from disk.
437          * constants have been adjusted for ext2
438          */
439         if ((error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) != 0)
440                 return (error);
441         es = (struct ext2fs *)bp->b_data;
442         if (ext2_check_sb_compat(es, devvp->v_rdev, 0) != 0) {
443                 brelse(bp);
444                 return (EIO);           /* XXX needs translation */
445         }
446         fs = VFSTOEXT2(mp)->um_e2fs;
447         bcopy(bp->b_data, fs->e2fs, sizeof(struct ext2fs));
448
449         if((error = compute_sb_data(devvp, es, fs)) != 0) {
450                 brelse(bp);
451                 return (error);
452         }
453 #ifdef UNKLAR
454         if (fs->fs_sbsize < SBSIZE)
455                 bp->b_flags |= B_INVAL;
456 #endif
457         brelse(bp);
458
459 loop:
460         MNT_ILOCK(mp);
461         MNT_VNODE_FOREACH(vp, mp, mvp) {
462                 VI_LOCK(vp);
463                 if (vp->v_iflag & VI_DOOMED) {
464                         VI_UNLOCK(vp);
465                         continue;
466                 }
467                 MNT_IUNLOCK(mp);
468                 /*
469                  * Step 4: invalidate all cached file data.
470                  */
471                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
472                         MNT_VNODE_FOREACH_ABORT(mp, mvp);
473                         goto loop;
474                 }
475                 if (vinvalbuf(vp, 0, 0, 0))
476                         panic("ext2_reload: dirty2");
477
478                 /*
479                  * Step 5: re-read inode data for all active vnodes.
480                  */
481                 ip = VTOI(vp);
482                 error = bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
483                     (int)fs->e2fs_bsize, NOCRED, &bp);
484                 if (error) {
485                         VOP_UNLOCK(vp, 0);
486                         vrele(vp);
487                         MNT_VNODE_FOREACH_ABORT(mp, mvp);
488                         return (error);
489                 }
490                 ext2_ei2i((struct ext2fs_dinode *) ((char *)bp->b_data +
491                     EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number)), ip);
492                 brelse(bp);
493                 VOP_UNLOCK(vp, 0);
494                 vrele(vp);
495                 MNT_ILOCK(mp);
496         }
497         MNT_IUNLOCK(mp);
498         return (0);
499 }
500
501 /*
502  * Common code for mount and mountroot.
503  */
504 static int
505 ext2_mountfs(struct vnode *devvp, struct mount *mp)
506 {
507         struct ext2mount *ump;
508         struct buf *bp;
509         struct m_ext2fs *fs;
510         struct ext2fs *es;
511         struct cdev *dev = devvp->v_rdev;
512         struct g_consumer *cp;
513         struct bufobj *bo;
514         int error;
515         int ronly;
516
517         ronly = vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0);
518         /* XXX: use VOP_ACESS to check FS perms */
519         DROP_GIANT();
520         g_topology_lock();
521         error = g_vfs_open(devvp, &cp, "ext2fs", ronly ? 0 : 1);
522         g_topology_unlock();
523         PICKUP_GIANT();
524         VOP_UNLOCK(devvp, 0);
525         if (error)
526                 return (error);
527
528         /* XXX: should we check for some sectorsize or 512 instead? */
529         if (((SBSIZE % cp->provider->sectorsize) != 0) ||
530             (SBSIZE < cp->provider->sectorsize)) {
531                 DROP_GIANT();
532                 g_topology_lock();
533                 g_vfs_close(cp);
534                 g_topology_unlock();
535                 PICKUP_GIANT();
536                 return (EINVAL);
537         }
538
539         bo = &devvp->v_bufobj;
540         bo->bo_private = cp;
541         bo->bo_ops = g_vfs_bufops;
542         if (devvp->v_rdev->si_iosize_max != 0)
543                 mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
544         if (mp->mnt_iosize_max > MAXPHYS)
545                 mp->mnt_iosize_max = MAXPHYS;
546
547         bp = NULL;
548         ump = NULL;
549         if ((error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) != 0)
550                 goto out;
551         es = (struct ext2fs *)bp->b_data;
552         if (ext2_check_sb_compat(es, dev, ronly) != 0) {
553                 error = EINVAL;         /* XXX needs translation */
554                 goto out;
555         }
556         if ((es->e2fs_state & E2FS_ISCLEAN) == 0 ||
557             (es->e2fs_state & E2FS_ERRORS)) {
558                 if (ronly || (mp->mnt_flag & MNT_FORCE)) {
559                         printf(
560 "WARNING: Filesystem was not properly dismounted\n");
561                 } else {
562                         printf(
563 "WARNING: R/W mount denied.  Filesystem is not clean - run fsck\n");
564                         error = EPERM;
565                         goto out;
566                 }
567         }
568         ump = malloc(sizeof *ump, M_EXT2MNT, M_WAITOK);
569         bzero((caddr_t)ump, sizeof *ump);
570
571         /*
572          * I don't know whether this is the right strategy. Note that
573          * we dynamically allocate both an ext2_sb_info and an ext2_super_block
574          * while Linux keeps the super block in a locked buffer.
575          */
576         ump->um_e2fs = malloc(sizeof(struct m_ext2fs),
577                 M_EXT2MNT, M_WAITOK);
578         ump->um_e2fs->e2fs = malloc(sizeof(struct ext2fs),
579                 M_EXT2MNT, M_WAITOK);
580         mtx_init(EXT2_MTX(ump), "EXT2FS", "EXT2FS Lock", MTX_DEF);
581         bcopy(es, ump->um_e2fs->e2fs, (u_int)sizeof(struct ext2fs));
582         if ((error = compute_sb_data(devvp, ump->um_e2fs->e2fs, ump->um_e2fs)))
583                 goto out;
584
585         brelse(bp);
586         bp = NULL;
587         fs = ump->um_e2fs;
588         fs->e2fs_ronly = ronly; /* ronly is set according to mnt_flags */
589
590         /*
591          * If the fs is not mounted read-only, make sure the super block is
592          * always written back on a sync().
593          */
594         fs->e2fs_wasvalid = fs->e2fs->e2fs_state & E2FS_ISCLEAN ? 1 : 0;
595         if (ronly == 0) {
596                 fs->e2fs_fmod = 1;              /* mark it modified */
597                 fs->e2fs->e2fs_state &= ~E2FS_ISCLEAN;  /* set fs invalid */
598         }
599         mp->mnt_data = ump;
600         mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
601         mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
602         mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN;
603         MNT_ILOCK(mp);
604         mp->mnt_flag |= MNT_LOCAL;
605         MNT_IUNLOCK(mp);
606         ump->um_mountp = mp;
607         ump->um_dev = dev;
608         ump->um_devvp = devvp;
609         ump->um_bo = &devvp->v_bufobj;
610         ump->um_cp = cp;
611
612         /*
613          * Setting those two parameters allowed us to use
614          * ufs_bmap w/o changse!
615          */
616         ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
617         ump->um_bptrtodb = fs->e2fs->e2fs_log_bsize + 1;
618         ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
619         if (ronly == 0)
620                 ext2_sbupdate(ump, MNT_WAIT);
621         /*
622          * Initialize filesystem stat information in mount struct.
623          */
624         MNT_ILOCK(mp);
625         mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED |
626             MNTK_EXTENDED_SHARED;
627         MNT_IUNLOCK(mp);
628         return (0);
629 out:
630         if (bp)
631                 brelse(bp);
632         if (cp != NULL) {
633                 DROP_GIANT();
634                 g_topology_lock();
635                 g_vfs_close(cp);
636                 g_topology_unlock();
637                 PICKUP_GIANT();
638         }
639         if (ump) {
640                 mtx_destroy(EXT2_MTX(ump));
641                 free(ump->um_e2fs->e2fs_gd, M_EXT2MNT);
642                 free(ump->um_e2fs->e2fs_contigdirs, M_EXT2MNT);
643                 free(ump->um_e2fs->e2fs, M_EXT2MNT);
644                 free(ump->um_e2fs, M_EXT2MNT);
645                 free(ump, M_EXT2MNT);
646                 mp->mnt_data = NULL;
647         }
648         return (error);
649 }
650
651 /*
652  * Unmount system call.
653  */
654 static int
655 ext2_unmount(struct mount *mp, int mntflags)
656 {
657         struct ext2mount *ump;
658         struct m_ext2fs *fs;
659         int error, flags, ronly;
660
661         flags = 0;
662         if (mntflags & MNT_FORCE) {
663                 if (mp->mnt_flag & MNT_ROOTFS)
664                         return (EINVAL);
665                 flags |= FORCECLOSE;
666         }
667         if ((error = ext2_flushfiles(mp, flags, curthread)) != 0)
668                 return (error);
669         ump = VFSTOEXT2(mp);
670         fs = ump->um_e2fs;
671         ronly = fs->e2fs_ronly;
672         if (ronly == 0 && ext2_cgupdate(ump, MNT_WAIT) == 0) {
673                 if (fs->e2fs_wasvalid)
674                         fs->e2fs->e2fs_state |= E2FS_ISCLEAN;
675                 ext2_sbupdate(ump, MNT_WAIT);
676         }
677
678         DROP_GIANT();
679         g_topology_lock();
680         g_vfs_close(ump->um_cp);
681         g_topology_unlock();
682         PICKUP_GIANT();
683         vrele(ump->um_devvp);
684         free(fs->e2fs_gd, M_EXT2MNT);
685         free(fs->e2fs_contigdirs, M_EXT2MNT);
686         free(fs->e2fs, M_EXT2MNT);
687         free(fs, M_EXT2MNT);
688         free(ump, M_EXT2MNT);
689         mp->mnt_data = NULL;
690         MNT_ILOCK(mp);
691         mp->mnt_flag &= ~MNT_LOCAL;
692         MNT_IUNLOCK(mp);
693         return (error);
694 }
695
696 /*
697  * Flush out all the files in a filesystem.
698  */
699 static int
700 ext2_flushfiles(struct mount *mp, int flags, struct thread *td)
701 {
702         int error;
703
704         error = vflush(mp, 0, flags, td);
705         return (error);
706 }
707 /*
708  * Get file system statistics.
709  */
710 int
711 ext2_statfs(struct mount *mp, struct statfs *sbp)
712 {
713         struct ext2mount *ump;
714         struct m_ext2fs *fs;
715         uint32_t overhead, overhead_per_group, ngdb;
716         int i, ngroups;
717
718         ump = VFSTOEXT2(mp);
719         fs = ump->um_e2fs;
720         if (fs->e2fs->e2fs_magic != E2FS_MAGIC)
721                 panic("ext2fs_statvfs");
722
723         /*
724          * Compute the overhead (FS structures)
725          */
726         overhead_per_group =
727             1 /* block bitmap */ +
728             1 /* inode bitmap */ +
729             fs->e2fs_itpg;
730         overhead = fs->e2fs->e2fs_first_dblock +
731             fs->e2fs_gcount * overhead_per_group;
732         if (fs->e2fs->e2fs_rev > E2FS_REV0 &&
733             fs->e2fs->e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) {
734                 for (i = 0, ngroups = 0; i < fs->e2fs_gcount; i++) {
735                         if (cg_has_sb(i))
736                                 ngroups++;
737                 }
738         } else {
739                 ngroups = fs->e2fs_gcount;
740         }
741         ngdb = fs->e2fs_gdbcount;
742         if (fs->e2fs->e2fs_rev > E2FS_REV0 &&
743             fs->e2fs->e2fs_features_compat & EXT2F_COMPAT_RESIZE)
744                 ngdb += fs->e2fs->e2fs_reserved_ngdb;
745         overhead += ngroups * (1 /* superblock */ + ngdb);
746
747         sbp->f_bsize = EXT2_FRAG_SIZE(fs);
748         sbp->f_iosize = EXT2_BLOCK_SIZE(fs);
749         sbp->f_blocks = fs->e2fs->e2fs_bcount - overhead;
750         sbp->f_bfree = fs->e2fs->e2fs_fbcount;
751         sbp->f_bavail = sbp->f_bfree - fs->e2fs->e2fs_rbcount;
752         sbp->f_files = fs->e2fs->e2fs_icount;
753         sbp->f_ffree = fs->e2fs->e2fs_ficount;
754         return (0);
755 }
756
757 /*
758  * Go through the disk queues to initiate sandbagged IO;
759  * go through the inodes to write those that have been modified;
760  * initiate the writing of the super block if it has been modified.
761  *
762  * Note: we are always called with the filesystem marked `MPBUSY'.
763  */
764 static int
765 ext2_sync(struct mount *mp, int waitfor)
766 {
767         struct vnode *mvp, *vp;
768         struct thread *td;
769         struct inode *ip;
770         struct ext2mount *ump = VFSTOEXT2(mp);
771         struct m_ext2fs *fs;
772         int error, allerror = 0;
773
774         td = curthread;
775         fs = ump->um_e2fs;
776         if (fs->e2fs_fmod != 0 && fs->e2fs_ronly != 0) {                /* XXX */
777                 printf("fs = %s\n", fs->e2fs_fsmnt);
778                 panic("ext2_sync: rofs mod");
779         }
780
781         /*
782          * Write back each (modified) inode.
783          */
784         MNT_ILOCK(mp);
785 loop:
786         MNT_VNODE_FOREACH(vp, mp, mvp) {
787                 VI_LOCK(vp);
788                 if (vp->v_type == VNON || (vp->v_iflag & VI_DOOMED)) {
789                         VI_UNLOCK(vp);
790                         continue;
791                 }
792                 MNT_IUNLOCK(mp);
793                 ip = VTOI(vp);
794                 if ((ip->i_flag &
795                     (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
796                     (vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
797                     waitfor == MNT_LAZY)) {
798                         VI_UNLOCK(vp);
799                         MNT_ILOCK(mp);
800                         continue;
801                 }
802                 error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, td);
803                 if (error) {
804                         MNT_ILOCK(mp);
805                         if (error == ENOENT) {
806                                 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
807                                 goto loop;
808                         }
809                         continue;
810                 }
811                 if ((error = VOP_FSYNC(vp, waitfor, td)) != 0)
812                         allerror = error;
813                 VOP_UNLOCK(vp, 0);
814                 vrele(vp);
815                 MNT_ILOCK(mp);
816         }
817         MNT_IUNLOCK(mp);
818
819         /*
820          * Force stale file system control information to be flushed.
821          */
822         if (waitfor != MNT_LAZY) {
823                 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
824                 if ((error = VOP_FSYNC(ump->um_devvp, waitfor, td)) != 0)
825                         allerror = error;
826                 VOP_UNLOCK(ump->um_devvp, 0);
827         }
828
829         /*
830          * Write back modified superblock.
831          */
832         if (fs->e2fs_fmod != 0) {
833                 fs->e2fs_fmod = 0;
834                 fs->e2fs->e2fs_wtime = time_second;
835                 if ((error = ext2_cgupdate(ump, waitfor)) != 0)
836                         allerror = error;
837         }
838         return (allerror);
839 }
840
841 /*
842  * Look up an EXT2FS dinode number to find its incore vnode, otherwise read it
843  * in from disk.  If it is in core, wait for the lock bit to clear, then
844  * return the inode locked.  Detection and handling of mount points must be
845  * done by the calling routine.
846  */
847 static int
848 ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
849 {
850         struct m_ext2fs *fs;
851         struct inode *ip;
852         struct ext2mount *ump;
853         struct buf *bp;
854         struct vnode *vp;
855         struct cdev *dev;
856         struct thread *td;
857         int i, error;
858         int used_blocks;
859
860         td = curthread;
861         error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL);
862         if (error || *vpp != NULL)
863                 return (error);
864
865         ump = VFSTOEXT2(mp);
866         dev = ump->um_dev;
867
868         /*
869          * If this malloc() is performed after the getnewvnode()
870          * it might block, leaving a vnode with a NULL v_data to be
871          * found by ext2_sync() if a sync happens to fire right then,
872          * which will cause a panic because ext2_sync() blindly
873          * dereferences vp->v_data (as well it should).
874          */
875         ip = malloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK | M_ZERO);
876
877         /* Allocate a new vnode/inode. */
878         if ((error = getnewvnode("ext2fs", mp, &ext2_vnodeops, &vp)) != 0) {
879                 *vpp = NULL;
880                 free(ip, M_EXT2NODE);
881                 return (error);
882         }
883         vp->v_data = ip;
884         ip->i_vnode = vp;
885         ip->i_e2fs = fs = ump->um_e2fs;
886         ip->i_ump  = ump;
887         ip->i_number = ino;
888
889         lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
890         error = insmntque(vp, mp);
891         if (error != 0) {
892                 free(ip, M_EXT2NODE);
893                 *vpp = NULL;
894                 return (error);
895         }
896         error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL);
897         if (error || *vpp != NULL)
898                 return (error);
899
900         /* Read in the disk contents for the inode, copy into the inode. */
901         if ((error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
902             (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) {
903                 /*
904                  * The inode does not contain anything useful, so it would
905                  * be misleading to leave it on its hash chain. With mode
906                  * still zero, it will be unlinked and returned to the free
907                  * list by vput().
908                  */
909                 brelse(bp);
910                 vput(vp);
911                 *vpp = NULL;
912                 return (error);
913         }
914         /* convert ext2 inode to dinode */
915         ext2_ei2i((struct ext2fs_dinode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
916                         ino_to_fsbo(fs, ino)), ip);
917         ip->i_block_group = ino_to_cg(fs, ino);
918         ip->i_next_alloc_block = 0;
919         ip->i_next_alloc_goal = 0;
920         ip->i_prealloc_count = 0;
921         ip->i_prealloc_block = 0;
922
923         /*
924          * Now we want to make sure that block pointers for unused
925          * blocks are zeroed out - ext2_balloc depends on this
926          * although for regular files and directories only
927          */
928         if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) {
929                 used_blocks = (ip->i_size+fs->e2fs_bsize-1) / fs->e2fs_bsize;
930                 for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++)
931                         ip->i_db[i] = 0;
932         }
933 /*
934         ext2_print_inode(ip);
935 */
936         bqrelse(bp);
937
938         /*
939          * Initialize the vnode from the inode, check for aliases.
940          * Note that the underlying vnode may have changed.
941          */
942         if ((error = ext2_vinit(mp, &ext2_fifoops, &vp)) != 0) {
943                 vput(vp);
944                 *vpp = NULL;
945                 return (error);
946         }
947
948         /*
949          * Finish inode initialization.
950          */
951
952         /*
953          * Set up a generation number for this inode if it does not
954          * already have one. This should only happen on old filesystems.
955          */
956         if (ip->i_gen == 0) {
957                 ip->i_gen = random() / 2 + 1;
958                 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
959                         ip->i_flag |= IN_MODIFIED;
960         }
961         *vpp = vp;
962         return (0);
963 }
964
965 /*
966  * File handle to vnode
967  *
968  * Have to be really careful about stale file handles:
969  * - check that the inode number is valid
970  * - call ext2_vget() to get the locked inode
971  * - check for an unallocated inode (i_mode == 0)
972  * - check that the given client host has export rights and return
973  *   those rights via. exflagsp and credanonp
974  */
975 static int
976 ext2_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp)
977 {
978         struct inode *ip;
979         struct ufid *ufhp;
980         struct vnode *nvp;
981         struct m_ext2fs *fs;
982         int error;
983
984         ufhp = (struct ufid *)fhp;
985         fs = VFSTOEXT2(mp)->um_e2fs;
986         if (ufhp->ufid_ino < EXT2_ROOTINO ||
987             ufhp->ufid_ino > fs->e2fs_gcount * fs->e2fs->e2fs_ipg)
988                 return (ESTALE);
989
990         error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp);
991         if (error) {
992                 *vpp = NULLVP;
993                 return (error);
994         }
995         ip = VTOI(nvp);
996         if (ip->i_mode == 0 ||
997             ip->i_gen != ufhp->ufid_gen || ip->i_nlink <= 0) {
998                 vput(nvp);
999                 *vpp = NULLVP;
1000                 return (ESTALE);
1001         }
1002         *vpp = nvp;
1003         vnode_create_vobject(*vpp, 0, curthread);
1004         return (0);
1005 }
1006
1007 /*
1008  * Write a superblock and associated information back to disk.
1009  */
1010 static int
1011 ext2_sbupdate(struct ext2mount *mp, int waitfor)
1012 {
1013         struct m_ext2fs *fs = mp->um_e2fs;
1014         struct ext2fs *es = fs->e2fs;
1015         struct buf *bp;
1016         int error = 0;
1017
1018         bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0, 0);
1019         bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2fs));
1020         if (waitfor == MNT_WAIT)
1021                 error = bwrite(bp);
1022         else
1023                 bawrite(bp);
1024
1025         /*
1026          * The buffers for group descriptors, inode bitmaps and block bitmaps
1027          * are not busy at this point and are (hopefully) written by the
1028          * usual sync mechanism. No need to write them here.
1029          */
1030         return (error);
1031 }
1032 int
1033 ext2_cgupdate(struct ext2mount *mp, int waitfor)
1034 {
1035         struct m_ext2fs *fs = mp->um_e2fs;
1036         struct buf *bp;
1037         int i, error = 0, allerror = 0;
1038
1039         allerror = ext2_sbupdate(mp, waitfor);
1040         for (i = 0; i < fs->e2fs_gdbcount; i++) {
1041                 bp = getblk(mp->um_devvp, fsbtodb(fs,
1042                     fs->e2fs->e2fs_first_dblock +
1043                     1 /* superblock */ + i), fs->e2fs_bsize, 0, 0, 0);
1044                 e2fs_cgsave(&fs->e2fs_gd[
1045                     i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
1046                     (struct ext2_gd *)bp->b_data, fs->e2fs_bsize);
1047                 if (waitfor == MNT_WAIT)
1048                         error = bwrite(bp);
1049                 else
1050                         bawrite(bp);
1051         }
1052
1053         if (!allerror && error)
1054                 allerror = error;
1055         return (allerror);
1056 }
1057 /*
1058  * Return the root of a filesystem.
1059  */
1060 static int
1061 ext2_root(struct mount *mp, int flags, struct vnode **vpp)
1062 {
1063         struct vnode *nvp;
1064         int error;
1065
1066         error = VFS_VGET(mp, EXT2_ROOTINO, LK_EXCLUSIVE, &nvp);
1067         if (error)
1068                 return (error);
1069         *vpp = nvp;
1070         return (0);
1071 }