rmdir now may be used to remove empty nodes from the pseudo-filesystem
This commit is contained in:
parent
66a0cfe88f
commit
5bae65fa6c
@ -6609,5 +6609,8 @@
|
||||
the kconfig-frontends tools (unverified) (2014-2-18).
|
||||
* fs/fs_opendir.c, fs_readdir.c, et al: Modified so that errors
|
||||
will not be reported if you attempt to list a empty pseudo-directory
|
||||
(2014-2-18).
|
||||
(2014-2-19).
|
||||
* fs/fs_rmdir.c: rmdir can be used to removed empty directories in
|
||||
the pseudo-filesystem such as might be left after umounting a
|
||||
file system (2014-2-19).
|
||||
|
||||
|
@ -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 3, 2014</p>
|
||||
<p>Last Updated: February 19, 2014</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -2727,7 +2727,7 @@ nsh>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b><code>rmdir</code></b></td>
|
||||
<td>!<code>CONFIG_DISABLE_MOUNTPOINT</code> && <code>CONFIG_NFILE_DESCRIPTORS</code> > 0 && <code>CONFIG_FS_WRITABLE</code><sup>4</sup></td>
|
||||
<td><code>CONFIG_NFILE_DESCRIPTORS</code> > 0</td>
|
||||
<td><code>CONFIG_NSH_DISABLE_RMDIR</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
55
fs/Makefile
55
fs/Makefile
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# fs/Makefile
|
||||
#
|
||||
# Copyright (C) 2007, 2008, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2007, 2008, 2011-2014 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -35,10 +35,10 @@
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
|
||||
CSRCS =
|
||||
CSRCS =
|
||||
|
||||
# If there are no file descriptors configured, then a small part of the
|
||||
# logic in this directory may still apply to socket descriptors
|
||||
@ -48,29 +48,30 @@ ifneq ($(CONFIG_NSOCKET_DESCRIPTORS),0)
|
||||
|
||||
# Socket descriptor support
|
||||
|
||||
CSRCS += fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_poll.c fs_select.c
|
||||
CSRCS += fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_poll.c fs_select.c
|
||||
endif
|
||||
|
||||
# Support for network access using streams
|
||||
|
||||
ifneq ($(CONFIG_NFILE_STREAMS),0)
|
||||
CSRCS += fs_fdopen.c
|
||||
CSRCS += fs_fdopen.c
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
# Common file/socket descriptor support
|
||||
|
||||
CSRCS += fs_close.c fs_closedir.c fs_dup.c fs_dup2.c fs_fcntl.c \
|
||||
fs_filedup.c fs_filedup2.c fs_ioctl.c fs_lseek.c fs_open.c \
|
||||
fs_opendir.c fs_poll.c fs_read.c fs_readdir.c fs_rewinddir.c \
|
||||
fs_seekdir.c fs_stat.c fs_statfs.c fs_select.c fs_write.c
|
||||
CSRCS += fs_files.c fs_foreachinode.c fs_inode.c fs_inodeaddref.c \
|
||||
fs_inodefind.c fs_inoderelease.c fs_inoderemove.c \
|
||||
fs_inodereserve.c
|
||||
CSRCS += fs_registerdriver.c fs_unregisterdriver.c
|
||||
CSRCS += fs_registerblockdriver.c fs_unregisterblockdriver.c \
|
||||
fs_findblockdriver.c fs_openblockdriver.c fs_closeblockdriver.c
|
||||
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_open.c
|
||||
CSRCS += fs_opendir.c fs_poll.c fs_read.c fs_readdir.c fs_rewinddir.c
|
||||
CSRCS += fs_rmdir.c fs_seekdir.c fs_stat.c fs_statfs.c fs_select.c
|
||||
CSRCS += fs_write.c
|
||||
CSRCS += fs_files.c fs_foreachinode.c fs_inode.c fs_inodeaddref.c
|
||||
CSRCS += fs_inodefind.c fs_inoderelease.c fs_inoderemove.c
|
||||
CSRCS += fs_inodereserve.c
|
||||
CSRCS += fs_registerdriver.c fs_unregisterdriver.c
|
||||
CSRCS += fs_registerblockdriver.c fs_unregisterblockdriver.c
|
||||
CSRCS += fs_findblockdriver.c fs_openblockdriver.c fs_closeblockdriver.c
|
||||
|
||||
DEPPATH =
|
||||
VPATH = .
|
||||
@ -80,7 +81,7 @@ include mmap/Make.defs
|
||||
# Stream support
|
||||
|
||||
ifneq ($(CONFIG_NFILE_STREAMS),0)
|
||||
CSRCS += fs_fdopen.c
|
||||
CSRCS += fs_fdopen.c
|
||||
endif
|
||||
|
||||
# Support for sendfile()
|
||||
@ -93,7 +94,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_SYSLOG),y)
|
||||
ifeq ($(CONFIG_SYSLOG_CHAR),y)
|
||||
CSRCS += fs_syslog.c
|
||||
CSRCS += fs_syslog.c
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -101,9 +102,9 @@ endif
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
|
||||
|
||||
CSRCS += fs_fsync.c fs_mkdir.c fs_mount.c fs_rename.c fs_rmdir.c \
|
||||
fs_umount.c fs_unlink.c
|
||||
CSRCS += fs_foreachmountpoint.c
|
||||
CSRCS += fs_fsync.c fs_mkdir.c fs_mount.c fs_rename.c fs_umount.c
|
||||
CSRCS += fs_unlink.c
|
||||
CSRCS += fs_foreachmountpoint.c
|
||||
|
||||
include fat/Make.defs
|
||||
include romfs/Make.defs
|
||||
@ -116,16 +117,16 @@ include procfs/Make.defs
|
||||
endif
|
||||
endif
|
||||
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
BIN = libfs$(LIBEXT)
|
||||
BIN = libfs$(LIBEXT)
|
||||
|
||||
SUBDIRS = mmap fat romfs nxffs nfs binfs procfs
|
||||
SUBDIRS = mmap fat romfs nxffs nfs binfs procfs
|
||||
|
||||
all: $(BIN)
|
||||
all: $(BIN)
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(call ASSEMBLE, $<, $@)
|
||||
|
@ -76,43 +76,85 @@ int rmdir(FAR const char *pathname)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
const char *relpath = NULL;
|
||||
int ret;
|
||||
int errcode;
|
||||
|
||||
/* Get an inode for this file */
|
||||
/* Get an inode for this file. inode_find() automatically increments the
|
||||
* reference count on the inode if one is found.
|
||||
*/
|
||||
|
||||
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 rmdir operation using the relative path
|
||||
* from the mountpoint.
|
||||
*/
|
||||
|
||||
/* Perform the rmdir operation using the relative path
|
||||
* at the mountpoint.
|
||||
if (inode->u.i_mops->rmdir)
|
||||
{
|
||||
int ret = inode->u.i_mops->rmdir(inode, relpath);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errcode = ENOSYS;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
/* If this is a "dangling" pseudo-file node (i.e., it has no operations)
|
||||
* then rmdir should remove the node.
|
||||
*/
|
||||
|
||||
if (inode->u.i_mops->rmdir)
|
||||
if (!inode->u.i_ops)
|
||||
{
|
||||
ret = inode->u.i_mops->rmdir(inode, relpath);
|
||||
if (ret < 0)
|
||||
int ret;
|
||||
|
||||
/* If the directory inode has children, however, then it cannot be
|
||||
* removed.
|
||||
*/
|
||||
|
||||
if (inode->i_child)
|
||||
{
|
||||
ret = -ret;
|
||||
errcode = ENOTEMPTY;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* Remove the inode. NOTE: Because we hold a reference count on the
|
||||
* inode, it will not be deleted now. But probably when inode_release()
|
||||
* is called below. inode_remove should return -EBUSY to indicate that
|
||||
* the inode was not deleted now.
|
||||
*/
|
||||
|
||||
inode_semtake();
|
||||
ret = inode_remove(pathname);
|
||||
inode_semgive();
|
||||
|
||||
if (ret < 0 && ret != -EBUSY)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ENOSYS;
|
||||
errcode = ENXIO;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
@ -121,10 +163,10 @@ int rmdir(FAR const char *pathname)
|
||||
inode_release(inode);
|
||||
return OK;
|
||||
|
||||
errout_with_inode:
|
||||
errout_with_inode:
|
||||
inode_release(inode);
|
||||
errout:
|
||||
set_errno(ret);
|
||||
errout:
|
||||
set_errno(errcode);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user