mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 13:13:08 +08:00
FS: Add the ability to mount a file system on top of en existing node in the psuedo-file system
This commit is contained in:
+42
-13
@@ -266,25 +266,54 @@ int mount(FAR const char *source, FAR const char *target,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
inode_semtake();
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
/* Check if the inode already exists */
|
||||
|
||||
mountpt_inode = inode_find(target, NULL);
|
||||
if (mountpt_inode != NULL)
|
||||
{
|
||||
/* Yes... Is is a directory node (i.e., not a driver or other special
|
||||
* node.
|
||||
*/
|
||||
|
||||
if (INODE_IS_SPECIAL(mountpt_inode))
|
||||
{
|
||||
fdbg("ERROR: target %s exists and is a special nodes\n", target);
|
||||
errcode = -ENOTDIR;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Successfully found. The reference count on the inode has been
|
||||
* incremented.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(mountpt_inode->u.i_mops == NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
/* Insert a dummy node -- we need to hold the inode semaphore
|
||||
* to do this because we will have a momentarily bad structure.
|
||||
*/
|
||||
|
||||
inode_semtake();
|
||||
ret = inode_reserve(target, &mountpt_inode);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* inode_reserve can fail for a couple of reasons, but the most likely
|
||||
* one is that the inode already exists. inode_reserve may return:
|
||||
*
|
||||
* -EINVAL - 'path' is invalid for this operation
|
||||
* -EEXIST - An inode already exists at 'path'
|
||||
* -ENOMEM - Failed to allocate in-memory resources for the operation
|
||||
*/
|
||||
ret = inode_reserve(target, &mountpt_inode);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* inode_reserve can fail for a couple of reasons, but the most likely
|
||||
* one is that the inode already exists. inode_reserve may return:
|
||||
*
|
||||
* -EINVAL - 'path' is invalid for this operation
|
||||
* -EEXIST - An inode already exists at 'path'
|
||||
* -ENOMEM - Failed to allocate in-memory resources for the operation
|
||||
*/
|
||||
|
||||
fdbg("ERROR: Failed to reserve inode\n");
|
||||
errcode = -ret;
|
||||
goto errout_with_semaphore;
|
||||
fdbg("ERROR: Failed to reserve inode for target %s\n", target);
|
||||
errcode = -ret;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bind the block driver to an instance of the file system. The file
|
||||
|
||||
+41
-20
@@ -41,6 +41,8 @@
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
@@ -152,34 +154,53 @@ int umount2(FAR const char *target, unsigned int flags)
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Successfully unbound */
|
||||
/* Successfully unbound. Convert the mountpoint inode to regular
|
||||
* pseudo-file inode.
|
||||
*/
|
||||
|
||||
|
||||
mountpt_inode->i_flags &= ~FSNODEFLAG_TYPE_MASK;
|
||||
mountpt_inode->i_private = NULL;
|
||||
mountpt_inode->u.i_mops = NULL;
|
||||
|
||||
/* Successfully unbound, remove the mountpoint inode from
|
||||
* the inode tree. The inode will not be deleted yet because
|
||||
* there is still at least reference on it (from the mount)
|
||||
*/
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
/* If the node has children, then do not delete it. */
|
||||
|
||||
ret = inode_remove(target);
|
||||
inode_semgive();
|
||||
|
||||
/* The return value of -EBUSY is normal (in fact, it should
|
||||
* not be OK)
|
||||
*/
|
||||
|
||||
if (ret != OK && ret != -EBUSY)
|
||||
if (mountpt_inode->i_child != NULL)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_mountpt;
|
||||
/* Just decrement the reference count (without deleting it) */
|
||||
|
||||
DEBUGASSERT(mountpt_inode->i_crefs > 0);
|
||||
mountpt_inode->i_crefs--;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Remove the mountpoint inode from the inode tree. The inode will
|
||||
* not be deleted yet because there is still at least reference on
|
||||
* it (from the mount)
|
||||
*/
|
||||
|
||||
/* Release the mountpoint inode and any block driver inode
|
||||
* returned by the file system unbind above. This should cause
|
||||
* the inode to be deleted (unless there are other references)
|
||||
*/
|
||||
ret = inode_remove(target);
|
||||
inode_semgive();
|
||||
|
||||
inode_release(mountpt_inode);
|
||||
/* The return value of -EBUSY is normal (in fact, it should
|
||||
* not be OK)
|
||||
*/
|
||||
|
||||
if (ret != OK && ret != -EBUSY)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_mountpt;
|
||||
}
|
||||
|
||||
/* Release the mountpoint inode and any block driver inode
|
||||
* returned by the file system unbind above. This should cause
|
||||
* the inode to be deleted (unless there are other references)
|
||||
*/
|
||||
|
||||
inode_release(mountpt_inode);
|
||||
}
|
||||
|
||||
/* Did the unbind method return a contained block driver */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user