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:
parent
e8af615578
commit
4db8c826d7
@ -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. */
|
||||
|
||||
|
@ -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) */
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user