aboutsummaryrefslogtreecommitdiffstats
path: root/fs/msdos/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/msdos/namei.c')
-rw-r--r--fs/msdos/namei.c56
1 files changed, 27 insertions, 29 deletions
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 05ff4f1d7026..e844b9809d27 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -14,12 +14,7 @@
14 14
15/* Characters that are undesirable in an MS-DOS file name */ 15/* Characters that are undesirable in an MS-DOS file name */
16static unsigned char bad_chars[] = "*?<>|\""; 16static unsigned char bad_chars[] = "*?<>|\"";
17static unsigned char bad_if_strict_pc[] = "+=,; "; 17static unsigned char bad_if_strict[] = "+=,; ";
18/* GEMDOS is less restrictive */
19static unsigned char bad_if_strict_atari[] = " ";
20
21#define bad_if_strict(opts) \
22 ((opts)->atari ? bad_if_strict_atari : bad_if_strict_pc)
23 18
24/***** Formats an MS-DOS file name. Rejects invalid names. */ 19/***** Formats an MS-DOS file name. Rejects invalid names. */
25static int msdos_format_name(const unsigned char *name, int len, 20static int msdos_format_name(const unsigned char *name, int len,
@@ -40,21 +35,20 @@ static int msdos_format_name(const unsigned char *name, int len,
40 /* Get rid of dot - test for it elsewhere */ 35 /* Get rid of dot - test for it elsewhere */
41 name++; 36 name++;
42 len--; 37 len--;
43 } else if (!opts->atari) 38 } else
44 return -EINVAL; 39 return -EINVAL;
45 } 40 }
46 /* 41 /*
47 * disallow names that _really_ start with a dot for MS-DOS, 42 * disallow names that _really_ start with a dot
48 * GEMDOS does not care
49 */ 43 */
50 space = !opts->atari; 44 space = 1;
51 c = 0; 45 c = 0;
52 for (walk = res; len && walk - res < 8; walk++) { 46 for (walk = res; len && walk - res < 8; walk++) {
53 c = *name++; 47 c = *name++;
54 len--; 48 len--;
55 if (opts->name_check != 'r' && strchr(bad_chars, c)) 49 if (opts->name_check != 'r' && strchr(bad_chars, c))
56 return -EINVAL; 50 return -EINVAL;
57 if (opts->name_check == 's' && strchr(bad_if_strict(opts), c)) 51 if (opts->name_check == 's' && strchr(bad_if_strict, c))
58 return -EINVAL; 52 return -EINVAL;
59 if (c >= 'A' && c <= 'Z' && opts->name_check == 's') 53 if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
60 return -EINVAL; 54 return -EINVAL;
@@ -94,7 +88,7 @@ static int msdos_format_name(const unsigned char *name, int len,
94 if (opts->name_check != 'r' && strchr(bad_chars, c)) 88 if (opts->name_check != 'r' && strchr(bad_chars, c))
95 return -EINVAL; 89 return -EINVAL;
96 if (opts->name_check == 's' && 90 if (opts->name_check == 's' &&
97 strchr(bad_if_strict(opts), c)) 91 strchr(bad_if_strict, c))
98 return -EINVAL; 92 return -EINVAL;
99 if (c < ' ' || c == ':' || c == '\\') 93 if (c < ' ' || c == ':' || c == '\\')
100 return -EINVAL; 94 return -EINVAL;
@@ -214,7 +208,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
214 208
215 dentry->d_op = &msdos_dentry_operations; 209 dentry->d_op = &msdos_dentry_operations;
216 210
217 lock_kernel(); 211 lock_super(sb);
218 res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); 212 res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
219 if (res == -ENOENT) 213 if (res == -ENOENT)
220 goto add; 214 goto add;
@@ -232,7 +226,7 @@ add:
232 if (dentry) 226 if (dentry)
233 dentry->d_op = &msdos_dentry_operations; 227 dentry->d_op = &msdos_dentry_operations;
234out: 228out:
235 unlock_kernel(); 229 unlock_super(sb);
236 if (!res) 230 if (!res)
237 return dentry; 231 return dentry;
238 return ERR_PTR(res); 232 return ERR_PTR(res);
@@ -243,6 +237,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name,
243 int is_dir, int is_hid, int cluster, 237 int is_dir, int is_hid, int cluster,
244 struct timespec *ts, struct fat_slot_info *sinfo) 238 struct timespec *ts, struct fat_slot_info *sinfo)
245{ 239{
240 struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
246 struct msdos_dir_entry de; 241 struct msdos_dir_entry de;
247 __le16 time, date; 242 __le16 time, date;
248 int err; 243 int err;
@@ -252,7 +247,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name,
252 if (is_hid) 247 if (is_hid)
253 de.attr |= ATTR_HIDDEN; 248 de.attr |= ATTR_HIDDEN;
254 de.lcase = 0; 249 de.lcase = 0;
255 fat_date_unix2dos(ts->tv_sec, &time, &date); 250 fat_date_unix2dos(ts->tv_sec, &time, &date, sbi->options.tz_utc);
256 de.cdate = de.adate = 0; 251 de.cdate = de.adate = 0;
257 de.ctime = 0; 252 de.ctime = 0;
258 de.ctime_cs = 0; 253 de.ctime_cs = 0;
@@ -286,7 +281,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
286 unsigned char msdos_name[MSDOS_NAME]; 281 unsigned char msdos_name[MSDOS_NAME];
287 int err, is_hid; 282 int err, is_hid;
288 283
289 lock_kernel(); 284 lock_super(sb);
290 285
291 err = msdos_format_name(dentry->d_name.name, dentry->d_name.len, 286 err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
292 msdos_name, &MSDOS_SB(sb)->options); 287 msdos_name, &MSDOS_SB(sb)->options);
@@ -315,7 +310,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
315 310
316 d_instantiate(dentry, inode); 311 d_instantiate(dentry, inode);
317out: 312out:
318 unlock_kernel(); 313 unlock_super(sb);
319 if (!err) 314 if (!err)
320 err = fat_flush_inodes(sb, dir, inode); 315 err = fat_flush_inodes(sb, dir, inode);
321 return err; 316 return err;
@@ -324,11 +319,12 @@ out:
324/***** Remove a directory */ 319/***** Remove a directory */
325static int msdos_rmdir(struct inode *dir, struct dentry *dentry) 320static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
326{ 321{
322 struct super_block *sb = dir->i_sb;
327 struct inode *inode = dentry->d_inode; 323 struct inode *inode = dentry->d_inode;
328 struct fat_slot_info sinfo; 324 struct fat_slot_info sinfo;
329 int err; 325 int err;
330 326
331 lock_kernel(); 327 lock_super(sb);
332 /* 328 /*
333 * Check whether the directory is not in use, then check 329 * Check whether the directory is not in use, then check
334 * whether it is empty. 330 * whether it is empty.
@@ -349,9 +345,9 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
349 inode->i_ctime = CURRENT_TIME_SEC; 345 inode->i_ctime = CURRENT_TIME_SEC;
350 fat_detach(inode); 346 fat_detach(inode);
351out: 347out:
352 unlock_kernel(); 348 unlock_super(sb);
353 if (!err) 349 if (!err)
354 err = fat_flush_inodes(inode->i_sb, dir, inode); 350 err = fat_flush_inodes(sb, dir, inode);
355 351
356 return err; 352 return err;
357} 353}
@@ -366,7 +362,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode)
366 struct timespec ts; 362 struct timespec ts;
367 int err, is_hid, cluster; 363 int err, is_hid, cluster;
368 364
369 lock_kernel(); 365 lock_super(sb);
370 366
371 err = msdos_format_name(dentry->d_name.name, dentry->d_name.len, 367 err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
372 msdos_name, &MSDOS_SB(sb)->options); 368 msdos_name, &MSDOS_SB(sb)->options);
@@ -404,14 +400,14 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode)
404 400
405 d_instantiate(dentry, inode); 401 d_instantiate(dentry, inode);
406 402
407 unlock_kernel(); 403 unlock_super(sb);
408 fat_flush_inodes(sb, dir, inode); 404 fat_flush_inodes(sb, dir, inode);
409 return 0; 405 return 0;
410 406
411out_free: 407out_free:
412 fat_free_clusters(dir, cluster); 408 fat_free_clusters(dir, cluster);
413out: 409out:
414 unlock_kernel(); 410 unlock_super(sb);
415 return err; 411 return err;
416} 412}
417 413
@@ -419,10 +415,11 @@ out:
419static int msdos_unlink(struct inode *dir, struct dentry *dentry) 415static int msdos_unlink(struct inode *dir, struct dentry *dentry)
420{ 416{
421 struct inode *inode = dentry->d_inode; 417 struct inode *inode = dentry->d_inode;
418 struct super_block *sb= inode->i_sb;
422 struct fat_slot_info sinfo; 419 struct fat_slot_info sinfo;
423 int err; 420 int err;
424 421
425 lock_kernel(); 422 lock_super(sb);
426 err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); 423 err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
427 if (err) 424 if (err)
428 goto out; 425 goto out;
@@ -434,9 +431,9 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
434 inode->i_ctime = CURRENT_TIME_SEC; 431 inode->i_ctime = CURRENT_TIME_SEC;
435 fat_detach(inode); 432 fat_detach(inode);
436out: 433out:
437 unlock_kernel(); 434 unlock_super(sb);
438 if (!err) 435 if (!err)
439 err = fat_flush_inodes(inode->i_sb, dir, inode); 436 err = fat_flush_inodes(sb, dir, inode);
440 437
441 return err; 438 return err;
442} 439}
@@ -618,10 +615,11 @@ error_inode:
618static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, 615static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
619 struct inode *new_dir, struct dentry *new_dentry) 616 struct inode *new_dir, struct dentry *new_dentry)
620{ 617{
618 struct super_block *sb = old_dir->i_sb;
621 unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME]; 619 unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
622 int err, is_hid; 620 int err, is_hid;
623 621
624 lock_kernel(); 622 lock_super(sb);
625 623
626 err = msdos_format_name(old_dentry->d_name.name, 624 err = msdos_format_name(old_dentry->d_name.name,
627 old_dentry->d_name.len, old_msdos_name, 625 old_dentry->d_name.len, old_msdos_name,
@@ -640,9 +638,9 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
640 err = do_msdos_rename(old_dir, old_msdos_name, old_dentry, 638 err = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
641 new_dir, new_msdos_name, new_dentry, is_hid); 639 new_dir, new_msdos_name, new_dentry, is_hid);
642out: 640out:
643 unlock_kernel(); 641 unlock_super(sb);
644 if (!err) 642 if (!err)
645 err = fat_flush_inodes(old_dir->i_sb, old_dir, new_dir); 643 err = fat_flush_inodes(sb, old_dir, new_dir);
646 return err; 644 return err;
647} 645}
648 646