This source file includes following definitions.
- sysv_dir_read
- 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_readdir(struct inode * inode, struct file * filp,
68 struct dirent * dirent, int count)
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, &bh_data);
84 if (!bh) {
85 filp->f_pos += sb->sv_block_size - offset;
86 continue;
87 }
88 while (offset < sb->sv_block_size && filp->f_pos < inode->i_size) {
89 de = (struct sysv_dir_entry *) (offset + bh_data);
90 offset += SYSV_DIRSIZE;
91 filp->f_pos += SYSV_DIRSIZE;
92 if (de->inode) {
93 for (i = 0; i < SYSV_NAMELEN; i++)
94 if ((c = de->name[i]) != 0)
95 put_fs_byte(c,i+dirent->d_name);
96 else
97 break;
98 if (i) {
99 if (de->inode > inode->i_sb->sv_ninodes)
100 printk("sysv_readdir: Bad inode number on dev 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n",
101 inode->i_dev, inode->i_ino, (off_t) filp->f_pos - SYSV_DIRSIZE, de->inode);
102 put_fs_long(de->inode,&dirent->d_ino);
103 put_fs_byte(0,i+dirent->d_name);
104 put_fs_word(i,&dirent->d_reclen);
105 brelse(bh);
106 return ROUND_UP(NAME_OFFSET(dirent)+i+1);
107 }
108 }
109 }
110 brelse(bh);
111 }
112 return 0;
113 }