This source file includes following definitions.
- umsdos_ioctl_fill
- UMSDOS_ioctl_dir
1
2
3
4
5
6
7
8
9 #include <asm/segment.h>
10 #include <linux/errno.h>
11 #include <linux/mm.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/fs.h>
15 #include <linux/msdos_fs.h>
16 #include <linux/umsdos_fs.h>
17
18 #define PRINTK(x)
19 #define Printk(x) printk x
20
21 struct UMSDOS_DIR_ONCE {
22 struct dirent *ent;
23 int count;
24 };
25
26
27
28
29
30 static int umsdos_ioctl_fill(
31 void * buf,
32 const char * name,
33 int name_len,
34 off_t offset,
35 ino_t ino)
36 {
37 int ret = -EINVAL;
38 struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *)buf;
39 if (d->count == 0){
40 memcpy_tofs (d->ent->d_name,name,name_len);
41 put_user ('\0',d->ent->d_name+name_len);
42 put_user (name_len,&d->ent->d_reclen);
43 put_user (ino,&d->ent->d_ino);
44 put_user (offset,&d->ent->d_off);
45 d->count = 1;
46 ret = 0;
47 }
48 return ret;
49 }
50
51
52
53
54
55 int UMSDOS_ioctl_dir (
56 struct inode *dir,
57 struct file *filp,
58 unsigned int cmd,
59 unsigned long data)
60 {
61 int ret = -EPERM;
62
63
64
65
66
67
68
69
70 if (verify_area(VERIFY_WRITE,(void*)data,sizeof(struct umsdos_ioctl)) < 0){
71 ret = -EFAULT;
72 }else if (current->euid == 0
73 || cmd == UMSDOS_GETVERSION){
74 struct umsdos_ioctl *idata = (struct umsdos_ioctl *)data;
75 ret = -EINVAL;
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 PRINTK (("ioctl %d ",cmd));
96 if (cmd == UMSDOS_GETVERSION){
97
98
99
100
101
102
103
104
105
106
107 put_fs_byte (UMSDOS_VERSION,&idata->version);
108 put_fs_byte (UMSDOS_RELEASE,&idata->release);
109 ret = 0;
110 }else if (cmd == UMSDOS_READDIR_DOS){
111
112
113
114
115
116
117
118 struct UMSDOS_DIR_ONCE bufk;
119 bufk.count = 0;
120 bufk.ent = &idata->dos_dirent;
121 msdos_readdir(dir,filp,&bufk,umsdos_ioctl_fill);
122 ret = bufk.count == 1 ? 1 : 0;
123 }else if (cmd == UMSDOS_READDIR_EMD){
124
125
126
127
128
129
130
131
132
133
134
135 struct inode *emd_dir = umsdos_emd_dir_lookup (dir,0);
136 if (emd_dir != NULL){
137 while (1){
138 if (filp->f_pos >= emd_dir->i_size){
139 ret = 0;
140 break;
141 }else{
142 struct umsdos_dirent entry;
143 off_t f_pos = filp->f_pos;
144 ret = umsdos_emd_dir_readentry (emd_dir,filp,&entry);
145 if (ret < 0){
146 break;
147 }else if (entry.name_len > 0){
148 struct umsdos_info info;
149 ret = entry.name_len;
150 umsdos_parse (entry.name,entry.name_len,&info);
151 info.f_pos = f_pos;
152 umsdos_manglename(&info);
153 memcpy_tofs(&idata->umsdos_dirent,&entry
154 ,sizeof(entry));
155 memcpy_tofs(&idata->dos_dirent.d_name
156 ,info.fake.fname,info.fake.len+1);
157 break;
158 }
159 }
160 }
161 iput (emd_dir);
162 }else{
163
164 ret = 0;
165 }
166 }else if (cmd == UMSDOS_INIT_EMD){
167
168
169
170
171
172
173
174
175
176
177
178 extern struct inode_operations umsdos_rdir_inode_operations;
179 struct inode *emd_dir = umsdos_emd_dir_lookup (dir,1);
180 ret = emd_dir != NULL;
181 iput (emd_dir);
182
183 dir->i_op = ret
184 ? &umsdos_dir_inode_operations
185 : &umsdos_rdir_inode_operations;
186 }else{
187 struct umsdos_ioctl data;
188 memcpy_fromfs (&data,idata,sizeof(data));
189 if (cmd == UMSDOS_CREAT_EMD){
190
191
192
193
194
195
196
197
198 struct umsdos_info info;
199
200
201 memcpy (&info.entry,&data.umsdos_dirent
202 ,sizeof(data.umsdos_dirent));
203 umsdos_parse (data.umsdos_dirent.name
204 ,data.umsdos_dirent.name_len,&info);
205 ret = umsdos_newentry (dir,&info);
206 }else if (cmd == UMSDOS_RENAME_DOS){
207
208
209
210
211
212
213
214
215
216 dir->i_count += 2;
217 ret = msdos_rename (dir
218 ,data.dos_dirent.d_name,data.dos_dirent.d_reclen
219 ,dir
220 ,data.umsdos_dirent.name,data.umsdos_dirent.name_len);
221 }else if (cmd == UMSDOS_UNLINK_EMD){
222
223
224
225
226
227
228
229
230 struct umsdos_info info;
231
232
233 memcpy (&info.entry,&data.umsdos_dirent
234 ,sizeof(data.umsdos_dirent));
235 umsdos_parse (data.umsdos_dirent.name
236 ,data.umsdos_dirent.name_len,&info);
237 ret = umsdos_delentry (dir,&info
238 ,S_ISDIR(data.umsdos_dirent.mode));
239 }else if (cmd == UMSDOS_UNLINK_DOS){
240
241
242
243
244
245
246
247 dir->i_count++;
248 ret = msdos_unlink (dir,data.dos_dirent.d_name
249 ,data.dos_dirent.d_reclen);
250 }else if (cmd == UMSDOS_RMDIR_DOS){
251
252
253
254
255
256
257
258 dir->i_count++;
259 ret = msdos_rmdir (dir,data.dos_dirent.d_name
260 ,data.dos_dirent.d_reclen);
261 }else if (cmd == UMSDOS_STAT_DOS){
262
263
264
265
266
267
268
269
270
271
272 struct inode *inode;
273 ret = umsdos_real_lookup (dir,data.dos_dirent.d_name
274 ,data.dos_dirent.d_reclen,&inode);
275 if (ret == 0){
276 data.stat.st_ino = inode->i_ino;
277 data.stat.st_mode = inode->i_mode;
278 data.stat.st_size = inode->i_size;
279 data.stat.st_atime = inode->i_atime;
280 data.stat.st_ctime = inode->i_ctime;
281 data.stat.st_mtime = inode->i_mtime;
282 memcpy_tofs (&idata->stat,&data.stat,sizeof(data.stat));
283 iput (inode);
284 }
285 }else if (cmd == UMSDOS_DOS_SETUP){
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305 dir->i_sb->u.msdos_sb.fs_uid = data.umsdos_dirent.uid;
306 dir->i_sb->u.msdos_sb.fs_gid = data.umsdos_dirent.gid;
307 dir->i_sb->u.msdos_sb.fs_umask = data.umsdos_dirent.mode;
308 ret = 0;
309 }
310 }
311 }
312 PRINTK (("ioctl return %d\n",ret));
313 return ret;
314 }
315
316
317