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