root/fs/ext2/dir.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ext2_dir_read
  2. ext2_readdir

   1 /*
   2  *  linux/fs/ext2/dir.c
   3  *
   4  *  Copyright (C) 1992, 1993  Remy Card (card@masi.ibp.fr)
   5  *
   6  *  from
   7  *
   8  *  linux/fs/minix/dir.c
   9  *
  10  *  Copyright (C) 1991, 1992  Linus Torvalds
  11  *
  12  *  ext2 directory handling functions
  13  */
  14 
  15 #include <asm/segment.h>
  16 
  17 #include <linux/errno.h>
  18 #include <linux/fs.h>
  19 #include <linux/ext2_fs.h>
  20 #include <linux/stat.h>
  21 #include <linux/sched.h>
  22 
  23 #if 0
  24 static int ext2_dir_read (struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
  25                             char * buf, int count)
  26 {
  27         return -EISDIR;
  28 }
  29 #endif
  30 
  31 /* static */ int ext2_file_read (struct inode *, struct file *, char *, int);
  32 static int ext2_readdir (struct inode *, struct file *, struct dirent *, int);
  33 
  34 static struct file_operations ext2_dir_operations = {
  35         NULL,                   /* lseek - default */
  36         ext2_file_read,         /* read */
  37         NULL,                   /* write - bad */
  38         ext2_readdir,           /* readdir */
  39         NULL,                   /* select - default */
  40         NULL,                   /* ioctl - default */
  41         NULL,                   /* mmap */
  42         NULL,                   /* no special open code */
  43         NULL,                   /* no special release code */
  44         NULL                    /* fsync */
  45 };
  46 
  47 /*
  48  * directories can handle most operations...
  49  */
  50 struct inode_operations ext2_dir_inode_operations = {
  51         &ext2_dir_operations,   /* default directory file-ops */
  52         ext2_create,            /* create */
  53         ext2_lookup,            /* lookup */
  54         ext2_link,              /* link */
  55         ext2_unlink,            /* unlink */
  56         ext2_symlink,           /* symlink */
  57         ext2_mkdir,             /* mkdir */
  58         ext2_rmdir,             /* rmdir */
  59         ext2_mknod,             /* mknod */
  60         ext2_rename,            /* rename */
  61         NULL,                   /* readlink */
  62         NULL,                   /* follow_link */
  63         NULL,                   /* bmap */
  64         ext2_truncate,  /* truncate */
  65         NULL                    /* permission */
  66 };
  67 
  68 static int ext2_readdir (struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
  69                          struct dirent * dirent, int count)
  70 {
  71         unsigned int offset, i;
  72         struct buffer_head * bh;
  73         struct ext2_dir_entry * de;
  74         struct super_block * sb;
  75 
  76         if (!inode || !S_ISDIR(inode->i_mode))
  77                 return -EBADF;
  78         sb = inode->i_sb;
  79         while (filp->f_pos < inode->i_size) {
  80                 offset = filp->f_pos & (sb->s_blocksize - 1);
  81                 bh = ext2_bread (inode, (filp->f_pos) >> EXT2_BLOCK_SIZE_BITS(sb), 0);
  82                 if (!bh) {
  83                         filp->f_pos += sb->s_blocksize - offset;
  84                         continue;
  85                 }
  86                 de = (struct ext2_dir_entry *) (offset + bh->b_data);
  87                 while (offset < sb->s_blocksize && filp->f_pos < inode->i_size) {
  88                         if (de->rec_len < EXT2_DIR_REC_LEN(1) ||
  89                             de->rec_len % 4 != 0 ||
  90                             de->rec_len < EXT2_DIR_REC_LEN(de->name_len)) {
  91                                 printk ("ext2_readdir: bad directory entry (dev %04x, dir %d)\n",
  92                                         inode->i_dev, inode->i_ino);
  93                                 printk ("offset=%d, inode=%d, rec_len=%d, name_len=%d\n",
  94                                         offset, de->inode, de->rec_len, de->name_len);
  95                                 brelse (bh);
  96                                 return 0;
  97                         }
  98                         offset += de->rec_len;
  99                         filp->f_pos += de->rec_len;
 100                         if (de->inode) {
 101                                 memcpy_tofs (dirent->d_name, de->name,
 102                                              de->name_len);
 103                                 put_fs_long (de->inode, &dirent->d_ino);
 104                                 put_fs_byte (0, de->name_len + dirent->d_name);
 105                                 put_fs_word (de->name_len, &dirent->d_reclen);
 106 #ifndef DONT_USE_DCACHE
 107                                 ext2_dcache_add (inode->i_dev, inode->i_ino,
 108                                                  de->name, de->name_len,
 109                                                  de->inode);
 110 #endif
 111                                 i = de->name_len;
 112                                 brelse (bh);
 113                                 return i;
 114                         }
 115                         de = (struct ext2_dir_entry *) ((char *) de +
 116                                                         de->rec_len);
 117                 }
 118                 brelse (bh);
 119         }
 120         return 0;
 121 }

/* [previous][next][first][last][top][bottom][index][help] */