drivers/pipes: Use inode reference counter instead of device reference counter to handle dup(). I found that if I dup() a pipe, the reference counter d_refs is not increased. If I close any of the fd, backed by the same pipe, the pipe will be freed. This causes any further usage on the fd referencing a non existent pipe. This change uses the inode reference counter, which is properly maintained during dup().

This commit is contained in:
Yang ChungFan 2019-08-06 07:31:57 -06:00 committed by Gregory Nutt
parent e8af615578
commit 4db8c826d7
3 changed files with 7 additions and 12 deletions

View File

@ -149,7 +149,7 @@ static int pipe_close(FAR struct file *filep)
/* Perform common close operations */
ret = pipecommon_close(filep);
if (ret == 0 && dev->d_refs == 0)
if (ret == 0 && inode->i_crefs == 1)
{
/* Release the pipe when there are no further open references to it. */

View File

@ -231,7 +231,7 @@ int pipecommon_open(FAR struct file *filep)
* is first opened.
*/
if (dev->d_refs == 0 && dev->d_buffer == NULL)
if (inode->i_crefs == 1 && dev->d_buffer == NULL)
{
dev->d_buffer = (FAR uint8_t *)kmm_malloc(dev->d_bufsize);
if (!dev->d_buffer)
@ -241,9 +241,6 @@ int pipecommon_open(FAR struct file *filep)
}
}
/* Increment the reference count on the pipe instance */
dev->d_refs++;
/* If opened for writing, increment the count of writers on the pipe instance */
@ -321,7 +318,7 @@ int pipecommon_close(FAR struct file *filep)
FAR struct pipe_dev_s *dev = inode->i_private;
int sval;
DEBUGASSERT(dev && dev->d_refs > 0);
DEBUGASSERT(dev && filep->f_inode->i_crefs > 0);
/* Make sure that we have exclusive access to the device structure.
* NOTE: close() is supposed to return EINTR if interrupted, however
@ -334,11 +331,11 @@ int pipecommon_close(FAR struct file *filep)
* still outstanding references to the pipe.
*/
/* Check if the decremented reference count would go to zero */
/* Check if the decremented inode reference count would go to zero */
if (--dev->d_refs > 0)
if (inode->i_crefs > 1)
{
/* No more references.. If opened for writing, decrement the count of
/* More references.. If opened for writing, decrement the count of
* writers on the pipe instance.
*/
@ -396,7 +393,6 @@ int pipecommon_close(FAR struct file *filep)
dev->d_wrndx = 0;
dev->d_rdndx = 0;
dev->d_refs = 0;
dev->d_nwriters = 0;
dev->d_nreaders = 0;
@ -896,7 +892,7 @@ int pipecommon_unlink(FAR struct inode *inode)
/* Are the any open references to the driver? */
if (dev->d_refs == 0)
if (inode->i_crefs == 1)
{
/* No.. free the buffer (if there is one) */

View File

@ -135,7 +135,6 @@ struct pipe_dev_s
pipe_ndx_t d_wrndx; /* Index in d_buffer to save next byte written */
pipe_ndx_t d_rdndx; /* Index in d_buffer to return the next byte read */
pipe_ndx_t d_bufsize; /* allocated size of d_buffer in bytes */
uint8_t d_refs; /* References counts on pipe (limited to 255) */
uint8_t d_nwriters; /* Number of reference counts for write access */
uint8_t d_nreaders; /* Number of reference counts for read access */
uint8_t d_pipeno; /* Pipe minor number */