| 1 | frodo | 308 | diff -r -u2 -p linux-2.6.22.unpatched/fs/fat/dir.c linux-2.6.22/fs/fat/dir.c | 
| 2 |  |  | --- linux-2.6.22.unpatched/fs/fat/dir.c 2007-11-06 22:45:27.000000000 +0100 | 
| 3 |  |  | +++ linux-2.6.22/fs/fat/dir.c   2007-11-06 22:59:08.000000000 +0100 | 
| 4 |  |  | @@ -242,4 +242,5 @@ static int fat_parse_long(struct inode * | 
| 5 | frodo | 303 | struct msdos_dir_slot *ds; | 
| 6 |  |  | unsigned char id, slot, slots, alias_checksum; | 
| 7 |  |  | +       int epoc = MSDOS_SB(dir->i_sb)->options.epoc; | 
| 8 |  |  |  | 
| 9 |  |  | if (!*unicode) { | 
| 10 | frodo | 308 | @@ -288,4 +289,8 @@ parse_long: | 
| 11 | frodo | 303 | if ((*de)->name[0] == DELETED_FLAG) | 
| 12 |  |  | return PARSE_INVALID; | 
| 13 | frodo | 308 | +       if (epoc && ((*de)->name[0] == EOD_FLAG)) { | 
| 14 |  |  | +               while (fat_get_entry(dir, pos, bh, de) >= 0); | 
| 15 | frodo | 303 | +               return PARSE_EOF; | 
| 16 | frodo | 308 | +       } | 
| 17 | frodo | 303 | if ((*de)->attr == ATTR_EXT) | 
| 18 |  |  | goto parse_long; | 
| 19 | frodo | 308 | @@ -321,4 +326,5 @@ int fat_search_long(struct inode *inode, | 
| 20 | frodo | 303 | loff_t cpos = 0; | 
| 21 |  |  | int chl, i, j, last_u, err; | 
| 22 |  |  | +       int epoc = sbi->options.epoc; | 
| 23 |  |  |  | 
| 24 |  |  | err = -ENOENT; | 
| 25 | frodo | 308 | @@ -330,4 +336,8 @@ parse_record: | 
| 26 | frodo | 303 | if (de->name[0] == DELETED_FLAG) | 
| 27 |  |  | continue; | 
| 28 | frodo | 308 | +               if (epoc && (de->name[0] == EOD_FLAG)) { | 
| 29 |  |  | +                       while (fat_get_entry(inode, &cpos, &bh, &de) >= 0); | 
| 30 | frodo | 303 | +                       goto EODir; | 
| 31 | frodo | 308 | +               } | 
| 32 | frodo | 303 | if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME)) | 
| 33 |  |  | continue; | 
| 34 | frodo | 308 | @@ -457,4 +467,6 @@ static int __fat_readdir(struct inode *i | 
| 35 | frodo | 303 | loff_t cpos; | 
| 36 |  |  | int ret = 0; | 
| 37 |  |  | +       int epoc = MSDOS_SB(sb)->options.epoc; | 
| 38 |  |  | + | 
| 39 |  |  |  | 
| 40 |  |  | lock_kernel(); | 
| 41 | frodo | 308 | @@ -487,4 +499,8 @@ parse_record: | 
| 42 | frodo | 303 | long_slots = 0; | 
| 43 |  |  | /* Check for long filename entry */ | 
| 44 | frodo | 308 | +       if (epoc && (de->name[0] == EOD_FLAG)) { | 
| 45 |  |  | +               while (fat_get_entry(inode, &cpos, &bh, &de) >= 0); | 
| 46 | frodo | 303 | +               goto EODir; | 
| 47 | frodo | 308 | +       } | 
| 48 | frodo | 303 | if (isvfat) { | 
| 49 |  |  | if (de->name[0] == DELETED_FLAG) | 
| 50 | frodo | 308 | @@ -810,5 +826,10 @@ static int fat_get_short_entry(struct in | 
| 51 | frodo | 303 | struct msdos_dir_entry **de) | 
| 52 |  |  | { | 
| 53 |  |  | +       int epoc = MSDOS_SB(dir->i_sb)->options.epoc; | 
| 54 |  |  | while (fat_get_entry(dir, pos, bh, de) >= 0) { | 
| 55 | frodo | 308 | +               if (epoc && ((*de)->name[0] == EOD_FLAG)) { | 
| 56 |  |  | +                       while (fat_get_entry(dir, pos, bh, de) >= 0); | 
| 57 | frodo | 303 | +                       return -ENOENT; | 
| 58 | frodo | 308 | +               } | 
| 59 | frodo | 303 | /* free entry or long name entry or volume label */ | 
| 60 |  |  | if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME)) | 
| 61 | frodo | 308 | @@ -1188,4 +1209,23 @@ error: | 
| 62 | frodo | 303 | } | 
| 63 |  |  |  | 
| 64 |  |  | +int fat_write_zero_entry(struct inode *dir, loff_t curr) | 
| 65 |  |  | +{ | 
| 66 |  |  | +       struct msdos_dir_entry *de = NULL; | 
| 67 |  |  | +       struct buffer_head *bh = NULL; | 
| 68 |  |  | +       loff_t pos; | 
| 69 |  |  | +       int err = 0; | 
| 70 |  |  | + | 
| 71 |  |  | +       pos = curr; | 
| 72 |  |  | +       if (fat_get_entry(dir,&pos,&bh,&de) < 0) | 
| 73 |  |  | +               return 0; | 
| 74 |  |  | + | 
| 75 |  |  | +       de->name[0] = EOD_FLAG; | 
| 76 |  |  | +       mark_buffer_dirty(bh); | 
| 77 |  |  | +       if (IS_DIRSYNC(dir)) | 
| 78 |  |  | +               err = sync_dirty_buffer(bh); | 
| 79 |  |  | +       brelse(bh); | 
| 80 |  |  | +       return err; | 
| 81 |  |  | +} | 
| 82 |  |  | + | 
| 83 |  |  | int fat_add_entries(struct inode *dir, void *slots, int nr_slots, | 
| 84 |  |  | struct fat_slot_info *sinfo) | 
| 85 | frodo | 308 | @@ -1197,4 +1237,6 @@ int fat_add_entries(struct inode *dir, v | 
| 86 | frodo | 303 | int err, free_slots, i, nr_bhs; | 
| 87 |  |  | loff_t pos, i_pos; | 
| 88 |  |  | +       int epoc = sbi->options.epoc; | 
| 89 |  |  | +       int last_entry = 0; | 
| 90 |  |  |  | 
| 91 |  |  | sinfo->nr_slots = nr_slots; | 
| 92 | frodo | 308 | @@ -1210,5 +1252,7 @@ int fat_add_entries(struct inode *dir, v | 
| 93 | frodo | 303 | goto error; | 
| 94 |  |  |  | 
| 95 |  |  | -               if (IS_FREE(de->name)) { | 
| 96 |  |  | +               if (epoc && (de->name[0] == EOD_FLAG)) | 
| 97 |  |  | +                       last_entry = 1; | 
| 98 |  |  | +               if (last_entry || IS_FREE(de->name)) { | 
| 99 |  |  | if (prev != bh) { | 
| 100 |  |  | get_bh(bh); | 
| 101 | frodo | 308 | @@ -1240,4 +1284,15 @@ found: | 
| 102 | frodo | 303 | pos -= free_slots * sizeof(*de); | 
| 103 |  |  | nr_slots -= free_slots; | 
| 104 |  |  | + | 
| 105 |  |  | +       /* We need to write an end-of-directory slot. And we do it first, | 
| 106 |  |  | +         * because we want to keep the directory in a readble state. | 
| 107 |  |  | +         * Note that there is no need to remove it on error, as it is beyond | 
| 108 |  |  | +         * the visible end of directory anyway. | 
| 109 |  |  | +         */ | 
| 110 |  |  | +        if (epoc && !nr_slots && last_entry) | 
| 111 |  |  | +                err = fat_write_zero_entry(dir, pos + free_slots * sizeof(*de)); | 
| 112 |  |  | +       if (err) | 
| 113 |  |  | +               goto error; | 
| 114 |  |  | + | 
| 115 |  |  | if (free_slots) { | 
| 116 |  |  | /* | 
| 117 | frodo | 308 | diff -r -u2 -p linux-2.6.22.unpatched/fs/fat/inode.c linux-2.6.22/fs/fat/inode.c | 
| 118 |  |  | --- linux-2.6.22.unpatched/fs/fat/inode.c       2007-11-06 22:45:27.000000000 +0100 | 
| 119 |  |  | +++ linux-2.6.22/fs/fat/inode.c 2007-11-06 22:47:36.000000000 +0100 | 
| 120 |  |  | @@ -857,4 +857,5 @@ enum { | 
| 121 | frodo | 303 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, | 
| 122 |  |  | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 
| 123 |  |  | +       Opt_epoc, | 
| 124 |  |  | Opt_obsolate, Opt_flush, Opt_err, | 
| 125 |  |  | }; | 
| 126 | frodo | 308 | @@ -879,4 +880,5 @@ static match_table_t fat_tokens = { | 
| 127 | frodo | 303 | {Opt_debug, "debug"}, | 
| 128 |  |  | {Opt_immutable, "sys_immutable"}, | 
| 129 |  |  | +       {Opt_epoc, "epoc"}, | 
| 130 |  |  | {Opt_obsolate, "conv=binary"}, | 
| 131 |  |  | {Opt_obsolate, "conv=text"}, | 
| 132 | frodo | 308 | @@ -1038,4 +1040,8 @@ static int parse_options(char *options, | 
| 133 | frodo | 303 | opts->flush = 1; | 
| 134 |  |  | break; | 
| 135 |  |  | +               case Opt_epoc: | 
| 136 |  |  | +                       opts->epoc = 1; | 
| 137 |  |  | +                       break; | 
| 138 |  |  | + | 
| 139 |  |  |  | 
| 140 |  |  | /* msdos specific */ | 
| 141 | frodo | 308 | diff -r -u2 -p linux-2.6.22.unpatched/include/linux/msdos_fs.h linux-2.6.22/include/linux/msdos_fs.h | 
| 142 |  |  | --- linux-2.6.22.unpatched/include/linux/msdos_fs.h     2007-11-06 22:46:01.000000000 +0100 | 
| 143 |  |  | +++ linux-2.6.22/include/linux/msdos_fs.h       2007-11-06 22:47:36.000000000 +0100 | 
| 144 |  |  | @@ -45,4 +45,5 @@ | 
| 145 | frodo | 303 |  | 
| 146 |  |  | #define DELETED_FLAG   0xe5    /* marks file as deleted when in name[0] */ | 
| 147 |  |  | +#define EOD_FLAG 0x00 /* marks end of directory when in name[0] for old fats */ | 
| 148 |  |  | #define IS_FREE(n)     (!*(n) || *(n) == DELETED_FLAG) | 
| 149 |  |  |  | 
| 150 | frodo | 308 | @@ -207,4 +208,5 @@ struct fat_mount_options { | 
| 151 | frodo | 303 | flush:1,         /* write things quickly */ | 
| 152 |  |  | nocase:1,        /* Does this need case conversion? 0=need case conversion*/ | 
| 153 | frodo | 306 | +                epoc:1,          /* Filename starting with 0x00 marks end of dir? */ | 
| 154 | frodo | 303 | usefree:1;       /* Use free_clusters for FAT32 */ | 
| 155 |  |  | }; |