10 #include <minix/paths.h>
12 #include <minix/syslib.h>
16 #define FSDEFAULT "mfs"
18 static char fspath
[] = "/service/:/usr/pkg/service/"; /* Must include trailing '/' */
20 static int rs_down(char *label
)
23 if(strlen(_PATH_MINIX_SERVICE
)+strlen(label
)+50 >= sizeof(cmd
))
25 sprintf(cmd
, _PATH_MINIX_SERVICE
" down '%s'", label
);
29 char *find_rslabel(char *args_line
);
31 int minix_mount(char *special
, char *name
, int mountflags
, int srvflags
,
32 char *type
, char *args
)
37 char label
[MNT_LABEL_LEN
];
46 if (type
== NULL
) type
= __UNCONST(FSDEFAULT
);
47 if (args
== NULL
) args
= __UNCONST("");
49 memset(path
, '\0', sizeof(path
));
51 /* Check service flags. */
52 if(srvflags
& MS_REUSE
)
55 if(srvflags
& MS_EXISTING
)
58 /* Make a label for the file system process. This label must be unique and
59 * may currently not exceed 16 characters including terminating null. For
60 * requests with an associated block device, we use the last path component
61 * name of the block special file (truncated to 12 characters, which is
62 * hopefully enough). For requests with no associated block device, we use
63 * the device number and inode of the mount point, in hexadecimal form.
67 p
= strrchr(special
, '/');
68 p
= p
? p
+ 1 : special
;
69 if (strchr(p
, '\'')) {
73 snprintf(label
, MNT_LABEL_LEN
, "fs_%.12s", p
);
75 /* check for a rslabel option in the arguments and try to use
78 rslabel
= find_rslabel(args
);
80 snprintf(label
, MNT_LABEL_LEN
, "%s", rslabel
);
83 if (stat(name
, &statbuf
) < 0) return -1;
84 snprintf(label
, MNT_LABEL_LEN
, "fs_%llx_%llx", statbuf
.st_dev
, statbuf
.st_ino
);
89 if (strlen(type
) < MNT_LABEL_LEN
) {
90 snprintf(label
, MNT_LABEL_LEN
, "%s", type
);
97 /* Sanity check on user input. */
98 if(strchr(args
, '\'')) {
102 /* start the fs-server if not using existing one */
104 /* See if the given type is even remotely valid. */
107 testpath
= strtok(fspath
, ":");
110 if (strlen(testpath
) + strlen(type
) >= sizeof(path
)) {
115 strcpy(path
, testpath
);
118 if (access(path
, F_OK
) == 0) break;
120 } while ((testpath
= strtok(NULL
, ":")) != NULL
);
122 if (testpath
== NULL
) {
123 /* We were not able to find type somewhere in "fspath" */
128 if (strlen(_PATH_MINIX_SERVICE
) + strlen(path
) + strlen(label
) +
129 strlen(args
) + 50 >= sizeof(cmd
)) {
134 sprintf(cmd
, _PATH_MINIX_SERVICE
135 " %sup %s -label '%s' -args '%s %s %s%s'",
136 reuse
? "-r ": "", path
, label
, special
, name
,
137 args
[0] ? "-o " : "", args
);
139 if ((r
= system(cmd
)) != 0) {
140 fprintf(stderr
, "mount: couldn't run %s\n", cmd
);
146 /* Now perform mount(). */
147 memset(&m
, 0, sizeof(m
));
148 m
.m_lc_vfs_mount
.flags
= mountflags
;
149 m
.m_lc_vfs_mount
.devlen
= special
? strlen(special
) + 1 : 0;
150 m
.m_lc_vfs_mount
.pathlen
= strlen(name
) + 1;
151 m
.m_lc_vfs_mount
.typelen
= strlen(type
) + 1;
152 m
.m_lc_vfs_mount
.labellen
= strlen(label
) + 1;
153 m
.m_lc_vfs_mount
.dev
= (vir_bytes
)special
;
154 m
.m_lc_vfs_mount
.path
= (vir_bytes
)name
;
155 m
.m_lc_vfs_mount
.type
= (vir_bytes
)type
;
156 m
.m_lc_vfs_mount
.label
= (vir_bytes
)label
;
157 r
= _syscall(VFS_PROC_NR
, VFS_MOUNT
, &m
);
159 if (r
!= OK
&& !use_existing
) {
160 /* If mount() failed, tell RS to shutdown FS process.
161 * No error check - won't do anything with this error anyway.
169 int minix_umount(const char *name
, int srvflags
)
171 char label
[MNT_LABEL_LEN
];
175 memset(&m
, 0, sizeof(m
));
176 m
.m_lc_vfs_umount
.name
= (vir_bytes
)name
;
177 m
.m_lc_vfs_umount
.namelen
= strlen(name
) + 1;
178 m
.m_lc_vfs_umount
.label
= (vir_bytes
)label
;
179 m
.m_lc_vfs_umount
.labellen
= sizeof(label
);
180 r
= _syscall(VFS_PROC_NR
, VFS_UMOUNT
, &m
);
182 /* don't shut down the driver when exist flag is set */
183 if (!(srvflags
& MS_EXISTING
)) {
185 /* VFS returns the label of the unmounted file system to us. */
193 char *find_rslabel(char *args_line
)
196 * Find and return the rslabel as given as optional
197 * agument to the mount command e.g.
198 * mount -o rslabel=bla
200 * mount -o rw,rslabel=bla
201 * or as found in fstab
203 char *buf
, *input
,*saveptr
;
204 buf
= input
= saveptr
= NULL
;
206 if (args_line
== NULL
) return NULL
;
208 /* copy the input args_line we are going to modify it*/
209 input
= strndup(args_line
,20);
210 if (input
== NULL
) /* EOM */
211 return NULL
; /* it is not that bad to not find a label */
213 /* locate rslabel= in the input */
214 buf
= strstr(input
,"rslabel=");
220 /* tokenise on "," starting from rslabel (e.g null terminate )*/
221 buf
= strtok_r(buf
,",",&saveptr
);
222 /* tokenise the result again using = and take the second entry */
223 buf
= strtok_r(buf
,"=",&saveptr
);
224 buf
= strtok_r(NULL
,"=",&saveptr
);
225 /* buf is now either NULL if there was no second token or
226 * the value we are searchig for