mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 08:38:38 +08:00
Add umount2(). umount() is now a macro that just calls umount2() with flags = 0.
This commit is contained in:
parent
9e2587ffe9
commit
f932b26db1
11 changed files with 111 additions and 23 deletions
55
TODO
55
TODO
|
@ -1,4 +1,4 @@
|
|||
NuttX TODO List (Last updated March 10, 2015)
|
||||
NuttX TODO List (Last updated March 14, 2015)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
|
@ -18,7 +18,7 @@ nuttx/
|
|||
(12) Network (net/, drivers/net)
|
||||
(4) USB (drivers/usbdev, drivers/usbhost)
|
||||
(11) Libraries (libc/, libm/)
|
||||
(11) File system/Generic drivers (fs/, drivers/)
|
||||
(12) File system/Generic drivers (fs/, drivers/)
|
||||
(9) Graphics subystem (graphics/)
|
||||
(1) Pascal add-on (pcode/)
|
||||
(1) Documentation (Documentation/)
|
||||
|
@ -1303,6 +1303,57 @@ o File system / Generic drivers (fs/, drivers/)
|
|||
Status: Open
|
||||
Priority: Medium
|
||||
|
||||
Title: UNMOUNT WITH OPEN FILES
|
||||
Description: What is the policy for umounting files that have open file
|
||||
references? Currently, umount() does the unmount
|
||||
unconditionally and this has been noted to cause crashes in
|
||||
some subsequent FAT file system operations. umount() is not
|
||||
a standard OS interface and so have no specification. Here
|
||||
are some possible behaviors or unmount() with open files:
|
||||
|
||||
1. Refuse to unmount() the file system if there are open
|
||||
references to files on the file system (i.e., the file
|
||||
system unbind() method returns a failure).
|
||||
2. The file system knows that it has open references and so
|
||||
does not unbind() immediately, but defers until the last
|
||||
file is closed.
|
||||
3. The file system performs the unbind() immediately, but
|
||||
returns an error for an any subsequent operations on the
|
||||
file system using one of the stale file handles.
|
||||
4. In your application, do not un-mount until you have closed
|
||||
all references to files or directories in the file system.
|
||||
This would probably be a good practice anyway.
|
||||
|
||||
I lieu of any real specifications, I often just do what Linux
|
||||
does. Here is now Linux does things:
|
||||
http://man7.org/linux/man-pages/man2/umount.2.html .
|
||||
Linux has have a umount2() that takes flags that control these
|
||||
behaviors. They have a couple of other options as well.
|
||||
|
||||
It is not explicitly stated in the manpage, but it looks like
|
||||
the Linux umount() does the first option: It should return
|
||||
EBUSY meaning that the "target could not be unmounted because
|
||||
it is busy." That one is pretty easy to implement within the
|
||||
filesystem unbind() method.
|
||||
|
||||
I now think for an embedded system with mostly removable
|
||||
storage devices, the option 3 is probably the most usable. For
|
||||
example, NuttX has a little automounter at nuttx/fs/mount/fs_automount.c
|
||||
That will automatically mount and unmount SD cards as they are
|
||||
inserted or removed. I think that is a desire-able feature on
|
||||
an embedded device. And I think it demands option 3 where the
|
||||
umount occurs immediately, but then subsequent operations on
|
||||
the volume fail.
|
||||
|
||||
The true lazy umount could also cause issues if the file is
|
||||
never closed. Of course if the media is gone, I would hope
|
||||
that the file access also fail in that case. But what if the
|
||||
media is inserted and removed many times. Seems like the lazy
|
||||
unmount could cause some problems and won't really buy you
|
||||
anything anyway (because the file I/O will fail anyway).
|
||||
Status: Open
|
||||
Priority: Medium-High
|
||||
|
||||
o Graphics subsystem (graphics/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ statfs NXstatfs
|
|||
system NXsystem
|
||||
tcgetattr NXtcgetattr
|
||||
tcsetattr NXtcsetattr
|
||||
umount NXumount
|
||||
umount2 NXumount2
|
||||
unlink NXunlink
|
||||
usleep NXusleep
|
||||
vfork NXvfork
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
|
||||
ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
|
||||
|
||||
CSRCS += fs_mount.c fs_umount.c fs_foreachmountpoint.c
|
||||
CSRCS += fs_mount.c fs_umount2.c fs_foreachmountpoint.c
|
||||
|
||||
ifeq ($(CONFIG_FS_AUTOMOUNTER),y)
|
||||
CSRCS += fs_automount.c
|
||||
|
|
|
@ -290,7 +290,7 @@ static int automount_unmount(FAR struct automounter_state_s *priv)
|
|||
|
||||
/* Un-mount the volume */
|
||||
|
||||
ret = umount(lower->mountpoint);
|
||||
ret = umount2(lower->mountpoint, MNT_FORCE);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
|
@ -305,7 +305,7 @@ static int automount_unmount(FAR struct automounter_state_s *priv)
|
|||
{
|
||||
fvdbg("WARNING: Volume is busy, try again later\n");
|
||||
|
||||
/* Start a timer to retry the umount after a delay */
|
||||
/* Start a timer to retry the umount2 after a delay */
|
||||
|
||||
ret = wd_start(priv->wdog, lower->udelay, automount_timeout, 1,
|
||||
(uint32_t)((uintptr_t)priv));
|
||||
|
@ -323,7 +323,7 @@ static int automount_unmount(FAR struct automounter_state_s *priv)
|
|||
|
||||
else
|
||||
{
|
||||
fvdbg("ERROR: umount failed: %d\n", errcode);
|
||||
fvdbg("ERROR: umount2 failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -353,7 +353,7 @@ int mount(FAR const char *source, FAR const char *target,
|
|||
/* We can release our reference to the blkdrver_inode, if the filesystem
|
||||
* wants to retain the blockdriver inode (which it should), then it must
|
||||
* have called inode_addref(). There is one reference on mountpt_inode
|
||||
* that will persist until umount() is called.
|
||||
* that will persist until umount2() is called.
|
||||
*/
|
||||
|
||||
#ifdef BDFS_SUPPORT
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* fs/mount/fs_umount.c
|
||||
* fs/mount/fs_umount2.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -70,7 +70,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: umount
|
||||
* Name: umount2
|
||||
*
|
||||
* Description:
|
||||
* umount() detaches the filesystem mounted at the path specified by
|
||||
|
@ -87,7 +87,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int umount(const char *target)
|
||||
int umount2(FAR const char *target, unsigned int flags)
|
||||
{
|
||||
FAR struct inode *mountpt_inode;
|
||||
FAR struct inode *blkdrvr_inode = NULL;
|
||||
|
@ -203,4 +203,3 @@ errout:
|
|||
set_errno(errcode);
|
||||
return ERROR;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* include/sys/mount.h
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -40,6 +40,8 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
@ -48,6 +50,41 @@
|
|||
|
||||
#define MS_RDONLY 1 /* Mount file system read-only */
|
||||
|
||||
/* Un-mount flags
|
||||
*
|
||||
* These flags control the behavior of umount2() when there are open file
|
||||
* references through the mountpoint. umount2() with no flag bits set is
|
||||
* equivalent to umount(), i.e., the umount() will fail with EBUSY if there
|
||||
* are open references on the file.
|
||||
*
|
||||
* MNT_FORCE - Force unmount even if busy. This can cause data loss.
|
||||
* MNT_DETACH - Perform a lazy unmount: make the mount point unavailable
|
||||
* for new accesses, and actually perform the unmount when the mount
|
||||
* point ceases to be busy.
|
||||
* MNT_EXPIRE - Mark the mount point as expired. If a mount point is not
|
||||
* currently in use, then an initial call to umount2() with this flag
|
||||
* fails with the error EAGAIN, but marks the mount point as expired. The
|
||||
* mount point remains expired as long as it isn't accessed by any
|
||||
* process. A second umount2() call specifying MNT_EXPIRE unmounts an
|
||||
* expired mount point. This flag cannot be specified with either
|
||||
* MNT_FORCE or MNT_DETACH.
|
||||
* UMOUNT_NOFOLLOW (- Don't dereference target if it is a symbolic link.
|
||||
* For Linux, this flag allows security problems to be avoided in
|
||||
* set-user-ID-root programs that allow unprivileged users to unmount
|
||||
* file systems. For NuttX, it is provided only for compatibility
|
||||
*
|
||||
* Not all options are supported on all file systems.
|
||||
*/
|
||||
|
||||
#define MNT_FORCE (1 << 0)
|
||||
#define MNT_DETACH (1 << 1)
|
||||
#define MNT_EXPIRE (1 << 2)
|
||||
#define UMOUNT_NOFOLLOW (0)
|
||||
|
||||
/* mount() is equivalent to umount2() with flags = 0 */
|
||||
|
||||
#define umount(t) umount2(t,0)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
@ -59,15 +96,16 @@
|
|||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
int mount(const char *source, const char *target,
|
||||
const char *filesystemtype, unsigned long mountflags,
|
||||
const void *data);
|
||||
int umount(const char *target);
|
||||
int mount(FAR const char *source, FAR const char *target,
|
||||
FAR const char *filesystemtype, unsigned long mountflags,
|
||||
FAR const void *data);
|
||||
int umount2(FAR const char *target, unsigned int flags);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -298,7 +298,7 @@
|
|||
# define SYS_mount (__SYS_mountpoint+2)
|
||||
# define SYS_rename (__SYS_mountpoint+3)
|
||||
# define SYS_rmdir (__SYS_mountpoint+4)
|
||||
# define SYS_umount (__SYS_mountpoint+5)
|
||||
# define SYS_umount2 (__SYS_mountpoint+5)
|
||||
# define SYS_unlink (__SYS_mountpoint+6)
|
||||
# define __SYS_shm (__SYS_mountpoint+7)
|
||||
# else
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
"timer_getoverrun","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","timer_t"
|
||||
"timer_gettime","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","timer_t","FAR struct itimerspec*"
|
||||
"timer_settime","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","timer_t","int","FAR const struct itimerspec*","FAR struct itimerspec*"
|
||||
"umount","sys/mount.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","const char*"
|
||||
"umount2","sys/mount.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char*","unsigned int"
|
||||
"unlink","unistd.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char*"
|
||||
"unsetenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","const char*"
|
||||
"up_assert","assert.h","","void","FAR const uint8_t*","int"
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -215,7 +215,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
|
|||
SYSCALL_LOOKUP(mount, 5, STUB_mount)
|
||||
SYSCALL_LOOKUP(rename, 2, STUB_rename)
|
||||
SYSCALL_LOOKUP(rmdir, 1, STUB_rmdir)
|
||||
SYSCALL_LOOKUP(umount, 1, STUB_umount)
|
||||
SYSCALL_LOOKUP(umount2, 2, STUB_umount2)
|
||||
SYSCALL_LOOKUP(unlink, 1, STUB_unlink)
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -223,7 +223,7 @@ uintptr_t STUB_mount(int nbr, uintptr_t parm1, uintptr_t parm2,
|
|||
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);
|
||||
uintptr_t STUB_rename(int nbr, uintptr_t parm1, uintptr_t parm2);
|
||||
uintptr_t STUB_rmdir(int nbr, uintptr_t parm1);
|
||||
uintptr_t STUB_umount(int nbr, uintptr_t parm1);
|
||||
uintptr_t STUB_umount2(int nbr, uintptr_t parm1, uintptr parm2);
|
||||
uintptr_t STUB_unlink(int nbr, uintptr_t parm1);
|
||||
|
||||
/* Shared memory interfaces */
|
||||
|
|
Loading…
Reference in a new issue