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

@ -6089,7 +6089,7 @@
* arch/arm/src/lpc31xx/lpc31_ehci.c: Add USB host trace support
(2013-11-19).
* configs/olimex-lpc-h3131/include/board.h, src/lpc31_boot.c,
lpc31_leds.c, lpc31_usbhost.c, and lpc_h3131.h: Add GPIO
lpc31_leds.c, lpc31_usbhost.c, and lpc_h3131.h: Add GPIO
support for LED1/2 and for USB power enable and overcurrent
detection (2013-11-19).
* configs/olimex-lpc-h3131/nsh/defconfig: Drop loops-per-msec
@ -6267,7 +6267,7 @@
README.txt, and src/stm32_highpri.c: This is the initial framework
for a test of the high priority, nested interrupt logic. Still
incomplete and does not yet run (2013-12-22).
* arch/arm/src/armv7-m/ram_vectors.h and up_ramvec_initialize.c:
* arch/arm/src/armv7-m/ram_vectors.h and up_ramvec_initialize.c:
Correct alignment of the RAM vector table (2013-12-22).
* Kconfig: Support configuration of interrupt controller debug output
(2013-12-22).
@ -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

@ -302,7 +302,7 @@ This is a test
# sudo mkdir /export
</pre></ul>
<p>
It is important that <code>/export</code> directory allow access to everyone (777 permissions) as we will be accessing the NFS share from the client with no authentication.
It is important that <code>/export</code> directory allow access to everyone (777 permissions) as we will be accessing the NFS share from the client with no authentication.
</p>
<ul><pre>
# sudo chmod 777 /export
@ -327,7 +327,7 @@ directory machine1(option11,option12)
In our case we are using all the default options except for the <code>ro</code> that we replaced with <code>rw</code> so that our client will have read and write access to the directory that we are exporting.
</p>
</p>
After we do all the require configurations, we are ready to start the server with the next command:
After we do all the require configurations, we are ready to start the server with the next command:
</p>
<ul><pre>
# sudo /etc/init.d/nfs-kernel-server start
@ -337,7 +337,7 @@ directory machine1(option11,option12)
or run command exportfs.
</p>
<ul><pre>
# sudo /etc/init.d/nfs-kernel-server start
# sudo /etc/init.d/nfs-kernel-server start
</pre></ul>
<p>Or</p>
<ul><pre>

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>
@ -1301,7 +1301,7 @@ nsh> df
Size Blocks Used Available Mounted on
64 6 6 0 /etc
512 985 2 983 /tmp
nsh>
nsh>
</pre></ul>
<p>
If <code>CONFIG_NSH_CMDOPT_DF_H</code> is defined in the NuttX configuration, then the <code>df</code> will also support an option <code>-h</code> which may be used to show the volume information in <i>human readable</i> format.
@ -1653,7 +1653,7 @@ losetup [-o <offset>] [-r] &lt;dev-path&gt; &lt;file-path&gt;
<b>Synopsis</b>.
Setup the loop device at &lt;dev-path&gt; to access the file at &lt;file-path&gt; as a block device.
In the following example a 256K file is created (<code>dd</code>) and <code>losetup</code> is
used to make the file accessible as a block device.
used to make the file accessible as a block device.
A FAT file system is created (<code>mkfatfs</code>) and mounted (<code>mount</code>).
Files can then be managed on the loop-mounted file.
<ul><pre>
@ -2488,7 +2488,7 @@ nsh>
<p>
The availability of the above commands depends upon features that
may or may not be enabled in the NuttX configuration file. The
may or may not be enabled in the NuttX configuration file. The
following <a href="#cmddependencies">table</a> indicates the dependency of each command on NuttX
configuration settings. General configuration settings are discussed
in the <a href="NuttxPortingGuide.html">NuttX Porting Guide.</a>
@ -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>
@ -3007,7 +3007,7 @@ set FOOBAR ABC_${FOO}_${BAR}
<li>
<code>CONFIG_NSH_USBCONSOLE</code>.
If defined, then the an arbitrary USB device may be used to as the NSH console.
In this case, <code>CONFIG_NSH_CONDEV</code> must be defined to indicate which USB device to use as the console.
In this case, <code>CONFIG_NSH_CONDEV</code> must be defined to indicate which USB device to use as the console.
The advantage of using a device other that /dev/console is that normal debug output can not use /dev/console while NSH uses <code>CONFIG_NSH_USBCONDEV</code>.
<p>
<code>CONFIG_NSH_USBCONDEV</code>.
@ -3365,7 +3365,7 @@ set FOOBAR ABC_${FOO}_${BAR}
<h3>4.1.1 NSH Initialization sequence</h3>
<p>
The NSH start-up sequence is very simple.
The NSH start-up sequence is very simple.
As an example, the code at <code>apps/examples/nsh/nsh_main.c</code> illustrates how to start NSH.
It simple does the following:
</p>
@ -3469,7 +3469,7 @@ mount -t vfat /dev/ram1 /tmp
</p>
<li>
<p>
Mount the FAT filesystem at a configured mountpoint, <code>/tmp</code>.
Mount the FAT filesystem at a configured mountpoint, <code>/tmp</code>.
</p>
</ul>
<p>
@ -3502,7 +3502,7 @@ mount -t vfat /dev/ram1 /tmp
<b>Overview.</b>
NSH supports a variety of commands as part of the NSH program.
All of the NSH commands are listed in the NSH documentation <a href="#cmdoverview">above</a>.
Not all of these commands may be available at any time, however.
Not all of these commands may be available at any time, however.
Many commands depend upon certain NuttX configuration options.
You can enter the help command at the NSH prompt to see the commands actual available:
</p>
@ -3619,7 +3619,7 @@ struct cmdmap_s
<p>
<b>Overview.</b>
In addition to these commands that are a part of NSH, external programs can also be executed as NSH commands.
These external programs are called &quot;Built-In&quot; Applications for historic reasons.
These external programs are called &quot;Built-In&quot; Applications for historic reasons.
That terminology is somewhat confusing because the actual NSH commands as described above are truly &quot;built-into&quot; NSH whereas these applications are really external to NuttX.
</p>
<p>
@ -3716,7 +3716,7 @@ Builtin Apps:
The NuttX build occurs in several phases as different build targets are executed:
(1) <i>context</i> when the configuration is established,
(2) <i>depend </i>when target dependencies are generated, and
(3) <i>default</i> (<code>all</code>) when the normal compilation and link operations are performed.
(3) <i>default</i> (<code>all</code>) when the normal compilation and link operations are performed.
Built-in application information is collected during the make <i>context</i> build phase.
</p>
@ -3912,7 +3912,7 @@ CONFIGURED_APPS += examples/hello
<li>
<p>
You replace the sample code at <code>apps/examples/nsh/nsh_main.c</code> with whatever start-up logic that you want.
NSH is a library at <code>apps/nshlib</code>.
NSH is a library at <code>apps/nshlib</code>.
<code>apps.examplex/nsh</code> is just a tiny, example start-up function (<code>CONFIG_USER_ENTRYPOINT</code>()) that that runs immediately and illustrates how to start NSH
If you want something else to run immediately then you can write your write your own custom <code>CONFIG_USER_ENTRYPOINT</code>() function and then start other tasks from your custom <code>CONFIG_USER_ENTRYPOINT</code>().
</p>
@ -3938,7 +3938,7 @@ CONFIGURED_APPS += examples/hello
NSH supports options to provide a start up script for NSH.
The start-up script contains any command support by NSH (i.e., that you see when you enter 'nsh&gt; help').
In general this capability is enabled with <code>CONFIG_NSH_ROMFSETC=y</code>, but has several other related configuration options as described with the <a href="#nshconfiguration">NSH-specific configuration settings</a> paragraph.
This capability also depends on:
This capability also depends on:
</p>
<ul>
@ -3962,26 +3962,26 @@ CONFIGURED_APPS += examples/hello
<p>
<b>Default Start-Up Behavior</b>.
The implementation that is provided is intended to provide great flexibility for the use of Start-Up files.
This paragraph will discuss the general behavior when all of the configuration options are set to the default values.
This paragraph will discuss the general behavior when all of the configuration options are set to the default values.
</p>
<p>
In this default case, enabling <code>CONFIG_NSH_ROMFSETC</code> will cause NSH to behave as follows at NSH start-up time:
In this default case, enabling <code>CONFIG_NSH_ROMFSETC</code> will cause NSH to behave as follows at NSH start-up time:
</p>
<ul>
<li>
<p>
NSH will create a read-only RAM disk (a ROM disk), containing a tiny ROMFS filesystem containing the following:
NSH will create a read-only RAM disk (a ROM disk), containing a tiny ROMFS filesystem containing the following:
</p>
<ul><pre>
`--init.d/
`-- rcS
</pre></ul>
<p>
Where <code>rcS</code> is the NSH start-up script.
Where <code>rcS</code> is the NSH start-up script.
</p>
<li>
<p>
NSH will then mount the ROMFS filesystem at <code>/etc</code>, resulting in:
NSH will then mount the ROMFS filesystem at <code>/etc</code>, resulting in:
</p>
<ul><pre>
|--dev/
@ -3992,7 +3992,7 @@ CONFIGURED_APPS += examples/hello
</pre></ul>
<li>
<p>
By default, the contents of <code>rcS</code> script are:
By default, the contents of <code>rcS</code> script are:
</p>
<ul><pre>
# Create a RAMDISK and mount it at /tmp
@ -4004,7 +4004,7 @@ mount -t vfat /dev/ram1 /tmp
<li>
<p>
NSH will execute the script at <code>/etc/init.d/rcS</code> at start-up (before the first NSH prompt).
After execution of the script, the root FS will look like:
After execution of the script, the root FS will look like:
</p>
<ul><pre>
|--dev/
@ -4048,7 +4048,7 @@ mount -t vfat /dev/ram1 /tmp
<p>
<b>Modifying the ROMFS Image</b>.
The contents of the <code>/etc</code> directory are retained in the file <code>apps/nshlib/nsh_romfsimg.h</code> OR, if <code>CONFIG_NSH_ARCHROMFS</code> is defined, <code>include/arch/board/rcs.template</code>.
In order to modify the start-up behavior, there are three things to study:
In order to modify the start-up behavior, there are three things to study:
</p>
<ol>
@ -4062,15 +4062,15 @@ mount -t vfat /dev/ram1 /tmp
<b><code>tools/mkromfsimg.sh</code> Script</b>.
The script <code>tools/mkromfsimg.sh</code> creates <code>nsh_romfsimg.h</code>.
It is not automatically executed.
If you want to change the configuration settings associated with creating and mounting the <code>/tmp</code> directory, then it will be necessary to re-generate this header file using the <code>tools/mkromfsimg.sh</code> script.
If you want to change the configuration settings associated with creating and mounting the <code>/tmp</code> directory, then it will be necessary to re-generate this header file using the <code>tools/mkromfsimg.sh</code> script.
</p>
<p>
The behavior of this script depends upon several things:
The behavior of this script depends upon several things:
</p>
<ol>
<li>
<p>
The configuration settings then installed configuration.
The configuration settings then installed configuration.
</p>
<li>
<p>
@ -4089,7 +4089,7 @@ mount -t vfat /dev/ram1 /tmp
<li>
<p>
<code><b>rcS.template</b></code>.
The file <code>apps/nshlib/rcS.template</code> contains the general form of the <code>rcS</code> file; configured values are plugged into this template file to produce the final <code>rcS</code> file.
The file <code>apps/nshlib/rcS.template</code> contains the general form of the <code>rcS</code> file; configured values are plugged into this template file to produce the final <code>rcS</code> file.
</p>
</ol>
@ -4273,7 +4273,7 @@ mount -t vfat /dev/ram1 /tmp
<li><a href="#custonshlib">NSH library (<code>nshlib</code>)</a></li>
<li><a href="#nshlibrary">NSH library (<code>nshlib</code>)</a></li>
<li><a href="#custonshlib"><code>nsh_archinitialize()</code></a></li>
<li><a href="#custonshlib"><code>nsh_consolemain()</code></a></li>
<li><a href="#custonshlib"><code>nsh_consolemain()</code></a></li>
<li><a href="#custonshlib"><code>nsh_initialize()</code></a></li>
<li><a href="#custonshlib"><code>nsh_main()</code></a></li>
<li><a href="#custinit"><code>nsh_main.c</code></a></li>

View file

@ -1550,7 +1550,7 @@ struct spi_dev_s *up_spiinitialize(int port)
(void)spi_setfrequency((struct spi_dev_s *)priv, 400000);
/* Set MSB first data order and the configured pad mux setting,
/* Set MSB first data order and the configured pad mux setting,
* Note that SPI mode 0 is assumed initially (CPOL=0 and CPHA=0).
*/

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
****************************************************************************/
@ -113,7 +131,7 @@ int mkdir(const char *pathname, mode_t mode)
}
}
else
{
{
errcode = ENOSYS;
goto errout_with_inode;
}
@ -125,10 +143,11 @@ int mkdir(const char *pathname, mode_t mode)
/* But mountpoints are not supported in this configuration */
errcode = EEXIST;
goto errout_with_inode;
goto errout_with_inode;
#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;
@ -144,7 +162,7 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
}
}
else
{
{
errcode = ENOSYS;
goto errout_with_newinode;
}
@ -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,38 +102,93 @@ 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)
{
ret = inode->u.i_mops->unlink(inode, relpath);
if (ret < 0)
if (inode->u.i_mops->unlink)
{
ret = -ret;
ret = inode->u.i_mops->unlink(inode, relpath);
if (ret < 0)
{
errcode = -ret;
goto errout_with_inode;
}
}
else
{
errcode = ENOSYS;
goto errout_with_inode;
}
}
else
{
ret = ENOSYS;
#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 */