diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-14 19:22:32 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-14 19:22:32 +0000 |
commit | cc3614dfe8f67033dca8c7c1f40c3367a0d3ca06 (patch) | |
tree | 45a3ce8d73b15e96d13ef6a48171a61a1a8449b8 /nuttx/fs/fat | |
parent | 930f9a13511a6d9bc2e44fadef42f6345d921667 (diff) | |
download | px4-firmware-cc3614dfe8f67033dca8c7c1f40c3367a0d3ca06.tar.gz px4-firmware-cc3614dfe8f67033dca8c7c1f40c3367a0d3ca06.tar.bz2 px4-firmware-cc3614dfe8f67033dca8c7c1f40c3367a0d3ca06.zip |
Finish dup logic for open files; fix bug in sigtimedwait(), would return wrong signo value if the signal was already pending
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5517 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/fat')
-rw-r--r-- | nuttx/fs/fat/fs_fat32.c | 126 | ||||
-rw-r--r-- | nuttx/fs/fat/fs_fat32.h | 1 | ||||
-rw-r--r-- | nuttx/fs/fat/fs_fat32util.c | 10 |
3 files changed, 124 insertions, 13 deletions
diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c index 788e6bebc..7164a9f8f 100644 --- a/nuttx/fs/fat/fs_fat32.c +++ b/nuttx/fs/fat/fs_fat32.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/fat/fs_fat32.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * References: @@ -86,7 +86,9 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer, size_t buflen); static off_t fat_seek(FAR struct file *filep, off_t offset, int whence); static int fat_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + static int fat_sync(FAR struct file *filep); +static int fat_dup(FAR const struct file *oldp, FAR struct file *newp); static int fat_opendir(struct inode *mountpt, const char *relpath, struct fs_dirent_s *dir); @@ -129,7 +131,7 @@ const struct mountpt_operations fat_operations = fat_ioctl, /* ioctl */ fat_sync, /* sync */ - NULL, /* dup */ + fat_dup, /* dup */ fat_opendir, /* opendir */ NULL, /* closedir */ @@ -313,7 +315,6 @@ static int fat_open(FAR struct file *filep, const char *relpath, /* Initialize the file private data (only need to initialize non-zero elements) */ - ff->ff_open = true; ff->ff_oflags = oflags; /* Save information that can be used later to recover the directory entry */ @@ -898,6 +899,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence) DEBUGASSERT(fs != NULL); /* Map the offset according to the whence option */ + switch (whence) { case SEEK_SET: /* The offset is set to offset bytes. */ @@ -971,6 +973,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence) ret = cluster; goto errout_with_semaphore; } + ff->ff_startcluster = cluster; } @@ -1233,6 +1236,123 @@ errout_with_semaphore: } /**************************************************************************** + * Name: fat_dup + * + * Description: Duplicate open file data in the new file structure. + * + ****************************************************************************/ + +static int fat_dup(FAR const struct file *oldp, FAR struct file *newp) +{ + FAR struct fat_mountpt_s *fs; + FAR struct fat_file_s *oldff; + FAR struct fat_file_s *newff; + int ret; + + fvdbg("Dup %p->%p\n", oldp, newp); + + /* Sanity checks */ + + DEBUGASSERT(oldp->f_priv != NULL && + newp->f_priv == NULL && + newp->f_inode != NULL); + + /* Recover our private data from the struct file instance */ + + fs = (struct fat_mountpt_s *)oldp->f_inode->i_private; + DEBUGASSERT(fs != NULL); + + /* Check if the mount is still healthy */ + + fat_semtake(fs); + ret = fat_checkmount(fs); + if (ret != OK) + { + goto errout_with_semaphore; + } + + /* Recover the old private data from the old struct file instance */ + + oldff = oldp->f_priv; + + /* Create a new instance of the file private date to describe the + * dup'ed file. + */ + + newff = (struct fat_file_s *)kmalloc(sizeof(struct fat_file_s)); + if (!newff) + { + ret = -ENOMEM; + goto errout_with_semaphore; + } + + /* Create a file buffer to support partial sector accesses */ + + newff->ff_buffer = (uint8_t*)fat_io_alloc(fs->fs_hwsectorsize); + if (!newff->ff_buffer) + { + ret = -ENOMEM; + goto errout_with_struct; + } + + /* Copy the rest of the open open file state from the old file structure. + * There are some assumptions and potential issues here: + * + * 1) We assume that the higher level logic has copied the elements of + * the file structure, in particular, the file position. + * 2) There is a problem with ff_size if there are multiple opened + * file structures, each believing they know the size of the file. + * If one instance modifies the file length, then the new size of + * the opened file will be unknown to the other. That is a lurking + * bug! + * + * One good solution to this might be to add a refernce count to the + * file structure. Then, instead of dup'ing the whole structure + * as is done here, just increment the reference count on the + * structure. The would have to be integrated with open logic as + * well, however, so that the same file structure is re-used if the + * file is re-opened. + */ + + newff->ff_bflags = 0; + newff->ff_oflags = oldff->ff_oflags; + newff->ff_sectorsincluster = oldff->ff_sectorsincluster; + newff->ff_dirindex = oldff->ff_dirindex; + newff->ff_currentcluster = oldff->ff_currentcluster; + newff->ff_dirsector = oldff->ff_dirsector; + newff->ff_size = oldff->ff_size; + newff->ff_currentsector = 0; + newff->ff_cachesector = 0; + + /* Attach the private date to the struct file instance */ + + newp->f_priv = newff; + + /* Then insert the new instance into the mountpoint structure. + * It needs to be there (1) to handle error conditions that effect + * all files, and (2) to inform the umount logic that we are busy + * (but a simple reference count could have done that). + */ + + newff->ff_next = fs->fs_head; + fs->fs_head = newff->ff_next; + + fat_semgive(fs); + return OK; + + /* Error exits -- goto's are nasty things, but they sure can make error + * handling a lot simpler. + */ + +errout_with_struct: + kfree(newff); + +errout_with_semaphore: + fat_semgive(fs); + return ret; +} + +/**************************************************************************** * Name: fat_opendir * * Description: Open a directory for read access diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h index 71a21333b..81f3f4675 100644 --- a/nuttx/fs/fat/fs_fat32.h +++ b/nuttx/fs/fat/fs_fat32.h @@ -752,7 +752,6 @@ struct fat_mountpt_s struct fat_file_s { struct fat_file_s *ff_next; /* Retained in a singly linked list */ - bool ff_open; /* true: The file is (still) open */ uint8_t ff_bflags; /* The file buffer flags */ uint8_t ff_oflags; /* Flags provided when file was opened */ uint8_t ff_sectorsincluster; /* Sectors remaining in cluster */ diff --git a/nuttx/fs/fat/fs_fat32util.c b/nuttx/fs/fat/fs_fat32util.c index 7231456d7..9aa1d3992 100644 --- a/nuttx/fs/fat/fs_fat32util.c +++ b/nuttx/fs/fat/fs_fat32util.c @@ -692,8 +692,6 @@ int fat_checkmount(struct fat_mountpt_s *fs) if (fs && fs->fs_mounted) { - struct fat_file_s *file; - /* We still think the mount is healthy. Check an see if this is * still the case */ @@ -715,14 +713,8 @@ int fat_checkmount(struct fat_mountpt_s *fs) /* If we get here, the mount is NOT healthy */ fs->fs_mounted = false; - - /* Make sure that this is flagged in every opened file */ - - for (file = fs->fs_head; file; file = file->ff_next) - { - file->ff_open = false; - } } + return -ENODEV; } |