unlink/rm can now be used on nodes in the pseudo-filesystem. There is new configuration option to suppress these costly and mostly useless operations on the pseudo-filesystem

This commit is contained in:
Gregory Nutt 2014-02-20 18:14:02 -06:00
parent d000752cf5
commit bebb5d8c4d
10 changed files with 233 additions and 63 deletions

View file

@ -6630,4 +6630,9 @@
but untested (2014-2-20).
* configs/olimex-lpc1766stck/ftpc: Configuration convert to use
the kconfig-frontends tools by Alan Carvalho de Assis (2014-2-20).
* fs/fs_mkdir.c: 'unlink' can now be used to remove things from the
pseudo-filesystem. A new configuration option as been added:
CONFIG_DISABLE_PSEUDOFS_OPERATIONS that effectively can be set
back out these recent changes in rmdir, mkdir, unlink, and rename
for operations on the pseudo-filesystem (2014-2-20).

View file

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttShell (NSH)</i></font></big></h1>
<p>Last Updated: February 19, 2014</p>
<p>Last Updated: February 20, 2014</p>
</td>
</tr>
</table>
@ -2664,7 +2664,7 @@ nsh>
</tr>
<tr>
<td><b><code>mkdir</code></b></td>
<td>!<code>CONFIG_DISABLE_MOUNTPOINT</code> &amp;&amp; <code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0 &amp;&amp; <code>CONFIG_FS_WRITABLE</code><sup>4</sup></td>
<td>(((!<code>CONFIG_DISABLE_MOUNTPOINT</code> &amp;&amp; <code>CONFIG_FS_WRITABLE</code>) || !<code>CONFIG_DISABLE_PSEUDOFS_OPERATIONS</code>) &amp;&amp; <code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0)<sup>4</sup></td>
<td><code>CONFIG_NSH_DISABLE_MKDIR</code></td>
</tr>
<tr>
@ -2689,7 +2689,7 @@ nsh>
</tr>
<tr>
<td><b><code>mv</code></b></td>
<td>!<code>CONFIG_DISABLE_MOUNTPOINT</code> &amp;&amp; <code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0 &amp;&amp; <code>CONFIG_FS_WRITABLE</code><sup>3</sup></td>
<td>(((!<code>CONFIG_DISABLE_MOUNTPOINT</code> &amp;&amp; <code>CONFIG_FS_WRITABLE</code>) || !<code>CONFIG_DISABLE_PSEUDOFS_OPERATIONS</code>) &amp;&amp; <code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0)<sup>4</sup></td>
<td><code>CONFIG_NSH_DISABLE_MV</code></td>
</tr>
<tr>
@ -2722,12 +2722,12 @@ nsh>
</tr>
<tr>
<td><b><code>rm</code></b></td>
<td>!<code>CONFIG_DISABLE_MOUNTPOINT</code> &amp;&amp; <code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0 &amp;&amp; <code>CONFIG_FS_WRITABLE</code><sup>4</sup></td>
<td>(((!<code>CONFIG_DISABLE_MOUNTPOINT</code> &amp;&amp; <code>CONFIG_FS_WRITABLE</code>) || !<code>CONFIG_DISABLE_PSEUDOFS_OPERATIONS</code>) &amp;&amp; <code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0)<sup>4</sup></td>
<td><code>CONFIG_NSH_DISABLE_RM</code></td>
</tr>
<tr>
<td><b><code>rmdir</code></b></td>
<td><code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0</td>
<td>(((!<code>CONFIG_DISABLE_MOUNTPOINT</code> &amp;&amp; <code>CONFIG_FS_WRITABLE</code>) || !<code>CONFIG_DISABLE_PSEUDOFS_OPERATIONS</code>) &amp;&amp; <code>CONFIG_NFILE_DESCRIPTORS</code> &gt; 0)<sup>4</sup></td>
<td><code>CONFIG_NSH_DISABLE_RMDIR</code></td>
</tr>
<tr>

View file

@ -9,6 +9,16 @@ config DISABLE_MOUNTPOINT
bool "Disable support for mount points"
default n
config DISABLE_PSEUDOFS_OPERATIONS
bool "Disable pseudo-filesytem operations"
default n
---help---
Disable certain operations on pseudo-file systems include mkdir,
rmdir, unlink, and rename. These are necessary for the logical
completeness of the illusion created by the pseudo-filesystem.
However, in practical embedded system, they are seldom needed and
you can save a little FLASH space by disabling the capability.
config FS_READABLE
bool
default n

View file

@ -65,7 +65,7 @@ CSRCS += fs_close.c fs_closedir.c fs_dup.c fs_dup2.c fs_fcntl.c
CSRCS += fs_filedup.c fs_filedup2.c fs_ioctl.c fs_lseek.c fs_mkdir.c
CSRCS += fs_open.c fs_opendir.c fs_poll.c fs_read.c fs_readdir.c
CSRCS += fs_rename.c fs_rewinddir.c fs_rmdir.c fs_seekdir.c fs_stat.c
CSRCS += fs_statfs.c fs_select.c fs_write.c
CSRCS += fs_statfs.c fs_select.c fs_unlink.c fs_write.c
CSRCS += fs_files.c fs_foreachinode.c fs_inode.c fs_inodeaddref.c
CSRCS += fs_inodebasename.c fs_inodefind.c fs_inoderelease.c
@ -104,8 +104,7 @@ endif
ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
CSRCS += fs_fsync.c fs_mount.c fs_umount.c fs_unlink.c
CSRCS += fs_foreachmountpoint.c
CSRCS += fs_fsync.c fs_mount.c fs_umount.c fs_foreachmountpoint.c
include fat/Make.defs
include romfs/Make.defs

View file

@ -46,9 +46,27 @@
#include "fs_internal.h"
/****************************************************************************
* Definitions
* Pre-processor Definitions
****************************************************************************/
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
#undef FS_HAVE_MKDIR
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_MKDIR 1
#endif
#ifdef FS_HAVE_MKDIR
/****************************************************************************
* Private Variables
****************************************************************************/
@ -129,6 +147,7 @@ int mkdir(const char *pathname, mode_t mode)
#endif
}
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* No inode exists that contains this path. Create a new inode in the
* pseudo-filesystem at this location.
*/
@ -147,6 +166,13 @@ int mkdir(const char *pathname, mode_t mode)
goto errout;
}
}
#else
else
{
errcode = ENXIO;
goto errout;
}
#endif
/* Directory successfully created */
@ -158,3 +184,5 @@ int mkdir(const char *pathname, mode_t mode)
set_errno(errcode);
return ERROR;
}
#endif /* FS_HAVE_MKDIR */

View file

@ -49,6 +49,24 @@
* Pre-processor Definitions
****************************************************************************/
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
#undef FS_HAVE_RENAME
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_RENAME 1
#endif
#ifdef FS_HAVE_RENAME
/****************************************************************************
* Private Variables
****************************************************************************/
@ -75,9 +93,9 @@
int rename(FAR const char *oldpath, FAR const char *newpath)
{
FAR struct inode *oldinode;
FAR struct inode *newinode;
const char *oldrelpath = NULL;
#ifndef CONFIG_DISABLE_MOUNTPOINT
FAR struct inode *newinode;
const char *newrelpath = NULL;
#endif
int errcode;
@ -155,6 +173,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
}
else
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
{
/* Create a new, empty inode at the destination location */
@ -210,6 +229,12 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
oldinode->i_child = NULL;
inode_semgive();
}
#else
{
errcode = ENXIO;
goto errout;
}
#endif
/* Successfully renamed */
@ -226,3 +251,5 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
set_errno(errcode);
return ERROR;
}
#endif /* FS_HAVE_RENAME */

View file

@ -49,6 +49,24 @@
* Pre-processor Definitions
****************************************************************************/
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
#undef FS_HAVE_RMDIR
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_RMDIR 1
#endif
#ifdef FS_HAVE_RMDIR
/****************************************************************************
* Private Variables
****************************************************************************/
@ -118,7 +136,8 @@ int rmdir(FAR const char *pathname)
else
#endif
/* If this is a "dangling" pseudo-file node (i.e., it has no operations)
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* If this is a "dangling" pseudo-directory node (i.e., it has no operations)
* then rmdir should remove the node.
*/
@ -153,10 +172,16 @@ int rmdir(FAR const char *pathname)
}
}
else
{
errcode = ENOTDIR;
goto errout_with_inode;
}
#else
{
errcode = ENXIO;
goto errout_with_inode;
}
#endif
/* Successfully removed the directory */
@ -170,3 +195,4 @@ errout:
return ERROR;
}
#endif /* FS_HAVE_RMDIR */

View file

@ -49,6 +49,24 @@
* Pre-processor Definitions
****************************************************************************/
#undef FS_HAVE_WRITABLE_MOUNTPOINT
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_WRITABLE) && \
CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_WRITABLE_MOUNTPOINT 1
#endif
#undef FS_HAVE_PSEUDOFS_OPERATIONS
#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && CONFIG_NFILE_STREAMS > 0
# define FS_HAVE_PSEUDOFS_OPERATIONS 1
#endif
#undef FS_HAVE_UNLINK
#if defined(FS_HAVE_WRITABLE_MOUNTPOINT) || defined(FS_HAVE_PSEUDOFS_OPERATIONS)
# define FS_HAVE_UNLINK 1
#endif
#ifdef FS_HAVE_UNLINK
/****************************************************************************
* Private Variables
****************************************************************************/
@ -76,6 +94,7 @@ int unlink(FAR const char *pathname)
{
FAR struct inode *inode;
const char *relpath = NULL;
int errcode;
int ret;
/* Get an inode for this file */
@ -83,22 +102,19 @@ int unlink(FAR const char *pathname)
inode = inode_find(pathname, &relpath);
if (!inode)
{
/* There is no mountpoint that includes in this path */
/* There is no inode that includes in this path */
ret = ENOENT;
errcode = ENOENT;
goto errout;
}
/* Verify that the inode is a valid mountpoint. */
#ifndef CONFIG_DISABLE_MOUNTPOINT
/* Check if the inode is a valid mountpoint. */
if (!INODE_IS_MOUNTPT(inode) || !inode->u.i_mops)
if (INODE_IS_MOUNTPT(inode) && inode->u.i_mops)
{
ret = ENXIO;
goto errout_with_inode;
}
/* Perform the unlink operation using the relative path
* at the mountpoint.
/* Perform the unlink operation using the relative path at the
* mountpoint.
*/
if (inode->u.i_mops->unlink)
@ -106,15 +122,73 @@ int unlink(FAR const char *pathname)
ret = inode->u.i_mops->unlink(inode, relpath);
if (ret < 0)
{
ret = -ret;
errcode = -ret;
goto errout_with_inode;
}
}
else
{
ret = ENOSYS;
errcode = ENOSYS;
goto errout_with_inode;
}
}
else
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
/* If this is a "dangling" pseudo-file node (i.e., it has operations) then rm
* should remove the node.
*/
if (inode->u.i_ops)
{
/* If this is a pseudo-file node (i.e., it has no operations)
* then rmdir should remove the node.
*/
if (inode->u.i_ops)
{
inode_semtake();
/* Refuse to unlink the inode if it has children. I.e., if it is
* functioning as a directory and the directory is not empty.
*/
if (inode->i_child != NULL)
{
errcode = ENOTEMPTY;
inode_semgive();
goto errout_with_inode;
}
/* Remove the old inode. Because we hold a reference count on the
* inode, it will not be deleted now. It will be deleted when all
* of the references to to the inode have been released (perhaps
* when inode_release() is called below). inode_remove() will
* return -EBUSY to indicate that the inode was not deleted now.
*/
ret = inode_remove(pathname);
inode_semgive();
if (ret < 0 && ret != -EBUSY)
{
errcode = -ret;
goto errout_with_inode;
}
}
else
{
errcode = EISDIR;
goto errout_with_inode;
}
}
#else
{
errcode = ENXIO;
goto errout_with_inode;
}
#endif
/* Successfully unlinked */
@ -124,7 +198,8 @@ int unlink(FAR const char *pathname)
errout_with_inode:
inode_release(inode);
errout:
set_errno(ret);
set_errno(errcode);
return ERROR;
}
#endif /* FS_HAVE_UNLINK */