2 * modified for EXT2FS support in Lites 1.1
4 * Aug 1995, Godmar Back (gback@cs.utah.edu)
5 * University of Utah, Department of Computer Science
8 * Copyright (c) 1989, 1991, 1993, 1994
9 * The Regents of the University of California. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
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 $
39 #include "opt_quota.h"
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/nlookup.h>
46 #include <sys/kernel.h>
47 #include <sys/vnode.h>
48 #include <sys/mount.h>
51 #include <sys/fcntl.h>
52 #include <sys/diskslice.h>
53 #include <sys/malloc.h>
55 #include <vm/vm_zone.h>
58 #include <sys/thread2.h>
63 #include "ext2_mount.h"
64 #include "ext2_extern.h"
68 #include "ext2_fs_sb.h"
70 extern struct vop_ops ext2_vnode_vops
;
71 extern struct vop_ops ext2_spec_vops
;
72 extern struct vop_ops ext2_fifo_vops
;
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
*);
88 static MALLOC_DEFINE(M_EXT2NODE
, "EXT2 node", "EXT2 vnode private part");
89 MALLOC_DEFINE(M_EXT2MNT
, "EXT2 mount", "EXT2 mount structure");
91 static struct vfsops ext2fs_vfsops
= {
92 .vfs_mount
= ext2_mount
,
93 .vfs_unmount
= ext2_unmount
,
94 .vfs_root
= ext2_root
, /* root inode via vget */
95 .vfs_quotactl
= ext2_quotactl
, /* quota operations */
96 .vfs_statfs
= ext2_statfs
,
97 .vfs_sync
= ext2_sync
,
98 .vfs_vget
= ext2_vget
,
99 .vfs_fhtovp
= ext2_fhtovp
,
100 .vfs_checkexp
= ext2_check_export
,
101 .vfs_vptofh
= ext2_vptofh
,
102 .vfs_init
= ext2_init
,
103 .vfs_uninit
= ext2_uninit
106 VFS_SET(ext2fs_vfsops
, ext2fs
, 0);
107 MODULE_VERSION(ext2fs
, 1);
109 static int ext2fs_inode_hash_lock
;
111 static int ext2_check_sb_compat (struct ext2_super_block
*es
,
112 cdev_t dev
, int ronly
);
113 static int compute_sb_data (struct vnode
*devvp
,
114 struct ext2_super_block
*es
,
115 struct ext2_sb_info
*fs
);
118 ext2_root(struct mount
*mp
, struct vnode
**vpp
)
123 error
= VFS_VGET(mp
, NULL
, (ino_t
)EXT2_ROOTINO
, &nvp
);
131 * Do operations associated with quotas
134 ext2_quotactl(struct mount
*mp
, int cmds
, uid_t uid
, caddr_t arg
,
140 int cmd
, type
, error
;
142 type
= cmds
& SUBCMDMASK
;
143 cmd
= cmds
>> SUBCMDSHIFT
;
164 error
= priv_check_cred(cred
, PRIV_UFS_QUOTAON
, 0);
168 error
= priv_check_cred(cred
, PRIV_UFS_QUOTAOFF
, 0);
172 error
= priv_check_cred(cred
, PRIV_VFS_SETQUOTA
, 0);
176 error
= priv_check_cred(cred
, PRIV_UFS_SETUSE
, 0);
180 if (uid
== cred
->cr_ruid
)
183 error
= priv_check_cred(cred
, PRIV_VFS_GETQUOTA
, 0);
199 if ((uint
)type
>= MAXQUOTAS
)
201 if (vfs_busy(mp
, LK_NOWAIT
))
207 error
= ext2_quotaon(cred
, mp
, type
, arg
);
211 error
= ext2_quotaoff(mp
, type
);
215 error
= ext2_setquota(mp
, uid
, type
, arg
);
219 error
= ext2_setuse(mp
, uid
, type
, arg
);
223 error
= ext2_getquota(mp
, uid
, type
, arg
);
227 error
= ext2_qsync(mp
);
240 * Initial UFS filesystems, done only once.
243 ext2_init(struct vfsconf
*vfsp
)
263 * data: this is actually a (struct ext2_args *)
266 ext2_mount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
269 struct ext2_args args
;
270 struct ext2_mount
*ump
= NULL
;
271 struct ext2_sb_info
*fs
;
275 struct nlookupdata nd
;
277 if ((error
= copyin(data
, (caddr_t
)&args
, sizeof (struct ext2_args
))) != 0)
281 * If updating, check whether changing from read-only to
282 * read/write; if there is no device name, that's all we do.
284 if (mp
->mnt_flag
& MNT_UPDATE
) {
287 devvp
= ump
->um_devvp
;
289 if (fs
->s_rd_only
== 0 && (mp
->mnt_flag
& MNT_RDONLY
)) {
291 if (mp
->mnt_flag
& MNT_FORCE
)
293 if (vfs_busy(mp
, LK_NOWAIT
))
295 error
= ext2_flushfiles(mp
, flags
);
297 if (!error
&& fs
->s_wasvalid
) {
298 fs
->s_es
->s_state
|= EXT2_VALID_FS
;
299 ext2_sbupdate(ump
, MNT_WAIT
);
302 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
303 VOP_OPEN(devvp
, FREAD
, FSCRED
, NULL
);
304 VOP_CLOSE(devvp
, FREAD
|FWRITE
, NULL
);
307 if (!error
&& (mp
->mnt_flag
& MNT_RELOAD
))
308 error
= ext2_reload(mp
, cred
);
311 if (ext2_check_sb_compat(fs
->s_es
, devvp
->v_rdev
,
312 (mp
->mnt_kern_flag
& MNTK_WANTRDWR
) == 0) != 0)
314 if (fs
->s_rd_only
&& (mp
->mnt_kern_flag
& MNTK_WANTRDWR
)) {
316 * If upgrade to read-write by non-root, then verify
317 * that user has necessary permissions on the device.
319 if (cred
->cr_uid
!= 0) {
320 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
321 error
= VOP_EACCESS(devvp
, VREAD
| VWRITE
, cred
);
329 if ((fs
->s_es
->s_state
& EXT2_VALID_FS
) == 0 ||
330 (fs
->s_es
->s_state
& EXT2_ERROR_FS
)) {
331 if (mp
->mnt_flag
& MNT_FORCE
) {
333 "WARNING: %s was not properly dismounted\n",
337 "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
342 fs
->s_es
->s_state
&= ~EXT2_VALID_FS
;
343 ext2_sbupdate(ump
, MNT_WAIT
);
345 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
346 VOP_OPEN(devvp
, FREAD
|FWRITE
, FSCRED
, NULL
);
347 VOP_CLOSE(devvp
, FREAD
, NULL
);
350 if (args
.fspec
== NULL
) {
352 * Process export requests.
354 return (vfs_export(mp
, &ump
->um_export
, &args
.export
));
358 * Not an update, or updating the name: look up the name
359 * and verify that it refers to a sensible block device.
362 error
= nlookup_init(&nd
, args
.fspec
, UIO_USERSPACE
, NLC_FOLLOW
);
364 error
= nlookup(&nd
);
366 error
= cache_vref(&nd
.nl_nch
, nd
.nl_cred
, &devvp
);
371 if (!vn_isdisk(devvp
, &error
)) {
377 * If mount by non-root, then verify that user has necessary
378 * permissions on the device.
380 if (cred
->cr_uid
!= 0) {
382 if ((mp
->mnt_flag
& MNT_RDONLY
) == 0)
383 accessmode
|= VWRITE
;
384 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
385 if ((error
= VOP_EACCESS(devvp
, accessmode
, cred
)) != 0) {
392 if ((mp
->mnt_flag
& MNT_UPDATE
) == 0) {
393 error
= ext2_mountfs(devvp
, mp
, cred
);
395 if (devvp
!= ump
->um_devvp
)
396 error
= EINVAL
; /* needs translation */
406 copyinstr(path
, fs
->fs_fsmnt
, sizeof(fs
->fs_fsmnt
) - 1, &size
);
407 bzero(fs
->fs_fsmnt
+ size
, sizeof(fs
->fs_fsmnt
) - size
);
408 copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1, &size
);
409 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
410 ext2_statfs(mp
, &mp
->mnt_stat
, cred
);
415 ext2_check_sb_compat(struct ext2_super_block
*es
, cdev_t dev
, int ronly
)
417 if (es
->s_magic
!= EXT2_SUPER_MAGIC
) {
418 kprintf("ext2fs: %s: wrong magic number %#x (expected %#x)\n",
419 devtoname(dev
), es
->s_magic
, EXT2_SUPER_MAGIC
);
422 if (es
->s_rev_level
> EXT2_GOOD_OLD_REV
) {
423 if (es
->s_feature_incompat
& ~EXT2_FEATURE_INCOMPAT_SUPP
) {
425 "WARNING: mount of %s denied due to unsupported optional features\n",
430 (es
->s_feature_ro_compat
& ~EXT2_FEATURE_RO_COMPAT_SUPP
)) {
432 "WARNING: R/W mount of %s denied due to unsupported optional features\n",
441 * this computes the fields of the ext2_sb_info structure from the
442 * data in the ext2_super_block structure read in
445 compute_sb_data(struct vnode
*devvp
, struct ext2_super_block
*es
,
446 struct ext2_sb_info
*fs
)
450 int logic_sb_block
= 1; /* XXX for now */
455 #define V(v) kprintf(#v"= %d\n", fs->v);
458 fs
->s_blocksize
= EXT2_MIN_BLOCK_SIZE
<< es
->s_log_block_size
;
460 fs
->s_bshift
= EXT2_MIN_BLOCK_LOG_SIZE
+ es
->s_log_block_size
;
462 fs
->s_fsbtodb
= es
->s_log_block_size
+ 1;
464 fs
->s_qbmask
= fs
->s_blocksize
- 1;
466 fs
->s_blocksize_bits
= EXT2_BLOCK_SIZE_BITS(es
);
468 fs
->s_frag_size
= EXT2_MIN_FRAG_SIZE
<< es
->s_log_frag_size
;
471 fs
->s_frags_per_block
= fs
->s_blocksize
/ fs
->s_frag_size
;
473 fs
->s_blocks_per_group
= es
->s_blocks_per_group
;
474 V(s_blocks_per_group
)
475 fs
->s_frags_per_group
= es
->s_frags_per_group
;
477 fs
->s_inodes_per_group
= es
->s_inodes_per_group
;
478 V(s_inodes_per_group
)
479 if (es
->s_rev_level
== EXT2_GOOD_OLD_REV
) {
480 fs
->s_first_ino
= EXT2_GOOD_OLD_FIRST_INO
;
481 fs
->s_inode_size
= EXT2_GOOD_OLD_INODE_SIZE
;
483 fs
->s_first_ino
= es
->s_first_ino
;
484 fs
->s_inode_size
= es
->s_inode_size
;
486 * Simple sanity check for superblock inode size value.
488 if (fs
->s_inode_size
< EXT2_GOOD_OLD_INODE_SIZE
||
489 fs
->s_inode_size
> fs
->s_blocksize
||
490 (fs
->s_inode_size
& (fs
->s_inode_size
- 1)) != 0) {
491 kprintf("EXT2-fs: invalid inode size %d\n",
498 fs
->s_inodes_per_block
= fs
->s_blocksize
/ EXT2_INODE_SIZE(fs
);
499 V(s_inodes_per_block
)
500 fs
->s_itb_per_group
= fs
->s_inodes_per_group
/fs
->s_inodes_per_block
;
502 fs
->s_desc_per_block
= fs
->s_blocksize
/ sizeof (struct ext2_group_desc
);
504 /* s_resuid / s_resgid ? */
505 fs
->s_groups_count
= (es
->s_blocks_count
- es
->s_first_data_block
+
506 EXT2_BLOCKS_PER_GROUP(fs
) - 1) /
507 EXT2_BLOCKS_PER_GROUP(fs
);
509 db_count
= (fs
->s_groups_count
+ EXT2_DESC_PER_BLOCK(fs
) - 1) /
510 EXT2_DESC_PER_BLOCK(fs
);
511 fs
->s_db_per_group
= db_count
;
514 fs
->s_group_desc
= kmalloc(db_count
* sizeof (struct buf
*),
515 M_EXT2MNT
, M_WAITOK
);
517 /* adjust logic_sb_block */
518 if (fs
->s_blocksize
> SBSIZE
)
520 * Godmar thinks: if the blocksize is greater than 1024,
521 * then, the superblock is logically part of block zero.
525 for (i
= 0; i
< db_count
; i
++) {
526 error
= bread(devvp
, fsbtodoff(fs
, logic_sb_block
+ i
+ 1),
527 fs
->s_blocksize
, &fs
->s_group_desc
[i
]);
529 for (j
= 0; j
< i
; j
++)
530 brelse(fs
->s_group_desc
[j
]);
531 kfree(fs
->s_group_desc
, M_EXT2MNT
);
532 kprintf("EXT2-fs: unable to read group descriptors (%d)\n", error
);
535 /* Set the B_LOCKED flag on the buffer, then brelse() it */
536 LCK_BUF(fs
->s_group_desc
[i
])
538 if (!ext2_check_descriptors(fs
)) {
539 for (j
= 0; j
< db_count
; j
++)
540 ULCK_BUF(fs
->s_group_desc
[j
])
541 kfree(fs
->s_group_desc
, M_EXT2MNT
);
542 kprintf("EXT2-fs: (ext2_check_descriptors failure) "
543 "unable to read group descriptors\n");
547 for (i
= 0; i
< EXT2_MAX_GROUP_LOADED
; i
++) {
548 fs
->s_inode_bitmap_number
[i
] = 0;
549 fs
->s_inode_bitmap
[i
] = NULL
;
550 fs
->s_block_bitmap_number
[i
] = 0;
551 fs
->s_block_bitmap
[i
] = NULL
;
553 fs
->s_loaded_inode_bitmaps
= 0;
554 fs
->s_loaded_block_bitmaps
= 0;
559 * Reload all incore data for a filesystem (used after running fsck on
560 * the root filesystem and finding things to fix). The filesystem must
561 * be mounted read-only.
563 * Things to do to update the mount:
564 * 1) invalidate all cached meta-data.
565 * 2) re-read superblock from disk.
566 * 3) re-read summary information from disk.
567 * 4) invalidate all inactive vnodes.
568 * 5) invalidate all cached file data.
569 * 6) re-read inode data for all active vnodes.
571 static int ext2_reload_scan(struct mount
*mp
, struct vnode
*vp
, void *rescan
);
578 struct ext2_sb_info
*fs
;
582 ext2_reload(struct mount
*mountp
, struct ucred
*cred
)
586 struct ext2_super_block
*es
;
587 struct ext2_sb_info
*fs
;
589 struct scaninfo scaninfo
;
591 if ((mountp
->mnt_flag
& MNT_RDONLY
) == 0)
594 * Step 1: invalidate all cached meta-data.
596 devvp
= VFSTOEXT2(mountp
)->um_devvp
;
597 if (vinvalbuf(devvp
, 0, 0, 0))
598 panic("ext2_reload: dirty1");
600 * Step 2: re-read superblock from disk.
601 * constants have been adjusted for ext2
603 if ((error
= bread(devvp
, SBOFF
, SBSIZE
, &bp
)) != 0)
605 es
= (struct ext2_super_block
*)bp
->b_data
;
606 if (ext2_check_sb_compat(es
, devvp
->v_rdev
, 0) != 0) {
608 return (EIO
); /* XXX needs translation */
610 fs
= VFSTOEXT2(mountp
)->um_e2fs
;
611 bcopy(bp
->b_data
, fs
->s_es
, sizeof(struct ext2_super_block
));
613 if((error
= compute_sb_data(devvp
, es
, fs
)) != 0) {
618 if (fs
->fs_sbsize
< SBSIZE
)
619 bp
->b_flags
|= B_INVAL
;
624 scaninfo
.devvp
= devvp
;
626 while (error
== 0 && scaninfo
.rescan
) {
628 error
= vmntvnodescan(mountp
, VMSC_GETVX
,
629 NULL
, ext2_reload_scan
, &scaninfo
);
635 ext2_reload_scan(struct mount
*mp
, struct vnode
*vp
, void *data
)
637 struct scaninfo
*info
= data
;
649 * Step 1: invalidate all cached file data.
651 if (vinvalbuf(vp
, 0, 0, 0))
652 panic("ext2_reload: dirty2");
654 * Step 2: re-read inode data for all active vnodes.
657 error
= bread(info
->devvp
,
658 fsbtodoff(info
->fs
, ino_to_fsba(info
->fs
, ip
->i_number
)),
659 (int)info
->fs
->s_blocksize
, &bp
);
662 ext2_ei2di((struct ext2_inode
*) ((char *)bp
->b_data
+
663 EXT2_INODE_SIZE(info
->fs
) * ino_to_fsbo(info
->fs
, ip
->i_number
)),
670 * Common code for mount and mountroot
673 ext2_mountfs(struct vnode
*devvp
, struct mount
*mp
, struct ucred
*cred
)
675 struct ext2_mount
*ump
;
677 struct ext2_sb_info
*fs
;
678 struct ext2_super_block
*es
;
684 * Disallow multiple mounts of the same device.
685 * Disallow mounting of a device that is currently in use
686 * (except for root, which might share swap device for miniroot).
687 * Flush out any old buffers remaining from a previous use.
689 if ((error
= vfs_mountedon(devvp
)) != 0)
691 if (vcount(devvp
) > 0)
693 if ((error
= vinvalbuf(devvp
, V_SAVE
, 0, 0)) != 0)
696 /* turn on this to force it to be read-only */
697 mp
->mnt_flag
|= MNT_RDONLY
;
700 ronly
= (mp
->mnt_flag
& MNT_RDONLY
) != 0;
701 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
702 error
= VOP_OPEN(devvp
, ronly
? FREAD
: FREAD
|FWRITE
, FSCRED
, NULL
);
707 if (dev
->si_iosize_max
!= 0)
708 mp
->mnt_iosize_max
= dev
->si_iosize_max
;
709 if (mp
->mnt_iosize_max
> MAXPHYS
)
710 mp
->mnt_iosize_max
= MAXPHYS
;
714 if ((error
= bread(devvp
, SBOFF
, SBSIZE
, &bp
)) != 0)
716 es
= (struct ext2_super_block
*)bp
->b_data
;
717 if (ext2_check_sb_compat(es
, dev
, ronly
) != 0) {
718 error
= EINVAL
; /* XXX needs translation */
721 if ((es
->s_state
& EXT2_VALID_FS
) == 0 ||
722 (es
->s_state
& EXT2_ERROR_FS
)) {
723 if (ronly
|| (mp
->mnt_flag
& MNT_FORCE
)) {
725 "WARNING: Filesystem was not properly dismounted\n");
728 "WARNING: R/W mount denied. Filesystem is not clean - run fsck\n");
733 ump
= kmalloc(sizeof *ump
, M_EXT2MNT
, M_WAITOK
| M_ZERO
);
734 ump
->um_malloctype
= M_EXT2NODE
;
735 ump
->um_blkatoff
= ext2_blkatoff
;
736 ump
->um_truncate
= ext2_truncate
;
737 ump
->um_update
= ext2_update
;
738 ump
->um_valloc
= ext2_valloc
;
739 ump
->um_vfree
= ext2_vfree
;
740 /* I don't know whether this is the right strategy. Note that
741 we dynamically allocate both a ext2_sb_info and a ext2_super_block
742 while Linux keeps the super block in a locked buffer
744 ump
->um_e2fs
= kmalloc(sizeof(struct ext2_sb_info
),
745 M_EXT2MNT
, M_WAITOK
);
746 ump
->um_e2fs
->s_es
= kmalloc(sizeof(struct ext2_super_block
),
747 M_EXT2MNT
, M_WAITOK
);
748 bcopy(es
, ump
->um_e2fs
->s_es
, (u_int
)sizeof(struct ext2_super_block
));
749 if ((error
= compute_sb_data(devvp
, ump
->um_e2fs
->s_es
, ump
->um_e2fs
)))
752 * We don't free the group descriptors allocated by compute_sb_data()
753 * until ext2_unmount(). This is OK since the mount will succeed.
758 fs
->s_rd_only
= ronly
; /* ronly is set according to mnt_flags */
759 /* if the fs is not mounted read-only, make sure the super block is
760 always written back on a sync()
762 fs
->s_wasvalid
= fs
->s_es
->s_state
& EXT2_VALID_FS
? 1 : 0;
764 fs
->s_dirt
= 1; /* mark it modified */
765 fs
->s_es
->s_state
&= ~EXT2_VALID_FS
; /* set fs invalid */
767 mp
->mnt_data
= (qaddr_t
)ump
;
768 mp
->mnt_stat
.f_fsid
.val
[0] = dev2udev(dev
);
769 mp
->mnt_stat
.f_fsid
.val
[1] = mp
->mnt_vfc
->vfc_typenum
;
770 mp
->mnt_maxsymlinklen
= EXT2_MAXSYMLINKLEN
;
771 mp
->mnt_flag
|= MNT_LOCAL
;
774 ump
->um_devvp
= devvp
;
775 /* setting those two parameters allows us to use
776 ext2_bmap w/o changse !
778 ump
->um_nindir
= EXT2_ADDR_PER_BLOCK(fs
);
779 ump
->um_bptrtodb
= fs
->s_es
->s_log_block_size
+ 1;
780 ump
->um_seqinc
= EXT2_FRAGS_PER_BLOCK(fs
);
781 for (i
= 0; i
< MAXQUOTAS
; i
++)
782 ump
->um_quotas
[i
] = NULLVP
;
783 dev
->si_mountpoint
= mp
;
785 vfs_add_vnodeops(mp
, &ext2_vnode_vops
, &mp
->mnt_vn_norm_ops
);
786 vfs_add_vnodeops(mp
, &ext2_spec_vops
, &mp
->mnt_vn_spec_ops
);
787 vfs_add_vnodeops(mp
, &ext2_fifo_vops
, &mp
->mnt_vn_fifo_ops
);
790 ext2_sbupdate(ump
, MNT_WAIT
);
795 vn_lock(devvp
, LK_EXCLUSIVE
| LK_RETRY
);
796 VOP_CLOSE(devvp
, ronly
? FREAD
: FREAD
|FWRITE
, NULL
);
799 kfree(ump
->um_e2fs
->s_es
, M_EXT2MNT
);
800 kfree(ump
->um_e2fs
, M_EXT2MNT
);
801 kfree(ump
, M_EXT2MNT
);
802 mp
->mnt_data
= (qaddr_t
)0;
808 * unmount system call
811 ext2_unmount(struct mount
*mp
, int mntflags
)
813 struct ext2_mount
*ump
;
814 struct ext2_sb_info
*fs
;
815 int error
, flags
, ronly
, i
;
818 if (mntflags
& MNT_FORCE
) {
819 if (mp
->mnt_flag
& MNT_ROOTFS
)
823 if ((error
= ext2_flushfiles(mp
, flags
)) != 0)
827 ronly
= fs
->s_rd_only
;
830 fs
->s_es
->s_state
|= EXT2_VALID_FS
;
831 ext2_sbupdate(ump
, MNT_WAIT
);
834 /* release buffers containing group descriptors */
835 for(i
= 0; i
< fs
->s_db_per_group
; i
++)
836 ULCK_BUF(fs
->s_group_desc
[i
])
837 kfree(fs
->s_group_desc
, M_EXT2MNT
);
839 /* release cached inode/block bitmaps */
840 for (i
= 0; i
< EXT2_MAX_GROUP_LOADED
; i
++)
841 if (fs
->s_inode_bitmap
[i
])
842 ULCK_BUF(fs
->s_inode_bitmap
[i
])
844 for (i
= 0; i
< EXT2_MAX_GROUP_LOADED
; i
++)
845 if (fs
->s_block_bitmap
[i
])
846 ULCK_BUF(fs
->s_block_bitmap
[i
])
848 ump
->um_devvp
->v_rdev
->si_mountpoint
= NULL
;
850 vn_lock(ump
->um_devvp
, LK_EXCLUSIVE
| LK_RETRY
);
851 error
= VOP_CLOSE(ump
->um_devvp
, ronly
? FREAD
: FREAD
|FWRITE
, NULL
);
852 vn_unlock(ump
->um_devvp
);
854 vrele(ump
->um_devvp
);
855 kfree(fs
->s_es
, M_EXT2MNT
);
856 kfree(fs
, M_EXT2MNT
);
857 kfree(ump
, M_EXT2MNT
);
858 mp
->mnt_data
= (qaddr_t
)0;
859 mp
->mnt_flag
&= ~MNT_LOCAL
;
864 * Flush out all the files in a filesystem.
867 ext2_flushfiles(struct mount
*mp
, int flags
)
869 struct ext2_mount
*ump
;
877 if (mp
->mnt_flag
& MNT_QUOTA
) {
878 if ((error
= vflush(mp
, 0, SKIPSYSTEM
|flags
)) != 0)
880 for (i
= 0; i
< MAXQUOTAS
; i
++) {
881 if (ump
->um_quotas
[i
] == NULLVP
)
883 ext2_quotaoff(mp
, i
);
886 * Here we fall through to vflush again to ensure
887 * that we have gotten rid of all the system vnodes.
891 error
= vflush(mp
, 0, flags
);
896 * Go through the disk queues to initiate sandbagged IO;
897 * go through the inodes to write those that have been modified;
898 * initiate the writing of the super block if it has been modified.
900 * Note: we are always called with the filesystem marked `MPBUSY'.
903 static int ext2_sync_scan(struct mount
*mp
, struct vnode
*vp
, void *data
);
906 ext2_sync(struct mount
*mp
, int waitfor
)
908 struct ext2_mount
*ump
= VFSTOEXT2(mp
);
909 struct ext2_sb_info
*fs
;
910 struct scaninfo scaninfo
;
914 if (fs
->s_dirt
!= 0 && fs
->s_rd_only
!= 0) { /* XXX */
915 kprintf("fs = %s\n", fs
->fs_fsmnt
);
916 panic("ext2_sync: rofs mod");
920 * Write back each (modified) inode.
922 scaninfo
.allerror
= 0;
924 scaninfo
.waitfor
= waitfor
;
925 while (scaninfo
.rescan
) {
927 vmntvnodescan(mp
, VMSC_GETVP
|VMSC_NOWAIT
,
928 NULL
, ext2_sync_scan
, &scaninfo
);
932 * Force stale file system control information to be flushed.
934 if ((waitfor
& MNT_LAZY
) == 0) {
935 vn_lock(ump
->um_devvp
, LK_EXCLUSIVE
| LK_RETRY
);
936 if ((error
= VOP_FSYNC(ump
->um_devvp
, waitfor
, 0)) != 0)
937 scaninfo
.allerror
= error
;
938 vn_unlock(ump
->um_devvp
);
944 * Write back modified superblock.
946 if (fs
->s_dirt
!= 0) {
948 fs
->s_es
->s_wtime
= time_second
;
949 if ((error
= ext2_sbupdate(ump
, waitfor
)) != 0)
950 scaninfo
.allerror
= error
;
952 return (scaninfo
.allerror
);
956 ext2_sync_scan(struct mount
*mp
, struct vnode
*vp
, void *data
)
958 struct scaninfo
*info
= data
;
963 if (vp
->v_type
== VNON
||
965 (IN_ACCESS
| IN_CHANGE
| IN_MODIFIED
| IN_UPDATE
)) == 0 &&
966 (RB_EMPTY(&vp
->v_rbdirty_tree
) || (info
->waitfor
& MNT_LAZY
)))) {
969 if ((error
= VOP_FSYNC(vp
, info
->waitfor
, 0)) != 0)
970 info
->allerror
= error
;
975 * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it
976 * in from disk. If it is in core, wait for the lock bit to clear, then
977 * return the inode locked. Detection and handling of mount points must be
978 * done by the calling routine.
981 ext2_vget(struct mount
*mp
, struct vnode
*dvp
, ino_t ino
, struct vnode
**vpp
)
983 struct ext2_sb_info
*fs
;
985 struct ext2_mount
*ump
;
995 if ((*vpp
= ext2_ihashget(dev
, ino
)) != NULL
)
999 * Lock out the creation of new entries in the FFS hash table in
1000 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate
1003 if (ext2fs_inode_hash_lock
) {
1004 while (ext2fs_inode_hash_lock
) {
1005 ext2fs_inode_hash_lock
= -1;
1006 tsleep(&ext2fs_inode_hash_lock
, 0, "e2vget", 0);
1010 ext2fs_inode_hash_lock
= 1;
1013 * If this MALLOC() is performed after the getnewvnode()
1014 * it might block, leaving a vnode with a NULL v_data to be
1015 * found by ext2_sync() if a sync happens to fire right then,
1016 * which will cause a panic because ext2_sync() blindly
1017 * dereferences vp->v_data (as well it should).
1019 ip
= kmalloc(sizeof(struct inode
), M_EXT2NODE
, M_WAITOK
);
1021 /* Allocate a new vnode/inode. */
1022 if ((error
= getnewvnode(VT_EXT2FS
, mp
, &vp
, 0, LK_CANRECURSE
)) != 0) {
1023 if (ext2fs_inode_hash_lock
< 0)
1024 wakeup(&ext2fs_inode_hash_lock
);
1025 ext2fs_inode_hash_lock
= 0;
1027 kfree(ip
, M_EXT2NODE
);
1030 bzero((caddr_t
)ip
, sizeof(struct inode
));
1033 ip
->i_e2fs
= fs
= ump
->um_e2fs
;
1037 for (i
= 0; i
< MAXQUOTAS
; i
++)
1038 ip
->i_dquot
[i
] = NODQUOT
;
1041 * Put it onto its hash chain. Since our vnode is locked, other
1042 * requests for this inode will block if they arrive while we are
1043 * sleeping waiting for old data structures to be purged or for the
1044 * contents of the disk portion of this inode to be read.
1048 if (ext2fs_inode_hash_lock
< 0)
1049 wakeup(&ext2fs_inode_hash_lock
);
1050 ext2fs_inode_hash_lock
= 0;
1052 /* Read in the disk contents for the inode, copy into the inode. */
1054 kprintf("ext2_vget(%d) dbn= %d ", ino
, fsbtodb(fs
, ino_to_fsba(fs
, ino
)));
1056 error
= bread(ump
->um_devvp
, fsbtodoff(fs
, ino_to_fsba(fs
, ino
)),
1057 (int)fs
->s_blocksize
, &bp
);
1060 * The inode does not contain anything useful, so it would
1061 * be misleading to leave it on its hash chain. With mode
1062 * still zero, it will be unlinked and returned to the free
1070 /* convert ext2 inode to dinode */
1071 ext2_ei2di((struct ext2_inode
*) ((char *)bp
->b_data
+ EXT2_INODE_SIZE(fs
) *
1072 ino_to_fsbo(fs
, ino
)), &ip
->i_din
);
1073 ip
->i_block_group
= ino_to_cg(fs
, ino
);
1074 ip
->i_next_alloc_block
= 0;
1075 ip
->i_next_alloc_goal
= 0;
1076 ip
->i_prealloc_count
= 0;
1077 ip
->i_prealloc_block
= 0;
1078 /* now we want to make sure that block pointers for unused
1079 blocks are zeroed out - ext2_balloc depends on this
1080 although for regular files and directories only
1082 if(S_ISDIR(ip
->i_mode
) || S_ISREG(ip
->i_mode
)) {
1083 used_blocks
= (ip
->i_size
+fs
->s_blocksize
-1) / fs
->s_blocksize
;
1084 for(i
= used_blocks
; i
< EXT2_NDIR_BLOCKS
; i
++)
1088 ext2_print_inode(ip
);
1093 * Initialize the vnode from the inode, check for aliases.
1094 * Note that the underlying vnode may have changed.
1096 if ((error
= ext2_vinit(mp
, &vp
)) != 0) {
1103 * Finish inode initialization now that aliasing has been resolved.
1105 ip
->i_devvp
= ump
->um_devvp
;
1108 * Set up a generation number for this inode if it does not
1109 * already have one. This should only happen on old filesystems.
1111 if (ip
->i_gen
== 0) {
1112 ip
->i_gen
= krandom() / 2 + 1;
1113 if ((vp
->v_mount
->mnt_flag
& MNT_RDONLY
) == 0)
1114 ip
->i_flag
|= IN_MODIFIED
;
1117 * Return the locked and refd vnode.
1124 * File handle to vnode
1126 * Have to be really careful about stale file handles:
1127 * - check that the inode number is valid
1128 * - call ext2_vget() to get the locked inode
1129 * - check for an unallocated inode (i_mode == 0)
1130 * - check that the given client host has export rights and return
1131 * those rights via. exflagsp and credanonp
1134 ext2_fhtovp(struct mount
*mp
, struct vnode
*rootvp
,
1135 struct fid
*fhp
, struct vnode
**vpp
)
1138 struct ext2_sb_info
*fs
;
1143 ufhp
= (struct ufid
*)fhp
;
1144 fs
= VFSTOEXT2(mp
)->um_e2fs
;
1145 if (ufhp
->ufid_ino
< EXT2_ROOTINO
||
1146 ufhp
->ufid_ino
> fs
->s_groups_count
* fs
->s_es
->s_inodes_per_group
)
1149 error
= VFS_VGET(mp
, rootvp
, ufhp
->ufid_ino
, &nvp
);
1155 if (ip
->i_mode
== 0 ||
1156 ip
->i_gen
!= ufhp
->ufid_gen
||
1157 (VFSTOEXT2(mp
)->um_i_effnlink_valid
? ip
->i_effnlink
:
1158 ip
->i_nlink
) <= 0) {
1168 * Vnode pointer to File handle
1172 ext2_vptofh(struct vnode
*vp
, struct fid
*fhp
)
1178 ufhp
= (struct ufid
*)fhp
;
1179 ufhp
->ufid_len
= sizeof(struct ufid
);
1180 ufhp
->ufid_ino
= ip
->i_number
;
1181 ufhp
->ufid_gen
= ip
->i_gen
;
1186 * This is the generic part of fhtovp called after the underlying
1187 * filesystem has validated the file handle.
1189 * Verify that a host should have access to a filesystem.
1192 ext2_check_export(struct mount
*mp
, struct sockaddr
*nam
, int *exflagsp
,
1193 struct ucred
**credanonp
)
1196 struct ext2_mount
*ump
;
1198 ump
= VFSTOEXT2(mp
);
1200 * Get the export permission structure for this <mp, client> tuple.
1202 np
= vfs_export_lookup(mp
, &ump
->um_export
, nam
);
1206 *exflagsp
= np
->netc_exflags
;
1207 *credanonp
= &np
->netc_anon
;
1212 * Write a superblock and associated information back to disk.
1215 ext2_sbupdate(struct ext2_mount
*mp
, int waitfor
)
1217 struct ext2_sb_info
*fs
= mp
->um_e2fs
;
1218 struct ext2_super_block
*es
= fs
->s_es
;
1222 kprintf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
1224 bp
= getblk(mp
->um_devvp
, SBOFF
, SBSIZE
, 0, 0);
1225 bcopy((caddr_t
)es
, bp
->b_data
, (u_int
)sizeof(struct ext2_super_block
));
1226 if (waitfor
== MNT_WAIT
)
1232 * The buffers for group descriptors, inode bitmaps and block bitmaps
1233 * are not busy at this point and are (hopefully) written by the
1234 * usual sync mechanism. No need to write them here