MFS: getdents fixes
.Use a bigger buffer to hold results .Do not try to store more data than user buffer can hold
This commit is contained in:
parent
b6ea15115c
commit
fa9199e049
@ -11,7 +11,6 @@
|
|||||||
* should be more or less the same as
|
* should be more or less the same as
|
||||||
* NR_VNODES in vfs
|
* NR_VNODES in vfs
|
||||||
*/
|
*/
|
||||||
#define GETDENTS_BUFSIZ 257
|
|
||||||
|
|
||||||
#define INODE_HASH_LOG2 7 /* 2 based logarithm of the inode hash size */
|
#define INODE_HASH_LOG2 7 /* 2 based logarithm of the inode hash size */
|
||||||
#define INODE_HASH_SIZE ((unsigned long)1<<INODE_HASH_LOG2)
|
#define INODE_HASH_SIZE ((unsigned long)1<<INODE_HASH_LOG2)
|
||||||
|
@ -17,7 +17,6 @@ static int rw_chunk(struct inode *rip, u64_t position, unsigned off,
|
|||||||
size_t chunk, unsigned left, int rw_flag, cp_grant_id_t gid, unsigned
|
size_t chunk, unsigned left, int rw_flag, cp_grant_id_t gid, unsigned
|
||||||
buf_off, unsigned int block_size, int *completed);
|
buf_off, unsigned int block_size, int *completed);
|
||||||
|
|
||||||
static char getdents_buf[GETDENTS_BUFSIZ];
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* fs_readwrite *
|
* fs_readwrite *
|
||||||
@ -538,6 +537,9 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
int fs_getdents(void)
|
int fs_getdents(void)
|
||||||
{
|
{
|
||||||
|
#define GETDENTS_BUFSIZE (sizeof(struct dirent) + MFS_NAME_MAX + 1)
|
||||||
|
#define GETDENTS_ENTRIES 8
|
||||||
|
static char getdents_buf[GETDENTS_BUFSIZE * GETDENTS_ENTRIES];
|
||||||
register struct inode *rip;
|
register struct inode *rip;
|
||||||
int o, r, done;
|
int o, r, done;
|
||||||
unsigned int block_size, len, reclen;
|
unsigned int block_size, len, reclen;
|
||||||
@ -569,7 +571,7 @@ int fs_getdents(void)
|
|||||||
done = FALSE; /* Stop processing directory blocks when done is set */
|
done = FALSE; /* Stop processing directory blocks when done is set */
|
||||||
|
|
||||||
tmpbuf_off = 0; /* Offset in getdents_buf */
|
tmpbuf_off = 0; /* Offset in getdents_buf */
|
||||||
memset(getdents_buf, '\0', GETDENTS_BUFSIZ); /* Avoid leaking any data */
|
memset(getdents_buf, '\0', sizeof(getdents_buf)); /* Avoid leaking any data */
|
||||||
userbuf_off = 0; /* Offset in the user's buffer */
|
userbuf_off = 0; /* Offset in the user's buffer */
|
||||||
|
|
||||||
/* The default position for the next request is EOF. If the user's buffer
|
/* The default position for the next request is EOF. If the user's buffer
|
||||||
@ -609,7 +611,19 @@ int fs_getdents(void)
|
|||||||
/* Need the position of this entry in the directory */
|
/* Need the position of this entry in the directory */
|
||||||
ent_pos = block_pos + ((char *) dp - (bp->b_data));
|
ent_pos = block_pos + ((char *) dp - (bp->b_data));
|
||||||
|
|
||||||
if(tmpbuf_off + reclen > GETDENTS_BUFSIZ) {
|
if (userbuf_off + tmpbuf_off + reclen >= size) {
|
||||||
|
/* The user has no space for one more record */
|
||||||
|
done = TRUE;
|
||||||
|
|
||||||
|
/* Record the position of this entry, it is the
|
||||||
|
* starting point of the next request (unless the
|
||||||
|
* postion is modified with lseek).
|
||||||
|
*/
|
||||||
|
new_pos = ent_pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpbuf_off + reclen >= GETDENTS_BUFSIZE*GETDENTS_ENTRIES) {
|
||||||
r = sys_safecopyto(VFS_PROC_NR, gid,
|
r = sys_safecopyto(VFS_PROC_NR, gid,
|
||||||
(vir_bytes) userbuf_off,
|
(vir_bytes) userbuf_off,
|
||||||
(vir_bytes) getdents_buf,
|
(vir_bytes) getdents_buf,
|
||||||
@ -623,18 +637,6 @@ int fs_getdents(void)
|
|||||||
tmpbuf_off = 0;
|
tmpbuf_off = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(userbuf_off + tmpbuf_off + reclen > size) {
|
|
||||||
/* The user has no space for one more record */
|
|
||||||
done = TRUE;
|
|
||||||
|
|
||||||
/* Record the position of this entry, it is the
|
|
||||||
* starting point of the next request (unless the
|
|
||||||
* postion is modified with lseek).
|
|
||||||
*/
|
|
||||||
new_pos = ent_pos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dep = (struct dirent *) &getdents_buf[tmpbuf_off];
|
dep = (struct dirent *) &getdents_buf[tmpbuf_off];
|
||||||
dep->d_ino = dp->mfs_d_ino;
|
dep->d_ino = dp->mfs_d_ino;
|
||||||
dep->d_off = ent_pos;
|
dep->d_off = ent_pos;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user