This source file includes following definitions.
- minix_dir_read
- minix_readdir
1
2
3
4
5
6
7
8
9 #include <asm/segment.h>
10
11 #include <linux/errno.h>
12 #include <linux/fs.h>
13 #include <linux/minix_fs.h>
14 #include <linux/stat.h>
15
16 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
17 #define ROUND_UP(x) (((x)+3) & ~3)
18
19 static int minix_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
20 {
21 return -EISDIR;
22 }
23
24 static int minix_readdir(struct inode *, struct file *, struct dirent *, int);
25
26 static struct file_operations minix_dir_operations = {
27 NULL,
28 minix_dir_read,
29 NULL,
30 minix_readdir,
31 NULL,
32 NULL,
33 NULL,
34 NULL,
35 NULL,
36 file_fsync
37 };
38
39
40
41
42 struct inode_operations minix_dir_inode_operations = {
43 &minix_dir_operations,
44 minix_create,
45 minix_lookup,
46 minix_link,
47 minix_unlink,
48 minix_symlink,
49 minix_mkdir,
50 minix_rmdir,
51 minix_mknod,
52 minix_rename,
53 NULL,
54 NULL,
55 NULL,
56 minix_truncate,
57 NULL
58 };
59
60 static int minix_readdir(struct inode * inode, struct file * filp,
61 struct dirent * dirent, int count)
62 {
63 unsigned int offset,i,ret;
64 int version;
65 char c;
66 struct buffer_head * bh;
67 struct minix_dir_entry * de;
68 struct minix_sb_info * info;
69
70 if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode))
71 return -EBADF;
72 info = &inode->i_sb->u.minix_sb;
73 if (filp->f_pos & (info->s_dirsize - 1))
74 return -EBADF;
75 ret = 0;
76 while (!ret && filp->f_pos < inode->i_size) {
77 offset = filp->f_pos & 1023;
78 bh = minix_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
79 if (!bh) {
80 filp->f_pos += 1024-offset;
81 continue;
82 }
83 while (!ret && offset < 1024 && filp->f_pos < inode->i_size) {
84 de = (struct minix_dir_entry *) (offset + bh->b_data);
85 offset += info->s_dirsize;
86 filp->f_pos += info->s_dirsize;
87 retry:
88 if (de->inode) {
89 version = inode->i_version;
90 for (i = 0; i < info->s_namelen; i++)
91 if ((c = de->name[i]) != 0)
92 put_fs_byte(c,i+dirent->d_name);
93 else
94 break;
95 if (i) {
96 put_fs_long(de->inode,&dirent->d_ino);
97 put_fs_byte(0,i+dirent->d_name);
98 put_fs_word(i,&dirent->d_reclen);
99 if (version != inode->i_version)
100 goto retry;
101 ret = ROUND_UP(NAME_OFFSET(dirent)+i+1);
102 }
103 }
104 }
105 brelse(bh);
106 }
107 return ret;
108 }