diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
commit | e7c2a72e2680827d6a733931273a93461c0d8d1b (patch) | |
tree | c9abeda78ef7504062bb2e816bcf3e3c9d680112 /fs/sysv/dir.c | |
parent | ec6044459060a8c9ce7f64405c465d141898548c (diff) |
Import of Linux/MIPS 1.3.0
Diffstat (limited to 'fs/sysv/dir.c')
-rw-r--r-- | fs/sysv/dir.c | 67 |
1 files changed, 18 insertions, 49 deletions
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index a4b019228..cfd85993e 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c @@ -13,6 +13,10 @@ * SystemV/Coherent directory handling functions */ +#ifdef MODULE +#include <linux/module.h> +#endif + #include <asm/segment.h> #include <linux/errno.h> @@ -20,15 +24,12 @@ #include <linux/sysv_fs.h> #include <linux/stat.h> -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) -#define ROUND_UP(x) (((x)+3) & ~3) - static int sysv_dir_read(struct inode * inode, struct file * filp, char * buf, int count) { return -EISDIR; } -static int sysv_readdir(struct inode *, struct file *, struct dirent *, int); +static int sysv_readdir(struct inode *, struct file *, void *, filldir_t); static struct file_operations sysv_dir_operations = { NULL, /* lseek - default */ @@ -64,15 +65,14 @@ struct inode_operations sysv_dir_inode_operations = { NULL /* permission */ }; -static int sysv_readdir1 (struct inode * inode, struct file * filp, - struct dirent * dirent) +static int sysv_readdir(struct inode * inode, struct file * filp, + void * dirent, filldir_t filldir) { struct super_block * sb; unsigned int offset,i; - char c; struct buffer_head * bh; char* bh_data; - struct sysv_dir_entry * de; + struct sysv_dir_entry * de, sde; if (!inode || !(sb = inode->i_sb) || !S_ISDIR(inode->i_mode)) return -EBADF; @@ -88,57 +88,26 @@ static int sysv_readdir1 (struct inode * inode, struct file * filp, bh_data = bh->b_data; while (offset < sb->sv_block_size && filp->f_pos < inode->i_size) { de = (struct sysv_dir_entry *) (offset + bh_data); - offset += SYSV_DIRSIZE; - filp->f_pos += SYSV_DIRSIZE; if (de->inode) { - struct sysv_dir_entry sde; - /* Copy the directory entry first, because the directory - * might be modified while we sleep in put_fs_byte... + * might be modified while we sleep in filldir()... */ memcpy(&sde, de, sizeof(struct sysv_dir_entry)); - for (i = 0; i < SYSV_NAMELEN; i++) - if ((c = sde.name[i]) != 0) - put_fs_byte(c,i+dirent->d_name); - else - break; - if (i) { - if (sde.inode > inode->i_sb->sv_ninodes) - printk("sysv_readdir: Bad inode number on dev 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n", - inode->i_dev, inode->i_ino, (off_t) filp->f_pos - SYSV_DIRSIZE, sde.inode); - put_fs_long(sde.inode,&dirent->d_ino); - put_fs_byte(0,i+dirent->d_name); - put_fs_word(i,&dirent->d_reclen); + if (sde.inode > inode->i_sb->sv_ninodes) + printk("sysv_readdir: Bad inode number on dev 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n", + inode->i_dev, 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) { brelse(bh); - return ROUND_UP(NAME_OFFSET(dirent)+i+1); + return 0; } } + offset += SYSV_DIRSIZE; + filp->f_pos += SYSV_DIRSIZE; } brelse(bh); } return 0; } - -static int sysv_readdir(struct inode * inode, struct file * filp, - struct dirent * dirent, int count) -{ - int retval, stored; - - /* compatibility */ - if (count==1) - return sysv_readdir1(inode,filp,dirent); - - stored = 0; - while (count >= sizeof(struct dirent)) { - retval = sysv_readdir1(inode,filp,dirent); - if (retval < 0) - return retval; - if (!retval) - return stored; - dirent = (struct dirent *)((char *) dirent + retval); - stored += retval; - count -= retval; - } - return stored; -} |