OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [efs/] [dir.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.