Skip to content

Commit

Permalink
fs_inode:Change the type of i_crefs to atomic_int
Browse files Browse the repository at this point in the history
Summary:
  1.Modified the i_crefs from int16_t to atomic_int
  2.Modified the i_crefs add, delete, read, and initialize interfaces to atomic operations
The purpose of this change is to avoid deadlock in cross-core scenarios, where A Core blocks B Core’s request for a write operation to A Core when A Core requests a read operation to B Core.

Signed-off-by: chenrun1 <[email protected]>
  • Loading branch information
crafcat7 committed Sep 14, 2024
1 parent 11f06eb commit a13499f
Show file tree
Hide file tree
Showing 26 changed files with 54 additions and 134 deletions.
2 changes: 1 addition & 1 deletion arch/arm/src/cxd56xx/cxd56_sph.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ static int sph_open(struct file *filep)
{
/* Exclusive access */

if (filep->f_inode->i_crefs > 1)
if (atomic_load(&filep->f_inode->i_crefs) > 1)
{
return ERROR;
}
Expand Down
4 changes: 2 additions & 2 deletions arch/arm/src/cxd56xx/cxd56_uart0.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ static int uart0_open(struct file *filep)
int stop;
int ret;

if (inode->i_crefs > 1)
if (atomic_load(&inode->i_crefs) > 1)
{
return OK;
}
Expand Down Expand Up @@ -172,7 +172,7 @@ static int uart0_close(struct file *filep)
{
struct inode *inode = filep->f_inode;

if (inode->i_crefs == 1)
if (atomic_load(&inode->i_crefs) == 1)
{
fw_pd_uartdisable(0);
fw_pd_uartuninit(0);
Expand Down
2 changes: 1 addition & 1 deletion crypto/cryptodev.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static const struct file_operations g_cryptoops =

static struct inode g_cryptoinode =
{
.i_crefs = 1,
.i_crefs = ATOMIC_VAR_INIT(1),
.u.i_ops = &g_cryptofops
};

Expand Down
2 changes: 1 addition & 1 deletion drivers/serial/pty.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ static int pty_close(FAR struct file *filep)

/* Check if the decremented inode reference count would go to zero */

if (inode->i_crefs == 1)
if (atomic_load(&inode->i_crefs) == 1)
{
/* Did the (single) master just close its reference? */

Expand Down
7 changes: 1 addition & 6 deletions fs/inode/fs_inodeaddref.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@ int inode_addref(FAR struct inode *inode)

if (inode)
{
ret = inode_lock();
if (ret >= 0)
{
inode->i_crefs++;
inode_unlock();
}
atomic_fetch_add(&inode->i_crefs, 1);
}

return ret;
Expand Down
2 changes: 1 addition & 1 deletion fs/inode/fs_inodefind.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int inode_find(FAR struct inode_search_s *desc)

/* Increment the reference count on the inode */

node->i_crefs++;
atomic_fetch_add(&node->i_crefs, 1);
}

inode_unlock();
Expand Down
37 changes: 1 addition & 36 deletions fs/inode/fs_inoderelease.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,49 +47,14 @@

void inode_release(FAR struct inode *inode)
{
int ret;

if (inode)
{
/* Decrement the references of the inode */

do
{
ret = inode_lock();

/* This only possible error is due to cancellation of the thread.
* We need to try again anyway in this case, otherwise the
* reference count would be wrong.
*/

DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
while (ret < 0);

if (inode->i_crefs)
{
inode->i_crefs--;
}

/* If the subtree was previously deleted and the reference
* count has decrement to zero, then delete the inode
* now.
*/

if (inode->i_crefs <= 0)
if (atomic_fetch_sub(&inode->i_crefs, 1) <= 1)
{
/* If the inode has been properly unlinked, then the peer pointer
* should be NULL.
*/

inode_unlock();

DEBUGASSERT(inode->i_peer == NULL);
inode_free(inode);
}
else
{
inode_unlock();
}
}
}
4 changes: 2 additions & 2 deletions fs/inode/fs_inoderemove.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static FAR struct inode *inode_unlink(FAR const char *path)

node->i_peer = NULL;
node->i_parent = NULL;
node->i_crefs--;
atomic_fetch_sub(&node->i_crefs, 1);
}

RELEASE_SEARCH(&desc);
Expand Down Expand Up @@ -134,7 +134,7 @@ int inode_remove(FAR const char *path)
* to it
*/

if (node->i_crefs)
if (atomic_load(&node->i_crefs))
{
return -EBUSY;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/inode/fs_inodereserve.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static FAR struct inode *inode_alloc(FAR const char *name, mode_t mode)
if (node)
{
node->i_ino = g_ino++;
node->i_crefs = 1;
atomic_init(&node->i_crefs, 1);
#ifdef CONFIG_PSEUDOFS_ATTRIBUTES
node->i_mode = mode;
clock_gettime(CLOCK_REALTIME, &node->i_atime);
Expand Down
4 changes: 2 additions & 2 deletions fs/mount/fs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ int nx_mount(FAR const char *source, FAR const char *target,
if (drvr_inode != NULL)
#endif
{
drvr_inode->i_crefs++;
atomic_fetch_add(&drvr_inode->i_crefs, 1);
}
#endif

Expand Down Expand Up @@ -466,7 +466,7 @@ int nx_mount(FAR const char *source, FAR const char *target,
if (drvr_inode != NULL)
#endif
{
drvr_inode->i_crefs--;
atomic_fetch_sub(&drvr_inode->i_crefs, 1);
}
#endif

Expand Down
3 changes: 1 addition & 2 deletions fs/mount/fs_umount2.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ int nx_umount2(FAR const char *target, unsigned int flags)
{
/* Just decrement the reference count (without deleting it) */

DEBUGASSERT(mountpt_inode->i_crefs > 0);
mountpt_inode->i_crefs--;
atomic_fetch_sub(&mountpt_inode->i_crefs, 1);
inode_unlock();
}
else
Expand Down
4 changes: 2 additions & 2 deletions fs/mqueue/mq_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static int nxmq_file_close(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;

if (inode->i_crefs <= 0)
if (atomic_load(&inode->i_crefs) <= 0)
{
FAR struct mqueue_inode_s *msgq = inode->i_private;

Expand Down Expand Up @@ -322,7 +322,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name,

/* Set the initial reference count on this inode to one */

inode->i_crefs++;
atomic_fetch_add(&inode->i_crefs, 1);

if (created)
{
Expand Down
2 changes: 1 addition & 1 deletion fs/mqueue/mq_unlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

static void mq_inode_release(FAR struct inode *inode)
{
if (inode->i_crefs <= 1)
if (atomic_load(&inode->i_crefs) <= 1)
{
FAR struct mqueue_inode_s *msgq = inode->i_private;

Expand Down
2 changes: 1 addition & 1 deletion fs/notify/inotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static struct inode g_inotify_inode =
NULL,
NULL,
NULL,
1,
ATOMIC_VAR_INIT(1),
FSNODEFLAG_TYPE_DRIVER,
{
&g_inotify_fops
Expand Down
27 changes: 1 addition & 26 deletions fs/semaphore/sem_close.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ int nxsem_close(FAR sem_t *sem)
{
FAR struct nsem_inode_s *nsem;
struct inode *inode;
int ret;

DEBUGASSERT(sem);

Expand All @@ -81,51 +80,27 @@ int nxsem_close(FAR sem_t *sem)
DEBUGASSERT(nsem->ns_inode);
inode = nsem->ns_inode;

/* Decrement the reference count on the inode */

do
{
ret = inode_lock();

/* The only error that is expected is due to thread cancellation.
* At this point, we must continue to free the semaphore anyway.
*/

DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
while (ret < 0);

if (inode->i_crefs > 0)
{
inode->i_crefs--;
}

/* If the semaphore was previously unlinked and the reference count has
* decremented to zero, then release the semaphore and delete the inode
* now.
*/

if (inode->i_crefs <= 0)
if (atomic_fetch_sub(&inode->i_crefs, 1) <= 1)
{
/* Destroy the semaphore and free the container */

nxsem_destroy(&nsem->ns_sem);
group_free(NULL, nsem);

/* Release and free the inode container. If it has been properly
* unlinked, then the peer pointer should be NULL.
*/

inode_unlock();
#ifdef CONFIG_FS_NOTIFY
notify_close2(inode);
#endif
DEBUGASSERT(inode->i_peer == NULL);
inode_free(inode);
return OK;
}

inode_unlock();
return OK;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/semaphore/sem_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ int nxsem_open(FAR sem_t **sem, FAR const char *name, int oflags, ...)
/* Initialize the inode */

INODE_SET_NAMEDSEM(inode);
inode->i_crefs++;
atomic_fetch_add(&inode->i_crefs, 1);

/* Initialize the semaphore */

Expand Down
2 changes: 1 addition & 1 deletion fs/shm/shm_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name,
INODE_SET_SHM(inode);
inode->u.i_ops = &g_shmfs_operations;
inode->i_private = NULL;
inode->i_crefs++;
atomic_fetch_add(&inode->i_crefs, 1);
}

/* Associate the inode with a file structure */
Expand Down
35 changes: 12 additions & 23 deletions fs/shm/shmfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,15 @@ static int shmfs_release(FAR struct inode *inode)
* The inode is released after this call, hence checking if i_crefs <= 1.
*/

int ret = inode_lock();
if (ret >= 0)
inode_lock();
if (inode->i_parent == NULL && atomic_load(&inode->i_crefs) <= 1)
{
if (inode->i_parent == NULL &&
inode->i_crefs <= 1)
{
shmfs_free_object(inode->i_private);
inode->i_private = NULL;
ret = OK;
}

inode_unlock();
shmfs_free_object(inode->i_private);
inode->i_private = NULL;
}

return ret;
inode_unlock();
return OK;
}

/****************************************************************************
Expand Down Expand Up @@ -267,20 +261,15 @@ static int shmfs_truncate(FAR struct file *filep, off_t length)
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
static int shmfs_unlink(FAR struct inode *inode)
{
int ret = inode_lock();

if (ret >= 0)
inode_lock();
if (atomic_load(&inode->i_crefs) <= 1)
{
if (inode->i_crefs <= 1)
{
shmfs_free_object(inode->i_private);
inode->i_private = NULL;
}

inode_unlock();
shmfs_free_object(inode->i_private);
inode->i_private = NULL;
}

return ret;
inode_unlock();
return OK;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion fs/socket/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static struct inode g_sock_inode =
NULL, /* i_parent */
NULL, /* i_peer */
NULL, /* i_child */
1, /* i_crefs */
ATOMIC_VAR_INIT(1), /* i_crefs */
FSNODEFLAG_TYPE_SOCKET, /* i_flags */
{
&g_sock_fileops /* u */
Expand Down
6 changes: 3 additions & 3 deletions fs/vfs/fs_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static struct inode g_dir_inode =
NULL,
NULL,
NULL,
1,
ATOMIC_VAR_INIT(1),
0,
{ &g_dir_fileops },
};
Expand Down Expand Up @@ -216,7 +216,7 @@ static off_t seek_pseudodir(FAR struct file *filep, off_t offset)
{
/* Increment the reference count on this next node */

curr->i_crefs++;
atomic_fetch_add(&curr->i_crefs, 1);
}

inode_unlock();
Expand Down Expand Up @@ -383,7 +383,7 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir,
{
/* Increment the reference count on this next node */

pdir->next->i_crefs++;
atomic_fetch_add(&pdir->next->i_crefs, 1);
}

inode_unlock();
Expand Down
2 changes: 1 addition & 1 deletion fs/vfs/fs_epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static struct inode g_epoll_inode =
NULL, /* i_parent */
NULL, /* i_peer */
NULL, /* i_child */
1, /* i_crefs */
ATOMIC_VAR_INIT(1), /* i_crefs */
FSNODEFLAG_TYPE_DRIVER, /* i_flags */
{
&g_epoll_ops /* u */
Expand Down
2 changes: 1 addition & 1 deletion fs/vfs/fs_eventfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static struct inode g_eventfd_inode =
NULL, /* i_parent */
NULL, /* i_peer */
NULL, /* i_child */
1, /* i_crefs */
ATOMIC_VAR_INIT(1), /* i_crefs */
FSNODEFLAG_TYPE_DRIVER, /* i_flags */
{
&g_eventfd_fops /* u */
Expand Down
Loading

0 comments on commit a13499f

Please sign in to comment.