~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/sysv/dir.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/fs/sysv/dir.c
  3  *
  4  *  minix/dir.c
  5  *  Copyright (C) 1991, 1992  Linus Torvalds
  6  *
  7  *  coh/dir.c
  8  *  Copyright (C) 1993  Pascal Haible, Bruno Haible
  9  *
 10  *  sysv/dir.c
 11  *  Copyright (C) 1993  Bruno Haible
 12  *
 13  *  SystemV/Coherent directory handling functions
 14  */
 15 
 16 #include <linux/errno.h>
 17 #include <linux/fs.h>
 18 #include <linux/sysv_fs.h>
 19 #include <linux/stat.h>
 20 #include <linux/string.h>
 21 
 22 static int sysv_readdir(struct file *, void *, filldir_t);
 23 
 24 struct file_operations sysv_dir_operations = {
 25         read:           generic_read_dir,
 26         readdir:        sysv_readdir,
 27         fsync:          file_fsync,
 28 };
 29 
 30 static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
 31 {
 32         struct inode *inode = filp->f_dentry->d_inode;
 33         struct super_block * sb = inode->i_sb;
 34         unsigned int offset,i;
 35         struct buffer_head * bh;
 36         char* bh_data;
 37         struct sysv_dir_entry * de, sde;
 38 
 39         if ((unsigned long)(filp->f_pos) % SYSV_DIRSIZE)
 40                 return -EBADF;
 41         while (filp->f_pos < inode->i_size) {
 42                 offset = filp->f_pos & sb->sv_block_size_1;
 43                 bh = sysv_file_bread(inode, filp->f_pos >> sb->sv_block_size_bits, 0);
 44                 if (!bh) {
 45                         filp->f_pos += sb->sv_block_size - offset;
 46                         continue;
 47                 }
 48                 bh_data = bh->b_data;
 49                 while (offset < sb->sv_block_size && filp->f_pos < inode->i_size) {
 50                         de = (struct sysv_dir_entry *) (offset + bh_data);
 51                         if (de->inode) {
 52                                 /* Copy the directory entry first, because the directory
 53                                  * might be modified while we sleep in filldir()...
 54                                  */
 55                                 memcpy(&sde, de, sizeof(struct sysv_dir_entry));
 56 
 57                                 if (sde.inode > inode->i_sb->sv_ninodes)
 58                                         printk("sysv_readdir: Bad inode number on dev "
 59                                                "%s, ino %ld, offset 0x%04lx: %d is out of range\n",
 60                                                kdevname(inode->i_dev),
 61                                                inode->i_ino, (off_t) filp->f_pos, sde.inode);
 62 
 63                                 i = strnlen(sde.name, SYSV_NAMELEN);
 64                                 if (filldir(dirent, sde.name, i, filp->f_pos, sde.inode, DT_UNKNOWN) < 0) {
 65                                         brelse(bh);
 66                                         return 0;
 67                                 }
 68                         }
 69                         offset += SYSV_DIRSIZE;
 70                         filp->f_pos += SYSV_DIRSIZE;
 71                 }
 72                 brelse(bh);
 73         }
 74         return 0;
 75 }
 76 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.