[Libsysio-commit] HEAD: libsysio/drivers/native fs_native.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2005-08-04 20:17:19
|
Update of /cvsroot/libsysio/libsysio/drivers/native In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4518/drivers/native Modified Files: fs_native.c Log Message: Removed the internal getdirentries inode operation. The getdirentries function does not return the *next* block in it's basep argument. It simply return the cookie for the current block. We needed one that returns the *next*, so a new interface called filldirentries is present with this change. It takes, as it's second argument, a pointer to a value/result pair. The value should be set to the position to be read. The result is the position of the next block. All the included drivers have been updated. External drivers will require similar updates. Index: fs_native.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/drivers/native/fs_native.c,v retrieving revision 1.55 retrieving revision 1.56 diff -u -w -b -B -p -r1.55 -r1.56 --- fs_native.c 4 Feb 2005 00:21:45 -0000 1.55 +++ fs_native.c 4 Aug 2005 20:17:09 -0000 1.56 @@ -86,13 +86,10 @@ #endif #if defined(SYSIO_SYS_getdirentries) -#define DIR_STREAMED 0 #define DIR_CVT_64 0 #elif defined(SYSIO_SYS_getdents64) -#define DIR_STREAMED 1 #define DIR_CVT_64 0 #elif defined(SYSIO_SYS_getdents) -#define DIR_STREAMED 1 #if defined(_LARGEFILE64_SOURCE) #define DIR_CVT_64 1 /* @@ -143,7 +140,8 @@ struct native_inode_identifier { struct native_inode { unsigned ni_seekok : 1, /* can seek? */ - ni_attrvalid : 1; /* cached attrs ok? */ + ni_attrvalid : 1, /* cached attrs ok? */ + ni_resetfpos : 1; /* reset fpos? */ struct native_inode_identifier ni_ident; /* unique identifier */ struct file_identifier ni_fileid; /* ditto */ int ni_fd; /* host fildes */ @@ -178,10 +176,10 @@ static int native_inop_setattr(struct pn struct inode *ino, unsigned mask, struct intnl_stat *stbuf); -static ssize_t native_getdirentries(struct inode *ino, +static ssize_t native_filldirentries(struct inode *ino, + _SYSIO_OFF_T *posp, char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep); + size_t nbytes); static int native_inop_mkdir(struct pnode *pno, mode_t mode); static int native_inop_rmdir(struct pnode *pno); static int native_inop_symlink(struct pnode *pno, const char *data); @@ -213,7 +211,7 @@ static struct inode_ops native_i_ops = { native_inop_lookup, native_inop_getattr, native_inop_setattr, - native_getdirentries, + native_filldirentries, native_inop_mkdir, native_inop_rmdir, native_inop_symlink, @@ -324,6 +322,8 @@ native_i_new(struct filesys *fs, time_t return NULL; bzero(&nino->ni_ident, sizeof(nino->ni_ident)); nino->ni_seekok = 0; + nino->ni_attrvalid = 0; + nino->ni_resetfpos = 0; nino->ni_ident.dev = buf->st_dev; nino->ni_ident.ino = buf->st_ino; #ifdef HAVE_GENERATION @@ -952,26 +952,31 @@ native_pos(int fd, _SYSIO_OFF_T *offset, } static ssize_t -native_filldirentries(struct native_inode *nino, +native_ifilldirentries(struct native_inode *nino, + _SYSIO_OFF_T *posp, char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep) + size_t nbytes) { int err; ssize_t cc; - if (*basep < 0) + if (*posp < 0) return -EINVAL; -#if DIR_STREAMED /* * Stream-oriented access requires that we reposition prior to the * fill call. */ - if ((err = native_pos(nino->ni_fd, basep, SEEK_SET)) != 0) + assert(nino->ni_seekok); + if (*posp != nino->ni_fpos || nino->ni_resetfpos) { + nino->ni_fpos = *posp; + err = native_pos(nino->ni_fd, &nino->ni_fpos, SEEK_SET); + if (err) { + nino->ni_resetfpos = 1; return err; -#endif - nino->ni_fpos = *basep; + } + nino->ni_resetfpos = 0; + } cc = #if defined(SYSIO_SYS_getdirentries) @@ -979,7 +984,7 @@ native_filldirentries(struct native_inod nino->ni_fd, buf, nbytes, - basep); + &waste); #elif defined(SYSIO_SYS_getdents64) syscall(SYSIO_SYS_getdents64, nino->ni_fd, buf, nbytes); #elif defined(SYSIO_SYS_getdents) @@ -988,24 +993,26 @@ native_filldirentries(struct native_inod if (cc < 0) return -errno; -#if DIR_STREAMED /* * Stream-oriented access requires that we discover where we are * after the call. */ - *basep = 0; - if ((err = native_pos(nino->ni_fd, basep, SEEK_CUR)) != 0) + if ((err = native_pos(nino->ni_fd, &nino->ni_fpos, SEEK_CUR)) != 0) { + /* + * Leave the position at the old I suppose. + */ + nino->ni_resetfpos = 1; return err; -#endif - nino->ni_fpos = *basep; + } + *posp = nino->ni_fpos; return cc; } static ssize_t -native_getdirentries(struct inode *ino, +native_filldirentries(struct inode *ino, + _SYSIO_OFF_T *posp, char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep) + size_t nbytes) { struct native_inode *nino = I2NI(ino); #if DIR_CVT_64 @@ -1015,12 +1022,6 @@ native_getdirentries(struct inode *ino, struct dirent64 *d64p; size_t namlen; size_t reclen; - /* - * Work-around for broken 64 bit basep update - * Get value of basep to return from last directory - * entry d_off value - */ - _SYSIO_OFF_T last_offset = *basep; #else #define bp buf #define count nbytes @@ -1037,7 +1038,7 @@ native_getdirentries(struct inode *ino, return -ENOMEM; } #endif - cc = native_filldirentries(nino, bp, count, basep); + cc = native_ifilldirentries(nino, posp, bp, count); if (cc < 0) { #if DIR_CVT_64 free(bp); @@ -1047,30 +1048,31 @@ native_getdirentries(struct inode *ino, #if DIR_CVT_64 ldp = (struct linux_dirent *)bp; d64p = (struct dirent64 *)buf; - for (;;) { - if (cc < 0 || (size_t )cc <= sizeof(*ldp)) - break; + while (cc) { namlen = strlen(ldp->ld_name); - reclen = sizeof(*d64p) - sizeof(d64p->d_name) + namlen + 1; - if (nbytes < reclen) + reclen = sizeof(*d64p) - sizeof(d64p->d_name) + namlen; + if (nbytes <= reclen) break; d64p->d_ino = ldp->ld_ino; - d64p->d_off = ldp->ld_off; + d64p->d_off = nino->ni_fpos = ldp->ld_off; d64p->d_reclen = - (((reclen + sizeof(long) - 1)) / sizeof(long)) * - sizeof(long); + (((reclen + sizeof(long))) / sizeof(long)) * sizeof(long); if (nbytes < d64p->d_reclen) - d64p->d_reclen = reclen; + d64p->d_reclen = reclen + 1; d64p->d_type = DT_UNKNOWN; /* you lose -- sorry. */ - (void )strncpy(d64p->d_name, ldp->ld_name, namlen); - *(d64p->d_name + namlen) = '\0'; + (void )memcpy(d64p->d_name, ldp->ld_name, namlen); + /* + * Zero pad the rest. + */ + for (cp = d64p->d_name + namlen, n = d64p->d_reclen - reclen; + n; + n--) + *cp++ = 0; cc -= ldp->ld_reclen; ldp = (struct linux_dirent *)((char *)ldp + ldp->ld_reclen); nbytes -= d64p->d_reclen; - last_offset = d64p->d_off; d64p = (struct dirent64 *)((char *)d64p + d64p->d_reclen); } - nino->ni_fpos = *basep = last_offset; free(bp); cc = (d64p == (struct dirent64 *)buf && cc) @@ -1222,6 +1224,7 @@ native_inop_open(struct pnode *pno, int /* * Invariant; First open. Must init. */ + nino->ni_resetfpos = 0; nino->ni_fpos = 0; nino->ni_fd = fd; /* @@ -1259,6 +1262,7 @@ native_inop_close(struct inode *ino) return -errno; nino->ni_fd = -1; + nino->ni_resetfpos = 0; nino->ni_fpos = 0; return 0; } @@ -1348,13 +1352,10 @@ dopio(void *buf, size_t count, _SYSIO_OF { ssize_t cc; - if (!(off == nio->nio_nino->ni_fpos || nio->nio_nino->ni_seekok)) - return -ESPIPE; - if (!nio->nio_nino->ni_seekok) { if (off != nio->nio_nino->ni_fpos) { /* - * They've done a p{read,write} or somesuch. Can't + * They're trying to reposition. Can't * seek on this descriptor so we err out now. */ errno = ESPIPE; @@ -1407,8 +1408,11 @@ doiov(const struct iovec *iov, int err; err = native_pos(nio->nio_nino->ni_fd, &off, SEEK_SET); - if (err) + if (err) { + nio->nio_nino->ni_resetfpos = 1; return err; + } + nio->nio_nino->ni_resetfpos = 0; nio->nio_nino->ni_fpos = off; } |