lkml.org 
[lkml]   [1999]   [Oct]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] start of d_type changes (was: How to extend struct stat?)
Folks,

Here is a patch which changes the internel kernel API of f_op->readdir.
It is the simple and obvious change: each filesystem passes an
additional "unsigned char d_type" back to the filldir callback.
In the absence of useful information, they can pass DT_UNKNOWN.

Surprisingly many filesystems are able to pass useful information back.
So this patch does that when it's simple to code.

readdir is not the only thing which uses this callback, so the changes
are a bit bigger than you'd think. nfsd, umsdos and vfat needed minor
changes. The old struct dirent is also fixed in stone for some vfat and
umsdos ioctls. Binary compatibility is preserved.

No system calls are provided yet, so the information is not available to
user space. Watch this space.

There is one effect on user-space: <linux/dirent.h> is changed. Samba
and umsdos utils may need a #define to compile. Binary compatibility is
preserved, however.

I've removed the definition of `struct dirent' from <linux/dirent.h>
because it bore no relation to _either_ the getdents or readdir
interface. (They use private structures defined in fs/readdir.c, which
are different to `struct dirent'!). Take a look to see what's there
instead.

I haven't tested that the code works yet. I'm waiting to add a new
syscall. It does, however, compile cleanly.

Compiles ok
-----------

coda, minix, fat, msdos (no changes), vfat (no changes), isofs, hfs,
nfs, nfsd, umsdos, sysv, smbfs, ncpfs, hpfs, ntfs, ufs, efs, affs, romfs
qnx4, udf, adfs, ext2, proc, autofs, devpts

Type info (without inode lookup)
--------------------------------

These all compile, but are not tested. I cannot test most of them. The
changes are fairly trivial -- some things are complex like the isofs RR
change but I can test that.

adfs [not done -- maybe possible]
affs [not done -- definitely possible]
autofs [not done -- maybe possible]
coda [done]
devpts [done]
efs [not possible]
ext2 [done]
fat [done]
hfs [not done -- maybe possible]
hpfs [done -- directories and attributeless files only]
isofs [done including Rock Ridge]
minix [not possible]
ncpfs [partial -- does the other place need doing too?]
nfs [not possible with NFSv2]
ntfs [not done -- scary code]
proc [done except openpromfs -- help please]
qnx4 [done]
romfs [done]
smbfs [not done -- maybe possible]
sysv [not possible]
udf [done -- directories only]
ufs [done]
umsdos [done]

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 Sat Sep 4 04:51:38 1999
+++ linux-2.3/fs/adfs/dir.c Thu Oct 14 23:58:42 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 Sat Sep 4 04:51:38 1999
+++ linux-2.3/fs/affs/dir.c Thu Oct 14 23:59:49 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 Sat Sep 4 04:51:38 1999
+++ linux-2.3/fs/autofs/dir.c Fri Oct 15 00:01:08 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 Sat Sep 4 04:51:38 1999
+++ linux-2.3/fs/autofs/root.c Fri Oct 15 04:08:31 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/coda/dir.c.d_type linux-2.3/fs/coda/dir.c
--- linux-2.3/fs/coda/dir.c.d_type Sat Sep 4 04:54:35 1999
+++ linux-2.3/fs/coda/dir.c Fri Oct 15 04:35:21 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 Sat Sep 4 04:55:26 1999
+++ linux-2.3/fs/devpts/root.c Fri Oct 15 00:12: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 Sat Sep 4 04:51:38 1999
+++ linux-2.3/fs/efs/dir.c Fri Oct 15 00:15:49 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 Sat Sep 4 04:51:38 1999
+++ linux-2.3/fs/ext2/dir.c Fri Oct 15 04:18:19 1999
@@ -25,6 +25,7 @@
#include <linux/ext2_fs.h>
#include <linux/sched.h>
#include <linux/stat.h>
+#include <linux/dirent.h>

static ssize_t ext2_dir_read (struct file * filp, char * buf,
size_t count, loff_t *ppos)
@@ -105,6 +106,17 @@
return error_msg == NULL ? 1 : 0;
}

+static 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)
{
@@ -200,9 +212,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/fat/dir.c.d_type linux-2.3/fs/fat/dir.c
--- linux-2.3/fs/fat/dir.c.d_type Sat Sep 4 04:53:18 1999
+++ linux-2.3/fs/fat/dir.c Fri Oct 15 05:27:17 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 Sat Sep 4 04:51:39 1999
+++ linux-2.3/fs/hfs/dir_cap.c Fri Oct 15 00:34:59 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 Sat Sep 4 04:51:39 1999
+++ linux-2.3/fs/hfs/dir_dbl.c Fri Oct 15 00:35:57 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 Sat Sep 4 04:51:39 1999
+++ linux-2.3/fs/hfs/dir_nat.c Fri Oct 15 04:21:20 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 Sat Sep 4 04:50:15 1999
+++ linux-2.3/fs/hpfs/dir.c Fri Oct 15 03:40:45 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)
{
@@ -82,14 +83,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 = -1;
}
if (filp->f_pos == -1) {
- 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;
}
@@ -118,7 +119,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 Sat Sep 4 04:51:39 1999
+++ linux-2.3/fs/isofs/dir.c Fri Oct 15 06:35:36 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;
@@ -245,9 +247,12 @@
}
}

+ type = DT_DIR;
+ if (!(de->flags[-high_sierra] & 2))
+ type = DT_REG;
map = 1;
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 +279,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 Mon May 10 23:14:28 1999
+++ linux-2.3/fs/isofs/namei.c Fri Oct 15 06:04:35 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 Sat Sep 26 01:27:13 1998
+++ linux-2.3/fs/isofs/rock.c Fri Oct 15 06:36:02 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,26 @@
#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...).*/
+ 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 Sat Sep 4 04:51:39 1999
+++ linux-2.3/fs/minix/dir.c Fri Oct 15 00:51:42 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 Thu Oct 14 22:50:12 1999
+++ linux-2.3/fs/ncpfs/dir.c Fri Oct 15 01:12:07 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>

@@ -392,12 +393,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 finished;
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 finished;
filp->f_pos = 2;
@@ -435,7 +436,7 @@
if (!ino)
ino = iunique(dentry->d_inode->i_sb, 2);

- result = filldir(dirent, name, len, filp->f_pos, ino);
+ result = filldir(dirent, DT_UNKNOWN, name, len, filp->f_pos, ino);
if (!result)
filp->f_pos += 1;

@@ -450,6 +451,7 @@
struct inode *inode = dentry->d_inode;
struct qstr qname;
ino_t ino = 0;
+ unsigned char type = DT_UNKNOWN;
int result;

/* For getwd() we have to return the correct inode in d_ino if the
@@ -490,8 +492,10 @@
ncp_new_dentry(newdent);
}

- if (newdent->d_inode)
+ if (newdent->d_inode) {
ino = newdent->d_inode->i_ino;
+ type = IFTODT (newdent->d_inode->i_mode);
+ }

dput(newdent);

@@ -503,8 +507,8 @@
if (!ino)
ino = iunique(inode->i_sb, 2);

- result = filldir(dirent, entry->i.entryName, entry->i.nameLen,
- filp->f_pos, ino);
+ result = filldir(dirent, type, entry->i.entryName,
+ entry->i.nameLen, filp->f_pos, ino);
if (!result)
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 Sat Sep 4 04:54:36 1999
+++ linux-2.3/fs/nfs/dir.c Fri Oct 15 01:14:24 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 */

@@ -400,7 +401,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 Mon Apr 7 20:35:31 1997
+++ linux-2.3/fs/nfsd/nfs3xdr.c Fri Oct 15 06:54: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 Mon Oct 11 23:20:23 1999
+++ linux-2.3/fs/nfsd/nfsfh.c Fri Oct 15 07:03:56 1999
@@ -292,8 +292,8 @@
* for the second entry (the parent inode) and 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 nfsd_dirent *dirent = buf->dirent;
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 Wed Nov 26 22:08:38 1997
+++ linux-2.3/fs/nfsd/nfsxdr.c Fri Oct 15 06:55:15 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 Sat Sep 4 04:55:27 1999
+++ linux-2.3/fs/ntfs/fs.c Fri Oct 15 01:28:26 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 Mon Oct 11 23:18:23 1999
+++ linux-2.3/fs/proc/fd.c Fri Oct 15 04:01:58 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 Sat Sep 4 04:55:28 1999
+++ linux-2.3/fs/proc/openpromfs.c Fri Oct 15 04:01:32 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 Mon Oct 4 00:27:50 1999
+++ linux-2.3/fs/proc/root.c Fri Oct 15 04:04:43 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>
@@ -944,13 +945,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++;
@@ -969,7 +970,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;
@@ -1036,7 +1037,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 Sat Sep 4 04:52:21 1999
+++ linux-2.3/fs/qnx4/dir.c Fri Oct 15 01:31:25 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 Sat Sep 4 04:54:36 1999
+++ linux-2.3/fs/readdir.c Fri Oct 15 06:42:29 1999
@@ -36,7 +36,7 @@
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;
@@ -118,7 +118,7 @@
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_callback * buf = (struct getdents_callback *) __buf;
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 Sat Sep 4 04:55:28 1999
+++ linux-2.3/fs/romfs/inode.c Fri Oct 15 04:45:14 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++;
@@ -596,12 +605,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 Sat Sep 4 04:51:40 1999
+++ linux-2.3/fs/smbfs/dir.c Fri Oct 15 01:43:05 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 Sat Sep 4 04:51:40 1999
+++ linux-2.3/fs/sysv/dir.c Fri Oct 15 01:44:07 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 Thu Sep 9 02:18:27 1999
+++ linux-2.3/fs/udf/dir.c Fri Oct 15 01:52:32 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;
@@ -249,11 +251,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);
@@ -266,7 +272,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 Sat Sep 4 04:51:40 1999
+++ linux-2.3/fs/ufs/dir.c Fri Oct 15 02:29:46 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 Mon Apr 12 18:53:45 1999
+++ linux-2.3/fs/ufs/util.h Fri Oct 15 03:41:27 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 Sat Sep 4 04:53:20 1999
+++ linux-2.3/fs/umsdos/dir.c Fri Oct 15 02:29:21 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 Sat Sep 26 01:30:07 1998
+++ linux-2.3/fs/umsdos/ioctl.c Fri Oct 15 03:36:47 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 Sat Sep 4 04:51:40 1999
+++ linux-2.3/fs/umsdos/rdir.c Fri Oct 15 03:39:31 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 Thu Oct 14 23:31:45 1999
+++ linux-2.3/include/linux/dirent.h Fri Oct 15 06:50:26 1999
@@ -1,11 +1,64 @@
#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]; /* We must not include limits.h! */
+};
+
+/* 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! */
+};
+
+/* Structure returned by sys_getdirentries.
+ *
+ * Must be identical to Glibc 2.1's struct dirent so that Glibc's
+ * getdirentries can return these directly:
+ *
+ * unsigned long d_ino (all calls)
+ * long d_off (non-64 bit calls (may be 64 bits anyway))
+ * long long d_off (64 bit calls)
+ */
+struct getdirentries_dirent {
+ unsigned long d_ino;
+ long d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[256]; /* We must not include limits.h! */
+};
+struct getdirentries_dirent64 {
+ unsigned long d_ino;
+ long long d_off;
unsigned short d_reclen;
+ unsigned char d_type;
char d_name[256]; /* We must not include limits.h! */
};
+
+/* Type code stored in d_type. 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
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 Thu Oct 14 23:18:55 1999
+++ linux-2.3/include/linux/fs.h Fri Oct 15 00:18:24 1999
@@ -583,7 +583,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 Sat Sep 4 04:51:42 1999
+++ linux-2.3/include/linux/iso_fs.h Fri Oct 15 06:05:42 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 Fri Oct 15 02:43:09 1999
+++ linux-2.3/include/linux/msdos_fs.h Fri Oct 15 02:46:09 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 Fri Oct 15 06:50:49 1999
+++ linux-2.3/include/linux/nfsd/nfsd.h Fri Oct 15 07:07:21 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 Fri Oct 15 02:50:28 1999
+++ linux-2.3/include/linux/nfsd/xdr.h Fri Oct 15 07:00:37 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 Mon Apr 7 20:35:32 1997
+++ linux-2.3/include/linux/nfsd/xdr3.h Fri Oct 15 07:01:15 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 Thu Oct 14 23:22:16 1999
+++ linux-2.3/include/linux/umsdos_fs.h Fri Oct 15 06:50:39 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
-
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/

\
 
 \ /
  Last update: 2005-03-22 13:54    [W:1.582 / U:0.576 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site