/[public]/fat-epoc/trunk/fat-epoc-2.6.22.diff
ViewVC logotype

Contents of /fat-epoc/trunk/fat-epoc-2.6.22.diff

Parent Directory Parent Directory | Revision Log Revision Log


Revision 308 - (show annotations)
Tue Nov 6 22:14:36 2007 UTC (16 years, 4 months ago) by frodo
File size: 5202 byte(s)
(Frodo) Updated patch for 2.6.22.
It seems that in some cases, the end-of-directory was not properly signaled.
We now continue reading directory entries until there are really none left,
and this seems to stop the confusion.

1 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 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 @@ -288,4 +289,8 @@ parse_long:
11 if ((*de)->name[0] == DELETED_FLAG)
12 return PARSE_INVALID;
13 + if (epoc && ((*de)->name[0] == EOD_FLAG)) {
14 + while (fat_get_entry(dir, pos, bh, de) >= 0);
15 + return PARSE_EOF;
16 + }
17 if ((*de)->attr == ATTR_EXT)
18 goto parse_long;
19 @@ -321,4 +326,5 @@ int fat_search_long(struct inode *inode,
20 loff_t cpos = 0;
21 int chl, i, j, last_u, err;
22 + int epoc = sbi->options.epoc;
23
24 err = -ENOENT;
25 @@ -330,4 +336,8 @@ parse_record:
26 if (de->name[0] == DELETED_FLAG)
27 continue;
28 + if (epoc && (de->name[0] == EOD_FLAG)) {
29 + while (fat_get_entry(inode, &cpos, &bh, &de) >= 0);
30 + goto EODir;
31 + }
32 if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME))
33 continue;
34 @@ -457,4 +467,6 @@ static int __fat_readdir(struct inode *i
35 loff_t cpos;
36 int ret = 0;
37 + int epoc = MSDOS_SB(sb)->options.epoc;
38 +
39
40 lock_kernel();
41 @@ -487,4 +499,8 @@ parse_record:
42 long_slots = 0;
43 /* Check for long filename entry */
44 + if (epoc && (de->name[0] == EOD_FLAG)) {
45 + while (fat_get_entry(inode, &cpos, &bh, &de) >= 0);
46 + goto EODir;
47 + }
48 if (isvfat) {
49 if (de->name[0] == DELETED_FLAG)
50 @@ -810,5 +826,10 @@ static int fat_get_short_entry(struct in
51 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 + if (epoc && ((*de)->name[0] == EOD_FLAG)) {
56 + while (fat_get_entry(dir, pos, bh, de) >= 0);
57 + return -ENOENT;
58 + }
59 /* free entry or long name entry or volume label */
60 if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
61 @@ -1188,4 +1209,23 @@ error:
62 }
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 @@ -1197,4 +1237,6 @@ int fat_add_entries(struct inode *dir, v
86 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 @@ -1210,5 +1252,7 @@ int fat_add_entries(struct inode *dir, v
93 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 @@ -1240,4 +1284,15 @@ found:
102 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 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 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 @@ -879,4 +880,5 @@ static match_table_t fat_tokens = {
127 {Opt_debug, "debug"},
128 {Opt_immutable, "sys_immutable"},
129 + {Opt_epoc, "epoc"},
130 {Opt_obsolate, "conv=binary"},
131 {Opt_obsolate, "conv=text"},
132 @@ -1038,4 +1040,8 @@ static int parse_options(char *options,
133 opts->flush = 1;
134 break;
135 + case Opt_epoc:
136 + opts->epoc = 1;
137 + break;
138 +
139
140 /* msdos specific */
141 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
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 @@ -207,4 +208,5 @@ struct fat_mount_options {
151 flush:1, /* write things quickly */
152 nocase:1, /* Does this need case conversion? 0=need case conversion*/
153 + epoc:1, /* Filename starting with 0x00 marks end of dir? */
154 usefree:1; /* Use free_clusters for FAT32 */
155 };

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26