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