diff options
-rw-r--r-- | nuttx/TODO | 55 | ||||
-rw-r--r-- | nuttx/arch/sim/src/nuttx-names.dat | 2 | ||||
-rw-r--r-- | nuttx/fs/mount/Make.defs | 2 | ||||
-rw-r--r-- | nuttx/fs/mount/fs_automount.c | 6 | ||||
-rw-r--r-- | nuttx/fs/mount/fs_mount.c | 2 | ||||
-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.h | 50 | ||||
-rw-r--r-- | nuttx/include/sys/syscall.h | 2 | ||||
-rw-r--r-- | nuttx/syscall/syscall.csv | 2 | ||||
-rw-r--r-- | nuttx/syscall/syscall_lookup.h | 2 | ||||
-rw-r--r-- | nuttx/syscall/syscall_stublookup.c | 2 |
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 */ |