[PATCH] dirent->d_type support

Jamie Lokier (lkd@tantalophile.demon.co.uk)
Wed, 17 Nov 1999 22:56:56 +0100


Stephen C. Tweedie wrote:
> > I have a dirent->d_type patch which I really should get on with
> > submitting... Is anyone actually interested in it?
>
> Definitely --- ext2 is already maintaining the information, we might as
> well use it.

Then enjoy.....

Here is the d_type patch for Linux 2.3.26. Now that it's possible to
turn on the "filetype" capability of ext2, this is useful. This is the
first release of the complete patch.

It adds BSD/Glibc d_type capability to the directory-reading system call
"getdents". Every filesystem is modifed to return a file type along
with each directory entry, when that can be done without reading any
more of the storage medium. This allows operations like "find /" and
"find . -type f" to run faster because they can tell which entries are
directories and which are not.

I rejected adding a new system call. Instead, I extended getdents() to
return data in a backward compatible way. The d_type information as
placed at the end of each dirent record, and can be recognised
unambiguously.

- Almost every application will get the d_type information via Glibc,
which already has support in the API. As the support can be added
to Glibc easily and efficiently, no new call is required.

- There is no problem modifying getdents() in such a way that older
applications and libraries are fine.

- It is simpler to modify getdents() than to add a new call
using a new data layout.

- It is simpler for the app/library to call getdents() and see if it
has returned the additional data. The alternative would require
dealing with multiple data formats, for compatibility with older
kernels.

- This method leaves room for more information to be returned in
future, if someone finds a need for that.

- This method leads to the smallest kernel.

Every filesystem in the main distribution (2.3.26) has been updated.
(NB: the NFS updates may not patch cleanly on 2.3.28):

ext2 [FULL SUPPORT, TESTED]
isofs/norock [FULL SUPPORT, TESTED]
isofs/rock [FULL SUPPORT, TESTED]
msdos [FULL SUPPORT, TESTED]
vfat [FULL SUPPORT, TESTED]
procfs [FULL SUPPORT, TESTED] # Except openpromfs on Sparcs.
devpts [FULL SUPPORT, TESTED]
coda [FULL SUPPORT, not tested]
ncpfs [FULL SUPPORT, not tested]
qnx4 [FULL SUPPORT, not tested]
romfs [FULL SUPPORT, not tested]
ufs [FULL SUPPORT, not tested]
umsdos [FULL SUPPORT, tried to test] # umsdos was broken already
adfs [UPDATED, not tested] # Only . and .. possible.
affs [UPDATED, not tested] # More support may be possible.
autofs [UPDATED, TESTED] # More support may be possible.
bfs [UPDATED, not tested] # No support possible.
efs [UPDATED, not tested] # No support possible.
hfs [LIMITED, not tested] # More support may be possible.
hpfs [DIR&REG ONLY, not tested] # More support may be possible.
minix [UPDATED, not tested] # No support possible.
nfs [UPDATED, not tested] # No support possible.
nfsd [UPDATED, not tested] # Updated for readdir change.
ntfs [UPDATED, not tested] # Code too scary to add support.
smbfs [UPDATED, not tested] # More support may be possible.
sysv [UPDATED, not tested] # No support possible.
udf [DIR ONLY, not tested] # More support may be possible.

Let me know what you think.

Enjoy,
-- Jamie

ps. There is available a different, much smaller patch which can also
optimise "find /" type operations (but not "find . -type f"). It
optimises O_DIRECTORY|O_NOFOLLOW opens. The principle of that patch is
not entirely obsoleted by this one, though for the supported filesystems
it is obsoleted. Anyway, that patch might be interesting for 2.2.x.

---------- start of patch ----------

diff -u linux-2.3/fs/adfs/dir.c.d_type linux-2.3/fs/adfs/dir.c
--- linux-2.3/fs/adfs/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/adfs/dir.c Sun Nov 7 16:19:44 1999
@@ -9,6 +9,7 @@
#include <linux/adfs_fs.h>
#include <linux/sched.h>
#include <linux/stat.h>
+#include <linux/dirent.h>

static ssize_t adfs_dirread (struct file *filp, char *buf,
size_t siz, loff_t *ppos)
@@ -322,12 +323,13 @@

if (filp->f_pos < 2) {
if (filp->f_pos < 1) {
- if (filldir (dirent, ".", 1, 0, inode->i_ino) < 0)
+ if (filldir (dirent, DT_DIR, ".", 1,
+ 0, inode->i_ino) < 0)
return 0;
filp->f_pos ++;
}
- if (filldir (dirent, "..", 2, 1,
- adfs_inode_generate (parent_object_id, 0)) < 0)
+ if (filldir (dirent, DT_DIR, "..", 2,
+ 1, adfs_inode_generate (parent_object_id, 0)) < 0)
return 0;
filp->f_pos ++;
}
@@ -339,7 +341,8 @@
if (!adfs_dir_get (sb, bh, buffers, pos, dir_object_id, &ide))
break;

- if (filldir (dirent, ide.name, ide.name_len, filp->f_pos, ide.inode_no) < 0)
+ if (filldir (dirent, DT_UNKNOWN, ide.name, ide.name_len,
+ filp->f_pos, ide.inode_no) < 0)
return 0;
filp->f_pos ++;
pos += 26;
diff -u linux-2.3/fs/affs/dir.c.d_type linux-2.3/fs/affs/dir.c
--- linux-2.3/fs/affs/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/affs/dir.c Sun Nov 7 16:19:44 1999
@@ -23,6 +23,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/amigaffs.h>
+#include <linux/dirent.h>

static int affs_readdir(struct file *, void *, filldir_t);
static ssize_t affs_dir_read(struct file *, char *, size_t, loff_t *);
@@ -98,14 +99,14 @@

if (filp->f_pos == 0) {
filp->private_data = (void *)0;
- if (filldir(dirent,".",1,filp->f_pos,inode->i_ino) < 0) {
+ if (filldir(dirent,DT_DIR,".",1,filp->f_pos,inode->i_ino) < 0) {
return 0;
}
++filp->f_pos;
stored++;
}
if (filp->f_pos == 1) {
- if (filldir(dirent,"..",2,filp->f_pos,affs_parent_ino(inode)) < 0) {
+ if (filldir(dirent,DT_DIR,"..",2,filp->f_pos,affs_parent_ino(inode)) < 0) {
return stored;
}
filp->f_pos = 2;
@@ -161,7 +162,7 @@
pr_debug("AFFS: readdir(): filldir(\"%.*s\",ino=%lu), i=%d\n",
namelen,name,ino,i);
filp->private_data = (void *)ino;
- if (filldir(dirent,name,namelen,filp->f_pos,ino) < 0)
+ if (filldir(dirent,DT_UNKNOWN,name,namelen,filp->f_pos,ino) < 0)
goto readdir_done;
filp->private_data = (void *)i;
affs_brelse(fh_bh);
diff -u linux-2.3/fs/autofs/dir.c.d_type linux-2.3/fs/autofs/dir.c
--- linux-2.3/fs/autofs/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/autofs/dir.c Sun Nov 7 16:19:44 1999
@@ -11,6 +11,7 @@
* ------------------------------------------------------------------------- */

#include "autofs_i.h"
+#include <linux/dirent.h>

static int autofs_dir_readdir(struct file *filp,
void *dirent, filldir_t filldir)
@@ -20,12 +21,12 @@
switch((unsigned long) filp->f_pos)
{
case 0:
- if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, ".", 1, 0, inode->i_ino) < 0)
return 0;
filp->f_pos++;
/* fall through */
case 1:
- if (filldir(dirent, "..", 2, 1, AUTOFS_ROOT_INO) < 0)
+ if (filldir(dirent, DT_DIR, "..", 2, 1, AUTOFS_ROOT_INO) < 0)
return 0;
filp->f_pos++;
/* fall through */
diff -u linux-2.3/fs/autofs/root.c.d_type linux-2.3/fs/autofs/root.c
--- linux-2.3/fs/autofs/root.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/autofs/root.c Sun Nov 7 16:19:44 1999
@@ -14,6 +14,7 @@
#include <linux/stat.h>
#include <linux/param.h>
#include "autofs_i.h"
+#include <linux/dirent.h>

static int autofs_root_readdir(struct file *,void *,filldir_t);
static struct dentry *autofs_root_lookup(struct inode *,struct dentry *);
@@ -79,19 +80,19 @@
switch(nr)
{
case 0:
- if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, ".", 1, nr, inode->i_ino) < 0)
return 0;
filp->f_pos = ++nr;
/* fall through */
case 1:
- if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, "..", 2, nr, inode->i_ino) < 0)
return 0;
filp->f_pos = ++nr;
/* fall through */
default:
while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent) ) {
if ( !ent->dentry || ent->dentry->d_mounts != ent->dentry ) {
- if (filldir(dirent,ent->name,ent->len,onr,ent->ino) < 0)
+ if (filldir(dirent,DT_UNKNOWN,ent->name,ent->len,onr,ent->ino) < 0)
return 0;
filp->f_pos = nr;
}
diff -u linux-2.3/fs/bfs/dir.c.d_type linux-2.3/fs/bfs/dir.c
--- linux-2.3/fs/bfs/dir.c.d_type Sun Nov 7 16:17:03 1999
+++ linux-2.3/fs/bfs/dir.c Sun Nov 7 16:30:35 1999
@@ -8,6 +8,7 @@
#include <linux/string.h>
#include <linux/bfs_fs.h>
#include <linux/locks.h>
+#include <linux/dirent.h>

#include "bfs_defs.h"

@@ -61,7 +62,7 @@
de = (struct bfs_dirent *)(bh->b_data + offset);
if (de->ino) {
int size = strnlen(de->name, BFS_NAMELEN);
- if (filldir(dirent, de->name, size, f->f_pos, de->ino) < 0) {
+ if (filldir(dirent, DT_UNKNOWN, de->name, size, f->f_pos, de->ino) < 0) {
brelse(bh);
return 0;
}
diff -u linux-2.3/fs/coda/dir.c.d_type linux-2.3/fs/coda/dir.c
--- linux-2.3/fs/coda/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/coda/dir.c Sun Nov 7 16:19:44 1999
@@ -18,6 +18,7 @@
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>
+#include <linux/dirent.h>

#include <linux/coda.h>
#include <linux/coda_linux.h>
@@ -737,12 +738,14 @@

/* if we don't have a null entry, copy it */
if ( vdirent->d_fileno && vdirent->d_reclen ) {
- int namlen = vdirent->d_namlen;
- off_t offs = filp->f_pos;
- ino_t ino = vdirent->d_fileno;
- char *name = vdirent->d_name;
+ int namlen = vdirent->d_namlen;
+ off_t offs = filp->f_pos;
+ ino_t ino = vdirent->d_fileno;
+ char *name = vdirent->d_name;
+ /* CDT_* types are the same as DT_* types. */
+ unsigned char type = vdirent->d_type;

- errfill = filldir(getdent, name, namlen,
+ errfill = filldir(getdent, type, name, namlen,
offs, ino);
CDEBUG(D_FILE, "entry %d: ino %ld, namlen %d, reclen %d, type %d, pos %d, string_offs %d, name %*s, offset %d, result: %d, errfill: %d.\n", i,vdirent->d_fileno, vdirent->d_namlen, vdirent->d_reclen, vdirent->d_type, pos, string_offset, vdirent->d_namlen, vdirent->d_name, (u_int) offs, result, errfill);
/* errfill means no space for filling in this round */
diff -u linux-2.3/fs/devpts/root.c.d_type linux-2.3/fs/devpts/root.c
--- linux-2.3/fs/devpts/root.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/devpts/root.c Sun Nov 7 16:19:44 1999
@@ -14,6 +14,7 @@
#include <linux/stat.h>
#include <linux/param.h>
#include <linux/string.h>
+#include <linux/dirent.h>
#include "devpts_i.h"

static int devpts_root_readdir(struct file *,void *,filldir_t);
@@ -86,12 +87,12 @@
switch(nr)
{
case 0:
- if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, ".", 1, nr, inode->i_ino) < 0)
return 0;
filp->f_pos = ++nr;
/* fall through */
case 1:
- if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, "..", 2, nr, inode->i_ino) < 0)
return 0;
filp->f_pos = ++nr;
/* fall through */
@@ -100,7 +101,7 @@
int ptynr = nr - 2;
if ( sbi->inodes[ptynr] ) {
genptsname(numbuf, ptynr);
- if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr) < 0 )
+ if ( filldir(dirent, DT_CHR, numbuf, strlen(numbuf), nr, nr) < 0 )
return 0;
}
filp->f_pos = ++nr;
diff -u linux-2.3/fs/efs/dir.c.d_type linux-2.3/fs/efs/dir.c
--- linux-2.3/fs/efs/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/efs/dir.c Sun Nov 7 16:19:44 1999
@@ -5,6 +5,7 @@
*/

#include <linux/efs_fs.h>
+#include <linux/dirent.h>

static int efs_readdir(struct file *, void *, filldir_t);

@@ -111,7 +112,7 @@
filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;

/* copy filename and data in dirslot */
- filldir(dirent, nameptr, namelen, filp->f_pos, inodenum);
+ filldir(dirent, DT_UNKNOWN, nameptr, namelen, filp->f_pos, inodenum);

/* sanity check */
if (nameptr - (char *) dirblock + namelen > EFS_DIRBSIZE) {
diff -u linux-2.3/fs/ext2/dir.c.d_type linux-2.3/fs/ext2/dir.c
--- linux-2.3/fs/ext2/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/ext2/dir.c Sun Nov 7 16:19:44 1999
@@ -20,6 +20,7 @@

#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/dirent.h>



@@ -102,6 +103,17 @@
return error_msg == NULL ? 1 : 0;
}

+static const char ext2_file_types [EXT2_FT_MAX] = {
+ DT_UNKNOWN, /* EXT2_FT_UNKNOWN */
+ DT_REG, /* EXT2_FT_REG_FILE */
+ DT_DIR, /* EXT2_FT_DIR */
+ DT_CHR, /* EXT2_FT_CHRDEV */
+ DT_BLK, /* EXT2_FT_BLKDEV */
+ DT_FIFO, /* EXT2_FT_FIFO */
+ DT_SOCK, /* EXT2_FT_SOCK */
+ DT_LNK, /* EXT2_FT_SYMLINK */
+};
+
static int ext2_readdir(struct file * filp,
void * dirent, filldir_t filldir)
{
@@ -197,9 +209,13 @@
* during the copy operation.
*/
unsigned long version = inode->i_version;
+ unsigned char type = DT_UNKNOWN;
+
+ if (de->file_type < EXT2_FT_MAX)
+ type = ext2_file_types [de->file_type];

- error = filldir(dirent, de->name,
- de->name_len,
+ error = filldir(dirent, type,
+ de->name, de->name_len,
filp->f_pos, le32_to_cpu(de->inode));
if (error)
break;
diff -u linux-2.3/fs/ext2/namei.c.d_type linux-2.3/fs/ext2/namei.c
--- linux-2.3/fs/ext2/namei.c.d_type Wed Nov 17 20:41:42 1999
+++ linux-2.3/fs/ext2/namei.c Wed Nov 17 20:40:35 1999
@@ -356,18 +356,20 @@
umode_t mode) {
if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
return;
- if (S_ISCHR(mode))
+ if (S_ISREG(mode))
+ de->file_type = EXT2_FT_REG_FILE;
+ else if (S_ISDIR(mode))
+ de->file_type = EXT2_FT_DIR;
+ else if (S_ISLNK(mode))
+ de->file_type = EXT2_FT_SYMLINK;
+ else if (S_ISSOCK(mode))
+ de->file_type = EXT2_FT_SOCK;
+ else if (S_ISFIFO(mode))
+ de->file_type = EXT2_FT_FIFO;
+ else if (S_ISCHR(mode))
de->file_type = EXT2_FT_CHRDEV;
else if (S_ISBLK(mode))
de->file_type = EXT2_FT_BLKDEV;
- else if (S_ISFIFO(mode))
- de->file_type = EXT2_FT_FIFO;
- else if (S_ISLNK(mode))
- de->file_type = EXT2_FT_SYMLINK;
- else if (S_ISREG(mode))
- de->file_type = EXT2_FT_REG_FILE;
- else if (S_ISDIR(mode))
- de->file_type = EXT2_FT_DIR;
}

/*
diff -u linux-2.3/fs/fat/dir.c.d_type linux-2.3/fs/fat/dir.c
--- linux-2.3/fs/fat/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/fat/dir.c Sun Nov 7 16:19:44 1999
@@ -297,12 +297,13 @@
int dotoffset = 0;
unsigned long *furrfu = &lpos;
unsigned long dummy;
+ unsigned char type;

cpos = filp->f_pos;
/* Fake . and .. for the root directory. */
if (inode->i_ino == MSDOS_ROOT_INO) {
while (cpos < 2) {
- if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO) < 0)
+ if (filldir(dirent, DT_DIR, "..", cpos+1, cpos, MSDOS_ROOT_INO) < 0)
return 0;
cpos++;
filp->f_pos++;
@@ -427,6 +428,10 @@

i = last + dotoffset;

+ type = DT_REG;
+ if ((de->attr & ATTR_DIR) && !IS_FREE(de->name))
+ type = DT_DIR;
+
lpos = cpos - (long_slots+1)*sizeof(struct msdos_dir_entry);
if (!memcmp(de->name,MSDOS_DOT,11))
inum = inode->i_ino;
@@ -445,7 +450,7 @@
if (!long_slots||shortnames) {
if (both)
bufname[i] = '\0';
- if (filldir(dirent, bufname, i, *furrfu, inum) < 0)
+ if (filldir(dirent, type, bufname, i, *furrfu, inum) < 0)
goto FillFailed;
} else {
char longname[275];
@@ -456,7 +461,8 @@
memcpy(&longname[long_len+1], bufname, i);
long_len += i;
}
- if (filldir(dirent, longname, long_len, *furrfu, inum) < 0)
+ if (filldir(dirent, type, longname, long_len,
+ *furrfu, inum) < 0)
goto FillFailed;
}

@@ -483,13 +489,14 @@

static int vfat_ioctl_fill(
void * buf,
+ unsigned char type,
const char * name,
int name_len,
off_t offset,
ino_t ino)
{
- struct dirent *d1 = (struct dirent *)buf;
- struct dirent *d2 = d1 + 1;
+ struct getdents_dirent *d1 = (struct getdents_dirent *)buf;
+ struct getdents_dirent *d2 = d1 + 1;
int len, slen;
int dotdir;

@@ -541,8 +548,9 @@
*/
switch (cmd) {
case VFAT_IOCTL_READDIR_BOTH: {
- struct dirent *d1 = (struct dirent *)arg;
- err = verify_area(VERIFY_WRITE, d1, sizeof(struct dirent[2]));
+ struct getdents_dirent *d1 = (struct getdents_dirent *)arg;
+ err = verify_area(VERIFY_WRITE, d1,
+ sizeof(struct getdents_dirent[2]));
if (err)
return err;
put_user(0, &d1->d_reclen);
@@ -550,9 +558,10 @@
vfat_ioctl_fill, 0, 1);
}
case VFAT_IOCTL_READDIR_SHORT: {
- struct dirent *d1 = (struct dirent *)arg;
+ struct getdents_dirent *d1 = (struct getdents_dirent *) arg;
put_user(0, &d1->d_reclen);
- err = verify_area(VERIFY_WRITE, d1, sizeof(struct dirent[2]));
+ err = verify_area(VERIFY_WRITE, d1,
+ sizeof(struct getdents_dirent[2]));
if (err)
return err;
return fat_readdirx(inode,filp,(void *)arg,
diff -u linux-2.3/fs/hfs/dir_cap.c.d_type linux-2.3/fs/hfs/dir_cap.c
--- linux-2.3/fs/hfs/dir_cap.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/hfs/dir_cap.c Sun Nov 7 16:19:44 1999
@@ -24,6 +24,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
+#include <linux/dirent.h>

/*================ Forward declarations ================*/

@@ -249,7 +250,7 @@

if (filp->f_pos == 0) {
/* Entry 0 is for "." */
- if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
+ if (filldir(dirent, DT_DIR, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
return 0;
}
filp->f_pos = 1;
@@ -265,7 +266,7 @@
cnid = entry->cnid;
}

- if (filldir(dirent, DOT_DOT->Name,
+ if (filldir(dirent, DT_DIR, DOT_DOT->Name,
DOT_DOT_LEN, 1, ntohl(cnid))) {
return 0;
}
@@ -292,7 +293,7 @@
ino = ntohl(cnid) | HFS_I(dir)->file_type;
len = hfs_namein(dir, tmp_name,
&((struct hfs_cat_key *)brec.key)->CName);
- if (filldir(dirent, tmp_name, len,
+ if (filldir(dirent, DT_UNKNOWN, tmp_name, len,
filp->f_pos, ino)) {
hfs_cat_close(entry, &brec);
return 0;
@@ -307,7 +308,7 @@
if ((entry->cnid == htonl(HFS_ROOT_CNID)) &&
(type == HFS_CAP_NDIR)) {
/* In root dir last-2 entry is for ".rootinfo" */
- if (filldir(dirent, DOT_ROOTINFO->Name,
+ if (filldir(dirent, DT_UNKNOWN, DOT_ROOTINFO->Name,
DOT_ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_FNDR)) {
return 0;
@@ -319,7 +320,7 @@
if (filp->f_pos == (dir->i_size - 2)) {
if (type == HFS_CAP_NDIR) {
/* In normal dirs last-1 entry is for ".finderinfo" */
- if (filldir(dirent, DOT_FINDERINFO->Name,
+ if (filldir(dirent, DT_UNKNOWN, DOT_FINDERINFO->Name,
DOT_FINDERINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_FDIR)) {
return 0;
@@ -331,7 +332,7 @@
if (filp->f_pos == (dir->i_size - 1)) {
if (type == HFS_CAP_NDIR) {
/* In normal dirs last entry is for ".resource" */
- if (filldir(dirent, DOT_RESOURCE->Name,
+ if (filldir(dirent, DT_UNKNOWN, DOT_RESOURCE->Name,
DOT_RESOURCE_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_RDIR)) {
return 0;
diff -u linux-2.3/fs/hfs/dir_dbl.c.d_type linux-2.3/fs/hfs/dir_dbl.c
--- linux-2.3/fs/hfs/dir_dbl.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/hfs/dir_dbl.c Sun Nov 7 16:19:44 1999
@@ -20,6 +20,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
+#include <linux/dirent.h>

/*================ Forward declarations ================*/

@@ -207,7 +208,7 @@

if (filp->f_pos == 0) {
/* Entry 0 is for "." */
- if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
+ if (filldir(dirent, DT_DIR, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
return 0;
}
filp->f_pos = 1;
@@ -215,7 +216,7 @@

if (filp->f_pos == 1) {
/* Entry 1 is for ".." */
- if (filldir(dirent, DOT_DOT->Name, DOT_DOT_LEN, 1,
+ if (filldir(dirent, DT_DIR, DOT_DOT->Name, DOT_DOT_LEN, 1,
hfs_get_hl(entry->key.ParID))) {
return 0;
}
@@ -253,7 +254,7 @@
&((struct hfs_cat_key *)brec.key)->CName);
}

- if (filldir(dirent, tmp_name, len, filp->f_pos, ino)) {
+ if (filldir(dirent, DT_UNKNOWN, tmp_name, len, filp->f_pos, ino)) {
hfs_cat_close(entry, &brec);
return 0;
}
@@ -265,7 +266,7 @@
if (filp->f_pos == (dir->i_size - 1)) {
if (entry->cnid == htonl(HFS_ROOT_CNID)) {
/* In root dir last entry is for "%RootInfo" */
- if (filldir(dirent, PCNT_ROOTINFO->Name,
+ if (filldir(dirent, DT_UNKNOWN, PCNT_ROOTINFO->Name,
PCNT_ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_DBL_HDR)) {
return 0;
diff -u linux-2.3/fs/hfs/dir_nat.c.d_type linux-2.3/fs/hfs/dir_nat.c
--- linux-2.3/fs/hfs/dir_nat.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/hfs/dir_nat.c Sun Nov 7 16:19:44 1999
@@ -26,6 +26,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
+#include <linux/dirent.h>

/*================ Forward declarations ================*/

@@ -231,7 +232,8 @@

if (filp->f_pos == 0) {
/* Entry 0 is for "." */
- if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
+ if (filldir(dirent, DT_DIR, DOT->Name, DOT_LEN,
+ 0, dir->i_ino)) {
return 0;
}
filp->f_pos = 1;
@@ -247,8 +249,8 @@
cnid = entry->cnid;
}

- if (filldir(dirent, DOT_DOT->Name,
- DOT_DOT_LEN, 1, ntohl(cnid))) {
+ if (filldir(dirent, DT_DIR, DOT_DOT->Name, DOT_DOT_LEN,
+ 1, ntohl(cnid))) {
return 0;
}
filp->f_pos = 2;
@@ -274,7 +276,7 @@
ino = ntohl(cnid) | HFS_I(dir)->file_type;
len = hfs_namein(dir, tmp_name,
&((struct hfs_cat_key *)brec.key)->CName);
- if (filldir(dirent, tmp_name, len,
+ if (filldir(dirent, DT_UNKNOWN, tmp_name, len,
filp->f_pos, ino)) {
hfs_cat_close(entry, &brec);
return 0;
@@ -288,14 +290,14 @@
if (filp->f_pos == (dir->i_size - 2)) {
if (type == HFS_NAT_NDIR) {
/* In normal dirs entry 2 is for ".AppleDouble" */
- if (filldir(dirent, DOT_APPLEDOUBLE->Name,
+ if (filldir(dirent, DT_DIR, DOT_APPLEDOUBLE->Name,
DOT_APPLEDOUBLE_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDIR)) {
return 0;
}
} else if (type == HFS_NAT_HDIR) {
/* In .AppleDouble entry 2 is for ".Parent" */
- if (filldir(dirent, DOT_PARENT->Name,
+ if (filldir(dirent, DT_UNKNOWN, DOT_PARENT->Name,
DOT_PARENT_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDR)) {
return 0;
@@ -308,7 +310,7 @@
/* handle ROOT/.AppleDouble/RootInfo as the last entry. */
if ((entry->cnid == htonl(HFS_ROOT_CNID)) &&
(type == HFS_NAT_HDIR)) {
- if (filldir(dirent, ROOTINFO->Name,
+ if (filldir(dirent, DT_UNKNOWN, ROOTINFO->Name,
ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDR)) {
return 0;
diff -u linux-2.3/fs/hpfs/dir.c.d_type linux-2.3/fs/hpfs/dir.c
--- linux-2.3/fs/hpfs/dir.c.d_type Sun Nov 7 16:16:36 1999
+++ linux-2.3/fs/hpfs/dir.c Sun Nov 7 16:19:44 1999
@@ -7,6 +7,7 @@
*/

#include "hpfs_fn.h"
+#include <linux/dirent.h>

int hpfs_dir_read(struct file *filp, char *name, size_t len, loff_t *loff)
{
@@ -109,14 +110,14 @@
return 0;
}
if (filp->f_pos == 0) {
- if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino) < 0) {
+ if (filldir(dirent, DT_DIR, ".", 1, filp->f_pos, inode->i_ino) < 0) {
hpfs_unlock_inode(inode);
return 0;
}
filp->f_pos = 11;
}
if (filp->f_pos == 11) {
- if (filldir(dirent, "..", 2, filp->f_pos, inode->i_hpfs_parent_dir) < 0) {
+ if (filldir(dirent, DT_DIR, "..", 2, filp->f_pos, inode->i_hpfs_parent_dir) < 0) {
hpfs_unlock_inode(inode);
return 0;
}
@@ -145,7 +146,10 @@
goto again;
}
tempname = hpfs_translate_name(inode->i_sb, de->name, de->namelen, lc, de->not_8x3);
- if (filldir(dirent, tempname, de->namelen, old_pos, de->fnode) < 0) {
+ if (filldir(dirent, (de->directory ? DT_DIR
+ : !de->has_ea ? DT_REG
+ : DT_UNKNOWN),
+ tempname, de->namelen, old_pos, de->fnode) < 0) {
filp->f_pos = old_pos;
if (tempname != (char *)de->name) kfree(tempname);
hpfs_brelse4(&qbh);
diff -u linux-2.3/fs/isofs/dir.c.d_type linux-2.3/fs/isofs/dir.c
--- linux-2.3/fs/isofs/dir.c.d_type Sun Nov 7 16:16:37 1999
+++ linux-2.3/fs/isofs/dir.c Wed Nov 17 20:23:12 1999
@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/locks.h>
#include <linux/config.h>
+#include <linux/dirent.h>

#include <asm/uaccess.h>

@@ -139,6 +140,7 @@
int first_de = 1;
char *p = NULL; /* Quiet GCC */
struct iso_directory_record *de;
+ unsigned char type;

if (filp->f_pos >= inode->i_size)
return 0;
@@ -218,7 +220,7 @@

/* Handle the case of the '.' directory */
if (de->name_len[0] == 1 && de->name[0] == 0) {
- if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, ".", 1, filp->f_pos, inode->i_ino) < 0)
break;
filp->f_pos += de_len;
continue;
@@ -229,7 +231,7 @@
/* Handle the case of the '..' directory */
if (de->name_len[0] == 1 && de->name[0] == 1) {
inode_number = filp->f_dentry->d_parent->d_inode->i_ino;
- if (filldir(dirent, "..", 2, filp->f_pos, inode_number) < 0)
+ if (filldir(dirent, DT_DIR, "..", 2, filp->f_pos, inode_number) < 0)
break;
filp->f_pos += de_len;
continue;
@@ -246,8 +248,9 @@
}

map = 1;
+ type = (de->flags[-high_sierra] & 2) ? DT_DIR : DT_REG;
if (inode->i_sb->u.isofs_sb.s_rock) {
- len = get_rock_ridge_filename(de, tmpname, inode);
+ len = get_rock_ridge_filename(de, tmpname, inode, &type);
if (len != 0) {
p = tmpname;
map = 0;
@@ -274,7 +277,7 @@
}
}
if (len > 0) {
- if (filldir(dirent, p, len, filp->f_pos, inode_number) < 0)
+ if (filldir(dirent, type, p, len, filp->f_pos, inode_number) < 0)
break;
}
filp->f_pos += de_len;
diff -u linux-2.3/fs/isofs/namei.c.d_type linux-2.3/fs/isofs/namei.c
--- linux-2.3/fs/isofs/namei.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/isofs/namei.c Sun Nov 7 16:19:44 1999
@@ -169,7 +169,7 @@
}
}
if (dir->i_sb->u.isofs_sb.s_rock &&
- ((i = get_rock_ridge_filename(de, page, dir)))) {
+ ((i = get_rock_ridge_filename(de, page, dir, 0)))) {
dlen = i;
dpnt = page;
#ifdef CONFIG_JOLIET
diff -u linux-2.3/fs/isofs/rock.c.d_type linux-2.3/fs/isofs/rock.c
--- linux-2.3/fs/isofs/rock.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/isofs/rock.c Wed Nov 17 20:26:58 1999
@@ -12,15 +12,16 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/malloc.h>
+#include <linux/dirent.h>

#include "rock.h"

/* These functions are designed to read the system areas of a directory record
* and extract relevant information. There are different functions provided
* depending upon what information we need at the time. One function fills
- * out an inode structure, a second one extracts a filename, a third one
- * returns a symbolic link name, and a fourth one returns the extent number
- * for the file. */
+ * out an inode structure, a second one extracts a filename and d_type value,
+ * a third one returns a symbolic link name, and a fourth one returns the
+ * extent number for the file. */

#define SIG(A,B) ((A << 8) | B)

@@ -151,7 +152,8 @@
}

int get_rock_ridge_filename(struct iso_directory_record * de,
- char * retname, struct inode * inode)
+ char * retname, struct inode * inode,
+ unsigned char * rettype)
{
int len;
unsigned char * chr;
@@ -214,6 +216,34 @@
#endif
if (buffer) kfree(buffer);
return -1;
+ case SIG('C','L'):
+#ifdef DEBUG
+ printk("RR: CL (%x)\n",inode->i_ino);
+#endif
+ /* Mode is set from relocated entry. Don't look it up as that misses
+ the point of the DT_* optimisation. */
+ if (rettype)
+ *rettype = DT_UNKNOWN;
+ break;
+ case SIG('P','X'):
+ /*
+ * Merge mode with previous type byte. It was either DT_DIR, DT_REG,
+ * or set by a previous PX record (should never repeat but hey...).
+ *
+ * Some RR directories have 0 (unknown) for the type here and
+ * are not flagged as directories in the base record. If you
+ * mount with norock, they look like empty files. But with
+ * RR, they are directories. This code sets the type to
+ * DT_UNKNOWN in that case (it would be DT_REG otherwise).
+ */
+ if (rettype) {
+ mode_t mode = isonum_733(rr->u.PX.mode);
+ if (!S_ISDIR(mode) && *rettype == DT_REG)
+ *rettype = IFTODT(mode);
+ else if (*rettype != IFTODT(mode))
+ *rettype = DT_UNKNOWN;
+ }
+ break;
default:
break;
}
diff -u linux-2.3/fs/minix/dir.c.d_type linux-2.3/fs/minix/dir.c
--- linux-2.3/fs/minix/dir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/minix/dir.c Sun Nov 7 16:19:44 1999
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/minix_fs.h>
#include <linux/stat.h>
+#include <linux/dirent.h>

#include <asm/uaccess.h>

@@ -85,7 +86,7 @@
de = (struct minix_dir_entry *) (offset + bh->b_data);
if (de->inode) {
int size = strnlen(de->name, info->s_namelen);
- if (filldir(dirent, de->name, size, filp->f_pos, de->inode) < 0) {
+ if (filldir(dirent, DT_UNKNOWN, de->name, size, filp->f_pos, de->inode) < 0) {
brelse(bh);
return 0;
}
diff -u linux-2.3/fs/ncpfs/dir.c.d_type linux-2.3/fs/ncpfs/dir.c
--- linux-2.3/fs/ncpfs/dir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/ncpfs/dir.c Sun Nov 7 16:19:44 1999
@@ -21,6 +21,7 @@
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <linux/locks.h>
+#include <linux/dirent.h>

#include <linux/ncp_fs.h>

@@ -508,12 +509,12 @@

result = 0;
if (filp->f_pos == 0) {
- if (filldir(dirent, ".", 1, 0, inode->i_ino))
+ if (filldir(dirent, DT_DIR, ".", 1, 0, inode->i_ino))
goto out;
filp->f_pos = 1;
}
if (filp->f_pos == 1) {
- if (filldir(dirent, "..", 2, 1,
+ if (filldir(dirent, DT_DIR, "..", 2, 1,
dentry->d_parent->d_inode->i_ino))
goto out;
filp->f_pos = 2;
@@ -564,9 +565,9 @@
dentry, filp->f_pos);
if (!dent)
goto invalid_cache;
- res = filldir(dirent, dent->d_name.name,
- dent->d_name.len, filp->f_pos,
- dent->d_inode->i_ino);
+ res = filldir(dirent, IFTODT (dent->d_inode->i_mode),
+ dent->d_name.name, dent->d_name.len,
+ filp->f_pos, dent->d_inode->i_ino);
dput(dent);
if (res)
goto finished;
@@ -639,6 +640,7 @@
struct ncp_cache_control ctl = *ctrl;
struct qstr qname;
ino_t ino = 0;
+ unsigned char type = DT_UNKNOWN;
int valid = 0;

vol2io(server, entry->i.entryName,
@@ -675,6 +677,7 @@

if (newdent->d_inode) {
ino = newdent->d_inode->i_ino;
+ type = IFTODT (newdent->d_inode->i_mode);
newdent->d_fsdata = (void *) ctl.fpos;
ncp_new_dentry(newdent);
}
@@ -706,7 +709,7 @@
ino = find_inode_number(dentry, &qname);
if (!ino)
ino = iunique(inode->i_sb, 2);
- ctl.filled = filldir(dirent, entry->i.entryName,
+ ctl.filled = filldir(dirent, type, entry->i.entryName,
entry->i.nameLen, filp->f_pos, ino);
if (!ctl.filled)
filp->f_pos += 1;
diff -u linux-2.3/fs/nfs/dir.c.d_type linux-2.3/fs/nfs/dir.c
--- linux-2.3/fs/nfs/dir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/nfs/dir.c Sun Nov 7 16:19:44 1999
@@ -30,6 +30,7 @@
#include <linux/nfs_fs.h>
#include <linux/nfs.h>
#include <linux/pagemap.h>
+#include <linux/dirent.h>

#include <asm/segment.h> /* for fs functions */

@@ -399,7 +400,7 @@
continue;

cookie = this_cookie;
- if (filldir(dirent, name, len, cookie, fileid) < 0)
+ if (filldir(dirent, DT_UNKNOWN, name, len, cookie, fileid) < 0)
break;
}

diff -u linux-2.3/fs/nfsd/nfs3xdr.c.d_type linux-2.3/fs/nfsd/nfs3xdr.c
--- linux-2.3/fs/nfsd/nfs3xdr.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/nfsd/nfs3xdr.c Sun Nov 7 16:19:44 1999
@@ -635,7 +635,7 @@

#define NFS3_ENTRYPLUS_BAGGAGE ((1 + 20 + 1 + NFS3_FHSIZE) << 2)
int
-nfs3svc_encode_entry(struct readdir_cd *cd, const char *name,
+nfs3svc_encode_entry(struct readdir_cd *cd, unsigned char type, const char *name,
int namlen, unsigned long offset, ino_t ino)
{
u32 *p = cd->buffer;
diff -u linux-2.3/fs/nfsd/nfsfh.c.d_type linux-2.3/fs/nfsd/nfsfh.c
--- linux-2.3/fs/nfsd/nfsfh.c.d_type Sun Nov 7 16:17:04 1999
+++ linux-2.3/fs/nfsd/nfsfh.c Sun Nov 7 16:19:44 1999
@@ -40,8 +40,8 @@
* A rather strange filldir function to capture
* the name matching the specified inode number.
*/
-static int filldir_one(void * __buf, const char * name, int len,
- off_t pos, ino_t ino)
+static int filldir_one(void * __buf, unsigned char type,
+ const char * name, int len, off_t pos, ino_t ino)
{
struct nfsd_getdents_callback *buf = __buf;
struct qstr *qs = buf->name;
diff -u linux-2.3/fs/nfsd/nfsxdr.c.d_type linux-2.3/fs/nfsd/nfsxdr.c
--- linux-2.3/fs/nfsd/nfsxdr.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/nfsd/nfsxdr.c Sun Nov 7 16:19:44 1999
@@ -423,7 +423,7 @@
}

int
-nfssvc_encode_entry(struct readdir_cd *cd, const char *name,
+nfssvc_encode_entry(struct readdir_cd *cd, unsigned char type, const char *name,
int namlen, off_t offset, ino_t ino)
{
u32 *p = cd->buffer;
diff -u linux-2.3/fs/ntfs/fs.c.d_type linux-2.3/fs/ntfs/fs.c
--- linux-2.3/fs/ntfs/fs.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/ntfs/fs.c Sun Nov 7 16:19:44 1999
@@ -28,6 +28,7 @@
#include <linux/nls.h>
#include <linux/locks.h>
#include <linux/init.h>
+#include <linux/dirent.h>

/* Forward declarations */
static struct inode_operations ntfs_dir_inode_operations;
@@ -197,7 +198,7 @@
ntfs_debug(DEBUG_OTHER, "readdir got %s,len %d\n",nf->name,nf->namelen);
/* filldir expects an off_t rather than an loff_t.
Hope we don't have more than 65535 index records */
- error=nf->filldir(nf->dirent,nf->name,nf->namelen,
+ error=nf->filldir(nf->dirent,DT_UNKNOWN,nf->name,nf->namelen,
(nf->ph<<16)|nf->pl,inum);
ntfs_free(nf->name);
/* Linux filldir errors are negative, other errors positive */
@@ -224,11 +225,11 @@
if(cb.ph==0xFFFF){
/* FIXME: Maybe we can return those with the previous call */
switch(cb.pl){
- case 0: filldir(dirent,".",1,filp->f_pos,dir->i_ino);
+ case 0: filldir(dirent,DT_DIR,".",1,filp->f_pos,dir->i_ino);
filp->f_pos=0xFFFF0001;
return 0;
/* FIXME: parent directory */
- case 1: filldir(dirent,"..",2,filp->f_pos,0);
+ case 1: filldir(dirent,DT_DIR,"..",2,filp->f_pos,0);
filp->f_pos=0xFFFF0002;
return 0;
}
diff -u linux-2.3/fs/proc/fd.c.d_type linux-2.3/fs/proc/fd.c
--- linux-2.3/fs/proc/fd.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/proc/fd.c Sun Nov 7 16:19:44 1999
@@ -15,6 +15,7 @@
#include <linux/file.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/dirent.h>

#include <asm/uaccess.h>

@@ -150,7 +151,7 @@
ino = inode->i_ino;
if (fd)
ino = (ino & 0xffff0000) | PROC_PID_INO;
- if (filldir(dirent, "..", fd+1, fd, ino) < 0)
+ if (filldir(dirent, DT_DIR, "..", fd+1, fd, ino) < 0)
goto out;
}

@@ -178,7 +179,7 @@
read_unlock(&tasklist_lock);

ino = (pid << 16) + PROC_PID_FD_DIR + fd;
- if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
+ if (filldir(dirent, DT_LNK, buf+j, NUMBUF-j, fd+2, ino) < 0)
goto out;

read_lock(&tasklist_lock);
diff -u linux-2.3/fs/proc/openpromfs.c.d_type linux-2.3/fs/proc/openpromfs.c
--- linux-2.3/fs/proc/openpromfs.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/proc/openpromfs.c Sun Nov 7 16:19:44 1999
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
+#include <linux/dirent.h>

#include <asm/openprom.h>
#include <asm/oplib.h>
@@ -855,12 +856,12 @@
i = filp->f_pos;
switch (i) {
case 0:
- if (filldir(dirent, ".", 1, i, ino) < 0) return 0;
+ if (filldir(dirent, DT_DIR, ".", 1, i, ino) < 0) return 0;
i++;
filp->f_pos++;
/* fall thru */
case 1:
- if (filldir(dirent, "..", 2, i,
+ if (filldir(dirent, DT_DIR, "..", 2, i,
(NODE(ino).parent == 0xffff) ?
PROC_ROOT_INO : NODE2INO(NODE(ino).parent)) < 0)
return 0;
@@ -877,7 +878,7 @@
while (node != 0xffff) {
if (prom_getname (nodes[node].node, buffer, 128) < 0)
return 0;
- if (filldir(dirent, buffer, strlen(buffer),
+ if (filldir(dirent, DT_UNKNOWN, buffer, strlen(buffer),
filp->f_pos, NODE2INO(node)) < 0)
return 0;
filp->f_pos++;
@@ -885,7 +886,8 @@
}
j = NODEP2INO(NODE(ino).first_prop);
if (!i) {
- if (filldir(dirent, ".node", 5, filp->f_pos, j) < 0)
+ if (filldir(dirent, DT_UNKNOWN, ".node", 5,
+ filp->f_pos, j) < 0)
return 0;
filp->f_pos++;
} else
@@ -894,9 +896,11 @@
if (ino == PROC_OPENPROM_FIRST + aliases) {
for (j++; i < aliases_nodes; i++, j++) {
if (alias_names [i]) {
- if (filldir (dirent, alias_names [i],
- strlen (alias_names [i]),
- filp->f_pos, j) < 0) return 0;
+ if (filldir (dirent, DT_UNKNOWN,
+ alias_names [i],
+ strlen (alias_names [i]),
+ filp->f_pos, j) < 0)
+ return 0;
filp->f_pos++;
}
}
@@ -907,7 +911,8 @@
j++;
if (i) i--;
else {
- if (filldir(dirent, p, strlen(p),
+ if (filldir(dirent, DT_UNKNOWN,
+ p, strlen(p),
filp->f_pos, j) < 0)
return 0;
filp->f_pos++;
@@ -918,8 +923,8 @@
if (d->node == n) {
if (i) i--;
else {
- if (filldir(dirent, d->name,
- strlen(d->name),
+ if (filldir(dirent, DT_UNKNOWN,
+ d->name, strlen(d->name),
filp->f_pos, d->inode) < 0)
return 0;
filp->f_pos++;
diff -u linux-2.3/fs/proc/root.c.d_type linux-2.3/fs/proc/root.c
--- linux-2.3/fs/proc/root.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/proc/root.c Sun Nov 7 16:19:44 1999
@@ -14,6 +14,7 @@
#include <linux/stat.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/dirent.h>
#include <asm/bitops.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
@@ -726,13 +727,13 @@
i = filp->f_pos;
switch (i) {
case 0:
- if (filldir(dirent, ".", 1, i, ino) < 0)
+ if (filldir(dirent, DT_DIR, ".", 1, i, ino) < 0)
return 0;
i++;
filp->f_pos++;
/* fall through */
case 1:
- if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0)
+ if (filldir(dirent, DT_DIR, "..", 2, i, de->parent->low_ino) < 0)
return 0;
i++;
filp->f_pos++;
@@ -751,7 +752,7 @@
}

do {
- if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0)
+ if (filldir(dirent, IFTODT (de->mode), de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0)
return 0;
filp->f_pos++;
de = de->next;
@@ -818,7 +819,7 @@
pid /= 10;
} while (pid);

- if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino) < 0)
+ if (filldir(dirent, DT_DIR, buf+j, PROC_NUMBUF-j, filp->f_pos, ino) < 0)
break;
filp->f_pos++;
}
diff -u linux-2.3/fs/qnx4/dir.c.d_type linux-2.3/fs/qnx4/dir.c
--- linux-2.3/fs/qnx4/dir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/qnx4/dir.c Sun Nov 7 16:19:44 1999
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/qnx4_fs.h>
#include <linux/stat.h>
+#include <linux/dirent.h>

#include <asm/segment.h>

@@ -57,7 +58,7 @@

if ((de->di_mode) || (de->di_status == QNX4_FILE_LINK)) {
if (de->di_status) {
- if (filldir(dirent, de->di_fname, size, filp->f_pos, de->di_first_xtnt.xtnt_blk) < 0) {
+ if (filldir(dirent, IFTODT (de->di_mode), de->di_fname, size, filp->f_pos, de->di_first_xtnt.xtnt_blk) < 0) {
brelse(bh);
return 0;
}
diff -u linux-2.3/fs/readdir.c.d_type linux-2.3/fs/readdir.c
--- linux-2.3/fs/readdir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/readdir.c Wed Nov 10 04:15:04 1999
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/file.h>
+#include <linux/dirent.h>
#include <linux/smp_lock.h>

#include <asm/uaccess.h>
@@ -24,22 +25,15 @@
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))

-struct old_linux_dirent {
- unsigned long d_ino;
- unsigned long d_offset;
- unsigned short d_namlen;
- char d_name[1];
-};
-
struct readdir_callback {
- struct old_linux_dirent * dirent;
+ struct readdir_dirent * dirent;
int count;
};

-static int fillonedir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+static int fillonedir(void * __buf, unsigned char type, const char * name, int namlen, off_t offset, ino_t ino)
{
struct readdir_callback * buf = (struct readdir_callback *) __buf;
- struct old_linux_dirent * dirent;
+ struct readdir_dirent * dirent;

if (buf->count)
return -EINVAL;
@@ -104,26 +98,21 @@
* New, all-improved, singing, dancing, iBCS2-compliant getdents()
* interface.
*/
-struct linux_dirent {
- unsigned long d_ino;
- unsigned long d_off;
- unsigned short d_reclen;
- char d_name[1];
-};
-
struct getdents_callback {
- struct linux_dirent * current_dir;
- struct linux_dirent * previous;
+ struct getdents_dirent * current_dir;
+ struct getdents_dirent * previous;
int count;
int error;
};

-static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+static int filldir(void * __buf, unsigned char type, const char * name, int namlen, off_t offset, ino_t ino)
{
- struct linux_dirent * dirent;
+ struct getdents_dirent * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);

+ if (type != DT_UNKNOWN)
+ reclen += sizeof(long);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
@@ -136,6 +125,16 @@
put_user(reclen, &dirent->d_reclen);
copy_to_user(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
+ /*
+ * This, plus adding sizeof(long) to reclen, allows d_type to be
+ * included in a backward & forward compatible way.
+ */
+ if (type != DT_UNKNOWN) {
+ put_user(0, (unsigned char *) dirent + reclen - (1 + sizeof (long)));
+ put_user(type, (unsigned char *) dirent + reclen - 2);
+ put_user(0, (unsigned char *) dirent + reclen - 1);
+ }
+
((char *) dirent) += reclen;
buf->current_dir = dirent;
buf->count -= reclen;
@@ -147,7 +146,7 @@
struct file * file;
struct dentry * dentry;
struct inode * inode;
- struct linux_dirent * lastdirent;
+ struct getdents_dirent * lastdirent;
struct getdents_callback buf;
int error;

@@ -165,7 +164,7 @@
if (!inode)
goto out_putf;

- buf.current_dir = (struct linux_dirent *) dirent;
+ buf.current_dir = (struct getdents_dirent *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
diff -u linux-2.3/fs/romfs/inode.c.d_type linux-2.3/fs/romfs/inode.c
--- linux-2.3/fs/romfs/inode.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/romfs/inode.c Sun Nov 7 16:19:44 1999
@@ -58,6 +58,7 @@
#include <linux/locks.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
+#include <linux/dirent.h>

#include <asm/uaccess.h>

@@ -258,6 +259,12 @@
return res;
}

+static mode_t romfs_modemap[] =
+{
+ 0, S_IFDIR+0644, S_IFREG+0644, S_IFLNK+0777,
+ S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644
+};
+
static int
romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
@@ -265,6 +272,7 @@
struct romfs_inode ri;
unsigned long offset, maxoff;
int j, ino, nextfh;
+ unsigned char type;
int stored = 0;
char fsname[ROMFS_MAXFN]; /* XXX dynamic? */

@@ -302,7 +310,8 @@
nextfh = ntohl(ri.next);
if ((nextfh & ROMFH_TYPE) == ROMFH_HRD)
ino = ntohl(ri.spec);
- if (filldir(dirent, fsname, j, offset, ino) < 0) {
+ type = IFTODT (romfs_modemap [nextfh & ROMFH_TYPE]);
+ if (filldir(dirent, type, fsname, j, offset, ino) < 0) {
return stored;
}
stored++;
@@ -593,12 +602,6 @@
NULL, /* permission */
NULL, /* smap */
NULL /* revalidate */
-};
-
-static mode_t romfs_modemap[] =
-{
- 0, S_IFDIR+0644, S_IFREG+0644, S_IFLNK+0777,
- S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644
};

static struct inode_operations *romfs_inoops[] =
diff -u linux-2.3/fs/smbfs/dir.c.d_type linux-2.3/fs/smbfs/dir.c
--- linux-2.3/fs/smbfs/dir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/smbfs/dir.c Sun Nov 7 16:19:44 1999
@@ -9,6 +9,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/dirent.h>

#include <linux/smb_fs.h>
#include <linux/smbno.h>
@@ -114,11 +115,11 @@
switch ((unsigned int) filp->f_pos)
{
case 0:
- if (filldir(dirent, ".", 1, 0, dir->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, ".", 1, 0, dir->i_ino) < 0)
goto out_free;
filp->f_pos = 1;
case 1:
- if (filldir(dirent, "..", 2, 1,
+ if (filldir(dirent, DT_DIR, "..", 2, 1,
dentry->d_parent->d_inode->i_ino) < 0)
goto out_free;
filp->f_pos = 2;
@@ -143,7 +144,7 @@
entry->ino = smb_invent_inos(1);
}

- if (filldir(dirent, entry->name, entry->len,
+ if (filldir(dirent, DT_UNKNOWN, entry->name, entry->len,
filp->f_pos, entry->ino) < 0)
break;
filp->f_pos += 1;
diff -u linux-2.3/fs/sysv/dir.c.d_type linux-2.3/fs/sysv/dir.c
--- linux-2.3/fs/sysv/dir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/sysv/dir.c Sun Nov 7 16:19:44 1999
@@ -18,6 +18,7 @@
#include <linux/sysv_fs.h>
#include <linux/stat.h>
#include <linux/string.h>
+#include <linux/dirent.h>

#include <asm/uaccess.h>

@@ -103,7 +104,7 @@
inode->i_ino, (off_t) filp->f_pos, sde.inode);

i = strnlen(sde.name, SYSV_NAMELEN);
- if (filldir(dirent, sde.name, i, filp->f_pos, sde.inode) < 0) {
+ if (filldir(dirent, DT_UNKNOWN, sde.name, i, filp->f_pos, sde.inode) < 0) {
brelse(bh);
return 0;
}
diff -u linux-2.3/fs/udf/dir.c.d_type linux-2.3/fs/udf/dir.c
--- linux-2.3/fs/udf/dir.c.d_type Sun Nov 7 16:16:38 1999
+++ linux-2.3/fs/udf/dir.c Sun Nov 7 16:19:44 1999
@@ -40,6 +40,7 @@
#include <linux/mm.h>
#include <linux/malloc.h>
#include <linux/udf_fs.h>
+#include <linux/dirent.h>
#endif

/* Prototypes for file operations */
@@ -142,7 +143,7 @@

if ( filp->f_pos == 0 )
{
- if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, ".", 1, filp->f_pos, dir->i_ino) < 0)
return 0;
}

@@ -159,6 +160,7 @@
struct FileIdentDesc cfi;
int block, iblock;
int nf_pos = filp->f_pos;
+ unsigned char ftype;
int flen;
char fname[255];
char *nameptr;
@@ -250,11 +252,15 @@
continue;
}

+ ftype = DT_DIR;
+ if ( (cfi.fileCharacteristics & FILE_DIRECTORY) == 0 )
+ ftype = DT_UNKNOWN;
+
iblock = udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0);

if (!lfi) /* parent directory */
{
- if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino) < 0)
+ if (filldir(dirent, DT_DIR, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino) < 0)
{
if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh);
@@ -267,7 +273,7 @@
{
if ((flen = udf_get_filename(nameptr, fname, lfi)))
{
- if (filldir(dirent, fname, flen, filp->f_pos, iblock) < 0)
+ if (filldir(dirent, ftype, fname, flen, filp->f_pos, iblock) < 0)
{
if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh);
diff -u linux-2.3/fs/ufs/dir.c.d_type linux-2.3/fs/ufs/dir.c
--- linux-2.3/fs/ufs/dir.c.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/fs/ufs/dir.c Sun Nov 7 16:19:44 1999
@@ -15,6 +15,7 @@

#include <linux/fs.h>
#include <linux/ufs_fs.h>
+#include <linux/dirent.h>

#include "swab.h"
#include "util.h"
@@ -125,7 +126,8 @@

UFSD(("filldir(%s,%u)\n", de->d_name, SWAB32(de->d_ino)))
UFSD(("namlen %u\n", ufs_get_de_namlen(de)))
- error = filldir(dirent, de->d_name, ufs_get_de_namlen(de),
+ error = filldir(dirent, ufs_get_de_type (de),
+ de->d_name, ufs_get_de_namlen(de),
filp->f_pos, SWAB32(de->d_ino));
if (error)
break;
diff -u linux-2.3/fs/ufs/util.h.d_type linux-2.3/fs/ufs/util.h
--- linux-2.3/fs/ufs/util.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/fs/ufs/util.h Sun Nov 7 16:19:44 1999
@@ -127,6 +127,11 @@
? (de->d_u.d_namlen = SWAB16(value)) \
: (de->d_u.d_44.d_namlen = value))

+#define ufs_get_de_type(de) \
+ (((flags & UFS_DE_MASK) == UFS_DE_OLD) \
+ ? DT_UNKNOWN \
+ : de->d_u.d_44.d_type)
+
#define ufs_set_de_type(de,mode) _ufs_set_de_type_(de,mode,flags,swab)
static inline void _ufs_set_de_type_(struct ufs_dir_entry * de, int mode,
unsigned flags, unsigned swab)
diff -u linux-2.3/fs/umsdos/dir.c.d_type linux-2.3/fs/umsdos/dir.c
--- linux-2.3/fs/umsdos/dir.c.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/fs/umsdos/dir.c Sun Nov 7 16:19:44 1999
@@ -16,6 +16,7 @@
#include <linux/limits.h>
#include <linux/umsdos_fs.h>
#include <linux/malloc.h>
+#include <linux/dirent.h>

#include <asm/uaccess.h>

@@ -79,6 +80,7 @@
*/

static int umsdos_dir_once ( void *buf,
+ unsigned char type,
const char *name,
int len,
off_t offset,
@@ -90,7 +92,7 @@
if (d->count == 0) {
PRINTK ((KERN_DEBUG "dir_once :%.*s: offset %Ld\n",
len, name, offset));
- ret = d->filldir (d->dirbuf, name, len, offset, ino);
+ ret = d->filldir (d->dirbuf, type, name, len, offset, ino);
d->stop = ret < 0;
d->count = 1;
}
@@ -135,7 +137,7 @@
*/

Printk ((KERN_WARNING "umsdos_readdir_x: pseudo_root thing UMSDOS_SPECIAL_DIRFPOS\n"));
- if (filldir (dirbuf, "DOS", 3,
+ if (filldir (dirbuf, DT_DIR, "DOS", 3,
UMSDOS_SPECIAL_DIRFPOS, UMSDOS_ROOT_INO) == 0) {
filp->f_pos++;
}
@@ -254,7 +256,8 @@
*/
if (inode != pseudo_root &&
(internal_read || !(entry.flags & UMSDOS_HIDDEN))) {
- if (filldir (dirbuf, entry.name, entry.name_len,
+ if (filldir (dirbuf, IFTODT (entry.mode),
+ entry.name, entry.name_len,
cur_f_pos, inode->i_ino) < 0) {
new_filp.f_pos = cur_f_pos;
}
diff -u linux-2.3/fs/umsdos/ioctl.c.d_type linux-2.3/fs/umsdos/ioctl.c
--- linux-2.3/fs/umsdos/ioctl.c.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/fs/umsdos/ioctl.c Sun Nov 7 16:19:44 1999
@@ -14,9 +14,10 @@
#include <linux/fs.h>
#include <linux/msdos_fs.h>
#include <linux/umsdos_fs.h>
+#include <linux/dirent.h>

struct UMSDOS_DIR_ONCE {
- struct dirent *ent;
+ struct getdents_dirent *ent;
int count;
};

@@ -26,6 +27,7 @@
*/
static int umsdos_ioctl_fill (
void *buf,
+ unsigned char type,
const char *name,
int name_len,
off_t offset,
diff -u linux-2.3/fs/umsdos/rdir.c.d_type linux-2.3/fs/umsdos/rdir.c
--- linux-2.3/fs/umsdos/rdir.c.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/fs/umsdos/rdir.c Sun Nov 7 16:19:44 1999
@@ -15,6 +15,7 @@
#include <linux/limits.h>
#include <linux/umsdos_fs.h>
#include <linux/malloc.h>
+#include <linux/dirent.h>

#include <asm/uaccess.h>

@@ -30,6 +31,7 @@
};

static int rdir_filldir ( void *buf,
+ unsigned char type,
const char *name,
int name_len,
off_t offset,
@@ -48,11 +50,11 @@
/* Make sure the .. entry points back to the pseudo_root */
ino = pseudo_root->i_ino;
}
- ret = d->filldir (d->dirbuf, name, name_len, offset, ino);
+ ret = d->filldir (d->dirbuf, type, name, name_len, offset, ino);
}
} else {
/* Any DOS directory */
- ret = d->filldir (d->dirbuf, name, name_len, offset, ino);
+ ret = d->filldir (d->dirbuf, type, name, name_len, offset, ino);
}
return ret;
}
diff -u linux-2.3/include/linux/dirent.h.d_type linux-2.3/include/linux/dirent.h
--- linux-2.3/include/linux/dirent.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/include/linux/dirent.h Sun Nov 7 16:19:44 1999
@@ -1,11 +1,64 @@
+/*
+ * API for directory reading system calls.
+ * Copyright (C) 1999 Jamie Lokier.
+ */
+
#ifndef _LINUX_DIRENT_H
#define _LINUX_DIRENT_H

-struct dirent {
- long d_ino;
- __kernel_off_t d_off;
+/*
+ * Structure returned by sys_readdir.
+ */
+struct readdir_dirent {
+ unsigned long d_ino;
+ unsigned long d_offset;
+ unsigned short d_namlen;
+ char d_name [256]; /* NAME_MAX + 1. */
+};
+
+/*
+ * Structure returned by sys_getdents.
+ */
+struct getdents_dirent {
+ unsigned long d_ino;
+ unsigned long d_off;
unsigned short d_reclen;
- char d_name[256]; /* We must not include limits.h! */
+ char d_name [256]; /* NAME_MAX + 1. */
};

-#endif
+/*
+ * Backward compatibility. This may go away.
+ */
+#define dirent getdents_dirent
+
+/*
+ * Returns the "d_type" value from a struct getdents_dirent. This is
+ * backward compatible with older kernels: it will return DT_UNKNOWN.
+ * It is also forward compatible: more information can be added in future.
+ */
+#define GETDENTS_DIRENT_D_TYPE(dent) \
+ (((dent)->d_reclen > ((dent)->d_name - (char *) (dent) + sizeof (long)) \
+ && !*((unsigned char *) (dent) + (dent)->d_reclen - (1 + sizeof (long)))) \
+ ? *((unsigned char *) (dent) + (dent)->d_reclen - 2) : DT_UNKNOWN)
+
+/*
+ * "d_type" type code. DT_UNKNOWN when no type is available.
+ * Must match Glibc values. These are quite standard.
+ */
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
+
+/*
+ * Convert to and from S_IFREG etc.
+ */
+#define DTTOIF(dirtype) ((dirtype) << 12)
+#define IFTODT(mode) (((mode) & 0170000) >> 12)
+
+#endif /* _LINUX_DIRENT_H */
diff -u linux-2.3/include/linux/fs.h.d_type linux-2.3/include/linux/fs.h
--- linux-2.3/include/linux/fs.h.d_type Sun Nov 7 16:18:57 1999
+++ linux-2.3/include/linux/fs.h Sun Nov 7 16:19:44 1999
@@ -596,7 +596,7 @@
* This allows the kernel to read directories into kernel space or
* to have different dirent layouts depending on the binary type.
*/
-typedef int (*filldir_t)(void *, const char *, int, off_t, ino_t);
+typedef int (*filldir_t)(void *, unsigned char, const char *, int, off_t, ino_t);

struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);
diff -u linux-2.3/include/linux/iso_fs.h.d_type linux-2.3/include/linux/iso_fs.h
--- linux-2.3/include/linux/iso_fs.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/include/linux/iso_fs.h Sun Nov 7 16:19:44 1999
@@ -176,7 +176,7 @@
extern int iso_date(char *, int);

extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *);
-extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *);
+extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *, unsigned char *);

extern char * get_rock_ridge_symlink(struct inode *);
extern int find_rock_ridge_relocation(struct iso_directory_record *, struct inode *);
diff -u linux-2.3/include/linux/msdos_fs.h.d_type linux-2.3/include/linux/msdos_fs.h
--- linux-2.3/include/linux/msdos_fs.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/include/linux/msdos_fs.h Sun Nov 7 16:19:44 1999
@@ -85,8 +85,8 @@
/*
* ioctl commands
*/
-#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
-#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
+#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct getdents_dirent [2])
+#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct getdents_dirent [2])

/*
* Conversion from and to little-endian byte order. (no-op on i386/i486)
diff -u linux-2.3/include/linux/nfsd/nfsd.h.d_type linux-2.3/include/linux/nfsd/nfsd.h
--- linux-2.3/include/linux/nfsd/nfsd.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/include/linux/nfsd/nfsd.h Sun Nov 7 16:19:45 1999
@@ -53,8 +53,8 @@
char eob; /* end of buffer */
char dotonly;
};
-typedef int (*encode_dent_fn)(struct readdir_cd *, const char *,
- int, off_t, ino_t);
+typedef int (*encode_dent_fn)(struct readdir_cd *, unsigned char,
+ const char *, int, off_t, ino_t);
typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);

/*
diff -u linux-2.3/include/linux/nfsd/xdr.h.d_type linux-2.3/include/linux/nfsd/xdr.h
--- linux-2.3/include/linux/nfsd/xdr.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/include/linux/nfsd/xdr.h Sun Nov 7 16:19:45 1999
@@ -151,8 +151,8 @@
int nfssvc_encode_statfsres(struct svc_rqst *, u32 *, struct nfsd_statfsres *);
int nfssvc_encode_readdirres(struct svc_rqst *, u32 *, struct nfsd_readdirres *);

-int nfssvc_encode_entry(struct readdir_cd *, const char *name,
- int namlen, off_t offset, ino_t ino);
+int nfssvc_encode_entry(struct readdir_cd *, unsigned char type,
+ const char *name, int namlen, off_t offset, ino_t ino);

int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);

diff -u linux-2.3/include/linux/nfsd/xdr3.h.d_type linux-2.3/include/linux/nfsd/xdr3.h
--- linux-2.3/include/linux/nfsd/xdr3.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/include/linux/nfsd/xdr3.h Sun Nov 7 16:19:45 1999
@@ -262,7 +262,8 @@
struct nfsd_fhandle *);
int nfs3svc_release_fhandle2(struct svc_rqst *, u32 *,
struct nfsd3_fhandle2 *);
-int nfs3svc_encode_entry(struct readdir_cd *, const char *name,
- int namlen, unsigned long offset, ino_t ino);
+int nfs3svc_encode_entry(struct readdir_cd *, unsigned char type,
+ const char *name, int namlen,
+ unsigned long offset, ino_t ino);

#endif /* LINUX_NFSD_XDR3_H */
diff -u linux-2.3/include/linux/umsdos_fs.h.d_type linux-2.3/include/linux/umsdos_fs.h
--- linux-2.3/include/linux/umsdos_fs.h.d_type Sun Nov 7 16:16:39 1999
+++ linux-2.3/include/linux/umsdos_fs.h Sun Nov 7 16:19:45 1999
@@ -127,7 +127,7 @@
#define UMSDOS_RENAME_DOS _IO(0x04,220) /* rename a file/directory in the DOS
* directory only */
struct umsdos_ioctl {
- struct dirent dos_dirent;
+ struct getdents_dirent dos_dirent;
struct umsdos_dirent umsdos_dirent;
/* The following structure is used to exchange some data
* with utilities (umsdos_progs/util/umsdosio.c). The first

---------- end of patch ----------

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/