Loop device should return -EINTR is interrupt by a signal

This commit is contained in:
Gregory Nutt
2014-11-27 09:12:15 -06:00
parent b29925a63b
commit d8107d2b97
+59 -39
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* drivers/loop.c * drivers/loop.c
* *
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2008-2009, 2011, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -87,16 +87,18 @@ struct loop_struct_s
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
static void loop_semtake(FAR struct loop_struct_s *dev); static int loop_semtake(FAR struct loop_struct_s *dev);
static int loop_open(FAR struct inode *inode); static int loop_open(FAR struct inode *inode);
static int loop_close(FAR struct inode *inode); static int loop_close(FAR struct inode *inode);
static ssize_t loop_read(FAR struct inode *inode, unsigned char *buffer, static ssize_t loop_read(FAR struct inode *inode, FAR unsigned char *buffer,
size_t start_sector, unsigned int nsectors); size_t start_sector, unsigned int nsectors);
#ifdef CONFIG_FS_WRITABLE #ifdef CONFIG_FS_WRITABLE
static ssize_t loop_write(FAR struct inode *inode, const unsigned char *buffer, static ssize_t loop_write(FAR struct inode *inode,
size_t start_sector, unsigned int nsectors); FAR const unsigned char *buffer,
size_t start_sector, unsigned int nsectors);
#endif #endif
static int loop_geometry(FAR struct inode *inode, struct geometry *geometry); static int loop_geometry(FAR struct inode *inode,
FAR struct geometry *geometry);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@@ -124,18 +126,26 @@ static const struct block_operations g_bops =
* Name: loop_semtake * Name: loop_semtake
****************************************************************************/ ****************************************************************************/
static void loop_semtake(FAR struct loop_struct_s *dev) static int loop_semtake(FAR struct loop_struct_s *dev)
{ {
int ret;
/* Take the semaphore (perhaps waiting) */ /* Take the semaphore (perhaps waiting) */
while (sem_wait(&dev->sem) != 0) ret = sem_wait(&dev->sem);
if (ret < 0)
{ {
int errcode = get_errno();
/* The only case that an error should occur here is if /* The only case that an error should occur here is if
* the wait was awakened by a signal. * the wait was awakened by a signal.
*/ */
ASSERT(get_errno() == EINTR); ASSERT(errcode == EINTR);
return -ret;
} }
return OK;
} }
/**************************************************************************** /****************************************************************************
@@ -148,26 +158,30 @@ static void loop_semtake(FAR struct loop_struct_s *dev)
static int loop_open(FAR struct inode *inode) static int loop_open(FAR struct inode *inode)
{ {
FAR struct loop_struct_s *dev; FAR struct loop_struct_s *dev;
int ret = OK; int ret;
DEBUGASSERT(inode && inode->i_private); DEBUGASSERT(inode && inode->i_private);
dev = (FAR struct loop_struct_s *)inode->i_private; dev = (FAR struct loop_struct_s *)inode->i_private;
/* Make sure we have exclusive access to the state structure */ /* Make sure we have exclusive access to the state structure */
loop_semtake(dev); ret = loop_semtake(dev);
if (dev->opencnt == MAX_OPENCNT) if (ret == OK)
{ {
return -EMFILE; if (dev->opencnt == MAX_OPENCNT)
} {
else ret = -EMFILE;
{ }
/* Increment the open count */ else
{
/* Increment the open count */
dev->opencnt++; dev->opencnt++;
}
loop_semgive(dev);
} }
loop_semgive(dev);
return ret; return ret;
} }
@@ -181,38 +195,42 @@ static int loop_open(FAR struct inode *inode)
static int loop_close(FAR struct inode *inode) static int loop_close(FAR struct inode *inode)
{ {
FAR struct loop_struct_s *dev; FAR struct loop_struct_s *dev;
int ret = OK; int ret;
DEBUGASSERT(inode && inode->i_private); DEBUGASSERT(inode && inode->i_private);
dev = (FAR struct loop_struct_s *)inode->i_private; dev = (FAR struct loop_struct_s *)inode->i_private;
/* Make sure we have exclusive access to the state structure */ /* Make sure we have exclusive access to the state structure */
loop_semtake(dev); ret = loop_semtake(dev);
if (dev->opencnt == 0) if (ret == OK)
{ {
return -EIO; if (dev->opencnt == 0)
} {
else ret = -EIO;
{ }
/* Decrement the open count */ else
{
/* Decrement the open count */
dev->opencnt--; dev->opencnt--;
}
loop_semgive(dev);
} }
loop_semgive(dev);
return ret; return ret;
} }
/**************************************************************************** /****************************************************************************
* Name: loop_read * Name: loop_read
* *
* Description: Read the specified numer of sectors * Description: Read the specified number of sectors
* *
****************************************************************************/ ****************************************************************************/
static ssize_t loop_read(FAR struct inode *inode, unsigned char *buffer, static ssize_t loop_read(FAR struct inode *inode, FAR unsigned char *buffer,
size_t start_sector, unsigned int nsectors) size_t start_sector, unsigned int nsectors)
{ {
FAR struct loop_struct_s *dev; FAR struct loop_struct_s *dev;
ssize_t nbytesread; ssize_t nbytesread;
@@ -264,8 +282,9 @@ static ssize_t loop_read(FAR struct inode *inode, unsigned char *buffer,
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_FS_WRITABLE #ifdef CONFIG_FS_WRITABLE
static ssize_t loop_write(FAR struct inode *inode, const unsigned char *buffer, static ssize_t loop_write(FAR struct inode *inode,
size_t start_sector, unsigned int nsectors) FAR const unsigned char *buffer,
size_t start_sector, unsigned int nsectors)
{ {
FAR struct loop_struct_s *dev; FAR struct loop_struct_s *dev;
ssize_t nbyteswritten; ssize_t nbyteswritten;
@@ -310,7 +329,8 @@ static ssize_t loop_write(FAR struct inode *inode, const unsigned char *buffer,
* *
****************************************************************************/ ****************************************************************************/
static int loop_geometry(FAR struct inode *inode, struct geometry *geometry) static int loop_geometry(FAR struct inode *inode,
FAR struct geometry *geometry)
{ {
FAR struct loop_struct_s *dev; FAR struct loop_struct_s *dev;
@@ -346,8 +366,8 @@ static int loop_geometry(FAR struct inode *inode, struct geometry *geometry)
* *
****************************************************************************/ ****************************************************************************/
int losetup(const char *devname, const char *filename, uint16_t sectsize, int losetup(FAR const char *devname, FAR const char *filename,
off_t offset, bool readonly) uint16_t sectsize, off_t offset, bool readonly)
{ {
FAR struct loop_struct_s *dev; FAR struct loop_struct_s *dev;
struct stat sb; struct stat sb;
@@ -453,7 +473,7 @@ errout_with_dev:
* *
****************************************************************************/ ****************************************************************************/
int loteardown(const char *devname) int loteardown(FAR const char *devname)
{ {
FAR struct loop_struct_s *dev; FAR struct loop_struct_s *dev;
FAR struct inode *inode; FAR struct inode *inode;
@@ -479,7 +499,7 @@ int loteardown(const char *devname)
return ret; return ret;
} }
/* Inode private data is a reference to the loop device stgructure */ /* Inode private data is a reference to the loop device structure */
dev = (FAR struct loop_struct_s *)inode->i_private; dev = (FAR struct loop_struct_s *)inode->i_private;
close_blockdriver(inode); close_blockdriver(inode);