#endif
#include <sys/queue.h>
-#include "xtio.h"
#include "sysio.h"
+#include "xtio.h"
#include "fs.h"
#include "mount.h"
#include "inode.h"
struct inode *ino,
unsigned mask,
struct intnl_stat *stbuf);
-static ssize_t _sysio_incore_dirop_getdirentries(struct inode *ino,
- char *buf,
- size_t nbytes,
- _SYSIO_OFF_T *basep);
+static ssize_t _sysio_incore_dirop_filldirentries(struct inode *ino,
+ _SYSIO_OFF_T *posp,
+ char *buf,
+ size_t nbytes);
static int _sysio_incore_dirop_mkdir(struct pnode *pno, mode_t mode);
static int _sysio_incore_dirop_rmdir(struct pnode *pno);
static int _sysio_incore_inop_open(struct pnode *pno, int flags, mode_t mode);
_sysio_incore_dirop_lookup,
_sysio_incore_inop_getattr,
_sysio_incore_inop_setattr,
- _sysio_incore_dirop_getdirentries,
+ _sysio_incore_dirop_filldirentries,
_sysio_incore_dirop_mkdir,
_sysio_incore_dirop_rmdir,
_sysio_incore_dirop_symlink,
struct inode **, \
struct intent *, \
const char *))_sysio_do_illop
-#define _sysio_incore_filop_getdirentries \
+#define _sysio_incore_filop_filldirentries \
(ssize_t (*)(struct inode *, \
- char *, \
- size_t, \
- _SYSIO_OFF_T *))_sysio_do_illop
+ _SYSIO_OFF_T *, \
+ char *, \
+ size_t))_sysio_do_illop
#define _sysio_incore_filop_mkdir \
(int (*)(struct pnode *, mode_t))_sysio_do_illop
#define _sysio_incore_filop_rmdir \
_sysio_incore_filop_lookup,
_sysio_incore_inop_getattr,
_sysio_incore_inop_setattr,
- _sysio_incore_filop_getdirentries,
+ _sysio_incore_filop_filldirentries,
_sysio_incore_filop_mkdir,
_sysio_incore_filop_rmdir,
_sysio_incore_filop_symlink,
_sysio_incore_filop_lookup,
_sysio_incore_inop_getattr,
_sysio_incore_inop_setattr,
- _sysio_incore_filop_getdirentries,
+ _sysio_incore_filop_filldirentries,
_sysio_incore_filop_mkdir,
_sysio_incore_filop_rmdir,
_sysio_incore_filop_symlink,
* Source is a specification for the root attributes of this
* new file system in the format:
*
- * <permissions>+<owner>+<group>
+ * <permissions>[+<owner>][-<group>]
*/
ul = strtoul(source, &cp, 0);
mode = (mode_t )ul & 07777;
- if (*cp != '+' ||
- (ul == ULONG_MAX && errno == ERANGE) ||
- (unsigned long)mode != ul ||
- mode > 07777)
- return -EINVAL;
- source = cp;
- l = strtol(source, &cp, 0);
- uid = (uid_t )l;
- if (*cp != '+' ||
- ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
- (long )uid != l)
- return -EINVAL;
- source = cp;
- l = strtol(source, &cp, 0);
- gid = (gid_t )l;
- if (*cp ||
- ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
- (long )gid != l)
- return -EINVAL;
+ uid = getuid(); /* default */
+ gid = getgid(); /* default */
+ if (*cp != '\0') {
+ /*
+ * Get user and/or group.
+ */
+ if (*cp != '+' ||
+ (ul == ULONG_MAX && errno == ERANGE) ||
+ (unsigned long)mode != ul ||
+ mode > 07777)
+ return -EINVAL;
+ source = cp;
+ l = strtol(source, &cp, 0);
+ uid = (uid_t )l;
+ if (((l == LONG_MIN || l == LONG_MAX) &&
+ errno == ERANGE) ||
+ (long )uid != l)
+ return -EINVAL;
+ if (*cp != '+')
+ return -EINVAL;
+ source = cp;
+ l = strtol(source, &cp, 0);
+ gid = (gid_t )l;
+ if (((l == LONG_MIN || l == LONG_MAX) &&
+ errno == ERANGE) ||
+ (long )gid != l)
+ return -EINVAL;
+ if (*cp != '\0')
+ return -EINVAL;
+ }
err = 0;
static struct intnl_dirent *
incore_directory_match(struct intnl_dirent *de,
- size_t reclen __IS_UNUSED,
+ size_t reclen,
struct lookup_data *ld)
{
+ size_t len;
#if defined(BSD) || defined(REDSTORM)
if (IFTODT(de->d_type) == DT_WHT)
return NULL;
#endif
- if (
#ifdef _DIRENT_HAVE_D_NAMLEN
- ld->name->len == de->d_namlen &&
+ len = de->d_namlen;
+#else
+ {
+ const char *cp, *end;
+
+ cp = de->d_name;
+ end = (const char *)de + reclen;
+ while (cp < end && *cp != '\0')
+ cp++;
+ len = cp - de->d_name;
+ }
#endif
+ if (ld->name->len == len &&
strncmp(de->d_name, ld->name->name, ld->name->len) == 0)
return de;
ld->de = de;
struct copy_info {
void *data;
size_t nbytes;
+ unsigned count;
};
/*
* Eumeration callback.
*
* Note:
- * On those systems supporting white-out entries, they are returned. On
- * systems without, they are not.
+ * Whiteout entries are never returned.
*/
static void *
incore_directory_enumerate(struct intnl_dirent *de,
size_t reclen,
struct copy_info *cinfo) {
+#ifdef DT_WHT
+ if (de->d_type == DT_WHT) {
+ /*
+ * Keep going but skip the copy.
+ */
+ return NULL;
+ }
+#endif
+ cinfo->count++;
if (reclen > cinfo->nbytes)
return de;
(void *)memcpy(cinfo->data, de, reclen);
}
static ssize_t
-_sysio_incore_dirop_getdirentries(struct inode *ino,
- char *buf,
- size_t nbytes,
- _SYSIO_OFF_T *basep)
+_sysio_incore_dirop_filldirentries(struct inode *ino,
+ _SYSIO_OFF_T *posp,
+ char *buf,
+ size_t nbytes)
{
struct incore_inode *icino = I2IC(ino);
off_t off;
struct intnl_dirent *de;
struct copy_info copy_info;
- if (*basep > icino->ici_st.st_size)
+ if (*posp >= icino->ici_st.st_size)
return 0;
de =
incore_directory_probe(icino->ici_data,
icino->ici_st.st_size,
- *basep,
+ *posp,
(probe_ty )incore_directory_position,
NULL,
- (char *)icino->ici_data + *basep);
+ (char *)icino->ici_data + *posp);
if (!de) {
/*
* Past EOF.
*/
- *basep = 0;
return 0;
}
copy_info.data = buf;
copy_info.nbytes = nbytes;
+ copy_info.count = 0;
off = (char *)de - (char *)icino->ici_data;
de =
incore_directory_probe(de,
(probe_ty )incore_directory_enumerate,
NULL,
©_info);
- nbytes -= copy_info.nbytes;
icino->ici_st.st_atime = time(NULL);
+ if (nbytes == copy_info.nbytes && copy_info.count)
+ return -EINVAL;
+ nbytes -= copy_info.nbytes;
+#if 0
if (!nbytes)
return -EOVERFLOW;
- *basep = nbytes;
+#endif
+ *posp += nbytes;
return (ssize_t )nbytes;
}