diff --git a/fs/nxffs/nxffs_ioctl.c b/fs/nxffs/nxffs_ioctl.c index d5fe2ece838..e24cf056486 100644 --- a/fs/nxffs/nxffs_ioctl.c +++ b/fs/nxffs/nxffs_ioctl.c @@ -47,6 +47,7 @@ #include #include +#include #include #include "nxffs.h" @@ -82,6 +83,7 @@ int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct nxffs_volume_s *volume; + int ret; fvdbg("cmd: %d arg: %08lx\n", cmd, arg); @@ -94,7 +96,45 @@ int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) volume = filep->f_inode->i_private; DEBUGASSERT(volume != NULL); - /* No ioctl commands yet supported */ + /* Get exclusive access to the volume. Note that the volume exclsem + * protects the open file list. + */ - return -ENOTTY; + ret = sem_wait(&volume->exclsem); + if (ret != OK) + { + ret = -errno; + fdbg("sem_wait failed: %d\n", ret); + goto errout; + } + + /* Only a reformat command is supported */ + + if (cmd == FIOC_REFORMAT) + { + fvdbg("Reformat command\n"); + + /* We cannot reformat the volume if there are any open inodes */ + + if (volume->ofiles) + { + fdbg("Open files\n"); + ret = -EBUSY; + goto errout_with_semaphore; + } + + /* Re-format the volume -- all is lost */ + + ret = nxffs_reformat(volume); + goto errout_with_semaphore; + } + + /* No other commands supported */ + + ret = -ENOTTY; + +errout_with_semaphore: + sem_post(&volume->exclsem); +errout: + return ret; } diff --git a/include/nuttx/ioctl.h b/include/nuttx/ioctl.h index 5eaf886c8aa..0c32004f8e8 100644 --- a/include/nuttx/ioctl.h +++ b/include/nuttx/ioctl.h @@ -94,17 +94,21 @@ * return (void*) base address * of file */ +#define FIOC_REFORMAT _FIOC(0x0002) /* IN: None + * OUT: None + */ + /* NuttX file system ioctl definitions */ #define _DIOCVALID(c) (_IOC_TYPE(c)==_DIOCBASE) #define _DIOC(nr) _IOC(_DIOCBASE,nr) -#define DIOC_GETPRIV _DIOC(0x0001) /* IN: Location to return handle (void **) +#define DIOC_GETPRIV _DIOC(0x0001) /* IN: Location to return handle (void **) * OUT: Reference to internal data * structure. May have a reference * incremented. */ -#define DIOC_RELPRIV _DIOC(0x0003) /* IN: None +#define DIOC_RELPRIV _DIOC(0x0003) /* IN: None * OUT: None, reference obtained by * FIOC_GETPRIV released. */