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