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