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