netbsd dirent.h, import sys/sys *.h, mfs cleanup
. add all sys/sys headers not already present to help compiling . take netbsd dirent.h and struct dirent; main result is introducing d_type and d_namlen that have to be set by getdents() in all FS code implementing it . d_off is gone . alignment of the struct has become 8 bytes instead of 4 . remove _MAX_BLOCK_SIZE, _MIN_BLOCK_SIZE, _STATIC_BLOCK_SIZE . libminlib: cleanup unused yet duplicate code . mfs: throw out the long-broken v1, v2 support . new test for dirent contents filled by getdents() Change-Id: I1459755c7ba5e5d1c9396d3a587ce6e63ddc283e
This commit is contained in:
@@ -44,6 +44,7 @@ SRCS+= _errno.c alarm.c alphasort.c arc4random.c assert.c basename.c clock.c \
|
||||
rewinddir.c scandir.c seekdir.c \
|
||||
setjmperr.c setmode.c \
|
||||
shquote.c shquotev.c sighold.c sigignore.c siginterrupt.c \
|
||||
sysctl.c sysctlbyname.c sysctlgetmibinfo.c sysctlnametomib.c \
|
||||
siglist.c signal.c signame.c sigrelse.c \
|
||||
sigset.c sigsetops.c sleep.c \
|
||||
stringlist.c sysconf.c \
|
||||
|
||||
@@ -69,6 +69,15 @@ static size_t __cvt_node_out(uint, const struct sysctlnode *, void **,
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __minix
|
||||
int __sysctl(const int *name, unsigned int namelen,
|
||||
void *oldp, size_t *oldlenp,
|
||||
const void *newp, size_t newlen)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
sysctl(const int *name, unsigned int namelen,
|
||||
void *oldp, size_t *oldlenp,
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
#include <sys/types.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/type.h> /* for unshort :-( */
|
||||
#include <minix/sysutil.h>
|
||||
#include "mfs/const.h" /* depends of -I flag in Makefile */
|
||||
#include "mfs/type.h" /* ditto */
|
||||
#include "mfs/inode.h" /* ditto */
|
||||
#include "mfs/super.h"
|
||||
#include <minix/fslib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* The next routine is copied from fsck.c and mkfs.c... (Re)define some
|
||||
* things for consistency. Some things should be done better.
|
||||
@@ -41,150 +43,16 @@ int block_size;
|
||||
return(nr_blocks);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* conv2 *
|
||||
*===========================================================================*/
|
||||
unsigned conv2(norm, w)
|
||||
int norm; /* TRUE if no swap, FALSE for byte swap */
|
||||
int w; /* promotion of 16-bit word to be swapped */
|
||||
uint8_t fs_mode_to_type(mode_t mode)
|
||||
{
|
||||
/* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
|
||||
if(S_ISREG(mode)) return DT_REG;
|
||||
else if(S_ISDIR(mode)) return DT_DIR;
|
||||
else if(S_ISLNK(mode)) return DT_LNK;
|
||||
else if(S_ISCHR(mode)) return DT_CHR;
|
||||
else if(S_ISBLK(mode)) return DT_BLK;
|
||||
else if(S_ISFIFO(mode)) return DT_FIFO;
|
||||
else if(S_ISSOCK(mode)) return DT_SOCK;
|
||||
|
||||
if (norm) return( (unsigned) w & 0xFFFF);
|
||||
return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
|
||||
panic("unknown type, mode 0x%x", mode);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* conv4 *
|
||||
*===========================================================================*/
|
||||
long conv4(norm, x)
|
||||
int norm; /* TRUE if no swap, FALSE for byte swap */
|
||||
long x; /* 32-bit long to be byte swapped */
|
||||
{
|
||||
/* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
|
||||
|
||||
unsigned lo, hi;
|
||||
long l;
|
||||
|
||||
if (norm) return(x); /* byte order was already ok */
|
||||
lo = conv2(FALSE, (int) x & 0xFFFF); /* low-order half, byte swapped */
|
||||
hi = conv2(FALSE, (int) (x>>16) & 0xFFFF); /* high-order half, swapped */
|
||||
l = ( (long) lo <<16) | hi;
|
||||
return(l);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* conv_inode *
|
||||
*===========================================================================*/
|
||||
void conv_inode(rip, dip, dip2, rw_flag, magic)
|
||||
register struct inode *rip; /* pointer to the in-core inode struct */
|
||||
register d1_inode *dip; /* pointer to the V1 on-disk inode struct */
|
||||
register d2_inode *dip2; /* pointer to the V2 on-disk inode struct */
|
||||
int rw_flag; /* READING or WRITING */
|
||||
int magic; /* magic number of file system */
|
||||
{
|
||||
/* Copy the inode from the disk block to the in-core table or vice versa.
|
||||
* If the fourth parameter below is FALSE, the bytes are swapped.
|
||||
*/
|
||||
switch (magic) {
|
||||
case SUPER_MAGIC: old_icopy(rip, dip, rw_flag, TRUE); break;
|
||||
case SUPER_REV: old_icopy(rip, dip, rw_flag, FALSE); break;
|
||||
case SUPER_V3:
|
||||
case SUPER_V2: new_icopy(rip, dip2, rw_flag, TRUE); break;
|
||||
case SUPER_V2_REV: new_icopy(rip, dip2, rw_flag, FALSE); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* old_icopy *
|
||||
*===========================================================================*/
|
||||
void old_icopy(rip, dip, direction, norm)
|
||||
register struct inode *rip; /* pointer to the in-core inode struct */
|
||||
register d1_inode *dip; /* pointer to the d1_inode inode struct */
|
||||
int direction; /* READING (from disk) or WRITING (to disk) */
|
||||
int norm; /* TRUE = do not swap bytes; FALSE = swap */
|
||||
|
||||
{
|
||||
/* 4 different on-disk inode layouts are supported, one for each combination
|
||||
* of V1.x/V2.x * bytes-swapped/not-swapped. When an inode is read or written
|
||||
* this routine handles the conversions so that the information in the inode
|
||||
* table is independent of the disk structure from which the inode came.
|
||||
* The old_icopy routine copies to and from V1 disks.
|
||||
*/
|
||||
|
||||
int i;
|
||||
|
||||
if (direction == READING) {
|
||||
/* Copy V1.x inode to the in-core table, swapping bytes if need be. */
|
||||
rip->i_mode = conv2(norm, dip->d1_mode);
|
||||
rip->i_uid = conv2(norm,dip->d1_uid );
|
||||
rip->i_size = conv4(norm,dip->d1_size);
|
||||
rip->i_mtime = conv4(norm,dip->d1_mtime);
|
||||
rip->i_atime = 0;
|
||||
rip->i_ctime = 0;
|
||||
rip->i_nlinks = (nlink_t) dip->d1_nlinks; /* 1 char */
|
||||
rip->i_gid = (gid_t) dip->d1_gid; /* 1 char */
|
||||
rip->i_ndzones = V1_NR_DZONES;
|
||||
rip->i_nindirs = V1_INDIRECTS;
|
||||
for (i = 0; i < V1_NR_TZONES; i++)
|
||||
rip->i_zone[i] = conv2(norm, (int) dip->d1_zone[i]);
|
||||
} else {
|
||||
/* Copying V1.x inode to disk from the in-core table. */
|
||||
dip->d1_mode = conv2(norm,rip->i_mode);
|
||||
dip->d1_uid = conv2(norm,rip->i_uid );
|
||||
dip->d1_size = conv4(norm,rip->i_size);
|
||||
dip->d1_mtime = conv4(norm,rip->i_mtime);
|
||||
dip->d1_nlinks = (nlink_t) rip->i_nlinks; /* 1 char */
|
||||
dip->d1_gid = (gid_t) rip->i_gid; /* 1 char */
|
||||
for (i = 0; i < V1_NR_TZONES; i++)
|
||||
dip->d1_zone[i] = conv2(norm, (int) rip->i_zone[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* new_icopy *
|
||||
*===========================================================================*/
|
||||
void new_icopy(rip, dip, direction, norm)
|
||||
register struct inode *rip; /* pointer to the in-core inode struct */
|
||||
register d2_inode *dip; /* pointer to the d2_inode struct */
|
||||
int direction; /* READING (from disk) or WRITING (to disk) */
|
||||
int norm; /* TRUE = do not swap bytes; FALSE = swap */
|
||||
|
||||
{
|
||||
/* Same as old_icopy, but to/from V2 disk layout. */
|
||||
|
||||
int i;
|
||||
|
||||
if (direction == READING) {
|
||||
/* Copy V2.x inode to the in-core table, swapping bytes if need be. */
|
||||
rip->i_mode = conv2(norm,dip->d2_mode);
|
||||
rip->i_uid = conv4(norm,dip->d2_uid );
|
||||
rip->i_nlinks = conv2(norm,(int) dip->d2_nlinks);
|
||||
rip->i_gid = conv4(norm,(int) dip->d2_gid );
|
||||
rip->i_size = conv4(norm,dip->d2_size);
|
||||
rip->i_atime = conv4(norm,dip->d2_atime);
|
||||
rip->i_ctime = conv4(norm,dip->d2_ctime);
|
||||
rip->i_mtime = conv4(norm,dip->d2_mtime);
|
||||
rip->i_ndzones = V2_NR_DZONES;
|
||||
rip->i_nindirs = V2_INDIRECTS(rip->i_sp->s_block_size);
|
||||
for (i = 0; i < V2_NR_TZONES; i++)
|
||||
rip->i_zone[i] = conv4(norm, (long) dip->d2_zone[i]);
|
||||
} else {
|
||||
/* Copying V2.x inode to disk from the in-core table. */
|
||||
dip->d2_mode = conv2(norm,rip->i_mode);
|
||||
dip->d2_uid = conv4(norm,rip->i_uid );
|
||||
dip->d2_nlinks = conv2(norm,rip->i_nlinks);
|
||||
dip->d2_gid = conv4(norm,rip->i_gid );
|
||||
dip->d2_size = conv4(norm,rip->i_size);
|
||||
dip->d2_atime = conv4(norm,rip->i_atime);
|
||||
dip->d2_ctime = conv4(norm,rip->i_ctime);
|
||||
dip->d2_mtime = conv4(norm,rip->i_mtime);
|
||||
for (i = 0; i < V2_NR_TZONES; i++)
|
||||
dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,9 +85,6 @@ puffs_nextdent(struct dirent **dent, const char *name, ino_t id, uint8_t dtype,
|
||||
if (o != 0)
|
||||
reclen += sizeof(long) - o;
|
||||
|
||||
/* FIXME: Set d_off?
|
||||
* dep->d_off =
|
||||
*/
|
||||
d->d_reclen = (unsigned short) reclen;
|
||||
(void)memcpy(d->d_name, name, (size_t)len);
|
||||
d->d_name[len] = '\0';
|
||||
|
||||
@@ -87,7 +87,7 @@ int do_getdents()
|
||||
struct sffs_attr attr;
|
||||
size_t len, off, user_off, user_left;
|
||||
off_t pos;
|
||||
int r;
|
||||
int r, namelen;
|
||||
/* must be at least sizeof(struct dirent) + NAME_MAX */
|
||||
static char buf[BLOCK_SIZE];
|
||||
|
||||
@@ -171,7 +171,9 @@ int do_getdents()
|
||||
}
|
||||
}
|
||||
|
||||
len = DWORD_ALIGN(sizeof(struct dirent) + strlen(name));
|
||||
/* record length incl. alignment. */
|
||||
namelen = strlen(name);
|
||||
len = _DIRENT_RECLEN(dent, namelen);
|
||||
|
||||
/* Is the user buffer too small to store another record?
|
||||
* Note that we will be rerequesting the same dentry upon a subsequent
|
||||
@@ -206,8 +208,9 @@ int do_getdents()
|
||||
/* Fill in the actual directory entry. */
|
||||
dent = (struct dirent *) &buf[off];
|
||||
dent->d_ino = INODE_NR(child);
|
||||
dent->d_off = pos;
|
||||
dent->d_reclen = len;
|
||||
dent->d_namlen = namelen;
|
||||
dent->d_type = IS_DIR(child) ? DT_DIR : DT_REG;
|
||||
strcpy(dent->d_name, name);
|
||||
|
||||
off += len;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "inc.h"
|
||||
#include <dirent.h>
|
||||
#include <minix/minlib.h>
|
||||
|
||||
#define GETDENTS_BUFSIZ 4096
|
||||
#define DWORD_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1))
|
||||
@@ -161,7 +162,8 @@ int fs_getdents(void)
|
||||
name = child->i_name;
|
||||
}
|
||||
|
||||
len = DWORD_ALIGN(sizeof(struct dirent) + strlen(name));
|
||||
/* record length incl. alignment. */
|
||||
len = _DIRENT_RECLEN(dent, strlen(name));
|
||||
|
||||
/* Is the user buffer too small to store another record? */
|
||||
if (user_off + off + len > user_left) {
|
||||
@@ -190,8 +192,9 @@ int fs_getdents(void)
|
||||
/* Fill in the actual directory entry. */
|
||||
dent = (struct dirent *) &buf[off];
|
||||
dent->d_ino = (ino_t) get_inode_number(child);
|
||||
dent->d_off = (off_t) pos;
|
||||
dent->d_reclen = len;
|
||||
dent->d_type = fs_mode_to_type(child->i_stat.mode);
|
||||
dent->d_namlen = strlen(name);
|
||||
strcpy(dent->d_name, name);
|
||||
|
||||
off += len;
|
||||
|
||||
Reference in New Issue
Block a user