summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-03-14 16:48:45 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-03-14 16:48:45 -0600
commite3fa0599d86506b6b79723ddffeca038440e40a6 (patch)
tree8929732aae71de32ef20b3fc60a6fa548b768051
parent42132b61b6b0add6342560394d578cf2c727b29c (diff)
downloadpx4-nuttx-e3fa0599d86506b6b79723ddffeca038440e40a6.tar.gz
px4-nuttx-e3fa0599d86506b6b79723ddffeca038440e40a6.tar.bz2
px4-nuttx-e3fa0599d86506b6b79723ddffeca038440e40a6.zip
Add umount2(). umount() is now a macro that just calls umount2() with flags = 0.
-rw-r--r--nuttx/TODO55
-rw-r--r--nuttx/arch/sim/src/nuttx-names.dat2
-rw-r--r--nuttx/fs/mount/Make.defs2
-rw-r--r--nuttx/fs/mount/fs_automount.c6
-rw-r--r--nuttx/fs/mount/fs_mount.c2
-rw-r--r--nuttx/fs/mount/fs_umount2.c (renamed from nuttx/fs/mount/fs_umount.c)9
-rw-r--r--nuttx/include/sys/mount.h50
-rw-r--r--nuttx/include/sys/syscall.h2
-rw-r--r--nuttx/syscall/syscall.csv2
-rw-r--r--nuttx/syscall/syscall_lookup.h2
-rw-r--r--nuttx/syscall/syscall_stublookup.c2
11 files changed, 111 insertions, 23 deletions
diff --git a/nuttx/TODO b/nuttx/TODO
index a2b3df9f0..c526a7d15 100644
--- a/nuttx/TODO
+++ b/nuttx/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/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/arch/sim/src/nuttx-names.dat b/nuttx/arch/sim/src/nuttx-names.dat
index 5456f2722..7cfe1bd38 100644
--- a/nuttx/arch/sim/src/nuttx-names.dat
+++ b/nuttx/arch/sim/src/nuttx-names.dat
@@ -41,7 +41,7 @@ statfs NXstatfs
system NXsystem
tcgetattr NXtcgetattr
tcsetattr NXtcsetattr
-umount NXumount
+umount2 NXumount2
unlink NXunlink
usleep NXusleep
vfork NXvfork
diff --git a/nuttx/fs/mount/Make.defs b/nuttx/fs/mount/Make.defs
index 26a6c0fd1..56596e81d 100644
--- a/nuttx/fs/mount/Make.defs
+++ b/nuttx/fs/mount/Make.defs
@@ -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
diff --git a/nuttx/fs/mount/fs_automount.c b/nuttx/fs/mount/fs_automount.c
index e8207cb42..1efa80ada 100644
--- a/nuttx/fs/mount/fs_automount.c
+++ b/nuttx/fs/mount/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;
}
}
diff --git a/nuttx/fs/mount/fs_mount.c b/nuttx/fs/mount/fs_mount.c
index 4263f618b..9921bbe6f 100644
--- a/nuttx/fs/mount/fs_mount.c
+++ b/nuttx/fs/mount/fs_mount.c
@@ -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
diff --git a/nuttx/fs/mount/fs_umount.c b/nuttx/fs/mount/fs_umount2.c
index e7ea1c2d4..6d0609f9e 100644
--- a/nuttx/fs/mount/fs_umount.c
+++ b/nuttx/fs/mount/fs_umount2.c
@@ -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;
}
-
diff --git a/nuttx/include/sys/mount.h b/nuttx/include/sys/mount.h
index 7acc2f03f..32b1ccfb3 100644
--- a/nuttx/include/sys/mount.h
+++ b/nuttx/include/sys/mount.h
@@ -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)
diff --git a/nuttx/include/sys/syscall.h b/nuttx/include/sys/syscall.h
index 79c8433b3..a4830ee2b 100644
--- a/nuttx/include/sys/syscall.h
+++ b/nuttx/include/sys/syscall.h
@@ -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
diff --git a/nuttx/syscall/syscall.csv b/nuttx/syscall/syscall.csv
index 1ad010d62..ee06e3821 100644
--- a/nuttx/syscall/syscall.csv
+++ b/nuttx/syscall/syscall.csv
@@ -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"
diff --git a/nuttx/syscall/syscall_lookup.h b/nuttx/syscall/syscall_lookup.h
index e6c41a477..0ba28c97b 100644
--- a/nuttx/syscall/syscall_lookup.h
+++ b/nuttx/syscall/syscall_lookup.h
@@ -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
diff --git a/nuttx/syscall/syscall_stublookup.c b/nuttx/syscall/syscall_stublookup.c
index 63db0d773..aeebeece6 100644
--- a/nuttx/syscall/syscall_stublookup.c
+++ b/nuttx/syscall/syscall_stublookup.c
@@ -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 */