| 1 | frodo | 284 | diff -r2 -u linux-source-2.6.12.unpatched/fs/fat/dir.c linux-source-2.6.12/fs/fat/dir.c | 
| 2 | frodo | 283 | --- linux-source-2.6.12.unpatched/fs/fat/dir.c  2005-06-17 21:48:29.000000000 +0200 | 
| 3 | frodo | 284 | +++ linux-source-2.6.12/fs/fat/dir.c    2005-11-21 21:00:07.000000000 +0100 | 
| 4 | frodo | 283 | @@ -221,4 +221,5 @@ | 
| 5 |  |  | loff_t cpos = 0; | 
| 6 |  |  | int chl, i, j, last_u, err; | 
| 7 |  |  | +       int epoc = sbi->options.epoc; | 
| 8 |  |  |  | 
| 9 |  |  | err = -ENOENT; | 
| 10 |  |  | @@ -230,4 +231,6 @@ | 
| 11 |  |  | if (de->name[0] == DELETED_FLAG) | 
| 12 |  |  | continue; | 
| 13 |  |  | +                if (epoc && (de->name[0] == EOD_FLAG)) | 
| 14 |  |  | +                        goto EODir; | 
| 15 |  |  | if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME)) | 
| 16 |  |  | continue; | 
| 17 |  |  | @@ -287,4 +290,6 @@ | 
| 18 |  |  | goto parse_long; | 
| 19 |  |  | } | 
| 20 |  |  | +                        if (epoc && (de->name[0] == EOD_FLAG)) | 
| 21 |  |  | +                                goto EODir; | 
| 22 |  |  | if (de->name[0] == DELETED_FLAG) | 
| 23 |  |  | continue; | 
| 24 |  |  | @@ -395,4 +400,6 @@ | 
| 25 |  |  | unsigned char long_slots; | 
| 26 |  |  | const char *fill_name; | 
| 27 |  |  | +        int epoc = MSDOS_SB(sb)->options.epoc; | 
| 28 |  |  | +        int last_entry = 0; | 
| 29 |  |  | int fill_len; | 
| 30 |  |  | wchar_t bufuname[14]; | 
| 31 |  |  | @@ -437,4 +444,8 @@ | 
| 32 |  |  | if (fat_get_entry(inode, &cpos, &bh, &de) == -1) | 
| 33 |  |  | goto EODir; | 
| 34 |  |  | +        if (epoc && (de->name[0] == EOD_FLAG)) | 
| 35 |  |  | +                last_entry = 1; | 
| 36 |  |  | +        if (last_entry) | 
| 37 |  |  | +                goto RecEnd; | 
| 38 |  |  | /* Check for long filename entry */ | 
| 39 |  |  | if (isvfat) { | 
| 40 |  |  | @@ -504,4 +515,8 @@ | 
| 41 |  |  | goto ParseLong; | 
| 42 |  |  | } | 
| 43 |  |  | +                if (epoc && (de->name[0] == EOD_FLAG)) { | 
| 44 |  |  | +                        last_entry = 1; | 
| 45 |  |  | +                        goto RecEnd; | 
| 46 |  |  | +                } | 
| 47 |  |  | if (de->name[0] == DELETED_FLAG) | 
| 48 |  |  | goto RecEnd; | 
| 49 |  |  | @@ -757,5 +772,8 @@ | 
| 50 |  |  | struct msdos_dir_entry **de) | 
| 51 |  |  | { | 
| 52 |  |  | +        int epoc = MSDOS_SB(dir->i_sb)->options.epoc; | 
| 53 |  |  | while (fat_get_entry(dir, pos, bh, de) >= 0) { | 
| 54 |  |  | +                if (epoc && ((*de)->name[0] == EOD_FLAG)) | 
| 55 |  |  | +                        return -ENOENT; | 
| 56 |  |  | /* free entry or long name entry or volume label */ | 
| 57 |  |  | if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME)) | 
| 58 |  |  | @@ -773,8 +791,11 @@ | 
| 59 |  |  | { | 
| 60 |  |  | loff_t offset; | 
| 61 |  |  | +        int epoc = MSDOS_SB(dir->i_sb)->options.epoc; | 
| 62 |  |  |  | 
| 63 |  |  | offset = 0; | 
| 64 |  |  | *bh = NULL; | 
| 65 |  |  | while (fat_get_short_entry(dir, &offset, bh, de) >= 0) { | 
| 66 |  |  | +                if (epoc && ((*de)->name[0] == EOD_FLAG)) | 
| 67 |  |  | +                        return -ENOENT; | 
| 68 |  |  | if (!strncmp((*de)->name, MSDOS_DOTDOT, MSDOS_NAME)) { | 
| 69 |  |  | *i_pos = fat_make_i_pos(dir->i_sb, *bh, *de); | 
| 70 |  |  | @@ -1135,4 +1156,25 @@ | 
| 71 |  |  | } | 
| 72 |  |  |  | 
| 73 |  |  | +/* Set the first character of the next entry to zero. */ | 
| 74 | frodo | 284 | +int fat_write_zero_entry(struct inode *dir, loff_t curr) | 
| 75 | frodo | 283 | +{ | 
| 76 |  |  | +       struct msdos_dir_entry *de = NULL; | 
| 77 |  |  | +       struct buffer_head *bh = NULL; | 
| 78 |  |  | +       loff_t pos; | 
| 79 | frodo | 284 | +       int err = 0; | 
| 80 | frodo | 283 | + | 
| 81 |  |  | +       pos = curr; | 
| 82 |  |  | +       if (fat_get_entry(dir,&pos,&bh,&de) < 0) | 
| 83 | frodo | 284 | +               return 0; | 
| 84 | frodo | 283 | + | 
| 85 |  |  | +       de->name[0] = EOD_FLAG; | 
| 86 |  |  | +       mark_buffer_dirty(bh); | 
| 87 |  |  | +       if (IS_DIRSYNC(dir)) | 
| 88 |  |  | +               err = sync_dirty_buffer(bh); | 
| 89 |  |  | +       brelse(bh); | 
| 90 | frodo | 284 | +       return err; | 
| 91 | frodo | 283 | +} | 
| 92 |  |  | + | 
| 93 |  |  | + | 
| 94 |  |  | int fat_add_entries(struct inode *dir, void *slots, int nr_slots, | 
| 95 |  |  | struct fat_slot_info *sinfo) | 
| 96 |  |  | @@ -1144,4 +1186,7 @@ | 
| 97 |  |  | int err, free_slots, i, nr_bhs; | 
| 98 |  |  | loff_t pos, i_pos; | 
| 99 |  |  | +        int epoc = sbi->options.epoc; | 
| 100 |  |  | +       int last_entry = 0; | 
| 101 |  |  | + | 
| 102 |  |  |  | 
| 103 |  |  | sinfo->nr_slots = nr_slots; | 
| 104 |  |  | @@ -1157,5 +1202,8 @@ | 
| 105 |  |  | goto error; | 
| 106 |  |  |  | 
| 107 |  |  | -               if (IS_FREE(de->name)) { | 
| 108 |  |  | +                if ((epoc && (de->name[0] == EOD_FLAG))) | 
| 109 |  |  | +                        last_entry = 1; | 
| 110 |  |  | + | 
| 111 |  |  | +               if (last_entry || IS_FREE(de->name)) { | 
| 112 |  |  | if (prev != bh) { | 
| 113 |  |  | get_bh(bh); | 
| 114 | frodo | 284 | @@ -1185,6 +1233,18 @@ | 
| 115 |  |  | found: | 
| 116 |  |  | err = 0; | 
| 117 |  |  | + | 
| 118 |  |  | pos -= free_slots * sizeof(*de); | 
| 119 |  |  | nr_slots -= free_slots; | 
| 120 |  |  | + | 
| 121 |  |  | +       /* We need to write an end-of-directory slot. And we do it first, | 
| 122 |  |  | +        * because we want to keep the directory in a readble state. | 
| 123 |  |  | +        * Note that there is no need to remove it on error, as it is beyond | 
| 124 |  |  | +        * the visible end of directory anyway. | 
| 125 |  |  | +        */ | 
| 126 | frodo | 283 | +       if (epoc && !nr_slots && last_entry) | 
| 127 | frodo | 284 | +               err = fat_write_zero_entry(dir, pos + free_slots * sizeof(*de)); | 
| 128 |  |  | +       if (err) | 
| 129 |  |  | +               goto error; | 
| 130 | frodo | 283 | + | 
| 131 | frodo | 284 | if (free_slots) { | 
| 132 |  |  | /* | 
| 133 |  |  | diff -r2 -u linux-source-2.6.12.unpatched/fs/fat/inode.c linux-source-2.6.12/fs/fat/inode.c | 
| 134 | frodo | 283 | --- linux-source-2.6.12.unpatched/fs/fat/inode.c        2005-06-17 21:48:29.000000000 +0200 | 
| 135 |  |  | +++ linux-source-2.6.12/fs/fat/inode.c  2005-11-20 20:45:29.000000000 +0100 | 
| 136 |  |  | @@ -756,4 +756,5 @@ | 
| 137 |  |  | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, | 
| 138 |  |  | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 
| 139 |  |  | +       Opt_epoc, | 
| 140 |  |  | Opt_obsolate, Opt_err, | 
| 141 |  |  | }; | 
| 142 |  |  | @@ -777,4 +778,5 @@ | 
| 143 |  |  | {Opt_debug, "debug"}, | 
| 144 |  |  | {Opt_immutable, "sys_immutable"}, | 
| 145 |  |  | +       {Opt_epoc, "epoc"}, | 
| 146 |  |  | {Opt_obsolate, "conv=binary"}, | 
| 147 |  |  | {Opt_obsolate, "conv=text"}, | 
| 148 |  |  | @@ -929,4 +931,8 @@ | 
| 149 |  |  | opts->codepage = option; | 
| 150 |  |  | break; | 
| 151 |  |  | +               case Opt_epoc: | 
| 152 |  |  | +                       opts->epoc = 1; | 
| 153 |  |  | +                       break; | 
| 154 |  |  | + | 
| 155 |  |  |  | 
| 156 |  |  | /* msdos specific */ | 
| 157 | frodo | 284 | diff -r2 -u linux-source-2.6.12.unpatched/include/linux/msdos_fs.h linux-source-2.6.12/include/linux/msdos_fs.h | 
| 158 | frodo | 283 | --- linux-source-2.6.12.unpatched/include/linux/msdos_fs.h      2005-06-17 21:48:29.000000000 +0200 | 
| 159 |  |  | +++ linux-source-2.6.12/include/linux/msdos_fs.h        2005-11-20 20:45:29.000000000 +0100 | 
| 160 |  |  | @@ -45,4 +45,5 @@ | 
| 161 |  |  |  | 
| 162 |  |  | #define DELETED_FLAG   0xe5    /* marks file as deleted when in name[0] */ | 
| 163 |  |  | +#define EOD_FLAG 0x00 /* marks end of directory when in name[0] for old fats */ | 
| 164 |  |  | #define IS_FREE(n)     (!*(n) || *(n) == DELETED_FLAG) | 
| 165 |  |  |  | 
| 166 |  |  | @@ -204,5 +205,7 @@ | 
| 167 |  |  | numtail:1,       /* Does first alias have a numeric '~1' type tail? */ | 
| 168 |  |  | atari:1,         /* Use Atari GEMDOS variation of MS-DOS fs */ | 
| 169 |  |  | -                nocase:1;        /* Does this need case conversion? 0=need case conversion*/ | 
| 170 |  |  | +                nocase:1,        /* Does this need case conversion? 0=need case conversion*/ | 
| 171 |  |  | +               epoc:1;          /* Filename starting with 0x00 marks end of dir? */ | 
| 172 |  |  | + | 
| 173 |  |  | }; | 
| 174 |  |  |  |