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 | ||||
| 				 * NR_VNODES in vfs | ||||
| 				 */ | ||||
| #define GETDENTS_BUFSIZ  257 | ||||
| 
 | ||||
| #define INODE_HASH_LOG2   7     /* 2 based logarithm of the inode hash size */ | ||||
| #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 | ||||
| 	buf_off, unsigned int block_size, int *completed); | ||||
| 
 | ||||
| static char getdents_buf[GETDENTS_BUFSIZ]; | ||||
| 
 | ||||
| /*===========================================================================*
 | ||||
|  *				fs_readwrite				     * | ||||
| @ -538,6 +537,9 @@ unsigned bytes_ahead;		/* bytes beyond position for immediate use */ | ||||
|  *===========================================================================*/ | ||||
| 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; | ||||
|   int o, r, done; | ||||
|   unsigned int block_size, len, reclen; | ||||
| @ -569,7 +571,7 @@ int fs_getdents(void) | ||||
|   done = FALSE;		/* Stop processing directory blocks when done is set */ | ||||
| 
 | ||||
|   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 */ | ||||
| 
 | ||||
|   /* 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 */ | ||||
| 		  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, | ||||
| 			  		     (vir_bytes) userbuf_off,  | ||||
| 					     (vir_bytes) getdents_buf, | ||||
| @ -623,18 +637,6 @@ int fs_getdents(void) | ||||
| 			  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->d_ino = dp->mfs_d_ino; | ||||
| 		dep->d_off = ent_pos; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Thomas Veerman
						Thomas Veerman