diff options
Diffstat (limited to 'fs/ext2/dir.c')
-rw-r--r-- | fs/ext2/dir.c | 54 |
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; } |