Getdents implementation in library/vfs/mfs.
Changed readdir, etc. to use getdents
This commit is contained in:
		
							parent
							
								
									12eb228aae
								
							
						
					
					
						commit
						ca448f0b0f
					
				| @ -59,20 +59,23 @@ struct _v7_direct { | |||||||
| /* Definitions for the directory(3) routines: */ | /* Definitions for the directory(3) routines: */ | ||||||
| typedef struct { | typedef struct { | ||||||
| 	char		_fd;	/* Filedescriptor of open directory */ | 	char		_fd;	/* Filedescriptor of open directory */ | ||||||
| 	char		_v7;	/* Directory is Version 7 */ | 	unsigned	_count;	/* This many bytes in _buf */ | ||||||
| 	short		_count;	/* This many objects in buf */ | 	unsigned	_pos;	/* Position in _buf */ | ||||||
| 	off_t		_pos;	/* Position in directory file */ | 	char		 _buf[_MAX_BLOCK_SIZE]; /* The size does not really
 | ||||||
| 	struct _fl_direct  *_ptr;	/* Next slot in buf */ | 						 * matter as long as the | ||||||
| 	struct _fl_direct  _buf[_FLEX_PER_BLOCK]; /* One block of a directory file */ | 						 * buffer is big enough  | ||||||
| 	struct _fl_direct  _v7f[_FLEX_PER_V7];	 /* V7 entry transformed to flex */ | 						 * to contain at least one  | ||||||
|  | 						 * entry. | ||||||
|  | 						 */ | ||||||
| } DIR; | } DIR; | ||||||
| 
 | 
 | ||||||
| #define _DIRENT_NAME_LEN 61 | #define _DIRENT_NAME_LEN 61 | ||||||
| 
 | 
 | ||||||
| struct dirent {		/* Largest entry (8 slots) */ | struct dirent {		/* Largest entry (8 slots) */ | ||||||
| 	ino_t		d_ino;		/* I-node number */ | 	ino_t		d_ino;		/* I-node number */ | ||||||
| 	unsigned char	d_extent;	/* Extended with this many slots */ | 	off_t 		d_off;		/* Offset in directory */ | ||||||
| 	char		d_name[_DIRENT_NAME_LEN];	/* Null terminated name */ | 	unsigned short	d_reclen;	/* Length of this record */ | ||||||
|  | 	char		d_name[1];	/* Null terminated name */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* Function Prototypes. */ | /* Function Prototypes. */ | ||||||
| @ -87,6 +90,9 @@ _PROTOTYPE( off_t telldir, (DIR *_dirp)					); | |||||||
| 
 | 
 | ||||||
| #define   dirfd(dirp)     ((dirp)->_fd) | #define   dirfd(dirp)     ((dirp)->_fd) | ||||||
| 
 | 
 | ||||||
|  | _PROTOTYPE( int getdents, (int _fildes, struct dirent *_buf, | ||||||
|  | 							size_t _nbyte)	); | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #endif /* _DIRENT_H */ | #endif /* _DIRENT_H */ | ||||||
|  | |||||||
| @ -64,6 +64,7 @@ | |||||||
| #define SVRCTL		  77 | #define SVRCTL		  77 | ||||||
| #define SYSUNAME	  78 | #define SYSUNAME	  78 | ||||||
| #define GETSYSINFO	  79	/* to PM or FS */ | #define GETSYSINFO	  79	/* to PM or FS */ | ||||||
|  | #define GETDENTS	  80	/* to FS */ | ||||||
| #define FSTATFS	 	  82	/* to FS */ | #define FSTATFS	 	  82	/* to FS */ | ||||||
| #define SELECT            85	/* to FS */ | #define SELECT            85	/* to FS */ | ||||||
| #define FCHDIR            86	/* to FS */ | #define FCHDIR            86	/* to FS */ | ||||||
|  | |||||||
| @ -128,7 +128,9 @@ | |||||||
| #define REQ_BREAD                38 | #define REQ_BREAD                38 | ||||||
| #define REQ_BWRITE               39 | #define REQ_BWRITE               39 | ||||||
| 
 | 
 | ||||||
| #define NREQS                    40 | #define REQ_GETDENTS		 40 | ||||||
|  | 
 | ||||||
|  | #define NREQS                    41 | ||||||
| 
 | 
 | ||||||
| #define FS_READY                 57 | #define FS_READY                 57 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ libc_FILES=" \ | |||||||
| 	_cprofile.c \
 | 	_cprofile.c \
 | ||||||
| 	_devctl.c \
 | 	_devctl.c \
 | ||||||
| 	__pm_findproc.c \
 | 	__pm_findproc.c \
 | ||||||
|  | 	_getdents.c \
 | ||||||
| 	_getnpid.c \
 | 	_getnpid.c \
 | ||||||
| 	_getsigset.c \
 | 	_getsigset.c \
 | ||||||
| 	_getnprocnr.c \
 | 	_getnprocnr.c \
 | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								lib/other/_getdents.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								lib/other/_getdents.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | #include <lib.h> | ||||||
|  | #define getdents _getdents | ||||||
|  | #include <dirent.h> | ||||||
|  | 
 | ||||||
|  | PUBLIC ssize_t getdents(fd, buffer, nbytes) | ||||||
|  | int fd; | ||||||
|  | struct dirent *buffer; | ||||||
|  | size_t nbytes; | ||||||
|  | { | ||||||
|  |   message m; | ||||||
|  | 
 | ||||||
|  |   m.m1_i1 = fd; | ||||||
|  |   m.m1_i2 = nbytes; | ||||||
|  |   m.m1_p1 = (char *) buffer; | ||||||
|  |   return _syscall(FS, GETDENTS, &m); | ||||||
|  | } | ||||||
| @ -19,14 +19,8 @@ int seekdir(DIR *dp, off_t pos) | |||||||
| 	if (dp == nil) { errno= EBADF; return -1; } | 	if (dp == nil) { errno= EBADF; return -1; } | ||||||
| 
 | 
 | ||||||
| 	dp->_count= 0; | 	dp->_count= 0; | ||||||
| 	dp->_ptr= dp->_buf; |  | ||||||
| 
 | 
 | ||||||
| 	off= pos & (sizeof(dp->_buf) - 1); | 	if (lseek(dp->_fd, pos, SEEK_SET) == -1) return -1; | ||||||
| 	dp->_pos= pos - off; |  | ||||||
| 
 |  | ||||||
| 	if (lseek(dp->_fd, dp->_pos, SEEK_SET) == -1) return -1; |  | ||||||
| 
 |  | ||||||
| 	while (dp->_pos < pos && readdir(dp) != nil) {} |  | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,11 +6,22 @@ | |||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <dirent.h> | #include <dirent.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
|  | #include <unistd.h> | ||||||
| 
 | 
 | ||||||
| off_t telldir(DIR *dp) | off_t telldir(DIR *dp) | ||||||
| /* Return the current read position in a directory. */ | /* Return the current read position in a directory. */ | ||||||
| { | { | ||||||
|  | 	struct dirent *dep; | ||||||
|  | 
 | ||||||
| 	if (dp == nil) { errno= EBADF; return -1; } | 	if (dp == nil) { errno= EBADF; return -1; } | ||||||
| 
 | 
 | ||||||
| 	return dp->_pos; | 	if (dp->_pos < dp->_count) | ||||||
|  | 	{ | ||||||
|  | 		/* Use position in next entry */ | ||||||
|  | 		dep= (struct dirent *)&dp->_buf[dp->_pos]; | ||||||
|  | 		return dep->d_off; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Get current offset in directory */ | ||||||
|  | 	return lseek(dp->_fd, 0, SEEK_CUR); | ||||||
| } | } | ||||||
|  | |||||||
| @ -44,7 +44,6 @@ DIR *opendir(const char *name) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	dp->_fd= d; | 	dp->_fd= d; | ||||||
| 	dp->_v7= -1; |  | ||||||
| 	dp->_count= 0; | 	dp->_count= 0; | ||||||
| 	dp->_pos= 0; | 	dp->_pos= 0; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,58 +2,44 @@ | |||||||
|  *								24 Apr 1989 |  *								24 Apr 1989 | ||||||
|  */ |  */ | ||||||
| #define nil 0 | #define nil 0 | ||||||
| #include <lib.h> |  | ||||||
| #define read	_read |  | ||||||
| #define readdir _readdir | #define readdir _readdir | ||||||
|  | #define getdents _getdents | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <sys/stat.h> | #include <sys/stat.h> | ||||||
| #include <dirent.h> | #include <dirent.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | #include <stddef.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <limits.h> | #include <limits.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| 
 | 
 | ||||||
| #define v7ent(p)	((struct _v7_direct *) (p)) |  | ||||||
| #define V7_EXTENT	(sizeof(struct _v7_direct) / sizeof(struct _fl_direct) - 1) |  | ||||||
| 
 |  | ||||||
| struct dirent *readdir(DIR *dp) | struct dirent *readdir(DIR *dp) | ||||||
| /* Return the next entry in a directory.  Handle V7 and FLEX format dirs. */ | /* Return the next entry in a directory. */ | ||||||
| { | { | ||||||
| 	struct dirent *e; | 	struct dirent *entp; | ||||||
|  | 	int count, pos, reclen; | ||||||
| 
 | 
 | ||||||
| 	if (dp == nil) { errno= EBADF; return nil; } | 	if (dp == nil) { errno= EBADF; return nil; } | ||||||
| 
 | 
 | ||||||
| 	do { | 	count= dp->_count; | ||||||
| 		if (dp->_count <= 0) { | 	pos= dp->_pos; | ||||||
| 			/* Read the next directory block. */ | 	if (count == 0 || pos >= count) | ||||||
| 			dp->_count= read(dp->_fd, dp->_buf, sizeof(dp->_buf)); | 	{ | ||||||
| 			if (dp->_count <= 0) return nil; | 		count= getdents(dp->_fd, (struct dirent *)dp->_buf, | ||||||
|  | 			sizeof(dp->_buf)); | ||||||
|  | 		if (count <= 0) return nil; | ||||||
|  | 		dp->_count= count; | ||||||
|  | 		dp->_pos= pos= 0; | ||||||
|  | 	} | ||||||
|  | 	entp= (struct dirent *)&((char *)dp->_buf)[pos]; | ||||||
|  | 	reclen= entp->d_reclen; | ||||||
|  | 	dp->_pos= pos+reclen; | ||||||
| 
 | 
 | ||||||
| 			dp->_count/= sizeof(dp->_buf[0]); | 	return entp; | ||||||
| 			dp->_ptr= dp->_buf; |  | ||||||
| 
 |  | ||||||
| 			/* Extent is zero of the first flex entry. */ |  | ||||||
| 			if (dp->_v7 == (char)-1) dp->_v7= dp->_buf[0].d_extent; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 		if (!dp->_v7) { | /*
 | ||||||
| 			/* FLEX. */ |  * $PchId: _readdir.c,v 1.6 2005/01/27 21:46:42 philip Exp $ | ||||||
| 			e= (struct dirent *) dp->_ptr; |  */ | ||||||
| 		} else { |  | ||||||
| 			/* V7: transform to FLEX. */ |  | ||||||
| 			e= (struct dirent *) dp->_v7f; |  | ||||||
| 			e->d_ino= v7ent(dp->_ptr)->d_ino; |  | ||||||
| 			e->d_extent= V7_EXTENT; |  | ||||||
| 			memcpy(e->d_name, v7ent(dp->_ptr)->d_name, DIRSIZ); |  | ||||||
| 			e->d_name[DIRSIZ]= 0; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		dp->_ptr+= 1 + e->d_extent; |  | ||||||
| 		dp->_count-= 1 + e->d_extent; |  | ||||||
| 		dp->_pos+= (1 + e->d_extent) * sizeof(*dp->_ptr); |  | ||||||
| 
 |  | ||||||
| 	} while (e->d_ino == 0); |  | ||||||
| 	return e; |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -37,6 +37,7 @@ libc_FILES=" \ | |||||||
| 	fstat.s \
 | 	fstat.s \
 | ||||||
| 	fstatfs.s \
 | 	fstatfs.s \
 | ||||||
| 	getcwd.s \
 | 	getcwd.s \
 | ||||||
|  | 	getdents.s \
 | ||||||
| 	getegid.s \
 | 	getegid.s \
 | ||||||
| 	geteuid.s \
 | 	geteuid.s \
 | ||||||
| 	getgid.s \
 | 	getgid.s \
 | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								lib/syscall/getdents.s
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								lib/syscall/getdents.s
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | .sect .text | ||||||
|  | .extern	__getdents
 | ||||||
|  | .define	_getdents
 | ||||||
|  | .align 2
 | ||||||
|  | 
 | ||||||
|  | _getdents: | ||||||
|  | 	jmp	__getdents | ||||||
| @ -46,6 +46,7 @@ int lookup(void); | |||||||
| int fs_slink(void); | int fs_slink(void); | ||||||
| int fs_rdlink(void); | int fs_rdlink(void); | ||||||
| int fs_breadwrite(void); | int fs_breadwrite(void); | ||||||
|  | int fs_getdents(void); | ||||||
| 
 | 
 | ||||||
| void init_inode_cache(void); | void init_inode_cache(void); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ | |||||||
| 
 | 
 | ||||||
| #include "fs.h" | #include "fs.h" | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
|  | #include <stddef.h> | ||||||
|  | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <minix/com.h> | #include <minix/com.h> | ||||||
| #include "buf.h" | #include "buf.h" | ||||||
| @ -556,3 +558,155 @@ unsigned bytes_ahead;		/* bytes beyond position for immediate use */ | |||||||
|   return(get_block(dev, baseblock, NORMAL)); |   return(get_block(dev, baseblock, NORMAL)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | #define GETDENTS_BUFSIZ	257 | ||||||
|  | 
 | ||||||
|  | PRIVATE char getdents_buf[GETDENTS_BUFSIZ]; | ||||||
|  | 
 | ||||||
|  | /*===========================================================================*
 | ||||||
|  |  *				fs_getdents				     * | ||||||
|  |  *===========================================================================*/ | ||||||
|  | PUBLIC int fs_getdents(void) | ||||||
|  | { | ||||||
|  |   register struct inode *rip; | ||||||
|  |   int o, r, block_size, len, reclen, done; | ||||||
|  |   ino_t ino; | ||||||
|  |   block_t b; | ||||||
|  |   cp_grant_id_t gid; | ||||||
|  |   size_t size, tmpbuf_off, userbuf_off; | ||||||
|  |   off_t pos, off, block_pos, new_pos, ent_pos; | ||||||
|  |   struct buf *bp; | ||||||
|  |   struct direct *dp; | ||||||
|  |   struct dirent *dep; | ||||||
|  |   char *cp; | ||||||
|  | 
 | ||||||
|  |   ino= fs_m_in.REQ_GDE_INODE; | ||||||
|  |   gid= fs_m_in.REQ_GDE_GRANT; | ||||||
|  |   size= fs_m_in.REQ_GDE_SIZE; | ||||||
|  |   pos= fs_m_in.REQ_GDE_POS; | ||||||
|  | 
 | ||||||
|  |   /* Check whether the position is properly aligned */ | ||||||
|  |   if (pos % DIR_ENTRY_SIZE) | ||||||
|  | 	return ENOENT; | ||||||
|  |    | ||||||
|  |   if ( (rip = get_inode(fs_dev, ino)) == NIL_INODE) { | ||||||
|  | printf("MFS(%d) get_inode by fs_getdents() failed\n", SELF_E); | ||||||
|  |         return(EINVAL); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   block_size= rip->i_sp->s_block_size; | ||||||
|  |   off= (pos % block_size);		/* Offset in block */ | ||||||
|  |   block_pos= pos-off; | ||||||
|  |   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 */ | ||||||
|  |   userbuf_off= 0;	/* Offset in the user's buffer */ | ||||||
|  | 
 | ||||||
|  |   /* The default position for the next request is EOF. If the user's buffer
 | ||||||
|  |    * fills up before EOF, new_pos will be modified. | ||||||
|  |    */ | ||||||
|  |   new_pos= rip->i_size; | ||||||
|  | 
 | ||||||
|  |   for (; block_pos < rip->i_size; block_pos += block_size) { | ||||||
|  | 	b = read_map(rip, block_pos);	/* get block number */ | ||||||
|  | 
 | ||||||
|  | 	/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */ | ||||||
|  | 	bp = get_block(rip->i_dev, b, NORMAL);	/* get a dir block */ | ||||||
|  | 
 | ||||||
|  | 	if (bp == NO_BLOCK) | ||||||
|  | 		panic(__FILE__,"get_block returned NO_BLOCK", NO_NUM); | ||||||
|  | 
 | ||||||
|  | 	/* Search a directory block. */ | ||||||
|  | 	if (block_pos < pos) | ||||||
|  | 		dp = &bp->b_dir[off / DIR_ENTRY_SIZE]; | ||||||
|  | 	else | ||||||
|  | 		dp = &bp->b_dir[0]; | ||||||
|  | 	for (; dp < &bp->b_dir[NR_DIR_ENTRIES(block_size)]; dp++) { | ||||||
|  | 		if (dp->d_ino == 0) | ||||||
|  | 			continue;	/* Entry is not in use */ | ||||||
|  | 
 | ||||||
|  | 		/* Compute the length of the name */ | ||||||
|  | 		cp= memchr(dp->d_name, '\0', NAME_MAX); | ||||||
|  | 		if (cp == NULL) | ||||||
|  | 			len= NAME_MAX; | ||||||
|  | 		else | ||||||
|  | 			len= cp-dp->d_name; | ||||||
|  | 		 | ||||||
|  | 
 | ||||||
|  | 		/* Compute record length */ | ||||||
|  | 		reclen= offsetof(struct dirent, d_name) + len + 1; | ||||||
|  | 		o= (reclen % sizeof(long)); | ||||||
|  | 		if (o != 0) | ||||||
|  | 			reclen += sizeof(long)-o; | ||||||
|  | 
 | ||||||
|  | 		/* Need the postition of this entry in the directory */ | ||||||
|  | 		ent_pos= block_pos + ((char *)dp - bp->b_data); | ||||||
|  | 
 | ||||||
|  | 		if (tmpbuf_off + reclen > GETDENTS_BUFSIZ) | ||||||
|  | 		{ | ||||||
|  | 			r= sys_safecopyto(FS_PROC_NR, gid, userbuf_off,  | ||||||
|  | 				(vir_bytes)getdents_buf, tmpbuf_off, D); | ||||||
|  | 			if (r != OK) | ||||||
|  | 			{ | ||||||
|  | 				panic(__FILE__, | ||||||
|  | 					"fs_getdents: sys_safecopyto failed\n", | ||||||
|  | 					r); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			userbuf_off += tmpbuf_off; | ||||||
|  | 			tmpbuf_off= 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (userbuf_off + tmpbuf_off + reclen > size) | ||||||
|  | 		{ | ||||||
|  | 			/* The user has no space for one more record */ | ||||||
|  | 			done= TRUE; | ||||||
|  | 
 | ||||||
|  | 			/* Record the postion 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->d_ino; | ||||||
|  | 		dep->d_off= ent_pos; | ||||||
|  | 		dep->d_reclen= reclen; | ||||||
|  | 		memcpy(dep->d_name, dp->d_name, len); | ||||||
|  | 		dep->d_name[len]= '\0'; | ||||||
|  | 		tmpbuf_off += reclen; | ||||||
|  | 	} | ||||||
|  | 	put_block(bp, DIRECTORY_BLOCK); | ||||||
|  | 	if (done) | ||||||
|  | 		break; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (tmpbuf_off != 0) | ||||||
|  |   { | ||||||
|  | 	r= sys_safecopyto(FS_PROC_NR, gid, userbuf_off,  | ||||||
|  | 		(vir_bytes)getdents_buf, tmpbuf_off, D); | ||||||
|  | 	if (r != OK) | ||||||
|  | 		panic(__FILE__, "fs_getdents: sys_safecopyto failed\n", r); | ||||||
|  | 
 | ||||||
|  | 	userbuf_off += tmpbuf_off; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   r= ENOSYS; | ||||||
|  |   fs_m_out.RES_GDE_POS_CHANGE= 0;	/* No change in case of an error */ | ||||||
|  |   if (done && userbuf_off == 0) | ||||||
|  | 	r= EINVAL;		/* The user's buffer is too small */ | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  | 	r= userbuf_off; | ||||||
|  | 	if (new_pos >= pos) | ||||||
|  | 		fs_m_out.RES_GDE_POS_CHANGE= new_pos-pos; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   put_inode(rip);		/* release the inode */ | ||||||
|  |   return(r); | ||||||
|  | } | ||||||
|  | |||||||
| @ -58,5 +58,6 @@ PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = { | |||||||
|         fs_new_driver,      /* 37  */ |         fs_new_driver,      /* 37  */ | ||||||
|         fs_breadwrite,       /* 38  */ |         fs_breadwrite,       /* 38  */ | ||||||
|         fs_breadwrite,       /* 39  */ |         fs_breadwrite,       /* 39  */ | ||||||
|  |         fs_getdents,	     /* 40  */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -95,7 +95,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = { | |||||||
| 	do_svrctl,	/* 77 = svrctl	*/ | 	do_svrctl,	/* 77 = svrctl	*/ | ||||||
| 	do_sysuname,	/* 78 = sysuname */ | 	do_sysuname,	/* 78 = sysuname */ | ||||||
| 	do_getsysinfo,	/* 79 = getsysinfo */ | 	do_getsysinfo,	/* 79 = getsysinfo */ | ||||||
| 	no_sys,		/* 80 = unused */ | 	no_sys,		/* 80 = (getdents) */ | ||||||
| 	no_sys, 	/* 81 = unused */ | 	no_sys, 	/* 81 = unused */ | ||||||
| 	no_sys, 	/* 82 = (fstatfs) */ | 	no_sys, 	/* 82 = (fstatfs) */ | ||||||
| 	no_sys, 	/* 83 = unused */ | 	no_sys, 	/* 83 = unused */ | ||||||
|  | |||||||
| @ -122,6 +122,7 @@ _PROTOTYPE( int do_umask, (void)					); | |||||||
| 
 | 
 | ||||||
| /* read.c */ | /* read.c */ | ||||||
| _PROTOTYPE( int do_read, (void)						); | _PROTOTYPE( int do_read, (void)						); | ||||||
|  | _PROTOTYPE( int do_getdents, (void)					); | ||||||
| _PROTOTYPE( int read_write, (int rw_flag)				); | _PROTOTYPE( int read_write, (int rw_flag)				); | ||||||
| 
 | 
 | ||||||
| /* request.c */ | /* request.c */ | ||||||
| @ -165,6 +166,8 @@ _PROTOTYPE( int req_newdriver, (endpoint_t fs_e, Dev_t dev, | |||||||
|             endpoint_t driver_e)                                        ); |             endpoint_t driver_e)                                        ); | ||||||
| _PROTOTYPE( int req_breadwrite, (breadwrite_req_t *req,  | _PROTOTYPE( int req_breadwrite, (breadwrite_req_t *req,  | ||||||
|             readwrite_res_t *res)                                       ); |             readwrite_res_t *res)                                       ); | ||||||
|  | _PROTOTYPE( int req_getdents, (endpoint_t fs_e, ino_t inode_nr, | ||||||
|  | 	off_t pos, cp_grant_id_t gid, size_t size, off_t *pos_change)	); | ||||||
| 
 | 
 | ||||||
| /* stadir.c */ | /* stadir.c */ | ||||||
| _PROTOTYPE( int do_chdir, (void)					); | _PROTOTYPE( int do_chdir, (void)					); | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ | |||||||
|  * |  * | ||||||
|  * The entry points into this file are |  * The entry points into this file are | ||||||
|  *   do_read:	 perform the READ system call by calling read_write |  *   do_read:	 perform the READ system call by calling read_write | ||||||
|  |  *   do_getdents: read entries from a directory (GETDENTS) | ||||||
|  *   read_write: actually do the work of READ and WRITE |  *   read_write: actually do the work of READ and WRITE | ||||||
|  * |  * | ||||||
|  * Changes for VFS: |  * Changes for VFS: | ||||||
| @ -290,3 +291,43 @@ int rw_flag;			/* READING or WRITING */ | |||||||
|   }         |   }         | ||||||
| #endif         | #endif         | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /*===========================================================================*
 | ||||||
|  |  *				do_getdents				     * | ||||||
|  |  *===========================================================================*/ | ||||||
|  | PUBLIC int do_getdents() | ||||||
|  | { | ||||||
|  | /* Perform the getdents(fd, buf, size) system call. */ | ||||||
|  |   int r; | ||||||
|  |   off_t pos_change; | ||||||
|  |   cp_grant_id_t gid; | ||||||
|  |   register struct filp *rfilp; | ||||||
|  | 
 | ||||||
|  |   /* Is the file descriptor valid? */ | ||||||
|  |   if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) { | ||||||
|  | 	  return(err_code); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   if (!(rfilp->filp_mode & R_BIT)) | ||||||
|  | 	return EBADF; | ||||||
|  | 
 | ||||||
|  |   if ((rfilp->filp_vno->v_mode & I_TYPE) != I_DIRECTORY) | ||||||
|  | 	return EBADF; | ||||||
|  | 
 | ||||||
|  |   gid=cpf_grant_magic(rfilp->filp_vno->v_fs_e, who_e, (vir_bytes) m_in.buffer, | ||||||
|  | 	m_in.nbytes, CPF_WRITE); | ||||||
|  |   if (gid < 0) panic(__FILE__, "cpf_grant_magic failed", gid); | ||||||
|  | 
 | ||||||
|  |   /* Issue request */ | ||||||
|  |   r= req_getdents(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,  | ||||||
|  | 	rfilp->filp_pos, gid, m_in.nbytes, &pos_change); | ||||||
|  | 
 | ||||||
|  |   cpf_revoke(gid); | ||||||
|  | 
 | ||||||
|  |   if (r > 0) | ||||||
|  | 	rfilp->filp_pos += pos_change; | ||||||
|  |   return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -831,6 +831,27 @@ readwrite_res_t *res; | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | PUBLIC int req_getdents(fs_e, inode_nr, pos, gid, size, pos_change) | ||||||
|  | endpoint_t fs_e; | ||||||
|  | ino_t inode_nr; | ||||||
|  | off_t pos; | ||||||
|  | cp_grant_id_t gid; | ||||||
|  | size_t size; | ||||||
|  | off_t *pos_change; | ||||||
|  | { | ||||||
|  | 	int r; | ||||||
|  | 	message m; | ||||||
|  | 
 | ||||||
|  | 	m.m_type= REQ_GETDENTS; | ||||||
|  | 	m.REQ_GDE_INODE= inode_nr; | ||||||
|  | 	m.REQ_GDE_GRANT= gid; | ||||||
|  | 	m.REQ_GDE_SIZE= size; | ||||||
|  | 	m.REQ_GDE_POS= pos; | ||||||
|  | 
 | ||||||
|  | 	r = fs_sendrec(fs_e, &m); | ||||||
|  | 	*pos_change= m.RES_GDE_POS_CHANGE; | ||||||
|  | 	return r; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #if 0           
 | #if 0           
 | ||||||
| @ -951,4 +972,3 @@ PUBLIC int fs_sendrec(endpoint_t fs_e, message *reqm) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -98,7 +98,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = { | |||||||
| 
 | 
 | ||||||
| 	no_sys,		/* 78 = (sysuname) */ | 	no_sys,		/* 78 = (sysuname) */ | ||||||
| 	do_getsysinfo,  /* 79 = getsysinfo */ | 	do_getsysinfo,  /* 79 = getsysinfo */ | ||||||
| 	no_sys,		/* 80 = unused */ | 	do_getdents,	/* 80 = getdents */ | ||||||
| 	no_sys,		/* 81 = unused */ | 	no_sys,		/* 81 = unused */ | ||||||
| 	do_fstatfs,	/* 82 = fstatfs */ | 	do_fstatfs,	/* 82 = fstatfs */ | ||||||
| 	no_sys,		/* 83 = unused */ | 	no_sys,		/* 83 = unused */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Philip Homburg
						Philip Homburg