The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/efs/dir.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * dir.c
    3  *
    4  * Copyright (c) 1999 Al Smith
    5  */
    6 
    7 #include <linux/efs_fs.h>
    8 
    9 static int efs_readdir(struct file *, void *, filldir_t);
   10 
   11 struct file_operations efs_dir_operations = {
   12         read:           generic_read_dir,
   13         readdir:        efs_readdir,
   14 };
   15 
   16 struct inode_operations efs_dir_inode_operations = {
   17         lookup:         efs_lookup,
   18 };
   19 
   20 static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
   21         struct inode *inode = filp->f_dentry->d_inode;
   22         struct buffer_head *bh;
   23 
   24         struct efs_dir          *dirblock;
   25         struct efs_dentry       *dirslot;
   26         efs_ino_t               inodenum;
   27         efs_block_t             block;
   28         int                     slot, namelen;
   29         char                    *nameptr;
   30 
   31         if (inode->i_size & (EFS_DIRBSIZE-1))
   32                 printk(KERN_WARNING "EFS: WARNING: readdir(): directory size not a multiple of EFS_DIRBSIZE\n");
   33 
   34         /* work out where this entry can be found */
   35         block = filp->f_pos >> EFS_DIRBSIZE_BITS;
   36 
   37         /* each block contains at most 256 slots */
   38         slot  = filp->f_pos & 0xff;
   39 
   40         /* look at all blocks */
   41         while (block < inode->i_blocks) {
   42                 /* read the dir block */
   43                 bh = sb_bread(inode->i_sb, efs_bmap(inode, block));
   44 
   45                 if (!bh) {
   46                         printk(KERN_ERR "EFS: readdir(): failed to read dir block %d\n", block);
   47                         break;
   48                 }
   49 
   50                 dirblock = (struct efs_dir *) bh->b_data; 
   51 
   52                 if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) {
   53                         printk(KERN_ERR "EFS: readdir(): invalid directory block\n");
   54                         brelse(bh);
   55                         break;
   56                 }
   57 
   58                 while (slot < dirblock->slots) {
   59                         if (dirblock->space[slot] == 0) {
   60                                 slot++;
   61                                 continue;
   62                         }
   63 
   64                         dirslot  = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot));
   65 
   66                         inodenum = be32_to_cpu(dirslot->inode);
   67                         namelen  = dirslot->namelen;
   68                         nameptr  = dirslot->name;
   69 
   70 #ifdef DEBUG
   71                         printk(KERN_DEBUG "EFS: readdir(): block %d slot %d/%d: inode %u, name \"%s\", namelen %u\n", block, slot, dirblock->slots-1, inodenum, nameptr, namelen);
   72 #endif
   73                         if (namelen > 0) {
   74                                 /* found the next entry */
   75                                 filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
   76 
   77                                 /* copy filename and data in dirslot */
   78                                 filldir(dirent, nameptr, namelen, filp->f_pos, inodenum, DT_UNKNOWN);
   79 
   80                                 /* sanity check */
   81                                 if (nameptr - (char *) dirblock + namelen > EFS_DIRBSIZE) {
   82                                         printk(KERN_WARNING "EFS: directory entry %d exceeds directory block\n", slot);
   83                                         slot++;
   84                                         continue;
   85                                 }
   86 
   87                                 /* store position of next slot */
   88                                 if (++slot == dirblock->slots) {
   89                                         slot = 0;
   90                                         block++;
   91                                 }
   92                                 brelse(bh);
   93                                 filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
   94                                 return 0;
   95                         }
   96                         slot++;
   97                 }
   98                 brelse(bh);
   99 
  100                 slot = 0;
  101                 block++;
  102         }
  103 
  104         filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
  105         return 0;
  106 }
  107 

Cache object: 69e778ead06cc7abab1b5105bee5fffa


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.