fs/mount/fs_mount.c
int mount(const char *source, const char *target,
          const char *filesystemtype, unsigned long mountflags,
          const void *data)
{
  int ret;
  int errcode = 0;
  struct Mount* mnt = NULL;
  struct Vnode *device = NULL;
  struct Vnode *mountpt_vnode = NULL;
  const struct fsmap_t *fsmap = NULL;
  const struct MountOps *mops = NULL;
  LIST_HEAD *mount_list = NULL;
#ifdef LOSCFG_DRIVERS_MTD
  mtd_partition *partition = NULL;
#endif

  if (filesystemtype == NULL)
    {
      errcode = -EINVAL;
      goto errout;
    }

  /* Verify required pointer arguments */

  DEBUGASSERT(target && filesystemtype);

  /* Find the specified filesystem.  Try the block driver file systems first */

  if ((fsmap = mount_findfs(filesystemtype)) == NULL || (fsmap->is_bdfs && !source))
    {
      PRINT_ERR("Failed to find file system %s\n", filesystemtype);
      errcode = -ENODEV;
      goto errout;
    }

  mops = fsmap->fs_mops;

  if (fsmap->is_bdfs && source)
    {
      /* Make sure that a block driver argument was provided */

      DEBUGASSERT(source);

      /* Find the block driver */

      ret = find_blockdriver(source, mountflags, &device);
      if (ret < 0)
        {
          PRINT_ERR("Failed to find block driver %s\n", source);
          errcode = ret;
          goto errout;
        }
    }

  VnodeHold();
  ret = VnodeLookup(target, &mountpt_vnode, 0);

  /* The mount point must be an existed vnode. */

  if (ret != OK)
    {
      PRINT_ERR("Failed to find valid mountpoint %s\n", target);
      errcode = -EINVAL;
      goto errout_with_lock;
    }
  if (mountpt_vnode->flag & VNODE_FLAG_MOUNT_NEW)
    {
      PRINT_ERR("can't mount to %s, already mounted.\n", target);
      errcode = -EINVAL;
      goto errout_with_lock;
    }

  /* Bind the block driver to an instance of the file system.  The file
   * system returns a reference to some opaque, fs-dependent structure
   * that encapsulates this binding.
   */

  if (mops->Mount == NULL)
    {
      /* The filesystem does not support the bind operation ??? */

      PRINTK("ERROR: Filesystem does not support bind\n");
      errcode = -ENOSYS;
      goto errout_with_lock;
    }

  /* Increment reference count for the reference we pass to the file system */
#ifdef LOSCFG_DRIVERS_MTD
  if (fsmap->is_mtd_support && (device != NULL))
    {
      partition = (mtd_partition *)((struct drv_data *)device->data)->priv;
      partition->mountpoint_name = (char *)zalloc(strlen(target) + 1);
      if (partition->mountpoint_name == NULL)
        {
          errcode = -ENOMEM;
          goto errout_with_lock;
        }
      (void)strncpy_s(partition->mountpoint_name, strlen(target) + 1, target, strlen(target));
      partition->mountpoint_name[strlen(target)] = '\0';
    }
#endif

  mnt = MountAlloc(mountpt_vnode, (struct MountOps*)mops);

#ifdef LOSCFG_FS_ZPFS
  if (strcmp(filesystemtype, ZPFS_NAME) == 0)
    {
      ret = ZpfsPrepare(source, target, mnt);
      if (ret < 0)
        {
          errcode = ret;
          goto errout_with_mountpt;
        }
    }
#endif

  mnt->mountFlags = mountflags;

  mountpt_vnode->useCount++;
  ret = mops->Mount(mnt, device, data);
  mountpt_vnode->useCount--;
  if (ret != 0)
    {
      /* The vnode is unhappy with the blkdrvr for some reason.  Back out
       * the count for the reference we failed to pass and exit with an
       * error.
       */

      PRINT_ERR("Bind method failed: %d\n", ret);
      errcode = ret;
#ifdef LOSCFG_DRIVERS_MTD
      if (fsmap->is_mtd_support && (device != NULL) && (partition != NULL))
        {
          free(partition->mountpoint_name);
          partition->mountpoint_name = NULL;
        }
#endif
      goto errout_with_mountpt;
    }
  mnt->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN;
  mnt->vnodeCovered->flag |= VNODE_FLAG_MOUNT_NEW;
  mnt->vnodeDev = device;
  mnt->ops = mops;
  if (target && (strlen(target) != 0))
    {
      ret = strcpy_s(mnt->pathName, PATH_MAX, target);
      if (ret != EOK)
        {
          PRINT_ERR("Failed to copy mount point pathname, errno %d\n", ret);
        }
    }

  if (source && (strlen(source) != 0))
    {
      ret = strcpy_s(mnt->devName, PATH_MAX, source);
      if (ret != EOK)
        {
          PRINT_ERR("Failed to copy dev name, errno %d\n", ret);
        }
    }

  //* We have it, now populate it with driver specific information. */

  mount_list = GetMountList();
  LOS_ListAdd(mount_list, &mnt->mountList);

  if (!strcmp("/", target))
    {
      ChangeRoot(mnt->vnodeCovered);
    }

  VnodeDrop();

  /* We can release our reference to the blkdrver_vnode, if the filesystem
   * wants to retain the blockdriver vnode (which it should), then it must
   * have called vnode_addref().  There is one reference on mountpt_vnode
   * that will persist until umount() is called.
   */

  return OK;

  /* A lot of goto's!  But they make the error handling much simpler */

errout_with_mountpt:
  if (mnt)
    {
      free(mnt);
    }
errout_with_lock:
  VnodeDrop();
errout:
  set_errno(-errcode);
  return VFS_ERROR;
}
/****************************************************************************
 * Name: mount
 *
 * Description:
 *   mount() attaches the filesystem specified by the 'source' block device
 *   name into the root file system at the path specified by 'target.'
 *
 * Return:
 *   Zero is returned on success; -1 is returned on an error and errno is
 *   set appropriately:
 *
 *   EACCES A component of a path was not searchable or mounting a read-only
 *      filesystem was attempted without giving the MS_RDONLY flag.
 *   EBUSY 'source' is already  mounted.
 *   EFAULT One of the pointer arguments points outside the user address
 *      space.
 *   EINVAL 'source' had an invalid superblock.
 *   ENODEV 'filesystemtype' not configured
 *   ENOENT A pathname was empty or had a nonexistent component.
 *   ENOMEM Could not allocate a memory to copy filenames or data into.
 *   ENOTBLK 'source' is not a block device
 *
 ****************************************************************************/
mount
Description:
mount() attaches the filesystem specified by the 'source' block device
name into the root file system at the path specified by 'target.'

Zero is returned on success; -1 is returned on an error and errno is
set appropriately.

EACCES A component of a path was not searchable or mounting a read-only
filesystem was attempted without giving the MS_RDONLY flag.
EBUSY 'source' is already  mounted.
EFAULT One of the pointer arguments points outside the user address
space.
EINVAL 'source' had an invalid superblock.
ENODEV 'filesystemtype' not configured
ENOENT A pathname was empty or had a nonexistent component.
ENOMEM Could not allocate a memory to copy filenames or data into.
ENOTBLK 'source' is not a block device
mount Description : mount () attaches the filesystem specified by the ' source ' block device name into the root file system at the path specified by ' target . ' Zero is returned on success ; - 1 is returned on an error and errno is set appropriately . EACCES A component of a path was not searchable or mounting a read - only filesystem was attempted without giving the MS_RDONLY flag . EBUSY ' source ' is already mounted . EFAULT One of the pointer arguments points outside the user address space . EINVAL ' source ' had an invalid superblock . ENODEV ' filesystemtype ' not configured ENOENT A pathname was empty or had a nonexistent component . ENOMEM Could not allocate a memory to copy filenames or data into . ENOTBLK ' source ' is not a block device
int mount(const char *source, const char *target,
          const char *filesystemtype, unsigned long mountflags,
          const void *data)
{
  int ret;
  int errcode = 0;
  struct Mount* mnt = NULL;
  struct Vnode *device = NULL;
  struct Vnode *mountpt_vnode = NULL;
  const struct fsmap_t *fsmap = NULL;
  const struct MountOps *mops = NULL;
  LIST_HEAD *mount_list = NULL;
#ifdef LOSCFG_DRIVERS_MTD
  mtd_partition *partition = NULL;
#endif
  if (filesystemtype == NULL)
    {
      errcode = -EINVAL;
      goto errout;
    }
  DEBUGASSERT(target && filesystemtype);
  if ((fsmap = mount_findfs(filesystemtype)) == NULL || (fsmap->is_bdfs && !source))
    {
      PRINT_ERR("Failed to find file system %s\n", filesystemtype);
      errcode = -ENODEV;
      goto errout;
    }
  mops = fsmap->fs_mops;
  if (fsmap->is_bdfs && source)
    {
      DEBUGASSERT(source);
      ret = find_blockdriver(source, mountflags, &device);
      if (ret < 0)
        {
          PRINT_ERR("Failed to find block driver %s\n", source);
          errcode = ret;
          goto errout;
        }
    }
  VnodeHold();
  ret = VnodeLookup(target, &mountpt_vnode, 0);
  if (ret != OK)
    {
      PRINT_ERR("Failed to find valid mountpoint %s\n", target);
      errcode = -EINVAL;
      goto errout_with_lock;
    }
  if (mountpt_vnode->flag & VNODE_FLAG_MOUNT_NEW)
    {
      PRINT_ERR("can't mount to %s, already mounted.\n", target);
      errcode = -EINVAL;
      goto errout_with_lock;
    }
  if (mops->Mount == NULL)
    {
      PRINTK("ERROR: Filesystem does not support bind\n");
      errcode = -ENOSYS;
      goto errout_with_lock;
    }
#ifdef LOSCFG_DRIVERS_MTD
  if (fsmap->is_mtd_support && (device != NULL))
    {
      partition = (mtd_partition *)((struct drv_data *)device->data)->priv;
      partition->mountpoint_name = (char *)zalloc(strlen(target) + 1);
      if (partition->mountpoint_name == NULL)
        {
          errcode = -ENOMEM;
          goto errout_with_lock;
        }
      (void)strncpy_s(partition->mountpoint_name, strlen(target) + 1, target, strlen(target));
      partition->mountpoint_name[strlen(target)] = '\0';
    }
#endif
  mnt = MountAlloc(mountpt_vnode, (struct MountOps*)mops);
#ifdef LOSCFG_FS_ZPFS
  if (strcmp(filesystemtype, ZPFS_NAME) == 0)
    {
      ret = ZpfsPrepare(source, target, mnt);
      if (ret < 0)
        {
          errcode = ret;
          goto errout_with_mountpt;
        }
    }
#endif
  mnt->mountFlags = mountflags;
  mountpt_vnode->useCount++;
  ret = mops->Mount(mnt, device, data);
  mountpt_vnode->useCount--;
  if (ret != 0)
    {
      PRINT_ERR("Bind method failed: %d\n", ret);
      errcode = ret;
#ifdef LOSCFG_DRIVERS_MTD
      if (fsmap->is_mtd_support && (device != NULL) && (partition != NULL))
        {
          free(partition->mountpoint_name);
          partition->mountpoint_name = NULL;
        }
#endif
      goto errout_with_mountpt;
    }
  mnt->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN;
  mnt->vnodeCovered->flag |= VNODE_FLAG_MOUNT_NEW;
  mnt->vnodeDev = device;
  mnt->ops = mops;
  if (target && (strlen(target) != 0))
    {
      ret = strcpy_s(mnt->pathName, PATH_MAX, target);
      if (ret != EOK)
        {
          PRINT_ERR("Failed to copy mount point pathname, errno %d\n", ret);
        }
    }
  if (source && (strlen(source) != 0))
    {
      ret = strcpy_s(mnt->devName, PATH_MAX, source);
      if (ret != EOK)
        {
          PRINT_ERR("Failed to copy dev name, errno %d\n", ret);
        }
    }
  mount_list = GetMountList();
  LOS_ListAdd(mount_list, &mnt->mountList);
  if (!strcmp("/", target))
    {
      ChangeRoot(mnt->vnodeCovered);
    }
  VnodeDrop();
  return OK;
errout_with_mountpt:
  if (mnt)
    {
      free(mnt);
    }
errout_with_lock:
  VnodeDrop();
errout:
  set_errno(-errcode);
  return VFS_ERROR;
}
int mount ( const char * source , const char * target , const char * filesystemtype , unsigned long mountflags , const void * data ) { int ret ; int errcode = 0 ; struct Mount * mnt = NULL ; struct Vnode * device = NULL ; struct Vnode * mountpt_vnode = NULL ; const struct fsmap_t * fsmap = NULL ; const struct MountOps * mops = NULL ; LIST_HEAD * mount_list = NULL ; #ifdef LOSCFG_DRIVERS_MTD mtd_partition * partition = NULL ; #endif if ( filesystemtype == NULL ) { errcode = - EINVAL ; goto errout ; } DEBUGASSERT ( target && filesystemtype ) ; if ( ( fsmap = mount_findfs ( filesystemtype ) ) == NULL || ( fsmap -> is_bdfs && ! source ) ) { PRINT_ERR ( " \n " , filesystemtype ) ; errcode = - ENODEV ; goto errout ; } mops = fsmap -> fs_mops ; if ( fsmap -> is_bdfs && source ) { DEBUGASSERT ( source ) ; ret = find_blockdriver ( source , mountflags , & device ) ; if ( ret < 0 ) { PRINT_ERR ( " \n " , source ) ; errcode = ret ; goto errout ; } } VnodeHold ( ) ; ret = VnodeLookup ( target , & mountpt_vnode , 0 ) ; if ( ret != OK ) { PRINT_ERR ( " \n " , target ) ; errcode = - EINVAL ; goto errout_with_lock ; } if ( mountpt_vnode -> flag & VNODE_FLAG_MOUNT_NEW ) { PRINT_ERR ( " \n " , target ) ; errcode = - EINVAL ; goto errout_with_lock ; } if ( mops -> Mount == NULL ) { PRINTK ( " \n " ) ; errcode = - ENOSYS ; goto errout_with_lock ; } #ifdef LOSCFG_DRIVERS_MTD if ( fsmap -> is_mtd_support && ( device != NULL ) ) { partition = ( mtd_partition * ) ( ( struct drv_data * ) device -> data ) -> priv ; partition -> mountpoint_name = ( char * ) zalloc ( strlen ( target ) + 1 ) ; if ( partition -> mountpoint_name == NULL ) { errcode = - ENOMEM ; goto errout_with_lock ; } ( void ) strncpy_s ( partition -> mountpoint_name , strlen ( target ) + 1 , target , strlen ( target ) ) ; partition -> mountpoint_name [ strlen ( target ) ] = ' \0 ' ; } #endif mnt = MountAlloc ( mountpt_vnode , ( struct MountOps * ) mops ) ; #ifdef LOSCFG_FS_ZPFS if ( strcmp ( filesystemtype , ZPFS_NAME ) == 0 ) { ret = ZpfsPrepare ( source , target , mnt ) ; if ( ret < 0 ) { errcode = ret ; goto errout_with_mountpt ; } } #endif mnt -> mountFlags = mountflags ; mountpt_vnode -> useCount ++ ; ret = mops -> Mount ( mnt , device , data ) ; mountpt_vnode -> useCount -- ; if ( ret != 0 ) { PRINT_ERR ( " \n " , ret ) ; errcode = ret ; #ifdef LOSCFG_DRIVERS_MTD if ( fsmap -> is_mtd_support && ( device != NULL ) && ( partition != NULL ) ) { free ( partition -> mountpoint_name ) ; partition -> mountpoint_name = NULL ; } #endif goto errout_with_mountpt ; } mnt -> vnodeBeCovered -> flag |= VNODE_FLAG_MOUNT_ORIGIN ; mnt -> vnodeCovered -> flag |= VNODE_FLAG_MOUNT_NEW ; mnt -> vnodeDev = device ; mnt -> ops = mops ; if ( target && ( strlen ( target ) != 0 ) ) { ret = strcpy_s ( mnt -> pathName , PATH_MAX , target ) ; if ( ret != EOK ) { PRINT_ERR ( " \n " , ret ) ; } } if ( source && ( strlen ( source ) != 0 ) ) { ret = strcpy_s ( mnt -> devName , PATH_MAX , source ) ; if ( ret != EOK ) { PRINT_ERR ( " \n " , ret ) ; } } mount_list = GetMountList ( ) ; LOS_ListAdd ( mount_list , & mnt -> mountList ) ; if ( ! strcmp ( " " , target ) ) { ChangeRoot ( mnt -> vnodeCovered ) ; } VnodeDrop ( ) ; return OK ; errout_with_mountpt : if ( mnt ) { free ( mnt ) ; } errout_with_lock : VnodeDrop ( ) ; errout : set_errno ( - errcode ) ; return VFS_ERROR ; }
Name: mount
 Description:
   mount() attaches the filesystem specified by the 'source' block device
   name into the root file system at the path specified by 'target.'
Name : mount Description : mount () attaches the filesystem specified by the ' source ' block device name into the root file system at the path specified by ' target . '
/* Verify required pointer arguments */ /* Find the specified filesystem.  Try the block driver file systems first */ /* Make sure that a block driver argument was provided */ /* Find the block driver */ /* The mount point must be an existed vnode. */ /* Bind the block driver to an instance of the file system.  The file
   * system returns a reference to some opaque, fs-dependent structure
   * that encapsulates this binding.
   */ /* The filesystem does not support the bind operation ??? */ /* Increment reference count for the reference we pass to the file system */ /* The vnode is unhappy with the blkdrvr for some reason.  Back out
       * the count for the reference we failed to pass and exit with an
       * error.
       */ //* We have it, now populate it with driver specific information. */ /* We can release our reference to the blkdrver_vnode, if the filesystem
   * wants to retain the blockdriver vnode (which it should), then it must
   * have called vnode_addref().  There is one reference on mountpt_vnode
   * that will persist until umount() is called.
   */ /* A lot of goto's!  But they make the error handling much simpler */