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 int err;
63
64
65
66
67
68
69
70
71
72 if ((err = verify_area(VERIFY_WRITE,(void*)data,sizeof(struct umsdos_ioctl))) < 0) {
73 ret = err;
74 }else if (current->euid == 0
75 || cmd == UMSDOS_GETVERSION){
76 struct umsdos_ioctl *idata = (struct umsdos_ioctl *)data;
77 ret = -EINVAL;
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 PRINTK (("ioctl %d ",cmd));
98 if (cmd == UMSDOS_GETVERSION){
99
100
101
102
103
104
105
106
107
108
109 put_fs_byte (UMSDOS_VERSION,&idata->version);
110 put_fs_byte (UMSDOS_RELEASE,&idata->release);
111 ret = 0;
112 }else if (cmd == UMSDOS_READDIR_DOS){
113
114
115
116
117
118
119
120 struct UMSDOS_DIR_ONCE bufk;
121 bufk.count = 0;
122 bufk.ent = &idata->dos_dirent;
123 fat_readdir(dir,filp,&bufk,umsdos_ioctl_fill);
124 ret = bufk.count == 1 ? 1 : 0;
125 }else if (cmd == UMSDOS_READDIR_EMD){
126
127
128
129
130
131
132
133
134
135
136
137 struct inode *emd_dir = umsdos_emd_dir_lookup (dir,0);
138 if (emd_dir != NULL){
139 while (1){
140 if (filp->f_pos >= emd_dir->i_size){
141 ret = 0;
142 break;
143 }else{
144 struct umsdos_dirent entry;
145 off_t f_pos = filp->f_pos;
146 ret = umsdos_emd_dir_readentry (emd_dir,filp,&entry);
147 if (ret < 0){
148 break;
149 }else if (entry.name_len > 0){
150 struct umsdos_info info;
151 ret = entry.name_len;
152 umsdos_parse (entry.name,entry.name_len,&info);
153 info.f_pos = f_pos;
154 umsdos_manglename(&info);
155 memcpy_tofs(&idata->umsdos_dirent,&entry
156 ,sizeof(entry));
157 memcpy_tofs(&idata->dos_dirent.d_name
158 ,info.fake.fname,info.fake.len+1);
159 break;
160 }
161 }
162 }
163 iput (emd_dir);
164 }else{
165
166 ret = 0;
167 }
168 }else if (cmd == UMSDOS_INIT_EMD){
169
170
171
172
173
174
175
176
177
178
179
180 extern struct inode_operations umsdos_rdir_inode_operations;
181 struct inode *emd_dir = umsdos_emd_dir_lookup (dir,1);
182 ret = emd_dir != NULL;
183 iput (emd_dir);
184
185 dir->i_op = ret
186 ? &umsdos_dir_inode_operations
187 : &umsdos_rdir_inode_operations;
188 }else{
189 struct umsdos_ioctl data;
190 memcpy_fromfs (&data,idata,sizeof(data));
191 if (cmd == UMSDOS_CREAT_EMD){
192
193
194
195
196
197
198
199
200 struct umsdos_info info;
201
202
203 memcpy (&info.entry,&data.umsdos_dirent
204 ,sizeof(data.umsdos_dirent));
205 umsdos_parse (data.umsdos_dirent.name
206 ,data.umsdos_dirent.name_len,&info);
207 ret = umsdos_newentry (dir,&info);
208 }else if (cmd == UMSDOS_RENAME_DOS){
209
210
211
212
213
214
215
216
217
218 dir->i_count += 2;
219 ret = msdos_rename (dir
220 ,data.dos_dirent.d_name,data.dos_dirent.d_reclen
221 ,dir
222 ,data.umsdos_dirent.name,data.umsdos_dirent.name_len);
223 }else if (cmd == UMSDOS_UNLINK_EMD){
224
225
226
227
228
229
230
231
232 struct umsdos_info info;
233
234
235 memcpy (&info.entry,&data.umsdos_dirent
236 ,sizeof(data.umsdos_dirent));
237 umsdos_parse (data.umsdos_dirent.name
238 ,data.umsdos_dirent.name_len,&info);
239 ret = umsdos_delentry (dir,&info
240 ,S_ISDIR(data.umsdos_dirent.mode));
241 }else if (cmd == UMSDOS_UNLINK_DOS){
242
243
244
245
246
247
248
249 dir->i_count++;
250 ret = msdos_unlink (dir,data.dos_dirent.d_name
251 ,data.dos_dirent.d_reclen);
252 }else if (cmd == UMSDOS_RMDIR_DOS){
253
254
255
256
257
258
259
260 dir->i_count++;
261 ret = msdos_rmdir (dir,data.dos_dirent.d_name
262 ,data.dos_dirent.d_reclen);
263 }else if (cmd == UMSDOS_STAT_DOS){
264
265
266
267
268
269
270
271
272
273
274 struct inode *inode;
275 ret = umsdos_real_lookup (dir,data.dos_dirent.d_name
276 ,data.dos_dirent.d_reclen,&inode);
277 if (ret == 0){
278 data.stat.st_ino = inode->i_ino;
279 data.stat.st_mode = inode->i_mode;
280 data.stat.st_size = inode->i_size;
281 data.stat.st_atime = inode->i_atime;
282 data.stat.st_ctime = inode->i_ctime;
283 data.stat.st_mtime = inode->i_mtime;
284 memcpy_tofs (&idata->stat,&data.stat,sizeof(data.stat));
285 iput (inode);
286 }
287 }else if (cmd == UMSDOS_DOS_SETUP){
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307 dir->i_sb->u.msdos_sb.options.fs_uid = data.umsdos_dirent.uid;
308 dir->i_sb->u.msdos_sb.options.fs_gid = data.umsdos_dirent.gid;
309 dir->i_sb->u.msdos_sb.options.fs_umask = data.umsdos_dirent.mode;
310 ret = 0;
311 }
312 }
313 }
314 PRINTK (("ioctl return %d\n",ret));
315 return ret;
316 }
317
318
319