fs: remove INODE_IS_SPECIAL() use others instead
Change-Id: I949f1ad012836e6cb233d5362fe2542732b5ecf4 Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
f5b59e287a
commit
3386941a10
@ -356,7 +356,7 @@ int nx_mount(FAR const char *source, FAR const char *target,
|
|||||||
* node)?
|
* node)?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (INODE_IS_SPECIAL(mountpt_inode))
|
if (!INODE_IS_PSEUDODIR(mountpt_inode))
|
||||||
{
|
{
|
||||||
ferr("ERROR: target %s exists and is a special node\n", target);
|
ferr("ERROR: target %s exists and is a special node\n", target);
|
||||||
ret = -ENOTDIR;
|
ret = -ENOTDIR;
|
||||||
|
179
fs/vfs/fs_stat.c
179
fs/vfs/fs_stat.c
@ -259,115 +259,110 @@ int inode_stat(FAR struct inode *inode, FAR struct stat *buf, int resolve)
|
|||||||
|
|
||||||
/* Handle "special" nodes */
|
/* Handle "special" nodes */
|
||||||
|
|
||||||
if (INODE_IS_SPECIAL(inode))
|
|
||||||
{
|
|
||||||
#if defined(CONFIG_FS_NAMED_SEMAPHORES)
|
#if defined(CONFIG_FS_NAMED_SEMAPHORES)
|
||||||
/* Check for a named semaphore */
|
/* Check for a named semaphore */
|
||||||
|
|
||||||
if (INODE_IS_NAMEDSEM(inode))
|
if (INODE_IS_NAMEDSEM(inode))
|
||||||
{
|
{
|
||||||
buf->st_mode = S_IFSEM;
|
buf->st_mode = S_IFSEM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CONFIG_DISABLE_MQUEUE)
|
#if !defined(CONFIG_DISABLE_MQUEUE)
|
||||||
/* Check for a message queue */
|
/* Check for a message queue */
|
||||||
|
|
||||||
if (INODE_IS_MQUEUE(inode))
|
if (INODE_IS_MQUEUE(inode))
|
||||||
{
|
{
|
||||||
buf->st_mode = S_IFMQ;
|
buf->st_mode = S_IFMQ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_FS_SHM)
|
#if defined(CONFIG_FS_SHM)
|
||||||
/* Check for shared memory */
|
/* Check for shared memory */
|
||||||
|
|
||||||
if (INODE_IS_SHM(inode))
|
if (INODE_IS_SHM(inode))
|
||||||
{
|
{
|
||||||
buf->st_mode = S_IFSHM;
|
buf->st_mode = S_IFSHM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_MTD)
|
#if defined(CONFIG_MTD)
|
||||||
/* Check for an MTD driver */
|
/* Check for an MTD driver */
|
||||||
|
|
||||||
if (INODE_IS_MTD(inode))
|
if (INODE_IS_MTD(inode))
|
||||||
{
|
{
|
||||||
struct mtd_geometry_s mtdgeo;
|
struct mtd_geometry_s mtdgeo;
|
||||||
|
|
||||||
buf->st_mode = S_IFMTD;
|
buf->st_mode = S_IFMTD;
|
||||||
buf->st_mode |= S_IROTH | S_IRGRP | S_IRUSR;
|
buf->st_mode |= S_IROTH | S_IRGRP | S_IRUSR;
|
||||||
buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR;
|
buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR;
|
||||||
|
|
||||||
if (inode->u.i_mtd != NULL &&
|
if (inode->u.i_mtd != NULL &&
|
||||||
MTD_IOCTL(inode->u.i_mtd, MTDIOC_GEOMETRY,
|
MTD_IOCTL(inode->u.i_mtd, MTDIOC_GEOMETRY,
|
||||||
(unsigned long)((uintptr_t)&mtdgeo)) >= 0)
|
(unsigned long)((uintptr_t)&mtdgeo)) >= 0)
|
||||||
{
|
|
||||||
buf->st_size = mtdgeo.neraseblocks * mtdgeo.erasesize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
|
||||||
/* Handle softlinks differently. Just call stat() recursively on the
|
|
||||||
* target of the softlink.
|
|
||||||
*
|
|
||||||
* REVISIT: This has the possibility of an infinite loop!
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (INODE_IS_SOFTLINK(inode))
|
|
||||||
{
|
|
||||||
if (resolve)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Increment the link counter. This is necessary to avoid
|
|
||||||
* infinite recursion if loops are encountered in the
|
|
||||||
* traversal. If we encounter more SYMLOOP_MAX symbolic links
|
|
||||||
* at any time during the traversal, error out.
|
|
||||||
*
|
|
||||||
* NOTE: That inode_search() will automatically skip over
|
|
||||||
* consecutive, intermediate symbolic links. Those numbers
|
|
||||||
* will not be included in the total.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (++buf->st_count > SYMLOOP_MAX)
|
|
||||||
{
|
|
||||||
return -ELOOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGASSERT(buf->st_count > 0); /* Check for unsigned integer overflow */
|
|
||||||
|
|
||||||
/* stat() the target of the soft link. */
|
|
||||||
|
|
||||||
ret = stat_recursive(inode->u.i_link, buf, 1);
|
|
||||||
|
|
||||||
/* If stat() fails, then there is a problem with the target of
|
|
||||||
* the symbolic link, but not with the symbolic link itself.
|
|
||||||
* We should still report success, just with less information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
RESET_BUF(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Make sure the caller knows that this is a symbolic link. */
|
|
||||||
|
|
||||||
buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFLNK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
|
buf->st_size = mtdgeo.neraseblocks * mtdgeo.erasesize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||||
|
/* Handle softlinks differently. Just call stat() recursively on the
|
||||||
|
* target of the softlink.
|
||||||
|
*
|
||||||
|
* REVISIT: This has the possibility of an infinite loop!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (INODE_IS_SOFTLINK(inode))
|
||||||
|
{
|
||||||
|
if (resolve)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Increment the link counter. This is necessary to avoid
|
||||||
|
* infinite recursion if loops are encountered in the
|
||||||
|
* traversal. If we encounter more SYMLOOP_MAX symbolic links
|
||||||
|
* at any time during the traversal, error out.
|
||||||
|
*
|
||||||
|
* NOTE: That inode_search() will automatically skip over
|
||||||
|
* consecutive, intermediate symbolic links. Those numbers
|
||||||
|
* will not be included in the total.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (++buf->st_count > SYMLOOP_MAX)
|
||||||
|
{
|
||||||
|
return -ELOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(buf->st_count > 0); /* Check for unsigned integer overflow */
|
||||||
|
|
||||||
|
/* stat() the target of the soft link. */
|
||||||
|
|
||||||
|
ret = stat_recursive(inode->u.i_link, buf, 1);
|
||||||
|
|
||||||
|
/* If stat() fails, then there is a problem with the target of
|
||||||
|
* the symbolic link, but not with the symbolic link itself.
|
||||||
|
* We should still report success, just with less information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
RESET_BUF(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Make sure the caller knows that this is a symbolic link. */
|
||||||
|
|
||||||
|
buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFLNK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle "normal inodes */
|
/* Handle "normal inodes */
|
||||||
|
|
||||||
else if (inode->u.i_ops != NULL)
|
if (inode->u.i_ops != NULL)
|
||||||
{
|
{
|
||||||
/* Determine read/write privileges based on the existence of read
|
/* Determine read/write privileges based on the existence of read
|
||||||
* and write methods.
|
* and write methods.
|
||||||
|
@ -106,96 +106,83 @@ int nx_unlink(FAR const char *pathname)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
|
||||||
/* If this is a "dangling" pseudo-file node (i.e., it has no operations)
|
|
||||||
* or a soft link, then rm should remove the node.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
|
||||||
/* A soft link is the only "specal" file that we can remove via unlink(). */
|
|
||||||
|
|
||||||
if (!INODE_IS_SPECIAL(inode) || INODE_IS_SOFTLINK(inode))
|
|
||||||
#else
|
|
||||||
if (!INODE_IS_SPECIAL(inode))
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/* If this is a pseudo-file node (i.e., it has no operations)
|
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||||
* then unlink should remove the node.
|
ret = inode_semtake();
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto errout_with_inode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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->u.i_ops != NULL)
|
if (inode->i_child != NULL)
|
||||||
{
|
{
|
||||||
ret = inode_semtake();
|
ret = -ENOTEMPTY;
|
||||||
|
goto errout_with_sem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify the driver that it has been unlinked. If there are no
|
||||||
|
* open references to the driver instance, then the driver should
|
||||||
|
* release all resources because it is no longer accessible.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (INODE_IS_DRIVER(inode) && inode->u.i_ops->unlink)
|
||||||
|
{
|
||||||
|
/* Notify the character driver that it has been unlinked */
|
||||||
|
|
||||||
|
ret = inode->u.i_ops->unlink(inode);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto errout_with_inode;
|
goto errout_with_sem;
|
||||||
}
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
ret = -ENOTEMPTY;
|
|
||||||
inode_semgive();
|
|
||||||
goto errout_with_inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Notify the driver that it has been unlinked. If there are no
|
|
||||||
* open references to the driver instance, then the driver should
|
|
||||||
* release all resources because it is no longer accessible.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (INODE_IS_DRIVER(inode) && inode->u.i_ops->unlink)
|
|
||||||
{
|
|
||||||
/* Notify the character driver that it has been unlinked */
|
|
||||||
|
|
||||||
ret = inode->u.i_ops->unlink(inode);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
goto errout_with_inode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||||
else if (INODE_IS_BLOCK(inode) && inode->u.i_bops->unlink)
|
else if (INODE_IS_BLOCK(inode) && inode->u.i_bops->unlink)
|
||||||
{
|
{
|
||||||
/* Notify the block driver that it has been unlinked */
|
/* Notify the block driver that it has been unlinked */
|
||||||
|
|
||||||
ret = inode->u.i_bops->unlink(inode);
|
ret = inode->u.i_bops->unlink(inode);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto errout_with_inode;
|
goto errout_with_sem;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
||||||
/* Remove the old inode. Because we hold a reference count on the
|
else if (INODE_IS_PSEUDODIR(inode) || INODE_IS_SOFTLINK(inode))
|
||||||
* inode, it will not be deleted now. It will be deleted when all
|
#else
|
||||||
* of the references to the inode have been released (perhaps
|
else if (INODE_IS_PSEUDODIR(inode))
|
||||||
* when inode_release() is called below). inode_remove() will
|
#endif
|
||||||
* return -EBUSY to indicate that the inode was not deleted now.
|
{
|
||||||
|
/* If this is a "dangling" pseudo-file node
|
||||||
|
* (i.e., it has no operations) or a soft link,
|
||||||
|
* then rm should remove the node.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = inode_remove(pathname);
|
|
||||||
inode_semgive();
|
|
||||||
|
|
||||||
if (ret < 0 && ret != -EBUSY)
|
|
||||||
{
|
|
||||||
goto errout_with_inode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = -EISDIR;
|
ret = -ENXIO;
|
||||||
|
goto errout_with_sem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 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)
|
||||||
|
{
|
||||||
goto errout_with_inode;
|
goto errout_with_inode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
ret = -ENXIO;
|
|
||||||
goto errout_with_inode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Successfully unlinked */
|
/* Successfully unlinked */
|
||||||
@ -204,6 +191,9 @@ int nx_unlink(FAR const char *pathname)
|
|||||||
RELEASE_SEARCH(&desc);
|
RELEASE_SEARCH(&desc);
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
|
errout_with_sem:
|
||||||
|
inode_semgive();
|
||||||
|
|
||||||
errout_with_inode:
|
errout_with_inode:
|
||||||
inode_release(inode);
|
inode_release(inode);
|
||||||
|
|
||||||
|
@ -108,23 +108,22 @@
|
|||||||
* Bit 4: Set if inode has been unlinked and is pending removal.
|
* Bit 4: Set if inode has been unlinked and is pending removal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FSNODEFLAG_TYPE_MASK 0x0000000f /* Isolates type field */
|
#define FSNODEFLAG_TYPE_MASK 0x0000000f /* Isolates type field */
|
||||||
#define FSNODEFLAG_TYPE_DRIVER 0x00000000 /* Character driver */
|
#define FSNODEFLAG_TYPE_PSEUDODIR 0x00000000 /* Pseudo dir (default) */
|
||||||
#define FSNODEFLAG_TYPE_BLOCK 0x00000001 /* Block driver */
|
#define FSNODEFLAG_TYPE_DRIVER 0x00000001 /* Character driver */
|
||||||
#define FSNODEFLAG_TYPE_MOUNTPT 0x00000002 /* Mount point */
|
#define FSNODEFLAG_TYPE_BLOCK 0x00000002 /* Block driver */
|
||||||
#define FSNODEFLAG_TYPE_SPECIAL 0x00000008 /* Special OS type */
|
#define FSNODEFLAG_TYPE_MOUNTPT 0x00000003 /* Mount point */
|
||||||
#define FSNODEFLAG_TYPE_NAMEDSEM 0x00000008 /* Named semaphore */
|
#define FSNODEFLAG_TYPE_NAMEDSEM 0x00000004 /* Named semaphore */
|
||||||
#define FSNODEFLAG_TYPE_MQUEUE 0x00000009 /* Message Queue */
|
#define FSNODEFLAG_TYPE_MQUEUE 0x00000005 /* Message Queue */
|
||||||
#define FSNODEFLAG_TYPE_SHM 0x0000000a /* Shared memory region */
|
#define FSNODEFLAG_TYPE_SHM 0x00000006 /* Shared memory region */
|
||||||
#define FSNODEFLAG_TYPE_MTD 0x0000000b /* Named MTD driver */
|
#define FSNODEFLAG_TYPE_MTD 0x00000007 /* Named MTD driver */
|
||||||
#define FSNODEFLAG_TYPE_SOFTLINK 0x0000000c /* Soft link */
|
#define FSNODEFLAG_TYPE_SOFTLINK 0x00000008 /* Soft link */
|
||||||
#define FSNODEFLAG_DELETED 0x00000010 /* Unlinked */
|
#define FSNODEFLAG_DELETED 0x00000010 /* Unlinked */
|
||||||
|
|
||||||
#define INODE_IS_TYPE(i,t) \
|
#define INODE_IS_TYPE(i,t) \
|
||||||
(((i)->i_flags & FSNODEFLAG_TYPE_MASK) == (t))
|
(((i)->i_flags & FSNODEFLAG_TYPE_MASK) == (t))
|
||||||
#define INODE_IS_SPECIAL(i) \
|
|
||||||
(((i)->i_flags & FSNODEFLAG_TYPE_SPECIAL) != 0)
|
|
||||||
|
|
||||||
|
#define INODE_IS_PSEUDODIR(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_PSEUDODIR)
|
||||||
#define INODE_IS_DRIVER(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_DRIVER)
|
#define INODE_IS_DRIVER(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_DRIVER)
|
||||||
#define INODE_IS_BLOCK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_BLOCK)
|
#define INODE_IS_BLOCK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_BLOCK)
|
||||||
#define INODE_IS_MOUNTPT(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MOUNTPT)
|
#define INODE_IS_MOUNTPT(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MOUNTPT)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user