2010-01-26 00:18:02 +01:00
|
|
|
/* This file contains mount and unmount functionality.
|
|
|
|
*
|
|
|
|
* The entry points into this file are:
|
|
|
|
* do_readsuper perform the READSUPER file system call
|
|
|
|
* do_unmount perform the UNMOUNT file system call
|
|
|
|
*
|
|
|
|
* Created:
|
|
|
|
* April 2009 (D.C. van Moolenbroek)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "inc.h"
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* do_readsuper *
|
|
|
|
*===========================================================================*/
|
2014-02-24 14:00:17 +01:00
|
|
|
int do_readsuper(void)
|
2010-01-26 00:18:02 +01:00
|
|
|
{
|
|
|
|
/* Mount the file system.
|
|
|
|
*/
|
|
|
|
char path[PATH_MAX];
|
|
|
|
struct inode *ino;
|
2012-04-09 18:08:26 +02:00
|
|
|
struct sffs_attr attr;
|
2010-01-26 00:18:02 +01:00
|
|
|
int r;
|
|
|
|
|
2012-04-09 18:08:26 +02:00
|
|
|
dprintf(("%s: readsuper (dev %x, flags %x)\n",
|
2013-11-15 19:01:25 +01:00
|
|
|
sffs_name, m_in.REQ_DEV, m_in.REQ_FLAGS));
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
if (m_in.REQ_FLAGS & REQ_ISROOT) {
|
2012-04-09 18:08:26 +02:00
|
|
|
printf("%s: attempt to mount as root device\n", sffs_name);
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
return EINVAL;
|
|
|
|
}
|
|
|
|
|
2012-04-09 18:08:26 +02:00
|
|
|
state.s_read_only = !!(m_in.REQ_FLAGS & REQ_RDONLY);
|
|
|
|
state.s_dev = m_in.REQ_DEV;
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
init_dentry();
|
|
|
|
ino = init_inode();
|
|
|
|
|
2012-04-09 18:08:26 +02:00
|
|
|
attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE;
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
/* We cannot continue if we fail to get the properties of the root inode at
|
|
|
|
* all, because we cannot guess the details of the root node to return to
|
|
|
|
* VFS. Print a (hopefully) helpful error message, and abort the mount.
|
|
|
|
*/
|
|
|
|
if ((r = verify_inode(ino, path, &attr)) != OK) {
|
2012-04-09 18:08:26 +02:00
|
|
|
if (r == EAGAIN)
|
|
|
|
printf("%s: shared folders disabled\n", sffs_name);
|
|
|
|
else if (sffs_params->p_prefix[0] && (r == ENOENT || r == EACCES))
|
|
|
|
printf("%s: unable to access the given prefix directory\n",
|
|
|
|
sffs_name);
|
2010-01-26 00:18:02 +01:00
|
|
|
else
|
2012-04-09 18:08:26 +02:00
|
|
|
printf("%s: unable to access shared folders\n", sffs_name);
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_out.RES_INODE_NR = INODE_NR(ino);
|
|
|
|
m_out.RES_MODE = get_mode(ino, attr.a_mode);
|
2014-02-24 17:02:03 +01:00
|
|
|
m_out.RES_FILE_SIZE = attr.a_size;
|
2012-04-09 18:08:26 +02:00
|
|
|
m_out.RES_UID = sffs_params->p_uid;
|
|
|
|
m_out.RES_GID = sffs_params->p_gid;
|
2010-01-26 00:18:02 +01:00
|
|
|
m_out.RES_DEV = NO_DEV;
|
2013-08-31 21:48:15 +02:00
|
|
|
m_out.RES_FLAGS = RES_64BIT;
|
2011-08-22 17:02:13 +02:00
|
|
|
|
2012-04-09 18:08:26 +02:00
|
|
|
state.s_mounted = TRUE;
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* do_unmount *
|
|
|
|
*===========================================================================*/
|
2014-02-24 14:00:17 +01:00
|
|
|
int do_unmount(void)
|
2010-01-26 00:18:02 +01:00
|
|
|
{
|
|
|
|
/* Unmount the file system.
|
|
|
|
*/
|
|
|
|
struct inode *ino;
|
|
|
|
|
2012-04-09 18:08:26 +02:00
|
|
|
dprintf(("%s: do_unmount\n", sffs_name));
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
/* Decrease the reference count of the root inode. */
|
2010-05-10 15:26:00 +02:00
|
|
|
if ((ino = find_inode(ROOT_INODE_NR)) == NULL)
|
2010-01-26 00:18:02 +01:00
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
put_inode(ino);
|
|
|
|
|
|
|
|
/* There should not be any referenced inodes anymore now. */
|
|
|
|
if (have_used_inode())
|
2012-04-09 18:08:26 +02:00
|
|
|
printf("%s: in-use inodes left at unmount time!\n", sffs_name);
|
2010-01-26 00:18:02 +01:00
|
|
|
|
2012-04-09 18:08:26 +02:00
|
|
|
state.s_mounted = FALSE;
|
2010-01-26 00:18:02 +01:00
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|