diff --git a/ChangeLog b/ChangeLog index b8f92e7870a..437134ea4fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6610,7 +6610,8 @@ * 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-19). - * fs/fs_rmdir.c: rmdir can be used to removed empty directories in + * fs/fs_rmdir.c: rmdir can now be used to remove empty directories in the pseudo-filesystem such as might be left after umounting a file system (2014-2-19). - + * fs/fs_mkdir.c: mkdir can now be used to create empty directories in + the pseudo-filesystem (2014-2-19). diff --git a/fs/Makefile b/fs/Makefile index 206d038a77e..828535cfe32 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -62,13 +62,15 @@ else # Common file/socket descriptor support 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_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_rewinddir.c fs_rmdir.c fs_seekdir.c fs_stat.c fs_statfs.c +CSRCS += fs_select.c 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 @@ -102,7 +104,7 @@ endif ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y) -CSRCS += fs_fsync.c fs_mkdir.c fs_mount.c fs_rename.c fs_umount.c +CSRCS += fs_fsync.c fs_mount.c fs_rename.c fs_umount.c CSRCS += fs_unlink.c CSRCS += fs_foreachmountpoint.c diff --git a/fs/fs_mkdir.c b/fs/fs_mkdir.c index 6e201ce3452..b99e001331d 100644 --- a/fs/fs_mkdir.c +++ b/fs/fs_mkdir.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/fs_mkdir.c * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -76,55 +76,85 @@ int mkdir(const char *pathname, mode_t mode) { FAR struct inode *inode; const char *relpath = NULL; + int errcode; int ret; - /* Get an inode for this file */ + /* Find the inode that includes this path */ inode = inode_find(pathname, &relpath); - if (!inode) + if (inode) { - /* There is no mountpoint that includes in this path */ + /* An inode was found that includes this path and possibly refers to a + * mountpoint. + */ - ret = ENOENT; - goto errout; - } +#ifndef CONFIG_DISABLE_MOUNTPOINT + /* Check if the inode is a valid mountpoint. */ - /* Verify that the inode is a valid mountpoint. */ - - if (!INODE_IS_MOUNTPT(inode) || !inode->u.i_mops) - { - ret = ENXIO; - goto errout_with_inode; - } - - /* Perform the mkdir operation using the relative path - * at the mountpoint. - */ - - if (inode->u.i_mops->mkdir) - { - ret = inode->u.i_mops->mkdir(inode, relpath, mode); - if (ret < 0) + if (!INODE_IS_MOUNTPT(inode) || !inode->u.i_mops) { - ret = -ret; + /* The inode is not a mountpoint */ + + errcode = ENXIO; goto errout_with_inode; } + + /* Perform the mkdir operation using the relative path + * at the mountpoint. + */ + + if (inode->u.i_mops->mkdir) + { + ret = inode->u.i_mops->mkdir(inode, relpath, mode); + if (ret < 0) + { + errcode = -ret; + goto errout_with_inode; + } + } + else + { + errcode = ENOSYS; + goto errout_with_inode; + } + + /* Release our reference on the inode */ + + inode_release(inode); +#else + /* But mountpoints are not supported in this configuration */ + + errocode = EEXIST; + goto errout_with_inode; +#endif } + + /* No inode exists that contains this path. Create a new inode in the + * pseudo-filesystem at this location. + */ + else - { - ret = ENOSYS; - goto errout_with_inode; + { + /* Create an inode in the pseudo-filesystem at this path */ + + inode_semtake(); + ret = inode_reserve(pathname, &inode); + inode_semgive(); + + if (ret < 0) + { + errcode = -ret; + goto errout; + } } /* Directory successfully created */ - inode_release(inode); return OK; errout_with_inode: inode_release(inode); errout: - set_errno(ret); + set_errno(errcode); return ERROR; } -