aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fat
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 20:25:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 20:25:34 -0400
commit27c1ee3f929555b71fa39ec0d81a7e7185de1b16 (patch)
tree42e40bdfe4efac660d650658019391536ce67a42 /fs/fat
parent37cd9600a9e20359b0283983c9e3a55d84347168 (diff)
parent086ff4b3a7fb9cdf41e6a5d0ccd99b86d84633a1 (diff)
Merge branch 'akpm' (Andrew's patch-bomb)
Merge Andrew's first set of patches: "Non-MM patches: - lots of misc bits - tree-wide have_clk() cleanups - quite a lot of printk tweaks. I draw your attention to "printk: convert the format for KERN_<LEVEL> to a 2 byte pattern" which looks a bit scary. But afaict it's solid. - backlight updates - lib/ feature work (notably the addition and use of memweight()) - checkpatch updates - rtc updates - nilfs updates - fatfs updates (partial, still waiting for acks) - kdump, proc, fork, IPC, sysctl, taskstats, pps, etc - new fault-injection feature work" * Merge emailed patches from Andrew Morton <akpm@linux-foundation.org>: (128 commits) drivers/misc/lkdtm.c: fix missing allocation failure check lib/scatterlist: do not re-write gfp_flags in __sg_alloc_table() fault-injection: add tool to run command with failslab or fail_page_alloc fault-injection: add selftests for cpu and memory hotplug powerpc: pSeries reconfig notifier error injection module memory: memory notifier error injection module PM: PM notifier error injection module cpu: rewrite cpu-notifier-error-inject module fault-injection: notifier error injection c/r: fcntl: add F_GETOWNER_UIDS option resource: make sure requested range is included in the root range include/linux/aio.h: cpp->C conversions fs: cachefiles: add support for large files in filesystem caching pps: return PTR_ERR on error in device_create taskstats: check nla_reserve() return sysctl: suppress kmemleak messages ipc: use Kconfig options for __ARCH_WANT_[COMPAT_]IPC_PARSE_VERSION ipc: compat: use signed size_t types for msgsnd and msgrcv ipc: allow compat IPC version field parsing if !ARCH_WANT_OLD_COMPAT_IPC ipc: add COMPAT_SHMLBA support ...
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/dir.c255
-rw-r--r--fs/fat/fat.h15
-rw-r--r--fs/fat/inode.c12
-rw-r--r--fs/fat/namei_msdos.c11
-rw-r--r--fs/fat/namei_vfat.c11
5 files changed, 161 insertions, 143 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 6eaa28c98ad1..dc49ed2cbffa 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -35,6 +35,11 @@
35#define FAT_MAX_UNI_CHARS ((MSDOS_SLOTS - 1) * 13 + 1) 35#define FAT_MAX_UNI_CHARS ((MSDOS_SLOTS - 1) * 13 + 1)
36#define FAT_MAX_UNI_SIZE (FAT_MAX_UNI_CHARS * sizeof(wchar_t)) 36#define FAT_MAX_UNI_SIZE (FAT_MAX_UNI_CHARS * sizeof(wchar_t))
37 37
38static inline unsigned char fat_tolower(unsigned char c)
39{
40 return ((c >= 'A') && (c <= 'Z')) ? c+32 : c;
41}
42
38static inline loff_t fat_make_i_pos(struct super_block *sb, 43static inline loff_t fat_make_i_pos(struct super_block *sb,
39 struct buffer_head *bh, 44 struct buffer_head *bh,
40 struct msdos_dir_entry *de) 45 struct msdos_dir_entry *de)
@@ -333,6 +338,124 @@ parse_long:
333 return 0; 338 return 0;
334} 339}
335 340
341/**
342 * fat_parse_short - Parse MS-DOS (short) directory entry.
343 * @sb: superblock
344 * @de: directory entry to parse
345 * @name: FAT_MAX_SHORT_SIZE array in which to place extracted name
346 * @dot_hidden: Nonzero == prepend '.' to names with ATTR_HIDDEN
347 *
348 * Returns the number of characters extracted into 'name'.
349 */
350static int fat_parse_short(struct super_block *sb,
351 const struct msdos_dir_entry *de,
352 unsigned char *name, int dot_hidden)
353{
354 const struct msdos_sb_info *sbi = MSDOS_SB(sb);
355 int isvfat = sbi->options.isvfat;
356 int nocase = sbi->options.nocase;
357 unsigned short opt_shortname = sbi->options.shortname;
358 struct nls_table *nls_disk = sbi->nls_disk;
359 wchar_t uni_name[14];
360 unsigned char c, work[MSDOS_NAME];
361 unsigned char *ptname = name;
362 int chi, chl, i, j, k;
363 int dotoffset = 0;
364 int name_len = 0, uni_len = 0;
365
366 if (!isvfat && dot_hidden && (de->attr & ATTR_HIDDEN)) {
367 *ptname++ = '.';
368 dotoffset = 1;
369 }
370
371 memcpy(work, de->name, sizeof(work));
372 /* see namei.c, msdos_format_name */
373 if (work[0] == 0x05)
374 work[0] = 0xE5;
375
376 /* Filename */
377 for (i = 0, j = 0; i < 8;) {
378 c = work[i];
379 if (!c)
380 break;
381 chl = fat_shortname2uni(nls_disk, &work[i], 8 - i,
382 &uni_name[j++], opt_shortname,
383 de->lcase & CASE_LOWER_BASE);
384 if (chl <= 1) {
385 if (!isvfat)
386 ptname[i] = nocase ? c : fat_tolower(c);
387 i++;
388 if (c != ' ') {
389 name_len = i;
390 uni_len = j;
391 }
392 } else {
393 uni_len = j;
394 if (isvfat)
395 i += min(chl, 8-i);
396 else {
397 for (chi = 0; chi < chl && i < 8; chi++, i++)
398 ptname[i] = work[i];
399 }
400 if (chl)
401 name_len = i;
402 }
403 }
404
405 i = name_len;
406 j = uni_len;
407 fat_short2uni(nls_disk, ".", 1, &uni_name[j++]);
408 if (!isvfat)
409 ptname[i] = '.';
410 i++;
411
412 /* Extension */
413 for (k = 8; k < MSDOS_NAME;) {
414 c = work[k];
415 if (!c)
416 break;
417 chl = fat_shortname2uni(nls_disk, &work[k], MSDOS_NAME - k,
418 &uni_name[j++], opt_shortname,
419 de->lcase & CASE_LOWER_EXT);
420 if (chl <= 1) {
421 k++;
422 if (!isvfat)
423 ptname[i] = nocase ? c : fat_tolower(c);
424 i++;
425 if (c != ' ') {
426 name_len = i;
427 uni_len = j;
428 }
429 } else {
430 uni_len = j;
431 if (isvfat) {
432 int offset = min(chl, MSDOS_NAME-k);
433 k += offset;
434 i += offset;
435 } else {
436 for (chi = 0; chi < chl && k < MSDOS_NAME;
437 chi++, i++, k++) {
438 ptname[i] = work[k];
439 }
440 }
441 if (chl)
442 name_len = i;
443 }
444 }
445
446 if (name_len > 0) {
447 name_len += dotoffset;
448
449 if (sbi->options.isvfat) {
450 uni_name[uni_len] = 0x0000;
451 name_len = fat_uni_to_x8(sb, uni_name, name,
452 FAT_MAX_SHORT_SIZE);
453 }
454 }
455
456 return name_len;
457}
458
336/* 459/*
337 * Return values: negative -> error, 0 -> not found, positive -> found, 460 * Return values: negative -> error, 0 -> not found, positive -> found,
338 * value is the total amount of slots, including the shortname entry. 461 * value is the total amount of slots, including the shortname entry.
@@ -344,15 +467,11 @@ int fat_search_long(struct inode *inode, const unsigned char *name,
344 struct msdos_sb_info *sbi = MSDOS_SB(sb); 467 struct msdos_sb_info *sbi = MSDOS_SB(sb);
345 struct buffer_head *bh = NULL; 468 struct buffer_head *bh = NULL;
346 struct msdos_dir_entry *de; 469 struct msdos_dir_entry *de;
347 struct nls_table *nls_disk = sbi->nls_disk;
348 unsigned char nr_slots; 470 unsigned char nr_slots;
349 wchar_t bufuname[14];
350 wchar_t *unicode = NULL; 471 wchar_t *unicode = NULL;
351 unsigned char work[MSDOS_NAME];
352 unsigned char bufname[FAT_MAX_SHORT_SIZE]; 472 unsigned char bufname[FAT_MAX_SHORT_SIZE];
353 unsigned short opt_shortname = sbi->options.shortname;
354 loff_t cpos = 0; 473 loff_t cpos = 0;
355 int chl, i, j, last_u, err, len; 474 int err, len;
356 475
357 err = -ENOENT; 476 err = -ENOENT;
358 while (1) { 477 while (1) {
@@ -380,47 +499,16 @@ parse_record:
380 goto end_of_dir; 499 goto end_of_dir;
381 } 500 }
382 501
383 memcpy(work, de->name, sizeof(de->name)); 502 /* Never prepend '.' to hidden files here.
384 /* see namei.c, msdos_format_name */ 503 * That is done only for msdos mounts (and only when
385 if (work[0] == 0x05) 504 * 'dotsOK=yes'); if we are executing here, it is in the
386 work[0] = 0xE5; 505 * context of a vfat mount.
387 for (i = 0, j = 0, last_u = 0; i < 8;) { 506 */
388 if (!work[i]) 507 len = fat_parse_short(sb, de, bufname, 0);
389 break; 508 if (len == 0)
390 chl = fat_shortname2uni(nls_disk, &work[i], 8 - i,
391 &bufuname[j++], opt_shortname,
392 de->lcase & CASE_LOWER_BASE);
393 if (chl <= 1) {
394 if (work[i] != ' ')
395 last_u = j;
396 } else {
397 last_u = j;
398 }
399 i += chl;
400 }
401 j = last_u;
402 fat_short2uni(nls_disk, ".", 1, &bufuname[j++]);
403 for (i = 8; i < MSDOS_NAME;) {
404 if (!work[i])
405 break;
406 chl = fat_shortname2uni(nls_disk, &work[i],
407 MSDOS_NAME - i,
408 &bufuname[j++], opt_shortname,
409 de->lcase & CASE_LOWER_EXT);
410 if (chl <= 1) {
411 if (work[i] != ' ')
412 last_u = j;
413 } else {
414 last_u = j;
415 }
416 i += chl;
417 }
418 if (!last_u)
419 continue; 509 continue;
420 510
421 /* Compare shortname */ 511 /* Compare shortname */
422 bufuname[last_u] = 0x0000;
423 len = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname));
424 if (fat_name_match(sbi, name, name_len, bufname, len)) 512 if (fat_name_match(sbi, name, name_len, bufname, len))
425 goto found; 513 goto found;
426 514
@@ -469,20 +557,15 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
469 struct msdos_sb_info *sbi = MSDOS_SB(sb); 557 struct msdos_sb_info *sbi = MSDOS_SB(sb);
470 struct buffer_head *bh; 558 struct buffer_head *bh;
471 struct msdos_dir_entry *de; 559 struct msdos_dir_entry *de;
472 struct nls_table *nls_disk = sbi->nls_disk;
473 unsigned char nr_slots; 560 unsigned char nr_slots;
474 wchar_t bufuname[14];
475 wchar_t *unicode = NULL; 561 wchar_t *unicode = NULL;
476 unsigned char c, work[MSDOS_NAME]; 562 unsigned char bufname[FAT_MAX_SHORT_SIZE];
477 unsigned char bufname[FAT_MAX_SHORT_SIZE], *ptname = bufname;
478 unsigned short opt_shortname = sbi->options.shortname;
479 int isvfat = sbi->options.isvfat; 563 int isvfat = sbi->options.isvfat;
480 int nocase = sbi->options.nocase;
481 const char *fill_name = NULL; 564 const char *fill_name = NULL;
482 unsigned long inum; 565 unsigned long inum;
483 unsigned long lpos, dummy, *furrfu = &lpos; 566 unsigned long lpos, dummy, *furrfu = &lpos;
484 loff_t cpos; 567 loff_t cpos;
485 int chi, chl, i, i2, j, last, last_u, dotoffset = 0, fill_len = 0; 568 int short_len = 0, fill_len = 0;
486 int ret = 0; 569 int ret = 0;
487 570
488 lock_super(sb); 571 lock_super(sb);
@@ -556,74 +639,10 @@ parse_record:
556 } 639 }
557 } 640 }
558 641
559 if (sbi->options.dotsOK) { 642 short_len = fat_parse_short(sb, de, bufname, sbi->options.dotsOK);
560 ptname = bufname; 643 if (short_len == 0)
561 dotoffset = 0;
562 if (de->attr & ATTR_HIDDEN) {
563 *ptname++ = '.';
564 dotoffset = 1;
565 }
566 }
567
568 memcpy(work, de->name, sizeof(de->name));
569 /* see namei.c, msdos_format_name */
570 if (work[0] == 0x05)
571 work[0] = 0xE5;
572 for (i = 0, j = 0, last = 0, last_u = 0; i < 8;) {
573 if (!(c = work[i]))
574 break;
575 chl = fat_shortname2uni(nls_disk, &work[i], 8 - i,
576 &bufuname[j++], opt_shortname,
577 de->lcase & CASE_LOWER_BASE);
578 if (chl <= 1) {
579 ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
580 if (c != ' ') {
581 last = i;
582 last_u = j;
583 }
584 } else {
585 last_u = j;
586 for (chi = 0; chi < chl && i < 8; chi++) {
587 ptname[i] = work[i];
588 i++; last = i;
589 }
590 }
591 }
592 i = last;
593 j = last_u;
594 fat_short2uni(nls_disk, ".", 1, &bufuname[j++]);
595 ptname[i++] = '.';
596 for (i2 = 8; i2 < MSDOS_NAME;) {
597 if (!(c = work[i2]))
598 break;
599 chl = fat_shortname2uni(nls_disk, &work[i2], MSDOS_NAME - i2,
600 &bufuname[j++], opt_shortname,
601 de->lcase & CASE_LOWER_EXT);
602 if (chl <= 1) {
603 i2++;
604 ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
605 if (c != ' ') {
606 last = i;
607 last_u = j;
608 }
609 } else {
610 last_u = j;
611 for (chi = 0; chi < chl && i2 < MSDOS_NAME; chi++) {
612 ptname[i++] = work[i2++];
613 last = i;
614 }
615 }
616 }
617 if (!last)
618 goto record_end; 644 goto record_end;
619 645
620 i = last + dotoffset;
621 j = last_u;
622
623 if (isvfat) {
624 bufuname[j] = 0x0000;
625 i = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname));
626 }
627 if (nr_slots) { 646 if (nr_slots) {
628 /* hack for fat_ioctl_filldir() */ 647 /* hack for fat_ioctl_filldir() */
629 struct fat_ioctl_filldir_callback *p = dirent; 648 struct fat_ioctl_filldir_callback *p = dirent;
@@ -631,12 +650,12 @@ parse_record:
631 p->longname = fill_name; 650 p->longname = fill_name;
632 p->long_len = fill_len; 651 p->long_len = fill_len;
633 p->shortname = bufname; 652 p->shortname = bufname;
634 p->short_len = i; 653 p->short_len = short_len;
635 fill_name = NULL; 654 fill_name = NULL;
636 fill_len = 0; 655 fill_len = 0;
637 } else { 656 } else {
638 fill_name = bufname; 657 fill_name = bufname;
639 fill_len = i; 658 fill_len = short_len;
640 } 659 }
641 660
642start_filldir: 661start_filldir:
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index fc35c5c69136..2deeeb86f331 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -217,6 +217,21 @@ static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len)
217#endif 217#endif
218} 218}
219 219
220static inline int fat_get_start(const struct msdos_sb_info *sbi,
221 const struct msdos_dir_entry *de)
222{
223 int cluster = le16_to_cpu(de->start);
224 if (sbi->fat_bits == 32)
225 cluster |= (le16_to_cpu(de->starthi) << 16);
226 return cluster;
227}
228
229static inline void fat_set_start(struct msdos_dir_entry *de, int cluster)
230{
231 de->start = cpu_to_le16(cluster);
232 de->starthi = cpu_to_le16(cluster >> 16);
233}
234
220static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len) 235static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len)
221{ 236{
222#ifdef __BIG_ENDIAN 237#ifdef __BIG_ENDIAN
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 0038b32cb362..05e897fe9866 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -369,10 +369,7 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
369 inode->i_op = sbi->dir_ops; 369 inode->i_op = sbi->dir_ops;
370 inode->i_fop = &fat_dir_operations; 370 inode->i_fop = &fat_dir_operations;
371 371
372 MSDOS_I(inode)->i_start = le16_to_cpu(de->start); 372 MSDOS_I(inode)->i_start = fat_get_start(sbi, de);
373 if (sbi->fat_bits == 32)
374 MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
375
376 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start; 373 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
377 error = fat_calc_dir_size(inode); 374 error = fat_calc_dir_size(inode);
378 if (error < 0) 375 if (error < 0)
@@ -385,9 +382,7 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
385 inode->i_mode = fat_make_mode(sbi, de->attr, 382 inode->i_mode = fat_make_mode(sbi, de->attr,
386 ((sbi->options.showexec && !is_exec(de->name + 8)) 383 ((sbi->options.showexec && !is_exec(de->name + 8))
387 ? S_IRUGO|S_IWUGO : S_IRWXUGO)); 384 ? S_IRUGO|S_IWUGO : S_IRWXUGO));
388 MSDOS_I(inode)->i_start = le16_to_cpu(de->start); 385 MSDOS_I(inode)->i_start = fat_get_start(sbi, de);
389 if (sbi->fat_bits == 32)
390 MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
391 386
392 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start; 387 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
393 inode->i_size = le32_to_cpu(de->size); 388 inode->i_size = le32_to_cpu(de->size);
@@ -613,8 +608,7 @@ retry:
613 else 608 else
614 raw_entry->size = cpu_to_le32(inode->i_size); 609 raw_entry->size = cpu_to_le32(inode->i_size);
615 raw_entry->attr = fat_make_attrs(inode); 610 raw_entry->attr = fat_make_attrs(inode);
616 raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart); 611 fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart);
617 raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
618 fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time, 612 fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time,
619 &raw_entry->date, NULL); 613 &raw_entry->date, NULL);
620 if (sbi->options.isvfat) { 614 if (sbi->options.isvfat) {
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 70d993a93805..b0e12bf9f4a1 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -246,8 +246,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name,
246 de.ctime_cs = 0; 246 de.ctime_cs = 0;
247 de.time = time; 247 de.time = time;
248 de.date = date; 248 de.date = date;
249 de.start = cpu_to_le16(cluster); 249 fat_set_start(&de, cluster);
250 de.starthi = cpu_to_le16(cluster >> 16);
251 de.size = 0; 250 de.size = 0;
252 251
253 err = fat_add_entries(dir, &de, 1, sinfo); 252 err = fat_add_entries(dir, &de, 1, sinfo);
@@ -530,9 +529,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
530 mark_inode_dirty(old_inode); 529 mark_inode_dirty(old_inode);
531 530
532 if (update_dotdot) { 531 if (update_dotdot) {
533 int start = MSDOS_I(new_dir)->i_logstart; 532 fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart);
534 dotdot_de->start = cpu_to_le16(start);
535 dotdot_de->starthi = cpu_to_le16(start >> 16);
536 mark_buffer_dirty_inode(dotdot_bh, old_inode); 533 mark_buffer_dirty_inode(dotdot_bh, old_inode);
537 if (IS_DIRSYNC(new_dir)) { 534 if (IS_DIRSYNC(new_dir)) {
538 err = sync_dirty_buffer(dotdot_bh); 535 err = sync_dirty_buffer(dotdot_bh);
@@ -572,9 +569,7 @@ error_dotdot:
572 corrupt = 1; 569 corrupt = 1;
573 570
574 if (update_dotdot) { 571 if (update_dotdot) {
575 int start = MSDOS_I(old_dir)->i_logstart; 572 fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart);
576 dotdot_de->start = cpu_to_le16(start);
577 dotdot_de->starthi = cpu_to_le16(start >> 16);
578 mark_buffer_dirty_inode(dotdot_bh, old_inode); 573 mark_buffer_dirty_inode(dotdot_bh, old_inode);
579 corrupt |= sync_dirty_buffer(dotdot_bh); 574 corrupt |= sync_dirty_buffer(dotdot_bh);
580 } 575 }
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 6cc480652433..6a6d8c0715a1 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -651,8 +651,7 @@ shortname:
651 de->time = de->ctime = time; 651 de->time = de->ctime = time;
652 de->date = de->cdate = de->adate = date; 652 de->date = de->cdate = de->adate = date;
653 de->ctime_cs = time_cs; 653 de->ctime_cs = time_cs;
654 de->start = cpu_to_le16(cluster); 654 fat_set_start(de, cluster);
655 de->starthi = cpu_to_le16(cluster >> 16);
656 de->size = 0; 655 de->size = 0;
657out_free: 656out_free:
658 __putname(uname); 657 __putname(uname);
@@ -965,9 +964,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
965 mark_inode_dirty(old_inode); 964 mark_inode_dirty(old_inode);
966 965
967 if (update_dotdot) { 966 if (update_dotdot) {
968 int start = MSDOS_I(new_dir)->i_logstart; 967 fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart);
969 dotdot_de->start = cpu_to_le16(start);
970 dotdot_de->starthi = cpu_to_le16(start >> 16);
971 mark_buffer_dirty_inode(dotdot_bh, old_inode); 968 mark_buffer_dirty_inode(dotdot_bh, old_inode);
972 if (IS_DIRSYNC(new_dir)) { 969 if (IS_DIRSYNC(new_dir)) {
973 err = sync_dirty_buffer(dotdot_bh); 970 err = sync_dirty_buffer(dotdot_bh);
@@ -1009,9 +1006,7 @@ error_dotdot:
1009 corrupt = 1; 1006 corrupt = 1;
1010 1007
1011 if (update_dotdot) { 1008 if (update_dotdot) {
1012 int start = MSDOS_I(old_dir)->i_logstart; 1009 fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart);
1013 dotdot_de->start = cpu_to_le16(start);
1014 dotdot_de->starthi = cpu_to_le16(start >> 16);
1015 mark_buffer_dirty_inode(dotdot_bh, old_inode); 1010 mark_buffer_dirty_inode(dotdot_bh, old_inode);
1016 corrupt |= sync_dirty_buffer(dotdot_bh); 1011 corrupt |= sync_dirty_buffer(dotdot_bh);
1017 } 1012 }