This source file includes following definitions.
- ext_dir_read
- ext_readdir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <asm/segment.h>
16
17 #include <linux/errno.h>
18 #include <linux/kernel.h>
19 #include <linux/fs.h>
20 #include <linux/ext_fs.h>
21 #include <linux/stat.h>
22
23 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
24 #define ROUND_UP(x) (((x)+3) & ~3)
25
26 static int ext_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
27 {
28 return -EISDIR;
29 }
30
31 static int ext_readdir(struct inode *, struct file *, struct dirent *, int);
32
33 static struct file_operations ext_dir_operations = {
34 NULL,
35 ext_dir_read,
36 NULL,
37 ext_readdir,
38 NULL,
39 NULL,
40 NULL,
41 NULL,
42 NULL,
43 file_fsync
44 };
45
46
47
48
49 struct inode_operations ext_dir_inode_operations = {
50 &ext_dir_operations,
51 ext_create,
52 ext_lookup,
53 ext_link,
54 ext_unlink,
55 ext_symlink,
56 ext_mkdir,
57 ext_rmdir,
58 ext_mknod,
59 ext_rename,
60 NULL,
61 NULL,
62 NULL,
63 ext_truncate,
64 NULL
65 };
66
67 static int ext_readdir(struct inode * inode, struct file * filp,
68 struct dirent * dirent, int count)
69 {
70 unsigned int i;
71 unsigned int ret;
72 off_t offset;
73 char c;
74 struct buffer_head * bh;
75 struct ext_dir_entry * de;
76
77 if (!inode || !S_ISDIR(inode->i_mode))
78 return -EBADF;
79 if ((filp->f_pos & 7) != 0)
80 return -EBADF;
81 ret = 0;
82 while (!ret && filp->f_pos < inode->i_size) {
83 offset = filp->f_pos & 1023;
84 bh = ext_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
85 if (!bh) {
86 filp->f_pos += 1024-offset;
87 continue;
88 }
89 for (i = 0; i < 1024 && i < offset; ) {
90 de = (struct ext_dir_entry *) (bh->b_data + i);
91 if (!de->rec_len)
92 break;
93 i += de->rec_len;
94 }
95 offset = i;
96 de = (struct ext_dir_entry *) (offset + bh->b_data);
97 while (!ret && offset < 1024 && filp->f_pos < inode->i_size) {
98 if (de->rec_len < 8 || de->rec_len % 8 != 0 ||
99 de->rec_len < de->name_len + 8 ||
100 (de->rec_len + (off_t) filp->f_pos - 1) / 1024 > ((off_t) filp->f_pos / 1024)) {
101 printk ("ext_readdir: bad dir entry, skipping\n");
102 printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\n",
103 inode->i_dev, inode->i_ino, offset, de->rec_len, de->name_len);
104 filp->f_pos += 1024-offset;
105 if (filp->f_pos > inode->i_size)
106 filp->f_pos = inode->i_size;
107 continue;
108 }
109 offset += de->rec_len;
110 filp->f_pos += de->rec_len;
111 if (de->inode) {
112 for (i = 0; i < de->name_len; i++)
113 if ((c = de->name[i]) != 0)
114 put_fs_byte(c,i+dirent->d_name);
115 else
116 break;
117 if (i) {
118 put_fs_long(de->inode,&dirent->d_ino);
119 put_fs_byte(0,i+dirent->d_name);
120 put_fs_word(i,&dirent->d_reclen);
121 ret = ROUND_UP(NAME_OFFSET(dirent)+i+1);
122 break;
123 }
124 }
125 de = (struct ext_dir_entry *) ((char *) de
126 + de->rec_len);
127 }
128 brelse(bh);
129 }
130 return ret;
131 }