This source file includes following definitions.
- minix_readdir
- minix_file_read
- minix_file_write
1
2
3
4
5
6
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <sys/dirent.h>
10 #include <sys/stat.h>
11
12 #include <linux/sched.h>
13 #include <linux/minix_fs.h>
14 #include <linux/kernel.h>
15 #include <asm/segment.h>
16
17 #define MIN(a,b) (((a)<(b))?(a):(b))
18 #define MAX(a,b) (((a)>(b))?(a):(b))
19
20 int minix_readdir(struct inode * inode, struct file * filp, struct dirent * dirent, int count)
21 {
22 unsigned int block,offset,i;
23 char c;
24 struct buffer_head * bh;
25 struct minix_dir_entry * de;
26
27 if (!inode || !S_ISDIR(inode->i_mode))
28 return -EBADF;
29 if (filp->f_pos & (sizeof (struct minix_dir_entry) - 1))
30 return -EBADF;
31 while (filp->f_pos < inode->i_size) {
32 offset = filp->f_pos & 1023;
33 block = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
34 if (!block || !(bh = bread(inode->i_dev,block))) {
35 filp->f_pos += 1024-offset;
36 continue;
37 }
38 de = (struct minix_dir_entry *) (offset + bh->b_data);
39 while (offset < 1024 && filp->f_pos < inode->i_size) {
40 offset += sizeof (struct minix_dir_entry);
41 filp->f_pos += sizeof (struct minix_dir_entry);
42 if (de->inode) {
43 for (i = 0; i < MINIX_NAME_LEN; i++)
44 if (c = de->name[i])
45 put_fs_byte(c,i+dirent->d_name);
46 else
47 break;
48 if (i) {
49 put_fs_long(de->inode,&dirent->d_ino);
50 put_fs_byte(0,i+dirent->d_name);
51 put_fs_word(i,&dirent->d_reclen);
52 brelse(bh);
53 return i;
54 }
55 }
56 de++;
57 }
58 brelse(bh);
59 }
60 return 0;
61 }
62
63 int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count)
64 {
65 int read,left,chars,nr;
66 struct buffer_head * bh;
67
68 if (!inode) {
69 printk("minix_file_read: inode = NULL\n");
70 return -EINVAL;
71 }
72 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
73 printk("minix_file_read: mode = %07o\n",inode->i_mode);
74 return -EINVAL;
75 }
76 if (filp->f_pos > inode->i_size)
77 left = 0;
78 else
79 left = inode->i_size - filp->f_pos;
80 if (left > count)
81 left = count;
82 read = 0;
83 while (left > 0) {
84 if (nr = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS)) {
85 if (!(bh=bread(inode->i_dev,nr)))
86 return read?read:-EIO;
87 } else
88 bh = NULL;
89 nr = filp->f_pos & (BLOCK_SIZE-1);
90 chars = MIN( BLOCK_SIZE-nr , left );
91 filp->f_pos += chars;
92 left -= chars;
93 read += chars;
94 if (bh) {
95 memcpy_tofs(buf,nr+bh->b_data,chars);
96 buf += chars;
97 brelse(bh);
98 } else {
99 while (chars-->0)
100 put_fs_byte(0,buf++);
101 }
102 }
103 inode->i_atime = CURRENT_TIME;
104 return read;
105 }
106
107 int minix_file_write(struct inode * inode, struct file * filp, char * buf, int count)
108 {
109 off_t pos;
110 int written,block,c;
111 struct buffer_head * bh;
112 char * p;
113
114 if (!inode) {
115 printk("minix_file_write: inode = NULL\n");
116 return -EINVAL;
117 }
118 if (!S_ISREG(inode->i_mode)) {
119 printk("minix_file_write: mode = %07o\n",inode->i_mode);
120 return -EINVAL;
121 }
122
123
124
125
126 if (filp->f_flags & O_APPEND)
127 pos = inode->i_size;
128 else
129 pos = filp->f_pos;
130 written = 0;
131 while (written<count) {
132 if (!(block = minix_create_block(inode,pos/BLOCK_SIZE))) {
133 if (!written)
134 written = -ENOSPC;
135 break;
136 }
137 c = BLOCK_SIZE - (pos % BLOCK_SIZE);
138 if (c > count-written)
139 c = count-written;
140 if (c == BLOCK_SIZE)
141 bh = getblk(inode->i_dev, block);
142 else
143 bh = bread(inode->i_dev,block);
144 if (!bh) {
145 if (!written)
146 written = -EIO;
147 break;
148 }
149 p = (pos % BLOCK_SIZE) + bh->b_data;
150 pos += c;
151 if (pos > inode->i_size) {
152 inode->i_size = pos;
153 inode->i_dirt = 1;
154 }
155 written += c;
156 memcpy_fromfs(p,buf,c);
157 buf += c;
158 bh->b_uptodate = 1;
159 bh->b_dirt = 1;
160 brelse(bh);
161 }
162 inode->i_mtime = CURRENT_TIME;
163 if (!(filp->f_flags & O_APPEND)) {
164 filp->f_pos = pos;
165 inode->i_ctime = CURRENT_TIME;
166 }
167 inode->i_dirt = 1;
168 return written;
169 }