1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#pragma once
#include "types.h"
#include "fs/open.h"
#include "proc/kmutex.h"
#include "util/list.h"
struct vnode;
struct file;
struct vfs;
struct fs;
struct slab_allocator;
/* name_match: fname should be null-terminated, name is namelen long */
#define name_match(fname, name, namelen) \
(strlen(fname) == namelen && !strncmp((fname), (name), (namelen)))
typedef struct fs_ops
{
/*
* Initialize vn_ops, vn_mode, vn_devid and vn_len.
* If the filesystem wishes, it may initialize and use vn_i.
*/
void (*read_vnode)(struct fs *fs, struct vnode *vn);
/*
* Called when the vnode's reference count drops to 0.
* Perform any necessary cleanup for the corresponding inode.
*/
void (*delete_vnode)(struct fs *fs, struct vnode *vn);
/*
* Optional. Default behavior is to vput() fs_root.
* Unmount the filesystem, performing any desired sanity checks
* and/or necessary cleanup.
* Return 0 on success; negative number on error.
*/
long (*umount)(struct fs *fs);
void (*sync)(struct fs *fs);
} fs_ops_t;
#ifndef STR_MAX
#define STR_MAX 32
#endif
/* similar to Linux's super_block. */
typedef struct fs
{
/*
* The string name of the device from which this file system should
* be mounted. This may be used by the mount function of some file
* systems which need to know which device they are mounting.
*/
char fs_dev[STR_MAX];
/*
* The type of file system this structure represents (given as a
* well-defined string). This is used by the generic VFS mount
* function to decide which filesystem-specific mount function to
* call. Valid values are hard-coded in vfs.c.
*/
char fs_type[STR_MAX];
#ifdef __MOUNTING__
/*
* If mounting is implemented then this should point to the vnode
* of the file that this file system is mounted on. For the root file
* system this will just point to the root of that file system.
*/
struct vnode *fs_mtpt;
/*
* An identifier for the mounted file system. This should be enlisted
* by the the kernel to keep track of all mounted file systems.
*/
list_link_t fs_link;
#endif
/*
* The following members are initialized by the filesystem
* implementation's mount routine:
*/
/*
* The struct of operations that define which filesystem-specific
* functions to call to perform filesystem manipulation.
*/
fs_ops_t *fs_ops;
/*
* The root vnode for this filesystem (not to be confused with
* either / (the root of VFS) or the vnode where the filesystem is
* mounted, which is on a different file system.
*/
struct vnode *fs_root;
/* Filesystem-specific data. */
void *fs_i;
struct slab_allocator *fs_vnode_allocator;
list_t vnode_list;
kmutex_t vnode_list_mutex;
kmutex_t vnode_rename_mutex;
} fs_t;
/* - this is the vnode on which we will mount the vfsroot fs.
*/
extern fs_t vfs_root_fs;
void do_sync();
/* VFS {{{ */
/*
* - called by the init process at system shutdown
* - at this point, init process is the only process running
* => so, there should be no "live" vnodes
*
* unmount the root filesystem (and first unmount any filesystems mounted
* on the root filesystem in the proper order (bottom up)).
*
*/
/* VFS }}} */
/* VFS Shutdown: */
/*
* Called by the init process at system shutdown.
*
* At this point, the init process is the only process running
* => so, there should be no "live" vnodes
*/
long vfs_shutdown();
/* Pathname resolution: */
/* (the corresponding definitions live in namev.c) */
long namev_lookup(struct vnode *dir, const char *name, size_t namelen,
struct vnode **out);
long namev_dir(struct vnode *base, const char *path, struct vnode **res_vnode,
const char **name, size_t *namelen);
long namev_open(struct vnode *base, const char *path, int oflags, int mode,
devid_t devid, struct vnode **res_vnode);
long namev_resolve(struct vnode *base, const char *path,
struct vnode **res_vnode);
long namev_get_child(struct vnode *dir, char *name, size_t namelen,
struct vnode **out);
long namev_get_parent(struct vnode *dir, struct vnode **out);
long namev_is_descendant(struct vnode *a, struct vnode *b);
#ifdef __GETCWD__
long lookup_name(struct vnode *dir, struct vnode *entry, char *buf,
size_t size);
long lookup_dirpath(struct vnode *dir, char *buf, size_t size);
#endif /* __GETCWD__ */
long mountfunc(fs_t *fs);
|