Various fixes to the recent, big procfs checkin

This commit is contained in:
Gregory Nutt
2013-12-12 11:08:20 -06:00
parent 0a91686566
commit f97be5131c
5 changed files with 187 additions and 139 deletions
+115 -99
View File
@@ -540,10 +540,12 @@ static ssize_t part_procfs_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
FAR struct part_procfs_file_s *attr;
ssize_t ret, total = 0, blkpererase;
FAR struct mtd_geometry_s geo;
ssize_t total = 0;
ssize_t blkpererase;
ssize_t ret;
#ifdef CONFIG_MTD_PARTITION_NAMES
char partname[11];
char partname[11];
FAR const char *ptr;
uint8_t x;
#endif
@@ -555,114 +557,128 @@ static ssize_t part_procfs_read(FAR struct file *filep, FAR char *buffer,
attr = (FAR struct part_procfs_file_s *)filep->f_priv;
DEBUGASSERT(attr);
/* Provide the requested data */
/* If we are at the end of the list, then return 0 signifying the
* end-of-file. This also handles the special case when there are
* no registered MTD partitions.
*/
if (attr->nextpart == g_pfirstpartition)
if (attr->nextpart)
{
/* Output a header before the first entry */
if (attr->nextpart == g_pfirstpartition)
{
#ifdef CONFIG_MTD_PARTITION_NAMES
total = snprintf(buffer, buflen, "Name Start Size");
total = snprintf(buffer, buflen, "Name Start Size");
#else
total = snprintf(buffer, buflen, " Start Size");
total = snprintf(buffer, buflen, " Start Size");
#endif
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MTD
total += snprintf(&buffer[total], buflen - total, " MTD\n");
total += snprintf(&buffer[total], buflen - total, " MTD\n");
#else
total += snprintf(&buffer[total], buflen - total, "\n");
total += snprintf(&buffer[total], buflen - total, "\n");
#endif
}
/* Provide the requested data */
do
{
/* Get the geometry of the FLASH device */
ret = attr->nextpart->parent->ioctl(attr->nextpart->parent,
MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo));
if (ret < 0)
{
fdbg("ERROR: mtd->ioctl failed: %d\n", ret);
return 0;
}
/* Get the number of blocks per erase. There must be an even number
* of blocks in one erase blocks.
*/
blkpererase = geo.erasesize / geo.blocksize;
/* Copy data from the next known partition */
#ifdef CONFIG_MTD_PARTITION_NAMES
if (attr->nextpart->name == NULL)
{
strcpy(partname, "(noname) ");
}
else
{
ptr = attr->nextpart->name;
for (x = 0; x < sizeof(partname) - 1; x++)
{
/* Test for end of partition name */
if (*ptr == ',' || *ptr == '\0')
{
/* Perform space fill for alignment */
partname[x] = ' ';
}
else
{
/* Copy next byte of partition name */
partname[x] = *ptr++;
}
}
partname[x] = '\0';
}
/* Terminate the partition name and add to output buffer */
ret = snprintf(&buffer[total], buflen - total, "%s%7d %7d",
partname, attr->nextpart->firstblock / blkpererase,
attr->nextpart->neraseblocks);
#else
ret = snprintf(&buffer[total], buflen - total, "%7d %7d",
attr->nextpart->firstblock / blkpererase,
attr->nextpart->neraseblocks);
#endif
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MTD
if (ret + total < buflen)
{
ret += snprintf(&buffer[total + ret], buflen - (total + ret),
" %s\n", attr->nextpart->parent->name);
}
#else
if (ret + total < buflen)
{
ret += snprintf(&buffer[total + ret], buflen - (total + ret),
"\n");
}
#endif
if (ret + total < buflen)
{
/* It fit in the buffer totally. Advance total and move to
* next partition.
*/
total += ret;
attr->nextpart = attr->nextpart->pnext;
}
else
{
/* This one didn't fit completely. Truncate the partial
* entry and break the loop.
*/
buffer[total] = '\0';
break;
}
}
while (attr->nextpart);
}
while (attr->nextpart)
{
/* Get the geometry of the FLASH device */
ret = attr->nextpart->parent->ioctl(attr->nextpart->parent, MTDIOC_GEOMETRY,
(unsigned long)((uintptr_t)&geo));
if (ret < 0)
{
fdbg("ERROR: mtd->ioctl failed: %d\n", ret);
return 0;
}
/* Get the number of blocks per erase. There must be an even number of
* blocks in one erase blocks.
*/
blkpererase = geo.erasesize / geo.blocksize;
/* Copy data from the next known partition */
#ifdef CONFIG_MTD_PARTITION_NAMES
if (attr->nextpart->name == NULL)
{
strcpy(partname, "(noname) ");
}
else
{
ptr = attr->nextpart->name;
for (x = 0; x < sizeof(partname) - 1; x++)
{
/* Test for end of partition name */
if (*ptr == ',' || *ptr == '\0')
{
/* Perform space fill for alignment */
partname[x] = ' ';
}
else
{
/* Copy next byte of partition name */
partname[x] = *ptr++;
}
}
partname[x] = '\0';
}
/* Terminate the partition name and add to output buffer */
ret = snprintf(&buffer[total], buflen - total, "%s%7d %7d",
partname, attr->nextpart->firstblock / blkpererase,
attr->nextpart->neraseblocks);
#else
ret = snprintf(&buffer[total], buflen - total, "%7d %7d",
attr->nextpart->firstblock / blkpererase,
attr->nextpart->neraseblocks);
#endif
#ifndef CONFIG_FS_PROCFS_EXCLUDE_MTD
if (ret + total < buflen)
{
ret += snprintf(&buffer[total + ret], buflen - (total + ret),
" %s\n", attr->nextpart->parent->name);
}
#else
if (ret + total < buflen)
{
ret += snprintf(&buffer[total + ret], buflen - (total + ret), "\n");
}
#endif
if (ret + total < buflen)
{
/* It fit in the buffer totally. Advance total and move to
* next partition.
*/
total += ret;
attr->nextpart = attr->nextpart->pnext;
}
else
{
/* This one didn't fit completely. Truncate the partial
* entry and break the loop.
*/
buffer[total] = '\0';
break;
}
}
/* Update the file offset */
if (total > 0)
+29 -17
View File
@@ -199,7 +199,8 @@ static ssize_t mtd_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
FAR struct mtd_file_s *priv;
ssize_t total = 0, ret;
ssize_t total = 0;
ssize_t ret;
fvdbg("buffer=%p buflen=%d\n", buffer, (int)buflen);
@@ -208,28 +209,39 @@ static ssize_t mtd_read(FAR struct file *filep, FAR char *buffer,
priv = (FAR struct mtd_file_s *)filep->f_priv;
DEBUGASSERT(priv);
/* Provide the requested data */
/* If we are at the end of the list, then return 0 signifying the
* end-of-file. This also handles the special case when there are
* no registered MTD devices.
*/
if (priv->pnextmtd == g_pfirstmtd)
if (priv->pnextmtd)
{
total = snprintf(buffer, buflen, "Num Device\n");
}
/* Output a header before the first entry */
while (priv->pnextmtd)
{
ret = snprintf(&buffer[total], buflen - total, "%-5d%s\n",
priv->pnextmtd->mtdno, priv->pnextmtd->name);
if (priv->pnextmtd == g_pfirstmtd)
{
total = snprintf(buffer, buflen, "Num Device\n");
}
if (ret + total < buflen)
/* The provide the requested data */
do
{
total += ret;
priv->pnextmtd = priv->pnextmtd->pnext;
}
else
{
buffer[total] = '\0';
break;
ret = snprintf(&buffer[total], buflen - total, "%-5d%s\n",
priv->pnextmtd->mtdno, priv->pnextmtd->name);
if (ret + total < buflen)
{
total += ret;
priv->pnextmtd = priv->pnextmtd->pnext;
}
else
{
buffer[total] = '\0';
break;
}
}
while (priv->pnextmtd);
}
/* Update the file offset */
+8 -4
View File
@@ -384,6 +384,7 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
FAR struct fs_dirent_s *dir)
{
FAR struct procfs_level0_s *level0;
FAR struct procfs_dir_priv_s *dirpriv;
FAR void *priv = NULL;
irqstate_t flags;
@@ -448,7 +449,10 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
if (match(g_procfsentries[x].pathpattern, relpath))
{
/* Match found! Call the handler's opendir routine */
/* Match found! Call the handler's opendir routine. If successful,
* this opendir routine will create an entry derived from struct
* procfs_dir_priv_s as dir->u.procfs.
*/
DEBUGASSERT(g_procfsentries[x].ops && g_procfsentries[x].ops->opendir);
ret = g_procfsentries[x].ops->opendir(relpath, dir);
@@ -459,8 +463,8 @@ static int procfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
/* Set the procfs_entry handler */
level0 = (FAR struct procfs_level0_s *) dir->u.procfs;
level0->procfsentry = &g_procfsentries[x];
dirpriv = (FAR struct procfs_dir_priv_s *)dir->u.procfs;
dirpriv->procfsentry = &g_procfsentries[x];
}
return ret;
@@ -684,7 +688,7 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
#endif /* CONFIG_FS_PROCFS_EXCLUDE_PROCESS */
}
/* Are we reading in intermediate subdirectory? */
/* Are we reading an intermediate subdirectory? */
else if (priv->level == 1 && priv->procfsentry == NULL)
{
+24 -8
View File
@@ -708,7 +708,6 @@ static int process_dup(FAR const struct file *oldp, FAR struct file *newp)
static int process_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
{
FAR struct tcb_s *tcb;
FAR void *priv = NULL;
irqstate_t flags;
fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL");
@@ -784,14 +783,15 @@ static int process_opendir(FAR const char *relpath, FAR struct fs_dirent_s *dir)
return -ENOMEM;
}
level1->base.level = 1;
level1->base.nentries = PROCFS_NATTRS;
level1->base.index = 0;
level1->pid = pid;
/* Note that the index and procentry pointer were implicitly nullified
* by kzalloc(). Only the remaining, non-zero entries need be initialized.
*/
priv = (FAR void *)level1;
level1->base.level = 1;
level1->base.nentries = PROCFS_NATTRS;
level1->pid = pid;
dir->u.procfs = priv;
dir->u.procfs = (FAR void *)level1;
return OK;
}
@@ -969,12 +969,28 @@ static int process_stat(const char *relpath, struct stat *buf)
buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR;
}
/* Verify that the process ID is followed by valid path segment delimiter */
else if (*ptr != '/')
{
/* We are required to return -ENOENT all all invalid paths */
fdbg("ERROR: Bad delimiter '%c' in relpath '%s'\n", *ptr, relpath);
return -ENOENT;
}
else
{
/* Otherwise, the second segment of the relpath should be a well
* known attribute of the task/thread.
*/
/* Skip over the path segment delimiter */
ptr++;
/* Lookup the well-known attribute string. */
ret = process_findattr(ptr);
if (ret < 0)
{
@@ -982,7 +998,7 @@ static int process_stat(const char *relpath, struct stat *buf)
return -ENOENT;
}
/* It's a read-only file name */
/* If the attribute exists, it is the name for a read-only file. */
buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR;
}
+11 -11
View File
@@ -52,9 +52,9 @@
struct procfs_operations
{
/* The mountpoint open method differs from the driver open method
* because it receives (1) the inode that contains the mountpoint
* private data, (2) the relative path into the mountpoint, and (3)
/* The procfs open method differs from the driver open method
* because it receives (1) the inode that contains the procfs
* private data, (2) the relative path into the procfs, and (3)
* information to manage privileges.
*/
@@ -74,7 +74,7 @@ struct procfs_operations
* are extended methods needed to deal with the unique needs of mounted
* file systems.
*
* Additional open-file-specific mountpoint operations:
* Additional open-file-specific procfs operations:
*/
int (*dup)(FAR const struct file *oldp, FAR struct file *newp);
@@ -99,8 +99,8 @@ struct procfs_operations
struct procfs_entry_s
{
FAR const char *pathpattern;
const struct procfs_operations *ops;
FAR const char *pathpattern;
FAR const struct procfs_operations *ops;
};
/* Specifies the common elements for an open file in the procfs
@@ -110,17 +110,17 @@ struct procfs_entry_s
struct procfs_file_s
{
const struct procfs_entry_s *pProcfsEntry;
FAR const struct procfs_entry_s *procfsentry;
};
/* The generic proc/ pseudo directory structure */
struct procfs_dir_priv_s
{
uint8_t level; /* Directory level. Currently 0 or 1 */
uint16_t index; /* Index to the next directory entry */
uint16_t nentries; /* Number of directory entries */
struct procfs_entry_s *pProcfsEntry; /* Pointer to procfs handler entry */
uint8_t level; /* Directory level. Currently 0 or 1 */
uint16_t index; /* Index to the next directory entry */
uint16_t nentries; /* Number of directory entries */
FAR const struct procfs_entry_s *procfsentry; /* Pointer to procfs handler entry */
};
/****************************************************************************