The last function we'll look at is the one that handles mount requests. Handling a mount request can be fairly tricky (there are lots of options), so we've just stuck with a simple version that does everything we need for the RAM disk.
When the RAM-disk resource manager starts up, there is no mounted RAM disk, so you must use the command-line mount command to mount one:
mount -Tramdisk /dev/ramdisk /ramdisk
The above command creates a RAM disk at the mount point /ramdisk.
The code is:
int
cfs_c_mount (resmgr_context_t *ctp, io_mount_t *msg,
RESMGR_HANDLE_T *handle, io_mount_extra_t *extra)
{
char *mnt_point;
char *mnt_type;
int ret;
cfs_attr_t *cfs_attr;
// 1) shortcuts
mnt_point = msg -> connect.path;
mnt_type = extra -> extra.srv.type;
// 2) Verify that it is a mount request, not something else
if (extra -> flags &
(_MOUNT_ENUMERATE | _MOUNT_UNMOUNT | _MOUNT_REMOUNT)) {
return (ENOTSUP);
}
// 3) decide if we should handle this request or not
if (!mnt_type || strcmp (mnt_type, "ramdisk")) {
return (ENOSYS);
}
// 4) create a new attributes structure and fill it
if (!(cfs_attr = malloc (sizeof (*cfs_attr)))) {
return (ENOMEM);
}
iofunc_attr_init (&cfs_attr -> attr, S_IFDIR | 0777,
NULL, NULL);
// 5) initializes extended attribute structure
cfs_attr_init (cfs_attr);
// set up the inode
cfs_attr -> attr.inode = (int) cfs_attr;
// create "." and ".."
cfs_a_mknod (cfs_attr, ".", S_IFDIR | 0755, NULL);
cfs_a_mknod (cfs_attr, "..", S_IFDIR | 0755, NULL);
// 6) attach the new pathname with the new value
ret = resmgr_attach (dpp, &resmgr_attr, mnt_point,
_FTYPE_ANY, _RESMGR_FLAG_DIR,
&connect_func, &io_func,
&cfs_attr -> attr);
if (ret == -1) {
free (cfs_attr);
return (errno);
}
return (EOK);
}
The code walkthrough is:
The inode needs to be unique on a per-device basis, so the easiest way of doing that is to give it the address of the attributes structure.