summaryrefslogtreecommitdiffstats
path: root/fs/ext2/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2/dir.c')
-rw-r--r--fs/ext2/dir.c54
1 files changed, 17 insertions, 37 deletions
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index c98139bc6..5b8bf9cc7 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -1,9 +1,10 @@
/*
* linux/fs/ext2/dir.c
*
- * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
*
* from
*
@@ -22,16 +23,13 @@
#include <linux/sched.h>
#include <linux/stat.h>
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
-#define ROUND_UP(x) (((x)+3) & ~3)
-
static int ext2_dir_read (struct inode * inode, struct file * filp,
char * buf, int count)
{
return -EISDIR;
}
-static int ext2_readdir (struct inode *, struct file *, struct dirent *, int);
+static int ext2_readdir (struct inode *, struct file *, void *, filldir_t);
static struct file_operations ext2_dir_operations = {
NULL, /* lseek - default */
@@ -92,16 +90,17 @@ int ext2_check_dir_entry (char * function, struct inode * dir,
if (error_msg != NULL)
ext2_error (dir->i_sb, function, "bad directory entry: %s\n"
"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
- error_msg, offset, de->inode, de->rec_len,
+ error_msg, offset, (unsigned long) de->inode, de->rec_len,
de->name_len);
return error_msg == NULL ? 1 : 0;
}
static int ext2_readdir (struct inode * inode, struct file * filp,
- struct dirent * dirent, int count)
+ void * dirent, filldir_t filldir)
{
+ int error = 0;
unsigned long offset, blk;
- int i, num, stored, dlen;
+ int i, num, stored;
struct buffer_head * bh, * tmp, * bha[16];
struct ext2_dir_entry * de;
struct super_block * sb;
@@ -115,7 +114,7 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
bh = NULL;
offset = filp->f_pos & (sb->s_blocksize - 1);
- while (count > 0 && !stored && filp->f_pos < inode->i_size) {
+ while (!error && !stored && filp->f_pos < inode->i_size) {
blk = (filp->f_pos) >> EXT2_BLOCK_SIZE_BITS(sb);
bh = ext2_bread (inode, blk, 0, &err);
if (!bh) {
@@ -167,7 +166,7 @@ revalidate:
filp->f_version = inode->i_version;
}
- while (count > 0 && filp->f_pos < inode->i_size
+ while (!error && filp->f_pos < inode->i_size
&& offset < sb->s_blocksize) {
de = (struct ext2_dir_entry *) (bh->b_data + offset);
if (!ext2_check_dir_entry ("ext2_readdir", inode, de,
@@ -179,18 +178,8 @@ revalidate:
brelse (bh);
return stored;
}
+ offset += de->rec_len;
if (de->inode) {
- dlen = ROUND_UP(NAME_OFFSET(dirent)
- + de->name_len + 1);
- /* Old libc libraries always use a
- count of 1. */
- if (count == 1 && !stored)
- count = dlen;
- if (count < dlen) {
- count = 0;
- break;
- }
-
/* We might block in the next section
* if the data destination is
* currently swapped out. So, use a
@@ -198,22 +187,13 @@ revalidate:
* not the directory has been modified
* during the copy operation. */
version = inode->i_version;
- i = de->name_len;
- memcpy_tofs (dirent->d_name, de->name, i);
- put_fs_long (de->inode, &dirent->d_ino);
- put_fs_byte (0, dirent->d_name + i);
- put_fs_word (i, &dirent->d_reclen);
- put_fs_long (dlen, &dirent->d_off);
+ error = filldir(dirent, de->name, de->name_len, filp->f_pos, de->inode);
+ if (error)
+ break;
if (version != inode->i_version)
goto revalidate;
- dcache_add(inode, de->name, de->name_len,
- de->inode);
-
- stored += dlen;
- count -= dlen;
- ((char *) dirent) += dlen;
+ stored ++;
}
- offset += de->rec_len;
filp->f_pos += de->rec_len;
}
offset = 0;
@@ -223,5 +203,5 @@ revalidate:
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
}
- return stored;
+ return 0;
}