minix/lib/libpuffs/mount.c
Thomas Veerman 490e0de548 Import librefuse and libpuffs
Import libpuffs and our port of libpuffs. The port was done as part of
GSoC 2011 FUSE project, done by Evgeniy Ivanov. The librefuse import
did not require any porting efforts. Libpuffs has been modified to
understand our VFS-FS protocol and translate between that and PUFFS. As
an example that it works, fuse-ntfs-3g from pkgsrc can be compiled and
used to mount ntfs partitions:
mount -t ntfs-3g <device> <mountpoint>

FUSE only works with the asynchronous version of VFS. See <docs/UPDATING> on
how to run AVFS.

This patch further includes some changes to mount(1) and mount(2) so it's
possible to use file systems provided by pkgsrc (note: manual modifications
to /etc/system.conf are still needed. There has been made an exception for
fuse-ntfs-3g, so it already as an entry).
2011-11-14 11:53:05 +00:00

142 lines
3.6 KiB
C

/* Created (MFS based):
* June 2011 (Evgeniy Ivanov)
*/
#include "fs.h"
#include <fcntl.h>
#include <string.h>
#include <minix/com.h>
#include <sys/stat.h>
#include <minix/ds.h>
#include <minix/vfsif.h>
#include "puffs_priv.h"
/*===========================================================================*
* fs_readsuper *
*===========================================================================*/
PUBLIC int fs_readsuper()
{
int r = OK;
cp_grant_id_t label_gid;
size_t label_len;
endpoint_t driver_e;
struct vattr *root_va;
fs_dev = fs_m_in.REQ_DEV;
label_gid = fs_m_in.REQ_GRANT;
label_len = fs_m_in.REQ_PATH_LEN;
is_readonly_fs = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
is_root_fs = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;
if (label_len > sizeof(fs_dev_label))
return(EINVAL);
r = sys_safecopyfrom(fs_m_in.m_source, label_gid, 0,
(vir_bytes)fs_dev_label, label_len, D);
if (r != OK) {
lpuffs_debug("%s:%d fs_readsuper: safecopyfrom failed: %d\n",
__FILE__, __LINE__, r);
return(EINVAL);
}
fs_m_out.RES_DEV = NO_DEV;
if (strlen(fs_dev_label)) {
/* Map the driver endpoint for this major */
r= ds_retrieve_label_endpt(fs_dev_label, &driver_e);
if (r != OK)
{
lpuffs_debug("fs_readsuper: ds_retrieve_label_endpt failed for '%s': %d\n",
fs_dev_label, r);
return EINVAL;
}
driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = driver_e;
/* Open the device the file system lives on. */
if (dev_open(driver_e, fs_dev, driver_e,
is_readonly_fs ? R_BIT : (R_BIT|W_BIT)) != OK) {
return(EINVAL);
}
fs_m_out.RES_DEV = fs_dev;
}
/* Open root pnode */
global_pu->pu_pn_root->pn_count = 1;
/* Root pnode properties */
root_va = &global_pu->pu_pn_root->pn_va;
fs_m_out.RES_INODE_NR = root_va->va_fileid;
fs_m_out.RES_MODE = root_va->va_mode;
fs_m_out.RES_FILE_SIZE_LO = root_va->va_size;
fs_m_out.RES_UID = root_va->va_uid;
fs_m_out.RES_GID = root_va->va_gid;
return(r);
}
/*===========================================================================*
* fs_mountpoint *
*===========================================================================*/
PUBLIC int fs_mountpoint()
{
/* This function looks up the mount point, it checks the condition whether
* the partition can be mounted on the pnode or not.
*/
int r = OK;
struct puffs_node *pn;
mode_t bits;
/*
* XXX: we assume that lookup was done first, so pnode can be found with
* puffs_pn_nodewalk.
*/
if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.REQ_INODE_NR)) == NULL)
return(EINVAL);
if (pn->pn_mountpoint) r = EBUSY;
/* It may not be special. */
bits = pn->pn_va.va_mode & I_TYPE;
if(bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL) r = ENOTDIR;
if (r == OK)
pn->pn_mountpoint = TRUE;
return(r);
}
/*===========================================================================*
* fs_unmount *
*===========================================================================*/
PUBLIC int fs_unmount()
{
int error;
/* XXX there is no information about flags, 0 should be safe enough */
error = global_pu->pu_ops.puffs_fs_unmount(global_pu, 0);
if (error) {
/* XXX we can't return any error to VFS */
lpuffs_debug("user handler failed to unmount filesystem!\
Force unmount!\n");
}
fs_sync();
if (strlen(fs_dev_label)) {
/* Close the device the file system lives on. */
dev_close(driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e, fs_dev);
}
/* Finish off the unmount. */
PU_SETSTATE(global_pu, PUFFS_STATE_UNMOUNTED);
unmountdone = TRUE;
global_pu->pu_pn_root->pn_count--;
return(OK);
}