4 #include <minix/vfsif.h>
5 #include <minix/bdev.h>
7 /*===========================================================================*
9 *===========================================================================*/
10 int fs_mount(dev_t dev
, unsigned int flags
, struct fsdriver_node
*root_node
,
11 unsigned int *res_flags
)
13 /* This function reads the superblock of the partition, gets the root inode
14 * and sends back the details of them.
16 struct inode
*root_ip
;
20 readonly
= (flags
& REQ_RDONLY
) ? 1 : 0;
22 /* Open the device the file system lives on. */
23 if (bdev_open(fs_dev
, readonly
? BDEV_R_BIT
: (BDEV_R_BIT
|BDEV_W_BIT
) ) !=
28 /* Fill in the super block. */
29 superblock
.s_dev
= fs_dev
; /* read_super() needs to know which dev */
30 r
= read_super(&superblock
);
32 /* Is it recognized as a Minix filesystem? */
34 superblock
.s_dev
= NO_DEV
;
39 /* clean check: if rw and not clean, switch to readonly */
40 if(!(superblock
.s_flags
& MFSFLAG_CLEAN
) && !readonly
) {
41 if(bdev_close(fs_dev
) != OK
)
42 panic("couldn't bdev_close after found unclean FS");
45 if (bdev_open(fs_dev
, BDEV_R_BIT
) != OK
) {
46 panic("couldn't bdev_open after found unclean FS");
49 printf("MFS: WARNING: FS 0x%llx unclean, mounting readonly\n", fs_dev
);
52 lmfs_set_blocksize(superblock
.s_block_size
);
54 /* Compute the current number of used zones, and report it to libminixfs.
55 * Note that libminixfs really wants numbers of *blocks*, but this MFS
56 * implementation dropped support for differing zone/block sizes a while ago.
58 used_zones
= superblock
.s_zones
- count_free_bits(&superblock
, ZMAP
);
60 lmfs_set_blockusage(superblock
.s_zones
, used_zones
);
62 /* Get the root inode of the mounted file system. */
63 if( (root_ip
= get_inode(fs_dev
, ROOT_INODE
)) == NULL
) {
64 printf("MFS: couldn't get root inode\n");
65 superblock
.s_dev
= NO_DEV
;
70 if(root_ip
->i_mode
== 0) {
71 printf("%s:%d zero mode for root inode?\n", __FILE__
, __LINE__
);
73 superblock
.s_dev
= NO_DEV
;
78 superblock
.s_rd_only
= readonly
;
80 /* Root inode properties */
81 root_node
->fn_ino_nr
= root_ip
->i_num
;
82 root_node
->fn_mode
= root_ip
->i_mode
;
83 root_node
->fn_size
= root_ip
->i_size
;
84 root_node
->fn_uid
= root_ip
->i_uid
;
85 root_node
->fn_gid
= root_ip
->i_gid
;
86 root_node
->fn_dev
= NO_DEV
;
88 *res_flags
= RES_NOFLAGS
;
91 if(!superblock
.s_rd_only
) {
92 superblock
.s_flags
&= ~MFSFLAG_CLEAN
;
93 if(write_super(&superblock
) != OK
)
94 panic("mounting: couldn't write dirty superblock");
101 /*===========================================================================*
103 *===========================================================================*/
104 int fs_mountpt(ino_t ino_nr
)
106 /* This function looks up the mount point, it checks the condition whether
107 * the partition can be mounted on the inode or not.
109 register struct inode
*rip
;
113 /* Temporarily open the file. */
114 if( (rip
= get_inode(fs_dev
, ino_nr
)) == NULL
)
117 if(rip
->i_mountpoint
) r
= EBUSY
;
119 /* It may not be special. */
120 bits
= rip
->i_mode
& I_TYPE
;
121 if (bits
== I_BLOCK_SPECIAL
|| bits
== I_CHAR_SPECIAL
) r
= ENOTDIR
;
125 if(r
== OK
) rip
->i_mountpoint
= TRUE
;
131 /*===========================================================================*
133 *===========================================================================*/
134 void fs_unmount(void)
136 /* Unmount a file system. */
138 struct inode
*rip
, *root_ip
;
140 /* See if the mounted device is busy. Only 1 inode using it should be
141 * open --the root inode-- and that inode only 1 time. This is an integrity
142 * check only: VFS expects the unmount to succeed either way.
145 for (rip
= &inode
[0]; rip
< &inode
[NR_INODES
]; rip
++)
146 if (rip
->i_count
> 0 && rip
->i_dev
== fs_dev
) count
+= rip
->i_count
;
148 printf("MFS: file system has %d in-use inodes!\n", count
);
150 if ((root_ip
= find_inode(fs_dev
, ROOT_INODE
)) == NULL
)
151 panic("MFS: couldn't find root inode\n");
155 /* force any cached blocks out of memory */
158 /* Mark it clean if we're allowed to write _and_ it was clean originally. */
159 if (!superblock
.s_rd_only
) {
160 superblock
.s_flags
|= MFSFLAG_CLEAN
;
161 write_super(&superblock
);
164 /* Close the device the file system lives on. */
167 /* Throw out blocks out of the VM cache, to prevent corruption later. */
168 lmfs_invalidate(fs_dev
);
170 /* Finish off the unmount. */
171 superblock
.s_dev
= NO_DEV
;