This source file includes following definitions.
- sysv_dir_read
- sysv_readdir1
- sysv_readdir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #ifdef MODULE
17 #include <linux/module.h>
18 #endif
19
20 #include <asm/segment.h>
21
22 #include <linux/errno.h>
23 #include <linux/fs.h>
24 #include <linux/sysv_fs.h>
25 #include <linux/stat.h>
26
27 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
28 #define ROUND_UP(x) (((x)+3) & ~3)
29
30 static int sysv_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
31 {
32 return -EISDIR;
33 }
34
35 static int sysv_readdir(struct inode *, struct file *, struct dirent *, int);
36
37 static struct file_operations sysv_dir_operations = {
38 NULL,
39 sysv_dir_read,
40 NULL,
41 sysv_readdir,
42 NULL,
43 NULL,
44 NULL,
45 NULL,
46 NULL,
47 file_fsync
48 };
49
50
51
52
53 struct inode_operations sysv_dir_inode_operations = {
54 &sysv_dir_operations,
55 sysv_create,
56 sysv_lookup,
57 sysv_link,
58 sysv_unlink,
59 sysv_symlink,
60 sysv_mkdir,
61 sysv_rmdir,
62 sysv_mknod,
63 sysv_rename,
64 NULL,
65 NULL,
66 NULL,
67 sysv_truncate,
68 NULL
69 };
70
71 static int sysv_readdir1 (struct inode * inode, struct file * filp,
72 struct dirent * dirent)
73 {
74 struct super_block * sb;
75 unsigned int offset,i;
76 char c;
77 struct buffer_head * bh;
78 char* bh_data;
79 struct sysv_dir_entry * de;
80
81 if (!inode || !(sb = inode->i_sb) || !S_ISDIR(inode->i_mode))
82 return -EBADF;
83 if ((unsigned long)(filp->f_pos) % SYSV_DIRSIZE)
84 return -EBADF;
85 while (filp->f_pos < inode->i_size) {
86 offset = filp->f_pos & sb->sv_block_size_1;
87 bh = sysv_file_bread(inode, filp->f_pos >> sb->sv_block_size_bits, 0);
88 if (!bh) {
89 filp->f_pos += sb->sv_block_size - offset;
90 continue;
91 }
92 bh_data = bh->b_data;
93 while (offset < sb->sv_block_size && filp->f_pos < inode->i_size) {
94 de = (struct sysv_dir_entry *) (offset + bh_data);
95 offset += SYSV_DIRSIZE;
96 filp->f_pos += SYSV_DIRSIZE;
97 if (de->inode) {
98 struct sysv_dir_entry sde;
99
100
101
102
103 memcpy(&sde, de, sizeof(struct sysv_dir_entry));
104
105 for (i = 0; i < SYSV_NAMELEN; i++)
106 if ((c = sde.name[i]) != 0)
107 put_fs_byte(c,i+dirent->d_name);
108 else
109 break;
110 if (i) {
111 if (sde.inode > inode->i_sb->sv_ninodes)
112 printk("sysv_readdir: Bad inode number on dev 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n",
113 inode->i_dev, inode->i_ino, (off_t) filp->f_pos - SYSV_DIRSIZE, sde.inode);
114 put_fs_long(sde.inode,&dirent->d_ino);
115 put_fs_byte(0,i+dirent->d_name);
116 put_fs_word(i,&dirent->d_reclen);
117 brelse(bh);
118 return ROUND_UP(NAME_OFFSET(dirent)+i+1);
119 }
120 }
121 }
122 brelse(bh);
123 }
124 return 0;
125 }
126
127 static int sysv_readdir(struct inode * inode, struct file * filp,
128 struct dirent * dirent, int count)
129 {
130 int retval, stored;
131
132
133 if (count==1)
134 return sysv_readdir1(inode,filp,dirent);
135
136 stored = 0;
137 while (count >= sizeof(struct dirent)) {
138 retval = sysv_readdir1(inode,filp,dirent);
139 if (retval < 0)
140 return retval;
141 if (!retval)
142 return stored;
143 dirent = (struct dirent *)((char *) dirent + retval);
144 stored += retval;
145 count -= retval;
146 }
147 return stored;
148 }