mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
Add umount2(). umount() is now a macro that just calls umount2() with flags = 0.
This commit is contained in:
@@ -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
|
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||||
@@ -18,7 +18,7 @@ nuttx/
|
|||||||
(12) Network (net/, drivers/net)
|
(12) Network (net/, drivers/net)
|
||||||
(4) USB (drivers/usbdev, drivers/usbhost)
|
(4) USB (drivers/usbdev, drivers/usbhost)
|
||||||
(11) Libraries (libc/, libm/)
|
(11) Libraries (libc/, libm/)
|
||||||
(11) File system/Generic drivers (fs/, drivers/)
|
(12) File system/Generic drivers (fs/, drivers/)
|
||||||
(9) Graphics subystem (graphics/)
|
(9) Graphics subystem (graphics/)
|
||||||
(1) Pascal add-on (pcode/)
|
(1) Pascal add-on (pcode/)
|
||||||
(1) Documentation (Documentation/)
|
(1) Documentation (Documentation/)
|
||||||
@@ -1303,6 +1303,57 @@ o File system / Generic drivers (fs/, drivers/)
|
|||||||
Status: Open
|
Status: Open
|
||||||
Priority: Medium
|
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/)
|
o Graphics subsystem (graphics/)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ statfs NXstatfs
|
|||||||
system NXsystem
|
system NXsystem
|
||||||
tcgetattr NXtcgetattr
|
tcgetattr NXtcgetattr
|
||||||
tcsetattr NXtcsetattr
|
tcsetattr NXtcsetattr
|
||||||
umount NXumount
|
umount2 NXumount2
|
||||||
unlink NXunlink
|
unlink NXunlink
|
||||||
usleep NXusleep
|
usleep NXusleep
|
||||||
vfork NXvfork
|
vfork NXvfork
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@
|
|||||||
ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
|
ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
|
||||||
ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
|
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)
|
ifeq ($(CONFIG_FS_AUTOMOUNTER),y)
|
||||||
CSRCS += fs_automount.c
|
CSRCS += fs_automount.c
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ static int automount_unmount(FAR struct automounter_state_s *priv)
|
|||||||
|
|
||||||
/* Un-mount the volume */
|
/* Un-mount the volume */
|
||||||
|
|
||||||
ret = umount(lower->mountpoint);
|
ret = umount2(lower->mountpoint, MNT_FORCE);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
int errcode = get_errno();
|
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");
|
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,
|
ret = wd_start(priv->wdog, lower->udelay, automount_timeout, 1,
|
||||||
(uint32_t)((uintptr_t)priv));
|
(uint32_t)((uintptr_t)priv));
|
||||||
@@ -323,7 +323,7 @@ static int automount_unmount(FAR struct automounter_state_s *priv)
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fvdbg("ERROR: umount failed: %d\n", errcode);
|
fvdbg("ERROR: umount2 failed: %d\n", errcode);
|
||||||
return -errcode;
|
return -errcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -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
|
/* We can release our reference to the blkdrver_inode, if the filesystem
|
||||||
* wants to retain the blockdriver inode (which it should), then it must
|
* wants to retain the blockdriver inode (which it should), then it must
|
||||||
* have called inode_addref(). There is one reference on mountpt_inode
|
* 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
|
#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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: umount
|
* Name: umount2
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* umount() detaches the filesystem mounted at the path specified by
|
* 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 *mountpt_inode;
|
||||||
FAR struct inode *blkdrvr_inode = NULL;
|
FAR struct inode *blkdrvr_inode = NULL;
|
||||||
@@ -203,4 +203,3 @@ errout:
|
|||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
+44
-6
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* include/sys/mount.h
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -40,6 +40,8 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/compiler.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -48,6 +50,41 @@
|
|||||||
|
|
||||||
#define MS_RDONLY 1 /* Mount file system read-only */
|
#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
|
* Public Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -59,15 +96,16 @@
|
|||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
#define EXTERN extern "C"
|
#define EXTERN extern "C"
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#else
|
#else
|
||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int mount(const char *source, const char *target,
|
int mount(FAR const char *source, FAR const char *target,
|
||||||
const char *filesystemtype, unsigned long mountflags,
|
FAR const char *filesystemtype, unsigned long mountflags,
|
||||||
const void *data);
|
FAR const void *data);
|
||||||
int umount(const char *target);
|
int umount2(FAR const char *target, unsigned int flags);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
|||||||
@@ -298,7 +298,7 @@
|
|||||||
# define SYS_mount (__SYS_mountpoint+2)
|
# define SYS_mount (__SYS_mountpoint+2)
|
||||||
# define SYS_rename (__SYS_mountpoint+3)
|
# define SYS_rename (__SYS_mountpoint+3)
|
||||||
# define SYS_rmdir (__SYS_mountpoint+4)
|
# 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_unlink (__SYS_mountpoint+6)
|
||||||
# define __SYS_shm (__SYS_mountpoint+7)
|
# define __SYS_shm (__SYS_mountpoint+7)
|
||||||
# else
|
# else
|
||||||
|
|||||||
+1
-1
@@ -144,7 +144,7 @@
|
|||||||
"timer_getoverrun","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","timer_t"
|
"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_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*"
|
"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*"
|
"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*"
|
"unsetenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","const char*"
|
||||||
"up_assert","assert.h","","void","FAR const uint8_t*","int"
|
"up_assert","assert.h","","void","FAR const uint8_t*","int"
|
||||||
|
|||||||
|
Can't render this file because it contains an unexpected character in line 135 and column 2.
|
@@ -215,7 +215,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
|
|||||||
SYSCALL_LOOKUP(mount, 5, STUB_mount)
|
SYSCALL_LOOKUP(mount, 5, STUB_mount)
|
||||||
SYSCALL_LOOKUP(rename, 2, STUB_rename)
|
SYSCALL_LOOKUP(rename, 2, STUB_rename)
|
||||||
SYSCALL_LOOKUP(rmdir, 1, STUB_rmdir)
|
SYSCALL_LOOKUP(rmdir, 1, STUB_rmdir)
|
||||||
SYSCALL_LOOKUP(umount, 1, STUB_umount)
|
SYSCALL_LOOKUP(umount2, 2, STUB_umount2)
|
||||||
SYSCALL_LOOKUP(unlink, 1, STUB_unlink)
|
SYSCALL_LOOKUP(unlink, 1, STUB_unlink)
|
||||||
# endif
|
# endif
|
||||||
#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 parm3, uintptr_t parm4, uintptr_t parm5);
|
||||||
uintptr_t STUB_rename(int nbr, uintptr_t parm1, uintptr_t parm2);
|
uintptr_t STUB_rename(int nbr, uintptr_t parm1, uintptr_t parm2);
|
||||||
uintptr_t STUB_rmdir(int nbr, uintptr_t parm1);
|
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);
|
uintptr_t STUB_unlink(int nbr, uintptr_t parm1);
|
||||||
|
|
||||||
/* Shared memory interfaces */
|
/* Shared memory interfaces */
|
||||||
|
|||||||
Reference in New Issue
Block a user