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 };
38
39 struct inode_operations msdos_file_inode_operations = {
40 &msdos_file_operations,
41 NULL,
42 NULL,
43 NULL,
44 NULL,
45 NULL,
46 NULL,
47 NULL,
48 NULL,
49 NULL,
50 NULL,
51 NULL,
52 msdos_bmap,
53 msdos_truncate
54 };
55
56
57
58 struct inode_operations msdos_file_inode_operations_no_bmap = {
59 &msdos_file_operations,
60 NULL,
61 NULL,
62 NULL,
63 NULL,
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 NULL,
69 NULL,
70 NULL,
71 NULL,
72 msdos_truncate
73 };
74
75
76 static int msdos_file_read(struct inode *inode,struct file *filp,char *buf,
77 int count)
78 {
79 char *start;
80 int left,offset,size,sector,cnt;
81 char ch;
82 struct buffer_head *bh;
83 void *data;
84
85
86 if (!inode) {
87 printk("msdos_file_read: inode = NULL\r\n");
88 return -EINVAL;
89 }
90 if (!S_ISREG(inode->i_mode)) {
91 printk("msdos_file_read: mode = %07o\n",inode->i_mode);
92 return -EINVAL;
93 }
94 if (filp->f_pos >= inode->i_size || count <= 0) return 0;
95 start = buf;
96 while (left = MIN(inode->i_size-filp->f_pos,count-(buf-start))) {
97 if (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS)))
98 break;
99 offset = filp->f_pos & (SECTOR_SIZE-1);
100 if (!(bh = msdos_sread(inode->i_dev,sector,&data))) break;
101 filp->f_pos += (size = MIN(SECTOR_SIZE-offset,left));
102 if (inode->i_data[D_BINARY]) {
103 memcpy_tofs(buf,data+offset,size);
104 buf += size;
105 }
106 else for (cnt = size; cnt; cnt--) {
107 if ((ch = *((char *) data+offset++)) == '\r')
108 size--;
109 else {
110 if (ch != 26) put_fs_byte(ch,buf++);
111 else {
112 filp->f_pos = inode->i_size;
113 brelse(bh);
114 return buf-start;
115 }
116 }
117 }
118 brelse(bh);
119 }
120 if (start == buf) return -EIO;
121 return buf-start;
122 }
123
124
125 static int msdos_file_write(struct inode *inode,struct file *filp,char *buf,
126 int count)
127 {
128 int sector,offset,size,left,written;
129 int error,carry;
130 char *start,*to,ch;
131 struct buffer_head *bh;
132 void *data;
133
134 if (!inode) {
135 printk("msdos_file_write: inode = NULL\n");
136 return -EINVAL;
137 }
138 if (!S_ISREG(inode->i_mode)) {
139 printk("msdos_file_write: mode = %07o\n",inode->i_mode);
140 return -EINVAL;
141 }
142
143
144
145
146 if (filp->f_flags & O_APPEND) filp->f_pos = inode->i_size;
147 if (count <= 0) return 0;
148 error = carry = 0;
149 for (start = buf; count || carry; count -= size) {
150 while (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS)))
151 if ((error = msdos_add_cluster(inode)) < 0) break;
152 if (error) break;
153 offset = filp->f_pos & (SECTOR_SIZE-1);
154 size = MIN(SECTOR_SIZE-offset,MAX(carry,count));
155 if (!(bh = msdos_sread(inode->i_dev,sector,&data))) {
156 error = -EIO;
157 break;
158 }
159 if (inode->i_data[D_BINARY]) {
160 memcpy_fromfs(data+(filp->f_pos & (SECTOR_SIZE-1)),
161 buf,written = size);
162 buf += size;
163 }
164 else {
165 written = left = SECTOR_SIZE-offset;
166 to = data+(filp->f_pos & (SECTOR_SIZE-1));
167 if (carry) {
168 *to++ = '\n';
169 left--;
170 carry = 0;
171 }
172 for (size = 0; size < count && left; size++) {
173 if ((ch = get_fs_byte(buf++)) == '\n') {
174 *to++ = '\r';
175 left--;
176 }
177 if (!left) carry = 1;
178 else {
179 *to++ = ch;
180 left--;
181 }
182 }
183 written -= left;
184 }
185 filp->f_pos += written;
186 if (filp->f_pos > inode->i_size) {
187 inode->i_size = filp->f_pos;
188 inode->i_dirt = 1;
189 }
190 bh->b_dirt = 1;
191 brelse(bh);
192 }
193 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
194 inode->i_data[D_ATTRS] |= ATTR_ARCH;
195 inode->i_dirt = 1;
196 return start == buf ? error : buf-start;
197 }
198
199
200 void msdos_truncate(struct inode *inode)
201 {
202 int cluster;
203
204 cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
205 (void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
206 inode->i_data[D_ATTRS] |= ATTR_ARCH;
207 inode->i_dirt = 1;
208 }