This source file includes following definitions.
- msdos_file_read
- msdos_file_write
- msdos_truncate
1
2
3
4
5
6
7
8
9 #include <asm/segment.h>
10 #include <asm/system.h>
11
12 #include <linux/sched.h>
13 #include <linux/fs.h>
14 #include <linux/msdos_fs.h>
15 #include <linux/errno.h>
16 #include <linux/fcntl.h>
17 #include <linux/stat.h>
18
19 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
20 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
21
22 static int msdos_file_read(struct inode *inode,struct file *filp,char *buf,
23 int count);
24 static int msdos_file_write(struct inode *inode,struct file *filp,char *buf,
25 int count);
26
27
28 static struct file_operations msdos_file_operations = {
29 NULL,
30 msdos_file_read,
31 msdos_file_write,
32 NULL,
33 NULL,
34 NULL,
35 NULL,
36 NULL,
37 NULL,
38 file_fsync
39 };
40
41 struct inode_operations msdos_file_inode_operations = {
42 &msdos_file_operations,
43 NULL,
44 NULL,
45 NULL,
46 NULL,
47 NULL,
48 NULL,
49 NULL,
50 NULL,
51 NULL,
52 NULL,
53 NULL,
54 msdos_bmap,
55 msdos_truncate,
56 NULL
57 };
58
59
60
61 struct inode_operations msdos_file_inode_operations_no_bmap = {
62 &msdos_file_operations,
63 NULL,
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 NULL,
69 NULL,
70 NULL,
71 NULL,
72 NULL,
73 NULL,
74 NULL,
75 msdos_truncate,
76 NULL
77 };
78
79
80 static int msdos_file_read(struct inode *inode,struct file *filp,char *buf,
81 int count)
82 {
83 char *start;
84 int left,offset,size,sector,cnt;
85 char ch;
86 struct buffer_head *bh;
87 void *data;
88
89
90 if (!inode) {
91 printk("msdos_file_read: inode = NULL\n");
92 return -EINVAL;
93 }
94 if (!S_ISREG(inode->i_mode)) {
95 printk("msdos_file_read: mode = %07o\n",inode->i_mode);
96 return -EINVAL;
97 }
98 if (filp->f_pos >= inode->i_size || count <= 0) return 0;
99 start = buf;
100 while ((left = MIN(inode->i_size-filp->f_pos,count-(buf-start))) > 0){
101 if (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS)))
102 break;
103 offset = filp->f_pos & (SECTOR_SIZE-1);
104 if (!(bh = msdos_sread(inode->i_dev,sector,&data))) break;
105 filp->f_pos += (size = MIN(SECTOR_SIZE-offset,left));
106 if (MSDOS_I(inode)->i_binary) {
107 memcpy_tofs(buf,data+offset,size);
108 buf += size;
109 }
110 else for (cnt = size; cnt; cnt--) {
111 if ((ch = *((char *) data+offset++)) == '\r')
112 size--;
113 else {
114 if (ch != 26) put_fs_byte(ch,buf++);
115 else {
116 filp->f_pos = inode->i_size;
117 brelse(bh);
118 if (start != buf
119 && !IS_RDONLY(inode))
120 inode->i_atime
121 = CURRENT_TIME;
122 return buf-start;
123 }
124 }
125 }
126 brelse(bh);
127 }
128 if (start == buf) return -EIO;
129 if (!IS_RDONLY(inode))
130 inode->i_atime = CURRENT_TIME;
131 return buf-start;
132 }
133
134
135 static int msdos_file_write(struct inode *inode,struct file *filp,char *buf,
136 int count)
137 {
138 int sector,offset,size,left,written;
139 int error,carry;
140 char *start,*to,ch;
141 struct buffer_head *bh;
142 void *data;
143
144 if (!inode) {
145 printk("msdos_file_write: inode = NULL\n");
146 return -EINVAL;
147 }
148 if (!S_ISREG(inode->i_mode)) {
149 printk("msdos_file_write: mode = %07o\n",inode->i_mode);
150 return -EINVAL;
151 }
152
153
154
155
156 if (filp->f_flags & O_APPEND) filp->f_pos = inode->i_size;
157 if (count <= 0) return 0;
158 error = carry = 0;
159 for (start = buf; count || carry; count -= size) {
160 while (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS)))
161 if ((error = msdos_add_cluster(inode)) < 0) break;
162 if (error) {
163 msdos_truncate(inode);
164 break;
165 }
166 offset = filp->f_pos & (SECTOR_SIZE-1);
167 size = MIN(SECTOR_SIZE-offset,MAX(carry,count));
168 if (!(bh = msdos_sread(inode->i_dev,sector,&data))) {
169 error = -EIO;
170 break;
171 }
172 if (MSDOS_I(inode)->i_binary) {
173 memcpy_fromfs(data+(filp->f_pos & (SECTOR_SIZE-1)),
174 buf,written = size);
175 buf += size;
176 }
177 else {
178 written = left = SECTOR_SIZE-offset;
179 to = (char *) data+(filp->f_pos & (SECTOR_SIZE-1));
180 if (carry) {
181 *to++ = '\n';
182 left--;
183 carry = 0;
184 }
185 for (size = 0; size < count && left; size++) {
186 if ((ch = get_fs_byte(buf++)) == '\n') {
187 *to++ = '\r';
188 left--;
189 }
190 if (!left) carry = 1;
191 else {
192 *to++ = ch;
193 left--;
194 }
195 }
196 written -= left;
197 }
198 filp->f_pos += written;
199 if (filp->f_pos > inode->i_size) {
200 inode->i_size = filp->f_pos;
201 inode->i_dirt = 1;
202 }
203 bh->b_dirt = 1;
204 brelse(bh);
205 }
206 if (start == buf)
207 return error;
208 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
209 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
210 inode->i_dirt = 1;
211 return buf-start;
212 }
213
214
215 void msdos_truncate(struct inode *inode)
216 {
217 int cluster;
218
219 cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
220 (void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
221 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
222 inode->i_dirt = 1;
223 }