aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fat
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /fs/fat
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/Makefile7
-rw-r--r--fs/fat/cache.c324
-rw-r--r--fs/fat/dir.c1271
-rw-r--r--fs/fat/fatent.c612
-rw-r--r--fs/fat/file.c308
-rw-r--r--fs/fat/inode.c1351
-rw-r--r--fs/fat/misc.c225
7 files changed, 4098 insertions, 0 deletions
diff --git a/fs/fat/Makefile b/fs/fat/Makefile
new file mode 100644
index 000000000000..bfb5f06cf2c8
--- /dev/null
+++ b/fs/fat/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Linux fat filesystem support.
3#
4
5obj-$(CONFIG_FAT_FS) += fat.o
6
7fat-objs := cache.o dir.o fatent.o file.o inode.o misc.o
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
new file mode 100644
index 000000000000..7c52e465a619
--- /dev/null
+++ b/fs/fat/cache.c
@@ -0,0 +1,324 @@
1/*
2 * linux/fs/fat/cache.c
3 *
4 * Written 1992,1993 by Werner Almesberger
5 *
6 * Mar 1999. AV. Changed cache, so that it uses the starting cluster instead
7 * of inode number.
8 * May 1999. AV. Fixed the bogosity with FAT32 (read "FAT28"). Fscking lusers.
9 */
10
11#include <linux/fs.h>
12#include <linux/msdos_fs.h>
13#include <linux/buffer_head.h>
14
15/* this must be > 0. */
16#define FAT_MAX_CACHE 8
17
18struct fat_cache {
19 struct list_head cache_list;
20 int nr_contig; /* number of contiguous clusters */
21 int fcluster; /* cluster number in the file. */
22 int dcluster; /* cluster number on disk. */
23};
24
25struct fat_cache_id {
26 unsigned int id;
27 int nr_contig;
28 int fcluster;
29 int dcluster;
30};
31
32static inline int fat_max_cache(struct inode *inode)
33{
34 return FAT_MAX_CACHE;
35}
36
37static kmem_cache_t *fat_cache_cachep;
38
39static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
40{
41 struct fat_cache *cache = (struct fat_cache *)foo;
42
43 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
44 SLAB_CTOR_CONSTRUCTOR)
45 INIT_LIST_HEAD(&cache->cache_list);
46}
47
48int __init fat_cache_init(void)
49{
50 fat_cache_cachep = kmem_cache_create("fat_cache",
51 sizeof(struct fat_cache),
52 0, SLAB_RECLAIM_ACCOUNT,
53 init_once, NULL);
54 if (fat_cache_cachep == NULL)
55 return -ENOMEM;
56 return 0;
57}
58
59void __exit fat_cache_destroy(void)
60{
61 if (kmem_cache_destroy(fat_cache_cachep))
62 printk(KERN_INFO "fat_cache: not all structures were freed\n");
63}
64
65static inline struct fat_cache *fat_cache_alloc(struct inode *inode)
66{
67 return kmem_cache_alloc(fat_cache_cachep, SLAB_KERNEL);
68}
69
70static inline void fat_cache_free(struct fat_cache *cache)
71{
72 BUG_ON(!list_empty(&cache->cache_list));
73 kmem_cache_free(fat_cache_cachep, cache);
74}
75
76static inline void fat_cache_update_lru(struct inode *inode,
77 struct fat_cache *cache)
78{
79 if (MSDOS_I(inode)->cache_lru.next != &cache->cache_list)
80 list_move(&cache->cache_list, &MSDOS_I(inode)->cache_lru);
81}
82
83static int fat_cache_lookup(struct inode *inode, int fclus,
84 struct fat_cache_id *cid,
85 int *cached_fclus, int *cached_dclus)
86{
87 static struct fat_cache nohit = { .fcluster = 0, };
88
89 struct fat_cache *hit = &nohit, *p;
90 int offset = -1;
91
92 spin_lock(&MSDOS_I(inode)->cache_lru_lock);
93 list_for_each_entry(p, &MSDOS_I(inode)->cache_lru, cache_list) {
94 /* Find the cache of "fclus" or nearest cache. */
95 if (p->fcluster <= fclus && hit->fcluster < p->fcluster) {
96 hit = p;
97 if ((hit->fcluster + hit->nr_contig) < fclus) {
98 offset = hit->nr_contig;
99 } else {
100 offset = fclus - hit->fcluster;
101 break;
102 }
103 }
104 }
105 if (hit != &nohit) {
106 fat_cache_update_lru(inode, hit);
107
108 cid->id = MSDOS_I(inode)->cache_valid_id;
109 cid->nr_contig = hit->nr_contig;
110 cid->fcluster = hit->fcluster;
111 cid->dcluster = hit->dcluster;
112 *cached_fclus = cid->fcluster + offset;
113 *cached_dclus = cid->dcluster + offset;
114 }
115 spin_unlock(&MSDOS_I(inode)->cache_lru_lock);
116
117 return offset;
118}
119
120static struct fat_cache *fat_cache_merge(struct inode *inode,
121 struct fat_cache_id *new)
122{
123 struct fat_cache *p;
124
125 list_for_each_entry(p, &MSDOS_I(inode)->cache_lru, cache_list) {
126 /* Find the same part as "new" in cluster-chain. */
127 if (p->fcluster == new->fcluster) {
128 BUG_ON(p->dcluster != new->dcluster);
129 if (new->nr_contig > p->nr_contig)
130 p->nr_contig = new->nr_contig;
131 return p;
132 }
133 }
134 return NULL;
135}
136
137static void fat_cache_add(struct inode *inode, struct fat_cache_id *new)
138{
139 struct fat_cache *cache, *tmp;
140
141 if (new->fcluster == -1) /* dummy cache */
142 return;
143
144 spin_lock(&MSDOS_I(inode)->cache_lru_lock);
145 if (new->id != FAT_CACHE_VALID &&
146 new->id != MSDOS_I(inode)->cache_valid_id)
147 goto out; /* this cache was invalidated */
148
149 cache = fat_cache_merge(inode, new);
150 if (cache == NULL) {
151 if (MSDOS_I(inode)->nr_caches < fat_max_cache(inode)) {
152 MSDOS_I(inode)->nr_caches++;
153 spin_unlock(&MSDOS_I(inode)->cache_lru_lock);
154
155 tmp = fat_cache_alloc(inode);
156 spin_lock(&MSDOS_I(inode)->cache_lru_lock);
157 cache = fat_cache_merge(inode, new);
158 if (cache != NULL) {
159 MSDOS_I(inode)->nr_caches--;
160 fat_cache_free(tmp);
161 goto out_update_lru;
162 }
163 cache = tmp;
164 } else {
165 struct list_head *p = MSDOS_I(inode)->cache_lru.prev;
166 cache = list_entry(p, struct fat_cache, cache_list);
167 }
168 cache->fcluster = new->fcluster;
169 cache->dcluster = new->dcluster;
170 cache->nr_contig = new->nr_contig;
171 }
172out_update_lru:
173 fat_cache_update_lru(inode, cache);
174out:
175 spin_unlock(&MSDOS_I(inode)->cache_lru_lock);
176}
177
178/*
179 * Cache invalidation occurs rarely, thus the LRU chain is not updated. It
180 * fixes itself after a while.
181 */
182static void __fat_cache_inval_inode(struct inode *inode)
183{
184 struct msdos_inode_info *i = MSDOS_I(inode);
185 struct fat_cache *cache;
186
187 while (!list_empty(&i->cache_lru)) {
188 cache = list_entry(i->cache_lru.next, struct fat_cache, cache_list);
189 list_del_init(&cache->cache_list);
190 i->nr_caches--;
191 fat_cache_free(cache);
192 }
193 /* Update. The copy of caches before this id is discarded. */
194 i->cache_valid_id++;
195 if (i->cache_valid_id == FAT_CACHE_VALID)
196 i->cache_valid_id++;
197}
198
199void fat_cache_inval_inode(struct inode *inode)
200{
201 spin_lock(&MSDOS_I(inode)->cache_lru_lock);
202 __fat_cache_inval_inode(inode);
203 spin_unlock(&MSDOS_I(inode)->cache_lru_lock);
204}
205
206static inline int cache_contiguous(struct fat_cache_id *cid, int dclus)
207{
208 cid->nr_contig++;
209 return ((cid->dcluster + cid->nr_contig) == dclus);
210}
211
212static inline void cache_init(struct fat_cache_id *cid, int fclus, int dclus)
213{
214 cid->id = FAT_CACHE_VALID;
215 cid->fcluster = fclus;
216 cid->dcluster = dclus;
217 cid->nr_contig = 0;
218}
219
220int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
221{
222 struct super_block *sb = inode->i_sb;
223 const int limit = sb->s_maxbytes >> MSDOS_SB(sb)->cluster_bits;
224 struct fat_entry fatent;
225 struct fat_cache_id cid;
226 int nr;
227
228 BUG_ON(MSDOS_I(inode)->i_start == 0);
229
230 *fclus = 0;
231 *dclus = MSDOS_I(inode)->i_start;
232 if (cluster == 0)
233 return 0;
234
235 if (fat_cache_lookup(inode, cluster, &cid, fclus, dclus) < 0) {
236 /*
237 * dummy, always not contiguous
238 * This is reinitialized by cache_init(), later.
239 */
240 cache_init(&cid, -1, -1);
241 }
242
243 fatent_init(&fatent);
244 while (*fclus < cluster) {
245 /* prevent the infinite loop of cluster chain */
246 if (*fclus > limit) {
247 fat_fs_panic(sb, "%s: detected the cluster chain loop"
248 " (i_pos %lld)", __FUNCTION__,
249 MSDOS_I(inode)->i_pos);
250 nr = -EIO;
251 goto out;
252 }
253
254 nr = fat_ent_read(inode, &fatent, *dclus);
255 if (nr < 0)
256 goto out;
257 else if (nr == FAT_ENT_FREE) {
258 fat_fs_panic(sb, "%s: invalid cluster chain"
259 " (i_pos %lld)", __FUNCTION__,
260 MSDOS_I(inode)->i_pos);
261 nr = -EIO;
262 goto out;
263 } else if (nr == FAT_ENT_EOF) {
264 fat_cache_add(inode, &cid);
265 goto out;
266 }
267 (*fclus)++;
268 *dclus = nr;
269 if (!cache_contiguous(&cid, *dclus))
270 cache_init(&cid, *fclus, *dclus);
271 }
272 nr = 0;
273 fat_cache_add(inode, &cid);
274out:
275 fatent_brelse(&fatent);
276 return nr;
277}
278
279static int fat_bmap_cluster(struct inode *inode, int cluster)
280{
281 struct super_block *sb = inode->i_sb;
282 int ret, fclus, dclus;
283
284 if (MSDOS_I(inode)->i_start == 0)
285 return 0;
286
287 ret = fat_get_cluster(inode, cluster, &fclus, &dclus);
288 if (ret < 0)
289 return ret;
290 else if (ret == FAT_ENT_EOF) {
291 fat_fs_panic(sb, "%s: request beyond EOF (i_pos %lld)",
292 __FUNCTION__, MSDOS_I(inode)->i_pos);
293 return -EIO;
294 }
295 return dclus;
296}
297
298int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
299{
300 struct super_block *sb = inode->i_sb;
301 struct msdos_sb_info *sbi = MSDOS_SB(sb);
302 sector_t last_block;
303 int cluster, offset;
304
305 *phys = 0;
306 if ((sbi->fat_bits != 32) && (inode->i_ino == MSDOS_ROOT_INO)) {
307 if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits))
308 *phys = sector + sbi->dir_start;
309 return 0;
310 }
311 last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
312 >> sb->s_blocksize_bits;
313 if (sector >= last_block)
314 return 0;
315
316 cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits);
317 offset = sector & (sbi->sec_per_clus - 1);
318 cluster = fat_bmap_cluster(inode, cluster);
319 if (cluster < 0)
320 return cluster;
321 else if (cluster)
322 *phys = fat_clus_to_blknr(sbi, cluster) + offset;
323 return 0;
324}
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
new file mode 100644
index 000000000000..e5ae1b720dde
--- /dev/null
+++ b/fs/fat/dir.c
@@ -0,0 +1,1271 @@
1/*
2 * linux/fs/fat/dir.c
3 *
4 * directory handling functions for fat-based filesystems
5 *
6 * Written 1992,1993 by Werner Almesberger
7 *
8 * Hidden files 1995 by Albert Cahalan <albert@ccs.neu.edu> <adc@coe.neu.edu>
9 *
10 * VFAT extensions by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
11 * Merged with msdos fs by Henrik Storner <storner@osiris.ping.dk>
12 * Rewritten for constant inumbers. Plugged buffer overrun in readdir(). AV
13 * Short name translation 1999, 2001 by Wolfram Pienkoss <wp@bszh.de>
14 */
15
16#include <linux/module.h>
17#include <linux/slab.h>
18#include <linux/time.h>
19#include <linux/msdos_fs.h>
20#include <linux/dirent.h>
21#include <linux/smp_lock.h>
22#include <linux/buffer_head.h>
23#include <asm/uaccess.h>
24
25static inline loff_t fat_make_i_pos(struct super_block *sb,
26 struct buffer_head *bh,
27 struct msdos_dir_entry *de)
28{
29 return ((loff_t)bh->b_blocknr << MSDOS_SB(sb)->dir_per_block_bits)
30 | (de - (struct msdos_dir_entry *)bh->b_data);
31}
32
33/* Returns the inode number of the directory entry at offset pos. If bh is
34 non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
35 returned in bh.
36 AV. Most often we do it item-by-item. Makes sense to optimize.
37 AV. OK, there we go: if both bh and de are non-NULL we assume that we just
38 AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
39 AV. It's done in fat_get_entry() (inlined), here the slow case lives.
40 AV. Additionally, when we return -1 (i.e. reached the end of directory)
41 AV. we make bh NULL.
42 */
43static int fat__get_entry(struct inode *dir, loff_t *pos,
44 struct buffer_head **bh, struct msdos_dir_entry **de)
45{
46 struct super_block *sb = dir->i_sb;
47 sector_t phys, iblock;
48 int offset;
49 int err;
50
51next:
52 if (*bh)
53 brelse(*bh);
54
55 *bh = NULL;
56 iblock = *pos >> sb->s_blocksize_bits;
57 err = fat_bmap(dir, iblock, &phys);
58 if (err || !phys)
59 return -1; /* beyond EOF or error */
60
61 *bh = sb_bread(sb, phys);
62 if (*bh == NULL) {
63 printk(KERN_ERR "FAT: Directory bread(block %llu) failed\n",
64 (unsigned long long)phys);
65 /* skip this block */
66 *pos = (iblock + 1) << sb->s_blocksize_bits;
67 goto next;
68 }
69
70 offset = *pos & (sb->s_blocksize - 1);
71 *pos += sizeof(struct msdos_dir_entry);
72 *de = (struct msdos_dir_entry *)((*bh)->b_data + offset);
73
74 return 0;
75}
76
77static inline int fat_get_entry(struct inode *dir, loff_t *pos,
78 struct buffer_head **bh,
79 struct msdos_dir_entry **de)
80{
81 /* Fast stuff first */
82 if (*bh && *de &&
83 (*de - (struct msdos_dir_entry *)(*bh)->b_data) < MSDOS_SB(dir->i_sb)->dir_per_block - 1) {
84 *pos += sizeof(struct msdos_dir_entry);
85 (*de)++;
86 return 0;
87 }
88 return fat__get_entry(dir, pos, bh, de);
89}
90
91/*
92 * Convert Unicode 16 to UTF8, translated Unicode, or ASCII.
93 * If uni_xlate is enabled and we can't get a 1:1 conversion, use a
94 * colon as an escape character since it is normally invalid on the vfat
95 * filesystem. The following four characters are the hexadecimal digits
96 * of Unicode value. This lets us do a full dump and restore of Unicode
97 * filenames. We could get into some trouble with long Unicode names,
98 * but ignore that right now.
99 * Ahem... Stack smashing in ring 0 isn't fun. Fixed.
100 */
101static int uni16_to_x8(unsigned char *ascii, wchar_t *uni, int uni_xlate,
102 struct nls_table *nls)
103{
104 wchar_t *ip, ec;
105 unsigned char *op, nc;
106 int charlen;
107 int k;
108
109 ip = uni;
110 op = ascii;
111
112 while (*ip) {
113 ec = *ip++;
114 if ( (charlen = nls->uni2char(ec, op, NLS_MAX_CHARSET_SIZE)) > 0) {
115 op += charlen;
116 } else {
117 if (uni_xlate == 1) {
118 *op = ':';
119 for (k = 4; k > 0; k--) {
120 nc = ec & 0xF;
121 op[k] = nc > 9 ? nc + ('a' - 10)
122 : nc + '0';
123 ec >>= 4;
124 }
125 op += 5;
126 } else {
127 *op++ = '?';
128 }
129 }
130 /* We have some slack there, so it's OK */
131 if (op>ascii+256) {
132 op = ascii + 256;
133 break;
134 }
135 }
136 *op = 0;
137 return (op - ascii);
138}
139
140static inline int
141fat_short2uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
142{
143 int charlen;
144
145 charlen = t->char2uni(c, clen, uni);
146 if (charlen < 0) {
147 *uni = 0x003f; /* a question mark */
148 charlen = 1;
149 }
150 return charlen;
151}
152
153static inline int
154fat_short2lower_uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
155{
156 int charlen;
157 wchar_t wc;
158
159 charlen = t->char2uni(c, clen, &wc);
160 if (charlen < 0) {
161 *uni = 0x003f; /* a question mark */
162 charlen = 1;
163 } else if (charlen <= 1) {
164 unsigned char nc = t->charset2lower[*c];
165
166 if (!nc)
167 nc = *c;
168
169 if ( (charlen = t->char2uni(&nc, 1, uni)) < 0) {
170 *uni = 0x003f; /* a question mark */
171 charlen = 1;
172 }
173 } else
174 *uni = wc;
175
176 return charlen;
177}
178
179static inline int
180fat_shortname2uni(struct nls_table *nls, unsigned char *buf, int buf_size,
181 wchar_t *uni_buf, unsigned short opt, int lower)
182{
183 int len = 0;
184
185 if (opt & VFAT_SFN_DISPLAY_LOWER)
186 len = fat_short2lower_uni(nls, buf, buf_size, uni_buf);
187 else if (opt & VFAT_SFN_DISPLAY_WIN95)
188 len = fat_short2uni(nls, buf, buf_size, uni_buf);
189 else if (opt & VFAT_SFN_DISPLAY_WINNT) {
190 if (lower)
191 len = fat_short2lower_uni(nls, buf, buf_size, uni_buf);
192 else
193 len = fat_short2uni(nls, buf, buf_size, uni_buf);
194 } else
195 len = fat_short2uni(nls, buf, buf_size, uni_buf);
196
197 return len;
198}
199
200/*
201 * Return values: negative -> error, 0 -> not found, positive -> found,
202 * value is the total amount of slots, including the shortname entry.
203 */
204int fat_search_long(struct inode *inode, const unsigned char *name,
205 int name_len, struct fat_slot_info *sinfo)
206{
207 struct super_block *sb = inode->i_sb;
208 struct msdos_sb_info *sbi = MSDOS_SB(sb);
209 struct buffer_head *bh = NULL;
210 struct msdos_dir_entry *de;
211 struct nls_table *nls_io = sbi->nls_io;
212 struct nls_table *nls_disk = sbi->nls_disk;
213 wchar_t bufuname[14];
214 unsigned char xlate_len, nr_slots;
215 wchar_t *unicode = NULL;
216 unsigned char work[8], bufname[260]; /* 256 + 4 */
217 int uni_xlate = sbi->options.unicode_xlate;
218 int utf8 = sbi->options.utf8;
219 int anycase = (sbi->options.name_check != 's');
220 unsigned short opt_shortname = sbi->options.shortname;
221 loff_t cpos = 0;
222 int chl, i, j, last_u, err;
223
224 err = -ENOENT;
225 while(1) {
226 if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
227 goto EODir;
228parse_record:
229 nr_slots = 0;
230 if (de->name[0] == DELETED_FLAG)
231 continue;
232 if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME))
233 continue;
234 if (de->attr != ATTR_EXT && IS_FREE(de->name))
235 continue;
236 if (de->attr == ATTR_EXT) {
237 struct msdos_dir_slot *ds;
238 unsigned char id;
239 unsigned char slot;
240 unsigned char slots;
241 unsigned char sum;
242 unsigned char alias_checksum;
243
244 if (!unicode) {
245 unicode = (wchar_t *)
246 __get_free_page(GFP_KERNEL);
247 if (!unicode) {
248 brelse(bh);
249 return -ENOMEM;
250 }
251 }
252parse_long:
253 slots = 0;
254 ds = (struct msdos_dir_slot *) de;
255 id = ds->id;
256 if (!(id & 0x40))
257 continue;
258 slots = id & ~0x40;
259 if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
260 continue;
261 nr_slots = slots;
262 alias_checksum = ds->alias_checksum;
263
264 slot = slots;
265 while (1) {
266 int offset;
267
268 slot--;
269 offset = slot * 13;
270 fat16_towchar(unicode + offset, ds->name0_4, 5);
271 fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
272 fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
273
274 if (ds->id & 0x40) {
275 unicode[offset + 13] = 0;
276 }
277 if (fat_get_entry(inode, &cpos, &bh, &de) < 0)
278 goto EODir;
279 if (slot == 0)
280 break;
281 ds = (struct msdos_dir_slot *) de;
282 if (ds->attr != ATTR_EXT)
283 goto parse_record;
284 if ((ds->id & ~0x40) != slot)
285 goto parse_long;
286 if (ds->alias_checksum != alias_checksum)
287 goto parse_long;
288 }
289 if (de->name[0] == DELETED_FLAG)
290 continue;
291 if (de->attr == ATTR_EXT)
292 goto parse_long;
293 if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
294 continue;
295 for (sum = 0, i = 0; i < 11; i++)
296 sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
297 if (sum != alias_checksum)
298 nr_slots = 0;
299 }
300
301 memcpy(work, de->name, sizeof(de->name));
302 /* see namei.c, msdos_format_name */
303 if (work[0] == 0x05)
304 work[0] = 0xE5;
305 for (i = 0, j = 0, last_u = 0; i < 8;) {
306 if (!work[i]) break;
307 chl = fat_shortname2uni(nls_disk, &work[i], 8 - i,
308 &bufuname[j++], opt_shortname,
309 de->lcase & CASE_LOWER_BASE);
310 if (chl <= 1) {
311 if (work[i] != ' ')
312 last_u = j;
313 } else {
314 last_u = j;
315 }
316 i += chl;
317 }
318 j = last_u;
319 fat_short2uni(nls_disk, ".", 1, &bufuname[j++]);
320 for (i = 0; i < 3;) {
321 if (!de->ext[i]) break;
322 chl = fat_shortname2uni(nls_disk, &de->ext[i], 3 - i,
323 &bufuname[j++], opt_shortname,
324 de->lcase & CASE_LOWER_EXT);
325 if (chl <= 1) {
326 if (de->ext[i] != ' ')
327 last_u = j;
328 } else {
329 last_u = j;
330 }
331 i += chl;
332 }
333 if (!last_u)
334 continue;
335
336 bufuname[last_u] = 0x0000;
337 xlate_len = utf8
338 ?utf8_wcstombs(bufname, bufuname, sizeof(bufname))
339 :uni16_to_x8(bufname, bufuname, uni_xlate, nls_io);
340 if (xlate_len == name_len)
341 if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
342 (anycase && !nls_strnicmp(nls_io, name, bufname,
343 xlate_len)))
344 goto Found;
345
346 if (nr_slots) {
347 xlate_len = utf8
348 ?utf8_wcstombs(bufname, unicode, sizeof(bufname))
349 :uni16_to_x8(bufname, unicode, uni_xlate, nls_io);
350 if (xlate_len != name_len)
351 continue;
352 if ((!anycase && !memcmp(name, bufname, xlate_len)) ||
353 (anycase && !nls_strnicmp(nls_io, name, bufname,
354 xlate_len)))
355 goto Found;
356 }
357 }
358
359Found:
360 nr_slots++; /* include the de */
361 sinfo->slot_off = cpos - nr_slots * sizeof(*de);
362 sinfo->nr_slots = nr_slots;
363 sinfo->de = de;
364 sinfo->bh = bh;
365 sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de);
366 err = 0;
367EODir:
368 if (unicode)
369 free_page((unsigned long)unicode);
370
371 return err;
372}
373
374EXPORT_SYMBOL(fat_search_long);
375
376struct fat_ioctl_filldir_callback {
377 struct dirent __user *dirent;
378 int result;
379 /* for dir ioctl */
380 const char *longname;
381 int long_len;
382 const char *shortname;
383 int short_len;
384};
385
386static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
387 filldir_t filldir, int short_only, int both)
388{
389 struct super_block *sb = inode->i_sb;
390 struct msdos_sb_info *sbi = MSDOS_SB(sb);
391 struct buffer_head *bh;
392 struct msdos_dir_entry *de;
393 struct nls_table *nls_io = sbi->nls_io;
394 struct nls_table *nls_disk = sbi->nls_disk;
395 unsigned char long_slots;
396 const char *fill_name;
397 int fill_len;
398 wchar_t bufuname[14];
399 wchar_t *unicode = NULL;
400 unsigned char c, work[8], bufname[56], *ptname = bufname;
401 unsigned long lpos, dummy, *furrfu = &lpos;
402 int uni_xlate = sbi->options.unicode_xlate;
403 int isvfat = sbi->options.isvfat;
404 int utf8 = sbi->options.utf8;
405 int nocase = sbi->options.nocase;
406 unsigned short opt_shortname = sbi->options.shortname;
407 unsigned long inum;
408 int chi, chl, i, i2, j, last, last_u, dotoffset = 0;
409 loff_t cpos;
410 int ret = 0;
411
412 lock_kernel();
413
414 cpos = filp->f_pos;
415 /* Fake . and .. for the root directory. */
416 if (inode->i_ino == MSDOS_ROOT_INO) {
417 while (cpos < 2) {
418 if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0)
419 goto out;
420 cpos++;
421 filp->f_pos++;
422 }
423 if (cpos == 2) {
424 dummy = 2;
425 furrfu = &dummy;
426 cpos = 0;
427 }
428 }
429 if (cpos & (sizeof(struct msdos_dir_entry)-1)) {
430 ret = -ENOENT;
431 goto out;
432 }
433
434 bh = NULL;
435GetNew:
436 long_slots = 0;
437 if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
438 goto EODir;
439 /* Check for long filename entry */
440 if (isvfat) {
441 if (de->name[0] == DELETED_FLAG)
442 goto RecEnd;
443 if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME))
444 goto RecEnd;
445 if (de->attr != ATTR_EXT && IS_FREE(de->name))
446 goto RecEnd;
447 } else {
448 if ((de->attr & ATTR_VOLUME) || IS_FREE(de->name))
449 goto RecEnd;
450 }
451
452 if (isvfat && de->attr == ATTR_EXT) {
453 struct msdos_dir_slot *ds;
454 unsigned char id;
455 unsigned char slot;
456 unsigned char slots;
457 unsigned char sum;
458 unsigned char alias_checksum;
459
460 if (!unicode) {
461 unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
462 if (!unicode) {
463 filp->f_pos = cpos;
464 brelse(bh);
465 ret = -ENOMEM;
466 goto out;
467 }
468 }
469ParseLong:
470 slots = 0;
471 ds = (struct msdos_dir_slot *) de;
472 id = ds->id;
473 if (!(id & 0x40))
474 goto RecEnd;
475 slots = id & ~0x40;
476 if (slots > 20 || !slots) /* ceil(256 * 2 / 26) */
477 goto RecEnd;
478 long_slots = slots;
479 alias_checksum = ds->alias_checksum;
480
481 slot = slots;
482 while (1) {
483 int offset;
484
485 slot--;
486 offset = slot * 13;
487 fat16_towchar(unicode + offset, ds->name0_4, 5);
488 fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
489 fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
490
491 if (ds->id & 0x40) {
492 unicode[offset + 13] = 0;
493 }
494 if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
495 goto EODir;
496 if (slot == 0)
497 break;
498 ds = (struct msdos_dir_slot *) de;
499 if (ds->attr != ATTR_EXT)
500 goto RecEnd; /* XXX */
501 if ((ds->id & ~0x40) != slot)
502 goto ParseLong;
503 if (ds->alias_checksum != alias_checksum)
504 goto ParseLong;
505 }
506 if (de->name[0] == DELETED_FLAG)
507 goto RecEnd;
508 if (de->attr == ATTR_EXT)
509 goto ParseLong;
510 if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
511 goto RecEnd;
512 for (sum = 0, i = 0; i < 11; i++)
513 sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
514 if (sum != alias_checksum)
515 long_slots = 0;
516 }
517
518 if (sbi->options.dotsOK) {
519 ptname = bufname;
520 dotoffset = 0;
521 if (de->attr & ATTR_HIDDEN) {
522 *ptname++ = '.';
523 dotoffset = 1;
524 }
525 }
526
527 memcpy(work, de->name, sizeof(de->name));
528 /* see namei.c, msdos_format_name */
529 if (work[0] == 0x05)
530 work[0] = 0xE5;
531 for (i = 0, j = 0, last = 0, last_u = 0; i < 8;) {
532 if (!(c = work[i])) break;
533 chl = fat_shortname2uni(nls_disk, &work[i], 8 - i,
534 &bufuname[j++], opt_shortname,
535 de->lcase & CASE_LOWER_BASE);
536 if (chl <= 1) {
537 ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
538 if (c != ' ') {
539 last = i;
540 last_u = j;
541 }
542 } else {
543 last_u = j;
544 for (chi = 0; chi < chl && i < 8; chi++) {
545 ptname[i] = work[i];
546 i++; last = i;
547 }
548 }
549 }
550 i = last;
551 j = last_u;
552 fat_short2uni(nls_disk, ".", 1, &bufuname[j++]);
553 ptname[i++] = '.';
554 for (i2 = 0; i2 < 3;) {
555 if (!(c = de->ext[i2])) break;
556 chl = fat_shortname2uni(nls_disk, &de->ext[i2], 3 - i2,
557 &bufuname[j++], opt_shortname,
558 de->lcase & CASE_LOWER_EXT);
559 if (chl <= 1) {
560 i2++;
561 ptname[i++] = (!nocase && c>='A' && c<='Z') ? c+32 : c;
562 if (c != ' ') {
563 last = i;
564 last_u = j;
565 }
566 } else {
567 last_u = j;
568 for (chi = 0; chi < chl && i2 < 3; chi++) {
569 ptname[i++] = de->ext[i2++];
570 last = i;
571 }
572 }
573 }
574 if (!last)
575 goto RecEnd;
576
577 i = last + dotoffset;
578 j = last_u;
579
580 lpos = cpos - (long_slots+1)*sizeof(struct msdos_dir_entry);
581 if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME))
582 inum = inode->i_ino;
583 else if (!memcmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) {
584 inum = parent_ino(filp->f_dentry);
585 } else {
586 loff_t i_pos = fat_make_i_pos(sb, bh, de);
587 struct inode *tmp = fat_iget(sb, i_pos);
588 if (tmp) {
589 inum = tmp->i_ino;
590 iput(tmp);
591 } else
592 inum = iunique(sb, MSDOS_ROOT_INO);
593 }
594
595 if (isvfat) {
596 bufuname[j] = 0x0000;
597 i = utf8 ? utf8_wcstombs(bufname, bufuname, sizeof(bufname))
598 : uni16_to_x8(bufname, bufuname, uni_xlate, nls_io);
599 }
600
601 fill_name = bufname;
602 fill_len = i;
603 if (!short_only && long_slots) {
604 /* convert the unicode long name. 261 is maximum size
605 * of unicode buffer. (13 * slots + nul) */
606 void *longname = unicode + 261;
607 int buf_size = PAGE_SIZE - (261 * sizeof(unicode[0]));
608 int long_len = utf8
609 ? utf8_wcstombs(longname, unicode, buf_size)
610 : uni16_to_x8(longname, unicode, uni_xlate, nls_io);
611
612 if (!both) {
613 fill_name = longname;
614 fill_len = long_len;
615 } else {
616 /* hack for fat_ioctl_filldir() */
617 struct fat_ioctl_filldir_callback *p = dirent;
618
619 p->longname = longname;
620 p->long_len = long_len;
621 p->shortname = bufname;
622 p->short_len = i;
623 fill_name = NULL;
624 fill_len = 0;
625 }
626 }
627 if (filldir(dirent, fill_name, fill_len, *furrfu, inum,
628 (de->attr & ATTR_DIR) ? DT_DIR : DT_REG) < 0)
629 goto FillFailed;
630
631RecEnd:
632 furrfu = &lpos;
633 filp->f_pos = cpos;
634 goto GetNew;
635EODir:
636 filp->f_pos = cpos;
637FillFailed:
638 if (bh)
639 brelse(bh);
640 if (unicode)
641 free_page((unsigned long)unicode);
642out:
643 unlock_kernel();
644 return ret;
645}
646
647static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
648{
649 struct inode *inode = filp->f_dentry->d_inode;
650 return fat_readdirx(inode, filp, dirent, filldir, 0, 0);
651}
652
653static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
654 loff_t offset, ino_t ino, unsigned int d_type)
655{
656 struct fat_ioctl_filldir_callback *buf = __buf;
657 struct dirent __user *d1 = buf->dirent;
658 struct dirent __user *d2 = d1 + 1;
659
660 if (buf->result)
661 return -EINVAL;
662 buf->result++;
663
664 if (name != NULL) {
665 /* dirent has only short name */
666 if (name_len >= sizeof(d1->d_name))
667 name_len = sizeof(d1->d_name) - 1;
668
669 if (put_user(0, d2->d_name) ||
670 put_user(0, &d2->d_reclen) ||
671 copy_to_user(d1->d_name, name, name_len) ||
672 put_user(0, d1->d_name + name_len) ||
673 put_user(name_len, &d1->d_reclen))
674 goto efault;
675 } else {
676 /* dirent has short and long name */
677 const char *longname = buf->longname;
678 int long_len = buf->long_len;
679 const char *shortname = buf->shortname;
680 int short_len = buf->short_len;
681
682 if (long_len >= sizeof(d1->d_name))
683 long_len = sizeof(d1->d_name) - 1;
684 if (short_len >= sizeof(d1->d_name))
685 short_len = sizeof(d1->d_name) - 1;
686
687 if (copy_to_user(d2->d_name, longname, long_len) ||
688 put_user(0, d2->d_name + long_len) ||
689 put_user(long_len, &d2->d_reclen) ||
690 put_user(ino, &d2->d_ino) ||
691 put_user(offset, &d2->d_off) ||
692 copy_to_user(d1->d_name, shortname, short_len) ||
693 put_user(0, d1->d_name + short_len) ||
694 put_user(short_len, &d1->d_reclen))
695 goto efault;
696 }
697 return 0;
698efault:
699 buf->result = -EFAULT;
700 return -EFAULT;
701}
702
703static int fat_dir_ioctl(struct inode * inode, struct file * filp,
704 unsigned int cmd, unsigned long arg)
705{
706 struct fat_ioctl_filldir_callback buf;
707 struct dirent __user *d1;
708 int ret, short_only, both;
709
710 switch (cmd) {
711 case VFAT_IOCTL_READDIR_SHORT:
712 short_only = 1;
713 both = 0;
714 break;
715 case VFAT_IOCTL_READDIR_BOTH:
716 short_only = 0;
717 both = 1;
718 break;
719 default:
720 return fat_generic_ioctl(inode, filp, cmd, arg);
721 }
722
723 d1 = (struct dirent __user *)arg;
724 if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2])))
725 return -EFAULT;
726 /*
727 * Yes, we don't need this put_user() absolutely. However old
728 * code didn't return the right value. So, app use this value,
729 * in order to check whether it is EOF.
730 */
731 if (put_user(0, &d1->d_reclen))
732 return -EFAULT;
733
734 buf.dirent = d1;
735 buf.result = 0;
736 down(&inode->i_sem);
737 ret = -ENOENT;
738 if (!IS_DEADDIR(inode)) {
739 ret = fat_readdirx(inode, filp, &buf, fat_ioctl_filldir,
740 short_only, both);
741 }
742 up(&inode->i_sem);
743 if (ret >= 0)
744 ret = buf.result;
745 return ret;
746}
747
748struct file_operations fat_dir_operations = {
749 .read = generic_read_dir,
750 .readdir = fat_readdir,
751 .ioctl = fat_dir_ioctl,
752 .fsync = file_fsync,
753};
754
755static int fat_get_short_entry(struct inode *dir, loff_t *pos,
756 struct buffer_head **bh,
757 struct msdos_dir_entry **de)
758{
759 while (fat_get_entry(dir, pos, bh, de) >= 0) {
760 /* free entry or long name entry or volume label */
761 if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
762 return 0;
763 }
764 return -ENOENT;
765}
766
767/*
768 * The ".." entry can not provide the "struct fat_slot_info" informations
769 * for inode. So, this function provide the some informations only.
770 */
771int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh,
772 struct msdos_dir_entry **de, loff_t *i_pos)
773{
774 loff_t offset;
775
776 offset = 0;
777 *bh = NULL;
778 while (fat_get_short_entry(dir, &offset, bh, de) >= 0) {
779 if (!strncmp((*de)->name, MSDOS_DOTDOT, MSDOS_NAME)) {
780 *i_pos = fat_make_i_pos(dir->i_sb, *bh, *de);
781 return 0;
782 }
783 }
784 return -ENOENT;
785}
786
787EXPORT_SYMBOL(fat_get_dotdot_entry);
788
789/* See if directory is empty */
790int fat_dir_empty(struct inode *dir)
791{
792 struct buffer_head *bh;
793 struct msdos_dir_entry *de;
794 loff_t cpos;
795 int result = 0;
796
797 bh = NULL;
798 cpos = 0;
799 while (fat_get_short_entry(dir, &cpos, &bh, &de) >= 0) {
800 if (strncmp(de->name, MSDOS_DOT , MSDOS_NAME) &&
801 strncmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) {
802 result = -ENOTEMPTY;
803 break;
804 }
805 }
806 brelse(bh);
807 return result;
808}
809
810EXPORT_SYMBOL(fat_dir_empty);
811
812/*
813 * fat_subdirs counts the number of sub-directories of dir. It can be run
814 * on directories being created.
815 */
816int fat_subdirs(struct inode *dir)
817{
818 struct buffer_head *bh;
819 struct msdos_dir_entry *de;
820 loff_t cpos;
821 int count = 0;
822
823 bh = NULL;
824 cpos = 0;
825 while (fat_get_short_entry(dir, &cpos, &bh, &de) >= 0) {
826 if (de->attr & ATTR_DIR)
827 count++;
828 }
829 brelse(bh);
830 return count;
831}
832
833/*
834 * Scans a directory for a given file (name points to its formatted name).
835 * Returns an error code or zero.
836 */
837int fat_scan(struct inode *dir, const unsigned char *name,
838 struct fat_slot_info *sinfo)
839{
840 struct super_block *sb = dir->i_sb;
841
842 sinfo->slot_off = 0;
843 sinfo->bh = NULL;
844 while (fat_get_short_entry(dir, &sinfo->slot_off, &sinfo->bh,
845 &sinfo->de) >= 0) {
846 if (!strncmp(sinfo->de->name, name, MSDOS_NAME)) {
847 sinfo->slot_off -= sizeof(*sinfo->de);
848 sinfo->nr_slots = 1;
849 sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de);
850 return 0;
851 }
852 }
853 return -ENOENT;
854}
855
856EXPORT_SYMBOL(fat_scan);
857
858static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
859{
860 struct super_block *sb = dir->i_sb;
861 struct buffer_head *bh;
862 struct msdos_dir_entry *de, *endp;
863 int err = 0, orig_slots;
864
865 while (nr_slots) {
866 bh = NULL;
867 if (fat_get_entry(dir, &pos, &bh, &de) < 0) {
868 err = -EIO;
869 break;
870 }
871
872 orig_slots = nr_slots;
873 endp = (struct msdos_dir_entry *)(bh->b_data + sb->s_blocksize);
874 while (nr_slots && de < endp) {
875 de->name[0] = DELETED_FLAG;
876 de++;
877 nr_slots--;
878 }
879 mark_buffer_dirty(bh);
880 if (IS_DIRSYNC(dir))
881 err = sync_dirty_buffer(bh);
882 brelse(bh);
883 if (err)
884 break;
885
886 /* pos is *next* de's position, so this does `- sizeof(de)' */
887 pos += ((orig_slots - nr_slots) * sizeof(*de)) - sizeof(*de);
888 }
889
890 return err;
891}
892
893int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
894{
895 struct msdos_dir_entry *de;
896 struct buffer_head *bh;
897 int err = 0, nr_slots;
898
899 /*
900 * First stage: Remove the shortname. By this, the directory
901 * entry is removed.
902 */
903 nr_slots = sinfo->nr_slots;
904 de = sinfo->de;
905 sinfo->de = NULL;
906 bh = sinfo->bh;
907 sinfo->bh = NULL;
908 while (nr_slots && de >= (struct msdos_dir_entry *)bh->b_data) {
909 de->name[0] = DELETED_FLAG;
910 de--;
911 nr_slots--;
912 }
913 mark_buffer_dirty(bh);
914 if (IS_DIRSYNC(dir))
915 err = sync_dirty_buffer(bh);
916 brelse(bh);
917 if (err)
918 return err;
919 dir->i_version++;
920
921 if (nr_slots) {
922 /*
923 * Second stage: remove the remaining longname slots.
924 * (This directory entry is already removed, and so return
925 * the success)
926 */
927 err = __fat_remove_entries(dir, sinfo->slot_off, nr_slots);
928 if (err) {
929 printk(KERN_WARNING
930 "FAT: Couldn't remove the long name slots\n");
931 }
932 }
933
934 dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
935 if (IS_DIRSYNC(dir))
936 (void)fat_sync_inode(dir);
937 else
938 mark_inode_dirty(dir);
939
940 return 0;
941}
942
943EXPORT_SYMBOL(fat_remove_entries);
944
945static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
946 struct buffer_head **bhs, int nr_bhs)
947{
948 struct super_block *sb = dir->i_sb;
949 sector_t last_blknr = blknr + MSDOS_SB(sb)->sec_per_clus;
950 int err, i, n;
951
952 /* Zeroing the unused blocks on this cluster */
953 blknr += nr_used;
954 n = nr_used;
955 while (blknr < last_blknr) {
956 bhs[n] = sb_getblk(sb, blknr);
957 if (!bhs[n]) {
958 err = -ENOMEM;
959 goto error;
960 }
961 memset(bhs[n]->b_data, 0, sb->s_blocksize);
962 set_buffer_uptodate(bhs[n]);
963 mark_buffer_dirty(bhs[n]);
964
965 n++;
966 blknr++;
967 if (n == nr_bhs) {
968 if (IS_DIRSYNC(dir)) {
969 err = fat_sync_bhs(bhs, n);
970 if (err)
971 goto error;
972 }
973 for (i = 0; i < n; i++)
974 brelse(bhs[i]);
975 n = 0;
976 }
977 }
978 if (IS_DIRSYNC(dir)) {
979 err = fat_sync_bhs(bhs, n);
980 if (err)
981 goto error;
982 }
983 for (i = 0; i < n; i++)
984 brelse(bhs[i]);
985
986 return 0;
987
988error:
989 for (i = 0; i < n; i++)
990 bforget(bhs[i]);
991 return err;
992}
993
994int fat_alloc_new_dir(struct inode *dir, struct timespec *ts)
995{
996 struct super_block *sb = dir->i_sb;
997 struct msdos_sb_info *sbi = MSDOS_SB(sb);
998 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
999 struct msdos_dir_entry *de;
1000 sector_t blknr;
1001 __le16 date, time;
1002 int err, cluster;
1003
1004 err = fat_alloc_clusters(dir, &cluster, 1);
1005 if (err)
1006 goto error;
1007
1008 blknr = fat_clus_to_blknr(sbi, cluster);
1009 bhs[0] = sb_getblk(sb, blknr);
1010 if (!bhs[0]) {
1011 err = -ENOMEM;
1012 goto error_free;
1013 }
1014
1015 fat_date_unix2dos(ts->tv_sec, &time, &date);
1016
1017 de = (struct msdos_dir_entry *)bhs[0]->b_data;
1018 /* filling the new directory slots ("." and ".." entries) */
1019 memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME);
1020 memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME);
1021 de->attr = de[1].attr = ATTR_DIR;
1022 de[0].lcase = de[1].lcase = 0;
1023 de[0].time = de[1].time = time;
1024 de[0].date = de[1].date = date;
1025 de[0].ctime_cs = de[1].ctime_cs = 0;
1026 if (sbi->options.isvfat) {
1027 /* extra timestamps */
1028 de[0].ctime = de[1].ctime = time;
1029 de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = date;
1030 } else {
1031 de[0].ctime = de[1].ctime = 0;
1032 de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = 0;
1033 }
1034 de[0].start = cpu_to_le16(cluster);
1035 de[0].starthi = cpu_to_le16(cluster >> 16);
1036 de[1].start = cpu_to_le16(MSDOS_I(dir)->i_logstart);
1037 de[1].starthi = cpu_to_le16(MSDOS_I(dir)->i_logstart >> 16);
1038 de[0].size = de[1].size = 0;
1039 memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
1040 set_buffer_uptodate(bhs[0]);
1041 mark_buffer_dirty(bhs[0]);
1042
1043 err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE);
1044 if (err)
1045 goto error_free;
1046
1047 return cluster;
1048
1049error_free:
1050 fat_free_clusters(dir, cluster);
1051error:
1052 return err;
1053}
1054
1055EXPORT_SYMBOL(fat_alloc_new_dir);
1056
1057static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
1058 int *nr_cluster, struct msdos_dir_entry **de,
1059 struct buffer_head **bh, loff_t *i_pos)
1060{
1061 struct super_block *sb = dir->i_sb;
1062 struct msdos_sb_info *sbi = MSDOS_SB(sb);
1063 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
1064 sector_t blknr, start_blknr, last_blknr;
1065 unsigned long size, copy;
1066 int err, i, n, offset, cluster[2];
1067
1068 /*
1069 * The minimum cluster size is 512bytes, and maximum entry
1070 * size is 32*slots (672bytes). So, iff the cluster size is
1071 * 512bytes, we may need two clusters.
1072 */
1073 size = nr_slots * sizeof(struct msdos_dir_entry);
1074 *nr_cluster = (size + (sbi->cluster_size - 1)) >> sbi->cluster_bits;
1075 BUG_ON(*nr_cluster > 2);
1076
1077 err = fat_alloc_clusters(dir, cluster, *nr_cluster);
1078 if (err)
1079 goto error;
1080
1081 /*
1082 * First stage: Fill the directory entry. NOTE: This cluster
1083 * is not referenced from any inode yet, so updates order is
1084 * not important.
1085 */
1086 i = n = copy = 0;
1087 do {
1088 start_blknr = blknr = fat_clus_to_blknr(sbi, cluster[i]);
1089 last_blknr = start_blknr + sbi->sec_per_clus;
1090 while (blknr < last_blknr) {
1091 bhs[n] = sb_getblk(sb, blknr);
1092 if (!bhs[n]) {
1093 err = -ENOMEM;
1094 goto error_nomem;
1095 }
1096
1097 /* fill the directory entry */
1098 copy = min(size, sb->s_blocksize);
1099 memcpy(bhs[n]->b_data, slots, copy);
1100 slots += copy;
1101 size -= copy;
1102 set_buffer_uptodate(bhs[n]);
1103 mark_buffer_dirty(bhs[n]);
1104 if (!size)
1105 break;
1106 n++;
1107 blknr++;
1108 }
1109 } while (++i < *nr_cluster);
1110
1111 memset(bhs[n]->b_data + copy, 0, sb->s_blocksize - copy);
1112 offset = copy - sizeof(struct msdos_dir_entry);
1113 get_bh(bhs[n]);
1114 *bh = bhs[n];
1115 *de = (struct msdos_dir_entry *)((*bh)->b_data + offset);
1116 *i_pos = fat_make_i_pos(sb, *bh, *de);
1117
1118 /* Second stage: clear the rest of cluster, and write outs */
1119 err = fat_zeroed_cluster(dir, start_blknr, ++n, bhs, MAX_BUF_PER_PAGE);
1120 if (err)
1121 goto error_free;
1122
1123 return cluster[0];
1124
1125error_free:
1126 brelse(*bh);
1127 *bh = NULL;
1128 n = 0;
1129error_nomem:
1130 for (i = 0; i < n; i++)
1131 bforget(bhs[i]);
1132 fat_free_clusters(dir, cluster[0]);
1133error:
1134 return err;
1135}
1136
1137int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
1138 struct fat_slot_info *sinfo)
1139{
1140 struct super_block *sb = dir->i_sb;
1141 struct msdos_sb_info *sbi = MSDOS_SB(sb);
1142 struct buffer_head *bh, *prev, *bhs[3]; /* 32*slots (672bytes) */
1143 struct msdos_dir_entry *de;
1144 int err, free_slots, i, nr_bhs;
1145 loff_t pos, i_pos;
1146
1147 sinfo->nr_slots = nr_slots;
1148
1149 /* First stage: search free direcotry entries */
1150 free_slots = nr_bhs = 0;
1151 bh = prev = NULL;
1152 pos = 0;
1153 err = -ENOSPC;
1154 while (fat_get_entry(dir, &pos, &bh, &de) > -1) {
1155 /* check the maximum size of directory */
1156 if (pos >= FAT_MAX_DIR_SIZE)
1157 goto error;
1158
1159 if (IS_FREE(de->name)) {
1160 if (prev != bh) {
1161 get_bh(bh);
1162 bhs[nr_bhs] = prev = bh;
1163 nr_bhs++;
1164 }
1165 free_slots++;
1166 if (free_slots == nr_slots)
1167 goto found;
1168 } else {
1169 for (i = 0; i < nr_bhs; i++)
1170 brelse(bhs[i]);
1171 prev = NULL;
1172 free_slots = nr_bhs = 0;
1173 }
1174 }
1175 if (dir->i_ino == MSDOS_ROOT_INO) {
1176 if (sbi->fat_bits != 32)
1177 goto error;
1178 } else if (MSDOS_I(dir)->i_start == 0) {
1179 printk(KERN_ERR "FAT: Corrupted directory (i_pos %lld)\n",
1180 MSDOS_I(dir)->i_pos);
1181 err = -EIO;
1182 goto error;
1183 }
1184
1185found:
1186 err = 0;
1187 pos -= free_slots * sizeof(*de);
1188 nr_slots -= free_slots;
1189 if (free_slots) {
1190 /*
1191 * Second stage: filling the free entries with new entries.
1192 * NOTE: If this slots has shortname, first, we write
1193 * the long name slots, then write the short name.
1194 */
1195 int size = free_slots * sizeof(*de);
1196 int offset = pos & (sb->s_blocksize - 1);
1197 int long_bhs = nr_bhs - (nr_slots == 0);
1198
1199 /* Fill the long name slots. */
1200 for (i = 0; i < long_bhs; i++) {
1201 int copy = min_t(int, sb->s_blocksize - offset, size);
1202 memcpy(bhs[i]->b_data + offset, slots, copy);
1203 mark_buffer_dirty(bhs[i]);
1204 offset = 0;
1205 slots += copy;
1206 size -= copy;
1207 }
1208 if (long_bhs && IS_DIRSYNC(dir))
1209 err = fat_sync_bhs(bhs, long_bhs);
1210 if (!err && i < nr_bhs) {
1211 /* Fill the short name slot. */
1212 int copy = min_t(int, sb->s_blocksize - offset, size);
1213 memcpy(bhs[i]->b_data + offset, slots, copy);
1214 mark_buffer_dirty(bhs[i]);
1215 if (IS_DIRSYNC(dir))
1216 err = sync_dirty_buffer(bhs[i]);
1217 }
1218 for (i = 0; i < nr_bhs; i++)
1219 brelse(bhs[i]);
1220 if (err)
1221 goto error_remove;
1222 }
1223
1224 if (nr_slots) {
1225 int cluster, nr_cluster;
1226
1227 /*
1228 * Third stage: allocate the cluster for new entries.
1229 * And initialize the cluster with new entries, then
1230 * add the cluster to dir.
1231 */
1232 cluster = fat_add_new_entries(dir, slots, nr_slots, &nr_cluster,
1233 &de, &bh, &i_pos);
1234 if (cluster < 0) {
1235 err = cluster;
1236 goto error_remove;
1237 }
1238 err = fat_chain_add(dir, cluster, nr_cluster);
1239 if (err) {
1240 fat_free_clusters(dir, cluster);
1241 goto error_remove;
1242 }
1243 if (dir->i_size & (sbi->cluster_size - 1)) {
1244 fat_fs_panic(sb, "Odd directory size");
1245 dir->i_size = (dir->i_size + sbi->cluster_size - 1)
1246 & ~((loff_t)sbi->cluster_size - 1);
1247 }
1248 dir->i_size += nr_cluster << sbi->cluster_bits;
1249 MSDOS_I(dir)->mmu_private += nr_cluster << sbi->cluster_bits;
1250 }
1251 sinfo->slot_off = pos;
1252 sinfo->de = de;
1253 sinfo->bh = bh;
1254 sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de);
1255
1256 return 0;
1257
1258error:
1259 brelse(bh);
1260 for (i = 0; i < nr_bhs; i++)
1261 brelse(bhs[i]);
1262 return err;
1263
1264error_remove:
1265 brelse(bh);
1266 if (free_slots)
1267 __fat_remove_entries(dir, pos, free_slots);
1268 return err;
1269}
1270
1271EXPORT_SYMBOL(fat_add_entries);
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
new file mode 100644
index 000000000000..4164cd54c4d1
--- /dev/null
+++ b/fs/fat/fatent.c
@@ -0,0 +1,612 @@
1/*
2 * Copyright (C) 2004, OGAWA Hirofumi
3 * Released under GPL v2.
4 */
5
6#include <linux/module.h>
7#include <linux/fs.h>
8#include <linux/msdos_fs.h>
9
10struct fatent_operations {
11 void (*ent_blocknr)(struct super_block *, int, int *, sector_t *);
12 void (*ent_set_ptr)(struct fat_entry *, int);
13 int (*ent_bread)(struct super_block *, struct fat_entry *,
14 int, sector_t);
15 int (*ent_get)(struct fat_entry *);
16 void (*ent_put)(struct fat_entry *, int);
17 int (*ent_next)(struct fat_entry *);
18};
19
20static void fat12_ent_blocknr(struct super_block *sb, int entry,
21 int *offset, sector_t *blocknr)
22{
23 struct msdos_sb_info *sbi = MSDOS_SB(sb);
24 int bytes = entry + (entry >> 1);
25 WARN_ON(entry < FAT_START_ENT || sbi->max_cluster <= entry);
26 *offset = bytes & (sb->s_blocksize - 1);
27 *blocknr = sbi->fat_start + (bytes >> sb->s_blocksize_bits);
28}
29
30static void fat_ent_blocknr(struct super_block *sb, int entry,
31 int *offset, sector_t *blocknr)
32{
33 struct msdos_sb_info *sbi = MSDOS_SB(sb);
34 int bytes = (entry << sbi->fatent_shift);
35 WARN_ON(entry < FAT_START_ENT || sbi->max_cluster <= entry);
36 *offset = bytes & (sb->s_blocksize - 1);
37 *blocknr = sbi->fat_start + (bytes >> sb->s_blocksize_bits);
38}
39
40static void fat12_ent_set_ptr(struct fat_entry *fatent, int offset)
41{
42 struct buffer_head **bhs = fatent->bhs;
43 if (fatent->nr_bhs == 1) {
44 WARN_ON(offset >= (bhs[0]->b_size - 1));
45 fatent->u.ent12_p[0] = bhs[0]->b_data + offset;
46 fatent->u.ent12_p[1] = bhs[0]->b_data + (offset + 1);
47 } else {
48 WARN_ON(offset != (bhs[0]->b_size - 1));
49 fatent->u.ent12_p[0] = bhs[0]->b_data + offset;
50 fatent->u.ent12_p[1] = bhs[1]->b_data;
51 }
52}
53
54static void fat16_ent_set_ptr(struct fat_entry *fatent, int offset)
55{
56 WARN_ON(offset & (2 - 1));
57 fatent->u.ent16_p = (__le16 *)(fatent->bhs[0]->b_data + offset);
58}
59
60static void fat32_ent_set_ptr(struct fat_entry *fatent, int offset)
61{
62 WARN_ON(offset & (4 - 1));
63 fatent->u.ent32_p = (__le32 *)(fatent->bhs[0]->b_data + offset);
64}
65
66static int fat12_ent_bread(struct super_block *sb, struct fat_entry *fatent,
67 int offset, sector_t blocknr)
68{
69 struct buffer_head **bhs = fatent->bhs;
70
71 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start);
72 bhs[0] = sb_bread(sb, blocknr);
73 if (!bhs[0])
74 goto err;
75
76 if ((offset + 1) < sb->s_blocksize)
77 fatent->nr_bhs = 1;
78 else {
79 /* This entry is block boundary, it needs the next block */
80 blocknr++;
81 bhs[1] = sb_bread(sb, blocknr);
82 if (!bhs[1])
83 goto err_brelse;
84 fatent->nr_bhs = 2;
85 }
86 fat12_ent_set_ptr(fatent, offset);
87 return 0;
88
89err_brelse:
90 brelse(bhs[0]);
91err:
92 printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n",
93 (unsigned long long)blocknr);
94 return -EIO;
95}
96
97static int fat_ent_bread(struct super_block *sb, struct fat_entry *fatent,
98 int offset, sector_t blocknr)
99{
100 struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
101
102 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start);
103 fatent->bhs[0] = sb_bread(sb, blocknr);
104 if (!fatent->bhs[0]) {
105 printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n",
106 (unsigned long long)blocknr);
107 return -EIO;
108 }
109 fatent->nr_bhs = 1;
110 ops->ent_set_ptr(fatent, offset);
111 return 0;
112}
113
114static int fat12_ent_get(struct fat_entry *fatent)
115{
116 u8 **ent12_p = fatent->u.ent12_p;
117 int next;
118
119 if (fatent->entry & 1)
120 next = (*ent12_p[0] >> 4) | (*ent12_p[1] << 4);
121 else
122 next = (*ent12_p[1] << 8) | *ent12_p[0];
123 next &= 0x0fff;
124 if (next >= BAD_FAT12)
125 next = FAT_ENT_EOF;
126 return next;
127}
128
129static int fat16_ent_get(struct fat_entry *fatent)
130{
131 int next = le16_to_cpu(*fatent->u.ent16_p);
132 WARN_ON((unsigned long)fatent->u.ent16_p & (2 - 1));
133 if (next >= BAD_FAT16)
134 next = FAT_ENT_EOF;
135 return next;
136}
137
138static int fat32_ent_get(struct fat_entry *fatent)
139{
140 int next = le32_to_cpu(*fatent->u.ent32_p) & 0x0fffffff;
141 WARN_ON((unsigned long)fatent->u.ent32_p & (4 - 1));
142 if (next >= BAD_FAT32)
143 next = FAT_ENT_EOF;
144 return next;
145}
146
147static void fat12_ent_put(struct fat_entry *fatent, int new)
148{
149 u8 **ent12_p = fatent->u.ent12_p;
150
151 if (new == FAT_ENT_EOF)
152 new = EOF_FAT12;
153
154 if (fatent->entry & 1) {
155 *ent12_p[0] = (new << 4) | (*ent12_p[0] & 0x0f);
156 *ent12_p[1] = new >> 4;
157 } else {
158 *ent12_p[0] = new & 0xff;
159 *ent12_p[1] = (*ent12_p[1] & 0xf0) | (new >> 8);
160 }
161
162 mark_buffer_dirty(fatent->bhs[0]);
163 if (fatent->nr_bhs == 2)
164 mark_buffer_dirty(fatent->bhs[1]);
165}
166
167static void fat16_ent_put(struct fat_entry *fatent, int new)
168{
169 if (new == FAT_ENT_EOF)
170 new = EOF_FAT16;
171
172 *fatent->u.ent16_p = cpu_to_le16(new);
173 mark_buffer_dirty(fatent->bhs[0]);
174}
175
176static void fat32_ent_put(struct fat_entry *fatent, int new)
177{
178 if (new == FAT_ENT_EOF)
179 new = EOF_FAT32;
180
181 WARN_ON(new & 0xf0000000);
182 new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff;
183 *fatent->u.ent32_p = cpu_to_le32(new);
184 mark_buffer_dirty(fatent->bhs[0]);
185}
186
187static int fat12_ent_next(struct fat_entry *fatent)
188{
189 u8 **ent12_p = fatent->u.ent12_p;
190 struct buffer_head **bhs = fatent->bhs;
191 u8 *nextp = ent12_p[1] + 1 + (fatent->entry & 1);
192
193 fatent->entry++;
194 if (fatent->nr_bhs == 1) {
195 WARN_ON(ent12_p[0] > (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 2)));
196 WARN_ON(ent12_p[1] > (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1)));
197 if (nextp < (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1))) {
198 ent12_p[0] = nextp - 1;
199 ent12_p[1] = nextp;
200 return 1;
201 }
202 } else {
203 WARN_ON(ent12_p[0] != (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1)));
204 WARN_ON(ent12_p[1] != (u8 *)bhs[1]->b_data);
205 ent12_p[0] = nextp - 1;
206 ent12_p[1] = nextp;
207 brelse(bhs[0]);
208 bhs[0] = bhs[1];
209 fatent->nr_bhs = 1;
210 return 1;
211 }
212 ent12_p[0] = NULL;
213 ent12_p[1] = NULL;
214 return 0;
215}
216
217static int fat16_ent_next(struct fat_entry *fatent)
218{
219 const struct buffer_head *bh = fatent->bhs[0];
220 fatent->entry++;
221 if (fatent->u.ent16_p < (__le16 *)(bh->b_data + (bh->b_size - 2))) {
222 fatent->u.ent16_p++;
223 return 1;
224 }
225 fatent->u.ent16_p = NULL;
226 return 0;
227}
228
229static int fat32_ent_next(struct fat_entry *fatent)
230{
231 const struct buffer_head *bh = fatent->bhs[0];
232 fatent->entry++;
233 if (fatent->u.ent32_p < (__le32 *)(bh->b_data + (bh->b_size - 4))) {
234 fatent->u.ent32_p++;
235 return 1;
236 }
237 fatent->u.ent32_p = NULL;
238 return 0;
239}
240
241static struct fatent_operations fat12_ops = {
242 .ent_blocknr = fat12_ent_blocknr,
243 .ent_set_ptr = fat12_ent_set_ptr,
244 .ent_bread = fat12_ent_bread,
245 .ent_get = fat12_ent_get,
246 .ent_put = fat12_ent_put,
247 .ent_next = fat12_ent_next,
248};
249
250static struct fatent_operations fat16_ops = {
251 .ent_blocknr = fat_ent_blocknr,
252 .ent_set_ptr = fat16_ent_set_ptr,
253 .ent_bread = fat_ent_bread,
254 .ent_get = fat16_ent_get,
255 .ent_put = fat16_ent_put,
256 .ent_next = fat16_ent_next,
257};
258
259static struct fatent_operations fat32_ops = {
260 .ent_blocknr = fat_ent_blocknr,
261 .ent_set_ptr = fat32_ent_set_ptr,
262 .ent_bread = fat_ent_bread,
263 .ent_get = fat32_ent_get,
264 .ent_put = fat32_ent_put,
265 .ent_next = fat32_ent_next,
266};
267
268static inline void lock_fat(struct msdos_sb_info *sbi)
269{
270 down(&sbi->fat_lock);
271}
272
273static inline void unlock_fat(struct msdos_sb_info *sbi)
274{
275 up(&sbi->fat_lock);
276}
277
278void fat_ent_access_init(struct super_block *sb)
279{
280 struct msdos_sb_info *sbi = MSDOS_SB(sb);
281
282 init_MUTEX(&sbi->fat_lock);
283
284 switch (sbi->fat_bits) {
285 case 32:
286 sbi->fatent_shift = 2;
287 sbi->fatent_ops = &fat32_ops;
288 break;
289 case 16:
290 sbi->fatent_shift = 1;
291 sbi->fatent_ops = &fat16_ops;
292 break;
293 case 12:
294 sbi->fatent_shift = -1;
295 sbi->fatent_ops = &fat12_ops;
296 break;
297 }
298}
299
300static inline int fat_ent_update_ptr(struct super_block *sb,
301 struct fat_entry *fatent,
302 int offset, sector_t blocknr)
303{
304 struct msdos_sb_info *sbi = MSDOS_SB(sb);
305 struct fatent_operations *ops = sbi->fatent_ops;
306 struct buffer_head **bhs = fatent->bhs;
307
308 /* Is this fatent's blocks including this entry? */
309 if (!fatent->nr_bhs || bhs[0]->b_blocknr != blocknr)
310 return 0;
311 /* Does this entry need the next block? */
312 if (sbi->fat_bits == 12 && (offset + 1) >= sb->s_blocksize) {
313 if (fatent->nr_bhs != 2 || bhs[1]->b_blocknr != (blocknr + 1))
314 return 0;
315 }
316 ops->ent_set_ptr(fatent, offset);
317 return 1;
318}
319
320int fat_ent_read(struct inode *inode, struct fat_entry *fatent, int entry)
321{
322 struct super_block *sb = inode->i_sb;
323 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
324 struct fatent_operations *ops = sbi->fatent_ops;
325 int err, offset;
326 sector_t blocknr;
327
328 if (entry < FAT_START_ENT || sbi->max_cluster <= entry) {
329 fatent_brelse(fatent);
330 fat_fs_panic(sb, "invalid access to FAT (entry 0x%08x)", entry);
331 return -EIO;
332 }
333
334 fatent_set_entry(fatent, entry);
335 ops->ent_blocknr(sb, entry, &offset, &blocknr);
336
337 if (!fat_ent_update_ptr(sb, fatent, offset, blocknr)) {
338 fatent_brelse(fatent);
339 err = ops->ent_bread(sb, fatent, offset, blocknr);
340 if (err)
341 return err;
342 }
343 return ops->ent_get(fatent);
344}
345
346/* FIXME: We can write the blocks as more big chunk. */
347static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
348 int nr_bhs)
349{
350 struct msdos_sb_info *sbi = MSDOS_SB(sb);
351 struct buffer_head *c_bh;
352 int err, n, copy;
353
354 err = 0;
355 for (copy = 1; copy < sbi->fats; copy++) {
356 sector_t backup_fat = sbi->fat_length * copy;
357
358 for (n = 0; n < nr_bhs; n++) {
359 c_bh = sb_getblk(sb, backup_fat + bhs[n]->b_blocknr);
360 if (!c_bh) {
361 err = -ENOMEM;
362 goto error;
363 }
364 memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);
365 set_buffer_uptodate(c_bh);
366 mark_buffer_dirty(c_bh);
367 if (sb->s_flags & MS_SYNCHRONOUS)
368 err = sync_dirty_buffer(c_bh);
369 brelse(c_bh);
370 if (err)
371 goto error;
372 }
373 }
374error:
375 return err;
376}
377
378int fat_ent_write(struct inode *inode, struct fat_entry *fatent,
379 int new, int wait)
380{
381 struct super_block *sb = inode->i_sb;
382 struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
383 int err;
384
385 ops->ent_put(fatent, new);
386 if (wait) {
387 err = fat_sync_bhs(fatent->bhs, fatent->nr_bhs);
388 if (err)
389 return err;
390 }
391 return fat_mirror_bhs(sb, fatent->bhs, fatent->nr_bhs);
392}
393
394static inline int fat_ent_next(struct msdos_sb_info *sbi,
395 struct fat_entry *fatent)
396{
397 if (sbi->fatent_ops->ent_next(fatent)) {
398 if (fatent->entry < sbi->max_cluster)
399 return 1;
400 }
401 return 0;
402}
403
404static inline int fat_ent_read_block(struct super_block *sb,
405 struct fat_entry *fatent)
406{
407 struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
408 sector_t blocknr;
409 int offset;
410
411 fatent_brelse(fatent);
412 ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr);
413 return ops->ent_bread(sb, fatent, offset, blocknr);
414}
415
416static void fat_collect_bhs(struct buffer_head **bhs, int *nr_bhs,
417 struct fat_entry *fatent)
418{
419 int n, i;
420
421 for (n = 0; n < fatent->nr_bhs; n++) {
422 for (i = 0; i < *nr_bhs; i++) {
423 if (fatent->bhs[n] == bhs[i])
424 break;
425 }
426 if (i == *nr_bhs) {
427 get_bh(fatent->bhs[n]);
428 bhs[i] = fatent->bhs[n];
429 (*nr_bhs)++;
430 }
431 }
432}
433
434int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
435{
436 struct super_block *sb = inode->i_sb;
437 struct msdos_sb_info *sbi = MSDOS_SB(sb);
438 struct fatent_operations *ops = sbi->fatent_ops;
439 struct fat_entry fatent, prev_ent;
440 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
441 int i, count, err, nr_bhs, idx_clus;
442
443 BUG_ON(nr_cluster > (MAX_BUF_PER_PAGE / 2)); /* fixed limit */
444
445 lock_fat(sbi);
446 if (sbi->free_clusters != -1 && sbi->free_clusters < nr_cluster) {
447 unlock_fat(sbi);
448 return -ENOSPC;
449 }
450
451 err = nr_bhs = idx_clus = 0;
452 count = FAT_START_ENT;
453 fatent_init(&prev_ent);
454 fatent_init(&fatent);
455 fatent_set_entry(&fatent, sbi->prev_free + 1);
456 while (count < sbi->max_cluster) {
457 if (fatent.entry >= sbi->max_cluster)
458 fatent.entry = FAT_START_ENT;
459 fatent_set_entry(&fatent, fatent.entry);
460 err = fat_ent_read_block(sb, &fatent);
461 if (err)
462 goto out;
463
464 /* Find the free entries in a block */
465 do {
466 if (ops->ent_get(&fatent) == FAT_ENT_FREE) {
467 int entry = fatent.entry;
468
469 /* make the cluster chain */
470 ops->ent_put(&fatent, FAT_ENT_EOF);
471 if (prev_ent.nr_bhs)
472 ops->ent_put(&prev_ent, entry);
473
474 fat_collect_bhs(bhs, &nr_bhs, &fatent);
475
476 sbi->prev_free = entry;
477 if (sbi->free_clusters != -1)
478 sbi->free_clusters--;
479
480 cluster[idx_clus] = entry;
481 idx_clus++;
482 if (idx_clus == nr_cluster)
483 goto out;
484
485 /*
486 * fat_collect_bhs() gets ref-count of bhs,
487 * so we can still use the prev_ent.
488 */
489 prev_ent = fatent;
490 }
491 count++;
492 if (count == sbi->max_cluster)
493 break;
494 } while (fat_ent_next(sbi, &fatent));
495 }
496
497 /* Couldn't allocate the free entries */
498 sbi->free_clusters = 0;
499 err = -ENOSPC;
500
501out:
502 unlock_fat(sbi);
503 fatent_brelse(&fatent);
504 if (!err) {
505 if (inode_needs_sync(inode))
506 err = fat_sync_bhs(bhs, nr_bhs);
507 if (!err)
508 err = fat_mirror_bhs(sb, bhs, nr_bhs);
509 }
510 for (i = 0; i < nr_bhs; i++)
511 brelse(bhs[i]);
512 fat_clusters_flush(sb);
513
514 if (err && idx_clus)
515 fat_free_clusters(inode, cluster[0]);
516
517 return err;
518}
519
520int fat_free_clusters(struct inode *inode, int cluster)
521{
522 struct super_block *sb = inode->i_sb;
523 struct msdos_sb_info *sbi = MSDOS_SB(sb);
524 struct fatent_operations *ops = sbi->fatent_ops;
525 struct fat_entry fatent;
526 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
527 int i, err, nr_bhs;
528
529 nr_bhs = 0;
530 fatent_init(&fatent);
531 lock_fat(sbi);
532 do {
533 cluster = fat_ent_read(inode, &fatent, cluster);
534 if (cluster < 0) {
535 err = cluster;
536 goto error;
537 } else if (cluster == FAT_ENT_FREE) {
538 fat_fs_panic(sb, "%s: deleting FAT entry beyond EOF",
539 __FUNCTION__);
540 err = -EIO;
541 goto error;
542 }
543
544 ops->ent_put(&fatent, FAT_ENT_FREE);
545 if (sbi->free_clusters != -1)
546 sbi->free_clusters++;
547
548 if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) {
549 if (sb->s_flags & MS_SYNCHRONOUS) {
550 err = fat_sync_bhs(bhs, nr_bhs);
551 if (err)
552 goto error;
553 }
554 err = fat_mirror_bhs(sb, bhs, nr_bhs);
555 if (err)
556 goto error;
557 for (i = 0; i < nr_bhs; i++)
558 brelse(bhs[i]);
559 nr_bhs = 0;
560 }
561 fat_collect_bhs(bhs, &nr_bhs, &fatent);
562 } while (cluster != FAT_ENT_EOF);
563
564 if (sb->s_flags & MS_SYNCHRONOUS) {
565 err = fat_sync_bhs(bhs, nr_bhs);
566 if (err)
567 goto error;
568 }
569 err = fat_mirror_bhs(sb, bhs, nr_bhs);
570error:
571 fatent_brelse(&fatent);
572 for (i = 0; i < nr_bhs; i++)
573 brelse(bhs[i]);
574 unlock_fat(sbi);
575
576 fat_clusters_flush(sb);
577
578 return err;
579}
580
581EXPORT_SYMBOL(fat_free_clusters);
582
583int fat_count_free_clusters(struct super_block *sb)
584{
585 struct msdos_sb_info *sbi = MSDOS_SB(sb);
586 struct fatent_operations *ops = sbi->fatent_ops;
587 struct fat_entry fatent;
588 int err = 0, free;
589
590 lock_fat(sbi);
591 if (sbi->free_clusters != -1)
592 goto out;
593
594 free = 0;
595 fatent_init(&fatent);
596 fatent_set_entry(&fatent, FAT_START_ENT);
597 while (fatent.entry < sbi->max_cluster) {
598 err = fat_ent_read_block(sb, &fatent);
599 if (err)
600 goto out;
601
602 do {
603 if (ops->ent_get(&fatent) == FAT_ENT_FREE)
604 free++;
605 } while (fat_ent_next(sbi, &fatent));
606 }
607 sbi->free_clusters = free;
608 fatent_brelse(&fatent);
609out:
610 unlock_fat(sbi);
611 return err;
612}
diff --git a/fs/fat/file.c b/fs/fat/file.c
new file mode 100644
index 000000000000..62ffa9139400
--- /dev/null
+++ b/fs/fat/file.c
@@ -0,0 +1,308 @@
1/*
2 * linux/fs/fat/file.c
3 *
4 * Written 1992,1993 by Werner Almesberger
5 *
6 * regular file handling primitives for fat-based filesystems
7 */
8
9#include <linux/module.h>
10#include <linux/time.h>
11#include <linux/msdos_fs.h>
12#include <linux/smp_lock.h>
13#include <linux/buffer_head.h>
14
15static ssize_t fat_file_aio_write(struct kiocb *iocb, const char __user *buf,
16 size_t count, loff_t pos)
17{
18 struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
19 int retval;
20
21 retval = generic_file_aio_write(iocb, buf, count, pos);
22 if (retval > 0) {
23 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
24 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
25 mark_inode_dirty(inode);
26// check the locking rules
27// if (IS_SYNC(inode))
28// fat_sync_inode(inode);
29 }
30 return retval;
31}
32
33static ssize_t fat_file_writev(struct file *filp, const struct iovec *iov,
34 unsigned long nr_segs, loff_t *ppos)
35{
36 struct inode *inode = filp->f_dentry->d_inode;
37 int retval;
38
39 retval = generic_file_writev(filp, iov, nr_segs, ppos);
40 if (retval > 0) {
41 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
42 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
43 mark_inode_dirty(inode);
44 }
45 return retval;
46}
47
48int fat_generic_ioctl(struct inode *inode, struct file *filp,
49 unsigned int cmd, unsigned long arg)
50{
51 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
52 u32 __user *user_attr = (u32 __user *)arg;
53
54 switch (cmd) {
55 case FAT_IOCTL_GET_ATTRIBUTES:
56 {
57 u32 attr;
58
59 if (inode->i_ino == MSDOS_ROOT_INO)
60 attr = ATTR_DIR;
61 else
62 attr = fat_attr(inode);
63
64 return put_user(attr, user_attr);
65 }
66 case FAT_IOCTL_SET_ATTRIBUTES:
67 {
68 u32 attr, oldattr;
69 int err, is_dir = S_ISDIR(inode->i_mode);
70 struct iattr ia;
71
72 err = get_user(attr, user_attr);
73 if (err)
74 return err;
75
76 down(&inode->i_sem);
77
78 if (IS_RDONLY(inode)) {
79 err = -EROFS;
80 goto up;
81 }
82
83 /*
84 * ATTR_VOLUME and ATTR_DIR cannot be changed; this also
85 * prevents the user from turning us into a VFAT
86 * longname entry. Also, we obviously can't set
87 * any of the NTFS attributes in the high 24 bits.
88 */
89 attr &= 0xff & ~(ATTR_VOLUME | ATTR_DIR);
90 /* Merge in ATTR_VOLUME and ATTR_DIR */
91 attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) |
92 (is_dir ? ATTR_DIR : 0);
93 oldattr = fat_attr(inode);
94
95 /* Equivalent to a chmod() */
96 ia.ia_valid = ATTR_MODE | ATTR_CTIME;
97 if (is_dir) {
98 ia.ia_mode = MSDOS_MKMODE(attr,
99 S_IRWXUGO & ~sbi->options.fs_dmask)
100 | S_IFDIR;
101 } else {
102 ia.ia_mode = MSDOS_MKMODE(attr,
103 (S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO))
104 & ~sbi->options.fs_fmask)
105 | S_IFREG;
106 }
107
108 /* The root directory has no attributes */
109 if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) {
110 err = -EINVAL;
111 goto up;
112 }
113
114 if (sbi->options.sys_immutable) {
115 if ((attr | oldattr) & ATTR_SYS) {
116 if (!capable(CAP_LINUX_IMMUTABLE)) {
117 err = -EPERM;
118 goto up;
119 }
120 }
121 }
122
123 /* This MUST be done before doing anything irreversible... */
124 err = notify_change(filp->f_dentry, &ia);
125 if (err)
126 goto up;
127
128 if (sbi->options.sys_immutable) {
129 if (attr & ATTR_SYS)
130 inode->i_flags |= S_IMMUTABLE;
131 else
132 inode->i_flags &= S_IMMUTABLE;
133 }
134
135 MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED;
136 mark_inode_dirty(inode);
137 up:
138 up(&inode->i_sem);
139 return err;
140 }
141 default:
142 return -ENOTTY; /* Inappropriate ioctl for device */
143 }
144}
145
146struct file_operations fat_file_operations = {
147 .llseek = generic_file_llseek,
148 .read = do_sync_read,
149 .write = do_sync_write,
150 .readv = generic_file_readv,
151 .writev = fat_file_writev,
152 .aio_read = generic_file_aio_read,
153 .aio_write = fat_file_aio_write,
154 .mmap = generic_file_mmap,
155 .ioctl = fat_generic_ioctl,
156 .fsync = file_fsync,
157 .sendfile = generic_file_sendfile,
158};
159
160int fat_notify_change(struct dentry *dentry, struct iattr *attr)
161{
162 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
163 struct inode *inode = dentry->d_inode;
164 int mask, error = 0;
165
166 lock_kernel();
167
168 /* FAT cannot truncate to a longer file */
169 if (attr->ia_valid & ATTR_SIZE) {
170 if (attr->ia_size > inode->i_size) {
171 error = -EPERM;
172 goto out;
173 }
174 }
175
176 error = inode_change_ok(inode, attr);
177 if (error) {
178 if (sbi->options.quiet)
179 error = 0;
180 goto out;
181 }
182 if (((attr->ia_valid & ATTR_UID) &&
183 (attr->ia_uid != sbi->options.fs_uid)) ||
184 ((attr->ia_valid & ATTR_GID) &&
185 (attr->ia_gid != sbi->options.fs_gid)) ||
186 ((attr->ia_valid & ATTR_MODE) &&
187 (attr->ia_mode & ~MSDOS_VALID_MODE)))
188 error = -EPERM;
189
190 if (error) {
191 if (sbi->options.quiet)
192 error = 0;
193 goto out;
194 }
195 error = inode_setattr(inode, attr);
196 if (error)
197 goto out;
198
199 if (S_ISDIR(inode->i_mode))
200 mask = sbi->options.fs_dmask;
201 else
202 mask = sbi->options.fs_fmask;
203 inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
204out:
205 unlock_kernel();
206 return error;
207}
208
209EXPORT_SYMBOL(fat_notify_change);
210
211/* Free all clusters after the skip'th cluster. */
212static int fat_free(struct inode *inode, int skip)
213{
214 struct super_block *sb = inode->i_sb;
215 int err, wait, free_start, i_start, i_logstart;
216
217 if (MSDOS_I(inode)->i_start == 0)
218 return 0;
219
220 /*
221 * Write a new EOF, and get the remaining cluster chain for freeing.
222 */
223 wait = IS_DIRSYNC(inode);
224 if (skip) {
225 struct fat_entry fatent;
226 int ret, fclus, dclus;
227
228 ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus);
229 if (ret < 0)
230 return ret;
231 else if (ret == FAT_ENT_EOF)
232 return 0;
233
234 fatent_init(&fatent);
235 ret = fat_ent_read(inode, &fatent, dclus);
236 if (ret == FAT_ENT_EOF) {
237 fatent_brelse(&fatent);
238 return 0;
239 } else if (ret == FAT_ENT_FREE) {
240 fat_fs_panic(sb,
241 "%s: invalid cluster chain (i_pos %lld)",
242 __FUNCTION__, MSDOS_I(inode)->i_pos);
243 ret = -EIO;
244 } else if (ret > 0) {
245 err = fat_ent_write(inode, &fatent, FAT_ENT_EOF, wait);
246 if (err)
247 ret = err;
248 }
249 fatent_brelse(&fatent);
250 if (ret < 0)
251 return ret;
252
253 free_start = ret;
254 i_start = i_logstart = 0;
255 fat_cache_inval_inode(inode);
256 } else {
257 fat_cache_inval_inode(inode);
258
259 i_start = free_start = MSDOS_I(inode)->i_start;
260 i_logstart = MSDOS_I(inode)->i_logstart;
261 MSDOS_I(inode)->i_start = 0;
262 MSDOS_I(inode)->i_logstart = 0;
263 }
264 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
265 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
266 if (wait) {
267 err = fat_sync_inode(inode);
268 if (err)
269 goto error;
270 } else
271 mark_inode_dirty(inode);
272 inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9);
273
274 /* Freeing the remained cluster chain */
275 return fat_free_clusters(inode, free_start);
276
277error:
278 if (i_start) {
279 MSDOS_I(inode)->i_start = i_start;
280 MSDOS_I(inode)->i_logstart = i_logstart;
281 }
282 return err;
283}
284
285void fat_truncate(struct inode *inode)
286{
287 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
288 const unsigned int cluster_size = sbi->cluster_size;
289 int nr_clusters;
290
291 /*
292 * This protects against truncating a file bigger than it was then
293 * trying to write into the hole.
294 */
295 if (MSDOS_I(inode)->mmu_private > inode->i_size)
296 MSDOS_I(inode)->mmu_private = inode->i_size;
297
298 nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits;
299
300 lock_kernel();
301 fat_free(inode, nr_clusters);
302 unlock_kernel();
303}
304
305struct inode_operations fat_file_inode_operations = {
306 .truncate = fat_truncate,
307 .setattr = fat_notify_change,
308};
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
new file mode 100644
index 000000000000..8ccee8415488
--- /dev/null
+++ b/fs/fat/inode.c
@@ -0,0 +1,1351 @@
1/*
2 * linux/fs/fat/inode.c
3 *
4 * Written 1992,1993 by Werner Almesberger
5 * VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner
6 * Rewritten for the constant inumbers support by Al Viro
7 *
8 * Fixes:
9 *
10 * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/time.h>
16#include <linux/slab.h>
17#include <linux/smp_lock.h>
18#include <linux/seq_file.h>
19#include <linux/msdos_fs.h>
20#include <linux/pagemap.h>
21#include <linux/buffer_head.h>
22#include <linux/mount.h>
23#include <linux/vfs.h>
24#include <linux/parser.h>
25#include <asm/unaligned.h>
26
27#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
28/* if user don't select VFAT, this is undefined. */
29#define CONFIG_FAT_DEFAULT_IOCHARSET ""
30#endif
31
32static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
33static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
34
35
36static int fat_add_cluster(struct inode *inode)
37{
38 int err, cluster;
39
40 err = fat_alloc_clusters(inode, &cluster, 1);
41 if (err)
42 return err;
43 /* FIXME: this cluster should be added after data of this
44 * cluster is writed */
45 err = fat_chain_add(inode, cluster, 1);
46 if (err)
47 fat_free_clusters(inode, cluster);
48 return err;
49}
50
51static int fat_get_block(struct inode *inode, sector_t iblock,
52 struct buffer_head *bh_result, int create)
53{
54 struct super_block *sb = inode->i_sb;
55 sector_t phys;
56 int err;
57
58 err = fat_bmap(inode, iblock, &phys);
59 if (err)
60 return err;
61 if (phys) {
62 map_bh(bh_result, sb, phys);
63 return 0;
64 }
65 if (!create)
66 return 0;
67 if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
68 fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
69 MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
70 return -EIO;
71 }
72 if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
73 err = fat_add_cluster(inode);
74 if (err)
75 return err;
76 }
77 MSDOS_I(inode)->mmu_private += sb->s_blocksize;
78 err = fat_bmap(inode, iblock, &phys);
79 if (err)
80 return err;
81 if (!phys)
82 BUG();
83 set_buffer_new(bh_result);
84 map_bh(bh_result, sb, phys);
85 return 0;
86}
87
88static int fat_writepage(struct page *page, struct writeback_control *wbc)
89{
90 return block_write_full_page(page, fat_get_block, wbc);
91}
92
93static int fat_readpage(struct file *file, struct page *page)
94{
95 return block_read_full_page(page, fat_get_block);
96}
97
98static int fat_prepare_write(struct file *file, struct page *page,
99 unsigned from, unsigned to)
100{
101 return cont_prepare_write(page, from, to, fat_get_block,
102 &MSDOS_I(page->mapping->host)->mmu_private);
103}
104
105static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
106{
107 return generic_block_bmap(mapping, block, fat_get_block);
108}
109
110static struct address_space_operations fat_aops = {
111 .readpage = fat_readpage,
112 .writepage = fat_writepage,
113 .sync_page = block_sync_page,
114 .prepare_write = fat_prepare_write,
115 .commit_write = generic_commit_write,
116 .bmap = _fat_bmap
117};
118
119/*
120 * New FAT inode stuff. We do the following:
121 * a) i_ino is constant and has nothing with on-disk location.
122 * b) FAT manages its own cache of directory entries.
123 * c) *This* cache is indexed by on-disk location.
124 * d) inode has an associated directory entry, all right, but
125 * it may be unhashed.
126 * e) currently entries are stored within struct inode. That should
127 * change.
128 * f) we deal with races in the following way:
129 * 1. readdir() and lookup() do FAT-dir-cache lookup.
130 * 2. rename() unhashes the F-d-c entry and rehashes it in
131 * a new place.
132 * 3. unlink() and rmdir() unhash F-d-c entry.
133 * 4. fat_write_inode() checks whether the thing is unhashed.
134 * If it is we silently return. If it isn't we do bread(),
135 * check if the location is still valid and retry if it
136 * isn't. Otherwise we do changes.
137 * 5. Spinlock is used to protect hash/unhash/location check/lookup
138 * 6. fat_clear_inode() unhashes the F-d-c entry.
139 * 7. lookup() and readdir() do igrab() if they find a F-d-c entry
140 * and consider negative result as cache miss.
141 */
142
143static void fat_hash_init(struct super_block *sb)
144{
145 struct msdos_sb_info *sbi = MSDOS_SB(sb);
146 int i;
147
148 spin_lock_init(&sbi->inode_hash_lock);
149 for (i = 0; i < FAT_HASH_SIZE; i++)
150 INIT_HLIST_HEAD(&sbi->inode_hashtable[i]);
151}
152
153static inline unsigned long fat_hash(struct super_block *sb, loff_t i_pos)
154{
155 unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb;
156 tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS * 2);
157 return tmp & FAT_HASH_MASK;
158}
159
160void fat_attach(struct inode *inode, loff_t i_pos)
161{
162 struct super_block *sb = inode->i_sb;
163 struct msdos_sb_info *sbi = MSDOS_SB(sb);
164
165 spin_lock(&sbi->inode_hash_lock);
166 MSDOS_I(inode)->i_pos = i_pos;
167 hlist_add_head(&MSDOS_I(inode)->i_fat_hash,
168 sbi->inode_hashtable + fat_hash(sb, i_pos));
169 spin_unlock(&sbi->inode_hash_lock);
170}
171
172EXPORT_SYMBOL(fat_attach);
173
174void fat_detach(struct inode *inode)
175{
176 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
177 spin_lock(&sbi->inode_hash_lock);
178 MSDOS_I(inode)->i_pos = 0;
179 hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
180 spin_unlock(&sbi->inode_hash_lock);
181}
182
183EXPORT_SYMBOL(fat_detach);
184
185struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
186{
187 struct msdos_sb_info *sbi = MSDOS_SB(sb);
188 struct hlist_head *head = sbi->inode_hashtable + fat_hash(sb, i_pos);
189 struct hlist_node *_p;
190 struct msdos_inode_info *i;
191 struct inode *inode = NULL;
192
193 spin_lock(&sbi->inode_hash_lock);
194 hlist_for_each_entry(i, _p, head, i_fat_hash) {
195 BUG_ON(i->vfs_inode.i_sb != sb);
196 if (i->i_pos != i_pos)
197 continue;
198 inode = igrab(&i->vfs_inode);
199 if (inode)
200 break;
201 }
202 spin_unlock(&sbi->inode_hash_lock);
203 return inode;
204}
205
206static int is_exec(unsigned char *extension)
207{
208 unsigned char *exe_extensions = "EXECOMBAT", *walk;
209
210 for (walk = exe_extensions; *walk; walk += 3)
211 if (!strncmp(extension, walk, 3))
212 return 1;
213 return 0;
214}
215
216static int fat_calc_dir_size(struct inode *inode)
217{
218 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
219 int ret, fclus, dclus;
220
221 inode->i_size = 0;
222 if (MSDOS_I(inode)->i_start == 0)
223 return 0;
224
225 ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
226 if (ret < 0)
227 return ret;
228 inode->i_size = (fclus + 1) << sbi->cluster_bits;
229
230 return 0;
231}
232
233/* doesn't deal with root inode */
234static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
235{
236 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
237 int error;
238
239 MSDOS_I(inode)->i_pos = 0;
240 inode->i_uid = sbi->options.fs_uid;
241 inode->i_gid = sbi->options.fs_gid;
242 inode->i_version++;
243 inode->i_generation = get_seconds();
244
245 if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
246 inode->i_generation &= ~1;
247 inode->i_mode = MSDOS_MKMODE(de->attr,
248 S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
249 inode->i_op = sbi->dir_ops;
250 inode->i_fop = &fat_dir_operations;
251
252 MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
253 if (sbi->fat_bits == 32)
254 MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
255
256 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
257 error = fat_calc_dir_size(inode);
258 if (error < 0)
259 return error;
260 MSDOS_I(inode)->mmu_private = inode->i_size;
261
262 inode->i_nlink = fat_subdirs(inode);
263 } else { /* not a directory */
264 inode->i_generation |= 1;
265 inode->i_mode = MSDOS_MKMODE(de->attr,
266 ((sbi->options.showexec &&
267 !is_exec(de->ext))
268 ? S_IRUGO|S_IWUGO : S_IRWXUGO)
269 & ~sbi->options.fs_fmask) | S_IFREG;
270 MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
271 if (sbi->fat_bits == 32)
272 MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
273
274 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
275 inode->i_size = le32_to_cpu(de->size);
276 inode->i_op = &fat_file_inode_operations;
277 inode->i_fop = &fat_file_operations;
278 inode->i_mapping->a_ops = &fat_aops;
279 MSDOS_I(inode)->mmu_private = inode->i_size;
280 }
281 if (de->attr & ATTR_SYS) {
282 if (sbi->options.sys_immutable)
283 inode->i_flags |= S_IMMUTABLE;
284 }
285 MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
286 /* this is as close to the truth as we can get ... */
287 inode->i_blksize = sbi->cluster_size;
288 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
289 & ~((loff_t)sbi->cluster_size - 1)) >> 9;
290 inode->i_mtime.tv_sec = inode->i_atime.tv_sec =
291 date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
292 inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = 0;
293 if (sbi->options.isvfat) {
294 int secs = de->ctime_cs / 100;
295 int csecs = de->ctime_cs % 100;
296 inode->i_ctime.tv_sec =
297 date_dos2unix(le16_to_cpu(de->ctime),
298 le16_to_cpu(de->cdate)) + secs;
299 inode->i_ctime.tv_nsec = csecs * 10000000;
300 } else
301 inode->i_ctime = inode->i_mtime;
302
303 return 0;
304}
305
306struct inode *fat_build_inode(struct super_block *sb,
307 struct msdos_dir_entry *de, loff_t i_pos)
308{
309 struct inode *inode;
310 int err;
311
312 inode = fat_iget(sb, i_pos);
313 if (inode)
314 goto out;
315 inode = new_inode(sb);
316 if (!inode) {
317 inode = ERR_PTR(-ENOMEM);
318 goto out;
319 }
320 inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
321 inode->i_version = 1;
322 err = fat_fill_inode(inode, de);
323 if (err) {
324 iput(inode);
325 inode = ERR_PTR(err);
326 goto out;
327 }
328 fat_attach(inode, i_pos);
329 insert_inode_hash(inode);
330out:
331 return inode;
332}
333
334EXPORT_SYMBOL(fat_build_inode);
335
336static void fat_delete_inode(struct inode *inode)
337{
338 if (!is_bad_inode(inode)) {
339 inode->i_size = 0;
340 fat_truncate(inode);
341 }
342 clear_inode(inode);
343}
344
345static void fat_clear_inode(struct inode *inode)
346{
347 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
348
349 if (is_bad_inode(inode))
350 return;
351 lock_kernel();
352 spin_lock(&sbi->inode_hash_lock);
353 fat_cache_inval_inode(inode);
354 hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
355 spin_unlock(&sbi->inode_hash_lock);
356 unlock_kernel();
357}
358
359static void fat_put_super(struct super_block *sb)
360{
361 struct msdos_sb_info *sbi = MSDOS_SB(sb);
362
363 if (!(sb->s_flags & MS_RDONLY))
364 fat_clusters_flush(sb);
365
366 if (sbi->nls_disk) {
367 unload_nls(sbi->nls_disk);
368 sbi->nls_disk = NULL;
369 sbi->options.codepage = fat_default_codepage;
370 }
371 if (sbi->nls_io) {
372 unload_nls(sbi->nls_io);
373 sbi->nls_io = NULL;
374 }
375 if (sbi->options.iocharset != fat_default_iocharset) {
376 kfree(sbi->options.iocharset);
377 sbi->options.iocharset = fat_default_iocharset;
378 }
379
380 sb->s_fs_info = NULL;
381 kfree(sbi);
382}
383
384static kmem_cache_t *fat_inode_cachep;
385
386static struct inode *fat_alloc_inode(struct super_block *sb)
387{
388 struct msdos_inode_info *ei;
389 ei = kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL);
390 if (!ei)
391 return NULL;
392 return &ei->vfs_inode;
393}
394
395static void fat_destroy_inode(struct inode *inode)
396{
397 kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
398}
399
400static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
401{
402 struct msdos_inode_info *ei = (struct msdos_inode_info *)foo;
403
404 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
405 SLAB_CTOR_CONSTRUCTOR) {
406 spin_lock_init(&ei->cache_lru_lock);
407 ei->nr_caches = 0;
408 ei->cache_valid_id = FAT_CACHE_VALID + 1;
409 INIT_LIST_HEAD(&ei->cache_lru);
410 INIT_HLIST_NODE(&ei->i_fat_hash);
411 inode_init_once(&ei->vfs_inode);
412 }
413}
414
415static int __init fat_init_inodecache(void)
416{
417 fat_inode_cachep = kmem_cache_create("fat_inode_cache",
418 sizeof(struct msdos_inode_info),
419 0, SLAB_RECLAIM_ACCOUNT,
420 init_once, NULL);
421 if (fat_inode_cachep == NULL)
422 return -ENOMEM;
423 return 0;
424}
425
426static void __exit fat_destroy_inodecache(void)
427{
428 if (kmem_cache_destroy(fat_inode_cachep))
429 printk(KERN_INFO "fat_inode_cache: not all structures were freed\n");
430}
431
432static int fat_remount(struct super_block *sb, int *flags, char *data)
433{
434 struct msdos_sb_info *sbi = MSDOS_SB(sb);
435 *flags |= MS_NODIRATIME | (sbi->options.isvfat ? 0 : MS_NOATIME);
436 return 0;
437}
438
439static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
440{
441 struct msdos_sb_info *sbi = MSDOS_SB(sb);
442
443 /* If the count of free cluster is still unknown, counts it here. */
444 if (sbi->free_clusters == -1) {
445 int err = fat_count_free_clusters(sb);
446 if (err)
447 return err;
448 }
449
450 buf->f_type = sb->s_magic;
451 buf->f_bsize = sbi->cluster_size;
452 buf->f_blocks = sbi->max_cluster - FAT_START_ENT;
453 buf->f_bfree = sbi->free_clusters;
454 buf->f_bavail = sbi->free_clusters;
455 buf->f_namelen = sbi->options.isvfat ? 260 : 12;
456
457 return 0;
458}
459
460static int fat_write_inode(struct inode *inode, int wait)
461{
462 struct super_block *sb = inode->i_sb;
463 struct msdos_sb_info *sbi = MSDOS_SB(sb);
464 struct buffer_head *bh;
465 struct msdos_dir_entry *raw_entry;
466 loff_t i_pos;
467 int err = 0;
468
469retry:
470 i_pos = MSDOS_I(inode)->i_pos;
471 if (inode->i_ino == MSDOS_ROOT_INO || !i_pos)
472 return 0;
473
474 lock_kernel();
475 bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits);
476 if (!bh) {
477 printk(KERN_ERR "FAT: unable to read inode block "
478 "for updating (i_pos %lld)\n", i_pos);
479 err = -EIO;
480 goto out;
481 }
482 spin_lock(&sbi->inode_hash_lock);
483 if (i_pos != MSDOS_I(inode)->i_pos) {
484 spin_unlock(&sbi->inode_hash_lock);
485 brelse(bh);
486 unlock_kernel();
487 goto retry;
488 }
489
490 raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
491 [i_pos & (sbi->dir_per_block - 1)];
492 if (S_ISDIR(inode->i_mode))
493 raw_entry->size = 0;
494 else
495 raw_entry->size = cpu_to_le32(inode->i_size);
496 raw_entry->attr = fat_attr(inode);
497 raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart);
498 raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
499 fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);
500 if (sbi->options.isvfat) {
501 fat_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
502 raw_entry->ctime_cs = (inode->i_ctime.tv_sec & 1) * 100 +
503 inode->i_ctime.tv_nsec / 10000000;
504 }
505 spin_unlock(&sbi->inode_hash_lock);
506 mark_buffer_dirty(bh);
507 if (wait)
508 err = sync_dirty_buffer(bh);
509 brelse(bh);
510out:
511 unlock_kernel();
512 return err;
513}
514
515int fat_sync_inode(struct inode *inode)
516{
517 return fat_write_inode(inode, 1);
518}
519
520EXPORT_SYMBOL(fat_sync_inode);
521
522static int fat_show_options(struct seq_file *m, struct vfsmount *mnt);
523static struct super_operations fat_sops = {
524 .alloc_inode = fat_alloc_inode,
525 .destroy_inode = fat_destroy_inode,
526 .write_inode = fat_write_inode,
527 .delete_inode = fat_delete_inode,
528 .put_super = fat_put_super,
529 .statfs = fat_statfs,
530 .clear_inode = fat_clear_inode,
531 .remount_fs = fat_remount,
532
533 .read_inode = make_bad_inode,
534
535 .show_options = fat_show_options,
536};
537
538/*
539 * a FAT file handle with fhtype 3 is
540 * 0/ i_ino - for fast, reliable lookup if still in the cache
541 * 1/ i_generation - to see if i_ino is still valid
542 * bit 0 == 0 iff directory
543 * 2/ i_pos(8-39) - if ino has changed, but still in cache
544 * 3/ i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
545 * 4/ i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
546 *
547 * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
548 * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
549 * of i_logstart is used to store the directory entry offset.
550 */
551
552static struct dentry *
553fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype,
554 int (*acceptable)(void *context, struct dentry *de),
555 void *context)
556{
557 if (fhtype != 3)
558 return ERR_PTR(-ESTALE);
559 if (len < 5)
560 return ERR_PTR(-ESTALE);
561
562 return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
563}
564
565static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
566{
567 struct inode *inode = NULL;
568 struct dentry *result;
569 __u32 *fh = inump;
570
571 inode = iget(sb, fh[0]);
572 if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
573 if (inode)
574 iput(inode);
575 inode = NULL;
576 }
577 if (!inode) {
578 loff_t i_pos;
579 int i_logstart = fh[3] & 0x0fffffff;
580
581 i_pos = (loff_t)fh[2] << 8;
582 i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
583
584 /* try 2 - see if i_pos is in F-d-c
585 * require i_logstart to be the same
586 * Will fail if you truncate and then re-write
587 */
588
589 inode = fat_iget(sb, i_pos);
590 if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
591 iput(inode);
592 inode = NULL;
593 }
594 }
595 if (!inode) {
596 /* For now, do nothing
597 * What we could do is:
598 * follow the file starting at fh[4], and record
599 * the ".." entry, and the name of the fh[2] entry.
600 * The follow the ".." file finding the next step up.
601 * This way we build a path to the root of
602 * the tree. If this works, we lookup the path and so
603 * get this inode into the cache.
604 * Finally try the fat_iget lookup again
605 * If that fails, then weare totally out of luck
606 * But all that is for another day
607 */
608 }
609 if (!inode)
610 return ERR_PTR(-ESTALE);
611
612
613 /* now to find a dentry.
614 * If possible, get a well-connected one
615 */
616 result = d_alloc_anon(inode);
617 if (result == NULL) {
618 iput(inode);
619 return ERR_PTR(-ENOMEM);
620 }
621 result->d_op = sb->s_root->d_op;
622 return result;
623}
624
625static int
626fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
627{
628 int len = *lenp;
629 struct inode *inode = de->d_inode;
630 u32 ipos_h, ipos_m, ipos_l;
631
632 if (len < 5)
633 return 255; /* no room */
634
635 ipos_h = MSDOS_I(inode)->i_pos >> 8;
636 ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
637 ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28;
638 *lenp = 5;
639 fh[0] = inode->i_ino;
640 fh[1] = inode->i_generation;
641 fh[2] = ipos_h;
642 fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
643 spin_lock(&de->d_lock);
644 fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart;
645 spin_unlock(&de->d_lock);
646 return 3;
647}
648
649static struct dentry *fat_get_parent(struct dentry *child)
650{
651 struct buffer_head *bh;
652 struct msdos_dir_entry *de;
653 loff_t i_pos;
654 struct dentry *parent;
655 struct inode *inode;
656 int err;
657
658 lock_kernel();
659
660 err = fat_get_dotdot_entry(child->d_inode, &bh, &de, &i_pos);
661 if (err) {
662 parent = ERR_PTR(err);
663 goto out;
664 }
665 inode = fat_build_inode(child->d_sb, de, i_pos);
666 brelse(bh);
667 if (IS_ERR(inode)) {
668 parent = ERR_PTR(PTR_ERR(inode));
669 goto out;
670 }
671 parent = d_alloc_anon(inode);
672 if (!parent) {
673 iput(inode);
674 parent = ERR_PTR(-ENOMEM);
675 }
676out:
677 unlock_kernel();
678
679 return parent;
680}
681
682static struct export_operations fat_export_ops = {
683 .decode_fh = fat_decode_fh,
684 .encode_fh = fat_encode_fh,
685 .get_dentry = fat_get_dentry,
686 .get_parent = fat_get_parent,
687};
688
689static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
690{
691 struct msdos_sb_info *sbi = MSDOS_SB(mnt->mnt_sb);
692 struct fat_mount_options *opts = &sbi->options;
693 int isvfat = opts->isvfat;
694
695 if (opts->fs_uid != 0)
696 seq_printf(m, ",uid=%u", opts->fs_uid);
697 if (opts->fs_gid != 0)
698 seq_printf(m, ",gid=%u", opts->fs_gid);
699 seq_printf(m, ",fmask=%04o", opts->fs_fmask);
700 seq_printf(m, ",dmask=%04o", opts->fs_dmask);
701 if (sbi->nls_disk)
702 seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
703 if (isvfat) {
704 if (sbi->nls_io)
705 seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
706
707 switch (opts->shortname) {
708 case VFAT_SFN_DISPLAY_WIN95 | VFAT_SFN_CREATE_WIN95:
709 seq_puts(m, ",shortname=win95");
710 break;
711 case VFAT_SFN_DISPLAY_WINNT | VFAT_SFN_CREATE_WINNT:
712 seq_puts(m, ",shortname=winnt");
713 break;
714 case VFAT_SFN_DISPLAY_WINNT | VFAT_SFN_CREATE_WIN95:
715 seq_puts(m, ",shortname=mixed");
716 break;
717 case VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95:
718 /* seq_puts(m, ",shortname=lower"); */
719 break;
720 default:
721 seq_puts(m, ",shortname=unknown");
722 break;
723 }
724 }
725 if (opts->name_check != 'n')
726 seq_printf(m, ",check=%c", opts->name_check);
727 if (opts->quiet)
728 seq_puts(m, ",quiet");
729 if (opts->showexec)
730 seq_puts(m, ",showexec");
731 if (opts->sys_immutable)
732 seq_puts(m, ",sys_immutable");
733 if (!isvfat) {
734 if (opts->dotsOK)
735 seq_puts(m, ",dotsOK=yes");
736 if (opts->nocase)
737 seq_puts(m, ",nocase");
738 } else {
739 if (opts->utf8)
740 seq_puts(m, ",utf8");
741 if (opts->unicode_xlate)
742 seq_puts(m, ",uni_xlate");
743 if (!opts->numtail)
744 seq_puts(m, ",nonumtail");
745 }
746
747 return 0;
748}
749
750enum {
751 Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
752 Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase,
753 Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
754 Opt_dots, Opt_nodots,
755 Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
756 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
757 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
758 Opt_obsolate, Opt_err,
759};
760
761static match_table_t fat_tokens = {
762 {Opt_check_r, "check=relaxed"},
763 {Opt_check_s, "check=strict"},
764 {Opt_check_n, "check=normal"},
765 {Opt_check_r, "check=r"},
766 {Opt_check_s, "check=s"},
767 {Opt_check_n, "check=n"},
768 {Opt_uid, "uid=%u"},
769 {Opt_gid, "gid=%u"},
770 {Opt_umask, "umask=%o"},
771 {Opt_dmask, "dmask=%o"},
772 {Opt_fmask, "fmask=%o"},
773 {Opt_codepage, "codepage=%u"},
774 {Opt_nocase, "nocase"},
775 {Opt_quiet, "quiet"},
776 {Opt_showexec, "showexec"},
777 {Opt_debug, "debug"},
778 {Opt_immutable, "sys_immutable"},
779 {Opt_obsolate, "conv=binary"},
780 {Opt_obsolate, "conv=text"},
781 {Opt_obsolate, "conv=auto"},
782 {Opt_obsolate, "conv=b"},
783 {Opt_obsolate, "conv=t"},
784 {Opt_obsolate, "conv=a"},
785 {Opt_obsolate, "fat=%u"},
786 {Opt_obsolate, "blocksize=%u"},
787 {Opt_obsolate, "cvf_format=%20s"},
788 {Opt_obsolate, "cvf_options=%100s"},
789 {Opt_obsolate, "posix"},
790 {Opt_err, NULL}
791};
792static match_table_t msdos_tokens = {
793 {Opt_nodots, "nodots"},
794 {Opt_nodots, "dotsOK=no"},
795 {Opt_dots, "dots"},
796 {Opt_dots, "dotsOK=yes"},
797 {Opt_err, NULL}
798};
799static match_table_t vfat_tokens = {
800 {Opt_charset, "iocharset=%s"},
801 {Opt_shortname_lower, "shortname=lower"},
802 {Opt_shortname_win95, "shortname=win95"},
803 {Opt_shortname_winnt, "shortname=winnt"},
804 {Opt_shortname_mixed, "shortname=mixed"},
805 {Opt_utf8_no, "utf8=0"}, /* 0 or no or false */
806 {Opt_utf8_no, "utf8=no"},
807 {Opt_utf8_no, "utf8=false"},
808 {Opt_utf8_yes, "utf8=1"}, /* empty or 1 or yes or true */
809 {Opt_utf8_yes, "utf8=yes"},
810 {Opt_utf8_yes, "utf8=true"},
811 {Opt_utf8_yes, "utf8"},
812 {Opt_uni_xl_no, "uni_xlate=0"}, /* 0 or no or false */
813 {Opt_uni_xl_no, "uni_xlate=no"},
814 {Opt_uni_xl_no, "uni_xlate=false"},
815 {Opt_uni_xl_yes, "uni_xlate=1"}, /* empty or 1 or yes or true */
816 {Opt_uni_xl_yes, "uni_xlate=yes"},
817 {Opt_uni_xl_yes, "uni_xlate=true"},
818 {Opt_uni_xl_yes, "uni_xlate"},
819 {Opt_nonumtail_no, "nonumtail=0"}, /* 0 or no or false */
820 {Opt_nonumtail_no, "nonumtail=no"},
821 {Opt_nonumtail_no, "nonumtail=false"},
822 {Opt_nonumtail_yes, "nonumtail=1"}, /* empty or 1 or yes or true */
823 {Opt_nonumtail_yes, "nonumtail=yes"},
824 {Opt_nonumtail_yes, "nonumtail=true"},
825 {Opt_nonumtail_yes, "nonumtail"},
826 {Opt_err, NULL}
827};
828
829static int parse_options(char *options, int is_vfat, int *debug,
830 struct fat_mount_options *opts)
831{
832 char *p;
833 substring_t args[MAX_OPT_ARGS];
834 int option;
835 char *iocharset;
836
837 opts->isvfat = is_vfat;
838
839 opts->fs_uid = current->uid;
840 opts->fs_gid = current->gid;
841 opts->fs_fmask = opts->fs_dmask = current->fs->umask;
842 opts->codepage = fat_default_codepage;
843 opts->iocharset = fat_default_iocharset;
844 if (is_vfat)
845 opts->shortname = VFAT_SFN_DISPLAY_LOWER|VFAT_SFN_CREATE_WIN95;
846 else
847 opts->shortname = 0;
848 opts->name_check = 'n';
849 opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0;
850 opts->utf8 = opts->unicode_xlate = 0;
851 opts->numtail = 1;
852 opts->nocase = 0;
853 *debug = 0;
854
855 if (!options)
856 return 0;
857
858 while ((p = strsep(&options, ",")) != NULL) {
859 int token;
860 if (!*p)
861 continue;
862
863 token = match_token(p, fat_tokens, args);
864 if (token == Opt_err) {
865 if (is_vfat)
866 token = match_token(p, vfat_tokens, args);
867 else
868 token = match_token(p, msdos_tokens, args);
869 }
870 switch (token) {
871 case Opt_check_s:
872 opts->name_check = 's';
873 break;
874 case Opt_check_r:
875 opts->name_check = 'r';
876 break;
877 case Opt_check_n:
878 opts->name_check = 'n';
879 break;
880 case Opt_nocase:
881 if (!is_vfat)
882 opts->nocase = 1;
883 else {
884 /* for backward compatibility */
885 opts->shortname = VFAT_SFN_DISPLAY_WIN95
886 | VFAT_SFN_CREATE_WIN95;
887 }
888 break;
889 case Opt_quiet:
890 opts->quiet = 1;
891 break;
892 case Opt_showexec:
893 opts->showexec = 1;
894 break;
895 case Opt_debug:
896 *debug = 1;
897 break;
898 case Opt_immutable:
899 opts->sys_immutable = 1;
900 break;
901 case Opt_uid:
902 if (match_int(&args[0], &option))
903 return 0;
904 opts->fs_uid = option;
905 break;
906 case Opt_gid:
907 if (match_int(&args[0], &option))
908 return 0;
909 opts->fs_gid = option;
910 break;
911 case Opt_umask:
912 if (match_octal(&args[0], &option))
913 return 0;
914 opts->fs_fmask = opts->fs_dmask = option;
915 break;
916 case Opt_dmask:
917 if (match_octal(&args[0], &option))
918 return 0;
919 opts->fs_dmask = option;
920 break;
921 case Opt_fmask:
922 if (match_octal(&args[0], &option))
923 return 0;
924 opts->fs_fmask = option;
925 break;
926 case Opt_codepage:
927 if (match_int(&args[0], &option))
928 return 0;
929 opts->codepage = option;
930 break;
931
932 /* msdos specific */
933 case Opt_dots:
934 opts->dotsOK = 1;
935 break;
936 case Opt_nodots:
937 opts->dotsOK = 0;
938 break;
939
940 /* vfat specific */
941 case Opt_charset:
942 if (opts->iocharset != fat_default_iocharset)
943 kfree(opts->iocharset);
944 iocharset = match_strdup(&args[0]);
945 if (!iocharset)
946 return -ENOMEM;
947 opts->iocharset = iocharset;
948 break;
949 case Opt_shortname_lower:
950 opts->shortname = VFAT_SFN_DISPLAY_LOWER
951 | VFAT_SFN_CREATE_WIN95;
952 break;
953 case Opt_shortname_win95:
954 opts->shortname = VFAT_SFN_DISPLAY_WIN95
955 | VFAT_SFN_CREATE_WIN95;
956 break;
957 case Opt_shortname_winnt:
958 opts->shortname = VFAT_SFN_DISPLAY_WINNT
959 | VFAT_SFN_CREATE_WINNT;
960 break;
961 case Opt_shortname_mixed:
962 opts->shortname = VFAT_SFN_DISPLAY_WINNT
963 | VFAT_SFN_CREATE_WIN95;
964 break;
965 case Opt_utf8_no: /* 0 or no or false */
966 opts->utf8 = 0;
967 break;
968 case Opt_utf8_yes: /* empty or 1 or yes or true */
969 opts->utf8 = 1;
970 break;
971 case Opt_uni_xl_no: /* 0 or no or false */
972 opts->unicode_xlate = 0;
973 break;
974 case Opt_uni_xl_yes: /* empty or 1 or yes or true */
975 opts->unicode_xlate = 1;
976 break;
977 case Opt_nonumtail_no: /* 0 or no or false */
978 opts->numtail = 1; /* negated option */
979 break;
980 case Opt_nonumtail_yes: /* empty or 1 or yes or true */
981 opts->numtail = 0; /* negated option */
982 break;
983
984 /* obsolete mount options */
985 case Opt_obsolate:
986 printk(KERN_INFO "FAT: \"%s\" option is obsolete, "
987 "not supported now\n", p);
988 break;
989 /* unknown option */
990 default:
991 printk(KERN_ERR "FAT: Unrecognized mount option \"%s\" "
992 "or missing value\n", p);
993 return -EINVAL;
994 }
995 }
996 /* UTF8 doesn't provide FAT semantics */
997 if (!strcmp(opts->iocharset, "utf8")) {
998 printk(KERN_ERR "FAT: utf8 is not a recommended IO charset"
999 " for FAT filesystems, filesystem will be case sensitive!\n");
1000 }
1001
1002 if (opts->unicode_xlate)
1003 opts->utf8 = 0;
1004
1005 return 0;
1006}
1007
1008static int fat_read_root(struct inode *inode)
1009{
1010 struct super_block *sb = inode->i_sb;
1011 struct msdos_sb_info *sbi = MSDOS_SB(sb);
1012 int error;
1013
1014 MSDOS_I(inode)->i_pos = 0;
1015 inode->i_uid = sbi->options.fs_uid;
1016 inode->i_gid = sbi->options.fs_gid;
1017 inode->i_version++;
1018 inode->i_generation = 0;
1019 inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
1020 inode->i_op = sbi->dir_ops;
1021 inode->i_fop = &fat_dir_operations;
1022 if (sbi->fat_bits == 32) {
1023 MSDOS_I(inode)->i_start = sbi->root_cluster;
1024 error = fat_calc_dir_size(inode);
1025 if (error < 0)
1026 return error;
1027 } else {
1028 MSDOS_I(inode)->i_start = 0;
1029 inode->i_size = sbi->dir_entries * sizeof(struct msdos_dir_entry);
1030 }
1031 inode->i_blksize = sbi->cluster_size;
1032 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
1033 & ~((loff_t)sbi->cluster_size - 1)) >> 9;
1034 MSDOS_I(inode)->i_logstart = 0;
1035 MSDOS_I(inode)->mmu_private = inode->i_size;
1036
1037 MSDOS_I(inode)->i_attrs = ATTR_NONE;
1038 inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0;
1039 inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0;
1040 inode->i_nlink = fat_subdirs(inode)+2;
1041
1042 return 0;
1043}
1044
1045/*
1046 * Read the super block of an MS-DOS FS.
1047 */
1048int fat_fill_super(struct super_block *sb, void *data, int silent,
1049 struct inode_operations *fs_dir_inode_ops, int isvfat)
1050{
1051 struct inode *root_inode = NULL;
1052 struct buffer_head *bh;
1053 struct fat_boot_sector *b;
1054 struct msdos_sb_info *sbi;
1055 u16 logical_sector_size;
1056 u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors;
1057 int debug;
1058 unsigned int media;
1059 long error;
1060 char buf[50];
1061
1062 sbi = kmalloc(sizeof(struct msdos_sb_info), GFP_KERNEL);
1063 if (!sbi)
1064 return -ENOMEM;
1065 sb->s_fs_info = sbi;
1066 memset(sbi, 0, sizeof(struct msdos_sb_info));
1067
1068 sb->s_flags |= MS_NODIRATIME;
1069 sb->s_magic = MSDOS_SUPER_MAGIC;
1070 sb->s_op = &fat_sops;
1071 sb->s_export_op = &fat_export_ops;
1072 sbi->dir_ops = fs_dir_inode_ops;
1073
1074 error = parse_options(data, isvfat, &debug, &sbi->options);
1075 if (error)
1076 goto out_fail;
1077
1078 error = -EIO;
1079 sb_min_blocksize(sb, 512);
1080 bh = sb_bread(sb, 0);
1081 if (bh == NULL) {
1082 printk(KERN_ERR "FAT: unable to read boot sector\n");
1083 goto out_fail;
1084 }
1085
1086 b = (struct fat_boot_sector *) bh->b_data;
1087 if (!b->reserved) {
1088 if (!silent)
1089 printk(KERN_ERR "FAT: bogus number of reserved sectors\n");
1090 brelse(bh);
1091 goto out_invalid;
1092 }
1093 if (!b->fats) {
1094 if (!silent)
1095 printk(KERN_ERR "FAT: bogus number of FAT structure\n");
1096 brelse(bh);
1097 goto out_invalid;
1098 }
1099
1100 /*
1101 * Earlier we checked here that b->secs_track and b->head are nonzero,
1102 * but it turns out valid FAT filesystems can have zero there.
1103 */
1104
1105 media = b->media;
1106 if (!FAT_VALID_MEDIA(media)) {
1107 if (!silent)
1108 printk(KERN_ERR "FAT: invalid media value (0x%02x)\n",
1109 media);
1110 brelse(bh);
1111 goto out_invalid;
1112 }
1113 logical_sector_size =
1114 le16_to_cpu(get_unaligned((__le16 *)&b->sector_size));
1115 if (!logical_sector_size
1116 || (logical_sector_size & (logical_sector_size - 1))
1117 || (logical_sector_size < 512)
1118 || (PAGE_CACHE_SIZE < logical_sector_size)) {
1119 if (!silent)
1120 printk(KERN_ERR "FAT: bogus logical sector size %u\n",
1121 logical_sector_size);
1122 brelse(bh);
1123 goto out_invalid;
1124 }
1125 sbi->sec_per_clus = b->sec_per_clus;
1126 if (!sbi->sec_per_clus
1127 || (sbi->sec_per_clus & (sbi->sec_per_clus - 1))) {
1128 if (!silent)
1129 printk(KERN_ERR "FAT: bogus sectors per cluster %u\n",
1130 sbi->sec_per_clus);
1131 brelse(bh);
1132 goto out_invalid;
1133 }
1134
1135 if (logical_sector_size < sb->s_blocksize) {
1136 printk(KERN_ERR "FAT: logical sector size too small for device"
1137 " (logical sector size = %u)\n", logical_sector_size);
1138 brelse(bh);
1139 goto out_fail;
1140 }
1141 if (logical_sector_size > sb->s_blocksize) {
1142 brelse(bh);
1143
1144 if (!sb_set_blocksize(sb, logical_sector_size)) {
1145 printk(KERN_ERR "FAT: unable to set blocksize %u\n",
1146 logical_sector_size);
1147 goto out_fail;
1148 }
1149 bh = sb_bread(sb, 0);
1150 if (bh == NULL) {
1151 printk(KERN_ERR "FAT: unable to read boot sector"
1152 " (logical sector size = %lu)\n",
1153 sb->s_blocksize);
1154 goto out_fail;
1155 }
1156 b = (struct fat_boot_sector *) bh->b_data;
1157 }
1158
1159 sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus;
1160 sbi->cluster_bits = ffs(sbi->cluster_size) - 1;
1161 sbi->fats = b->fats;
1162 sbi->fat_bits = 0; /* Don't know yet */
1163 sbi->fat_start = le16_to_cpu(b->reserved);
1164 sbi->fat_length = le16_to_cpu(b->fat_length);
1165 sbi->root_cluster = 0;
1166 sbi->free_clusters = -1; /* Don't know yet */
1167 sbi->prev_free = FAT_START_ENT;
1168
1169 if (!sbi->fat_length && b->fat32_length) {
1170 struct fat_boot_fsinfo *fsinfo;
1171 struct buffer_head *fsinfo_bh;
1172
1173 /* Must be FAT32 */
1174 sbi->fat_bits = 32;
1175 sbi->fat_length = le32_to_cpu(b->fat32_length);
1176 sbi->root_cluster = le32_to_cpu(b->root_cluster);
1177
1178 sb->s_maxbytes = 0xffffffff;
1179
1180 /* MC - if info_sector is 0, don't multiply by 0 */
1181 sbi->fsinfo_sector = le16_to_cpu(b->info_sector);
1182 if (sbi->fsinfo_sector == 0)
1183 sbi->fsinfo_sector = 1;
1184
1185 fsinfo_bh = sb_bread(sb, sbi->fsinfo_sector);
1186 if (fsinfo_bh == NULL) {
1187 printk(KERN_ERR "FAT: bread failed, FSINFO block"
1188 " (sector = %lu)\n", sbi->fsinfo_sector);
1189 brelse(bh);
1190 goto out_fail;
1191 }
1192
1193 fsinfo = (struct fat_boot_fsinfo *)fsinfo_bh->b_data;
1194 if (!IS_FSINFO(fsinfo)) {
1195 printk(KERN_WARNING
1196 "FAT: Did not find valid FSINFO signature.\n"
1197 " Found signature1 0x%08x signature2 0x%08x"
1198 " (sector = %lu)\n",
1199 le32_to_cpu(fsinfo->signature1),
1200 le32_to_cpu(fsinfo->signature2),
1201 sbi->fsinfo_sector);
1202 } else {
1203 sbi->free_clusters = le32_to_cpu(fsinfo->free_clusters);
1204 sbi->prev_free = le32_to_cpu(fsinfo->next_cluster);
1205 }
1206
1207 brelse(fsinfo_bh);
1208 }
1209
1210 sbi->dir_per_block = sb->s_blocksize / sizeof(struct msdos_dir_entry);
1211 sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1;
1212
1213 sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length;
1214 sbi->dir_entries =
1215 le16_to_cpu(get_unaligned((__le16 *)&b->dir_entries));
1216 if (sbi->dir_entries & (sbi->dir_per_block - 1)) {
1217 if (!silent)
1218 printk(KERN_ERR "FAT: bogus directroy-entries per block"
1219 " (%u)\n", sbi->dir_entries);
1220 brelse(bh);
1221 goto out_invalid;
1222 }
1223
1224 rootdir_sectors = sbi->dir_entries
1225 * sizeof(struct msdos_dir_entry) / sb->s_blocksize;
1226 sbi->data_start = sbi->dir_start + rootdir_sectors;
1227 total_sectors = le16_to_cpu(get_unaligned((__le16 *)&b->sectors));
1228 if (total_sectors == 0)
1229 total_sectors = le32_to_cpu(b->total_sect);
1230
1231 total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
1232
1233 if (sbi->fat_bits != 32)
1234 sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
1235
1236 /* check that FAT table does not overflow */
1237 fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
1238 total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
1239 if (total_clusters > MAX_FAT(sb)) {
1240 if (!silent)
1241 printk(KERN_ERR "FAT: count of clusters too big (%u)\n",
1242 total_clusters);
1243 brelse(bh);
1244 goto out_invalid;
1245 }
1246
1247 sbi->max_cluster = total_clusters + FAT_START_ENT;
1248 /* check the free_clusters, it's not necessarily correct */
1249 if (sbi->free_clusters != -1 && sbi->free_clusters > total_clusters)
1250 sbi->free_clusters = -1;
1251 /* check the prev_free, it's not necessarily correct */
1252 sbi->prev_free %= sbi->max_cluster;
1253 if (sbi->prev_free < FAT_START_ENT)
1254 sbi->prev_free = FAT_START_ENT;
1255
1256 brelse(bh);
1257
1258 /* set up enough so that it can read an inode */
1259 fat_hash_init(sb);
1260 fat_ent_access_init(sb);
1261
1262 /*
1263 * The low byte of FAT's first entry must have same value with
1264 * media-field. But in real world, too many devices is
1265 * writing wrong value. So, removed that validity check.
1266 *
1267 * if (FAT_FIRST_ENT(sb, media) != first)
1268 */
1269
1270 error = -EINVAL;
1271 sprintf(buf, "cp%d", sbi->options.codepage);
1272 sbi->nls_disk = load_nls(buf);
1273 if (!sbi->nls_disk) {
1274 printk(KERN_ERR "FAT: codepage %s not found\n", buf);
1275 goto out_fail;
1276 }
1277
1278 /* FIXME: utf8 is using iocharset for upper/lower conversion */
1279 if (sbi->options.isvfat) {
1280 sbi->nls_io = load_nls(sbi->options.iocharset);
1281 if (!sbi->nls_io) {
1282 printk(KERN_ERR "FAT: IO charset %s not found\n",
1283 sbi->options.iocharset);
1284 goto out_fail;
1285 }
1286 }
1287
1288 error = -ENOMEM;
1289 root_inode = new_inode(sb);
1290 if (!root_inode)
1291 goto out_fail;
1292 root_inode->i_ino = MSDOS_ROOT_INO;
1293 root_inode->i_version = 1;
1294 error = fat_read_root(root_inode);
1295 if (error < 0)
1296 goto out_fail;
1297 error = -ENOMEM;
1298 insert_inode_hash(root_inode);
1299 sb->s_root = d_alloc_root(root_inode);
1300 if (!sb->s_root) {
1301 printk(KERN_ERR "FAT: get root inode failed\n");
1302 goto out_fail;
1303 }
1304
1305 return 0;
1306
1307out_invalid:
1308 error = -EINVAL;
1309 if (!silent)
1310 printk(KERN_INFO "VFS: Can't find a valid FAT filesystem"
1311 " on dev %s.\n", sb->s_id);
1312
1313out_fail:
1314 if (root_inode)
1315 iput(root_inode);
1316 if (sbi->nls_io)
1317 unload_nls(sbi->nls_io);
1318 if (sbi->nls_disk)
1319 unload_nls(sbi->nls_disk);
1320 if (sbi->options.iocharset != fat_default_iocharset)
1321 kfree(sbi->options.iocharset);
1322 sb->s_fs_info = NULL;
1323 kfree(sbi);
1324 return error;
1325}
1326
1327EXPORT_SYMBOL(fat_fill_super);
1328
1329int __init fat_cache_init(void);
1330void __exit fat_cache_destroy(void);
1331
1332static int __init init_fat_fs(void)
1333{
1334 int ret;
1335
1336 ret = fat_cache_init();
1337 if (ret < 0)
1338 return ret;
1339 return fat_init_inodecache();
1340}
1341
1342static void __exit exit_fat_fs(void)
1343{
1344 fat_cache_destroy();
1345 fat_destroy_inodecache();
1346}
1347
1348module_init(init_fat_fs)
1349module_exit(exit_fat_fs)
1350
1351MODULE_LICENSE("GPL");
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
new file mode 100644
index 000000000000..2a0df2122f5d
--- /dev/null
+++ b/fs/fat/misc.c
@@ -0,0 +1,225 @@
1/*
2 * linux/fs/fat/misc.c
3 *
4 * Written 1992,1993 by Werner Almesberger
5 * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
6 * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
7 */
8
9#include <linux/module.h>
10#include <linux/fs.h>
11#include <linux/msdos_fs.h>
12#include <linux/buffer_head.h>
13
14/*
15 * fat_fs_panic reports a severe file system problem and sets the file system
16 * read-only. The file system can be made writable again by remounting it.
17 */
18void fat_fs_panic(struct super_block *s, const char *fmt, ...)
19{
20 va_list args;
21
22 printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n", s->s_id);
23
24 printk(KERN_ERR " ");
25 va_start(args, fmt);
26 vprintk(fmt, args);
27 va_end(args);
28 printk("\n");
29
30 if (!(s->s_flags & MS_RDONLY)) {
31 s->s_flags |= MS_RDONLY;
32 printk(KERN_ERR " File system has been set read-only\n");
33 }
34}
35
36EXPORT_SYMBOL(fat_fs_panic);
37
38/* Flushes the number of free clusters on FAT32 */
39/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
40void fat_clusters_flush(struct super_block *sb)
41{
42 struct msdos_sb_info *sbi = MSDOS_SB(sb);
43 struct buffer_head *bh;
44 struct fat_boot_fsinfo *fsinfo;
45
46 if (sbi->fat_bits != 32)
47 return;
48
49 bh = sb_bread(sb, sbi->fsinfo_sector);
50 if (bh == NULL) {
51 printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n");
52 return;
53 }
54
55 fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
56 /* Sanity check */
57 if (!IS_FSINFO(fsinfo)) {
58 printk(KERN_ERR "FAT: Did not find valid FSINFO signature.\n"
59 " Found signature1 0x%08x signature2 0x%08x"
60 " (sector = %lu)\n",
61 le32_to_cpu(fsinfo->signature1),
62 le32_to_cpu(fsinfo->signature2),
63 sbi->fsinfo_sector);
64 } else {
65 if (sbi->free_clusters != -1)
66 fsinfo->free_clusters = cpu_to_le32(sbi->free_clusters);
67 if (sbi->prev_free != -1)
68 fsinfo->next_cluster = cpu_to_le32(sbi->prev_free);
69 mark_buffer_dirty(bh);
70 if (sb->s_flags & MS_SYNCHRONOUS)
71 sync_dirty_buffer(bh);
72 }
73 brelse(bh);
74}
75
76/*
77 * fat_chain_add() adds a new cluster to the chain of clusters represented
78 * by inode.
79 */
80int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster)
81{
82 struct super_block *sb = inode->i_sb;
83 struct msdos_sb_info *sbi = MSDOS_SB(sb);
84 int ret, new_fclus, last;
85
86 /*
87 * We must locate the last cluster of the file to add this new
88 * one (new_dclus) to the end of the link list (the FAT).
89 */
90 last = new_fclus = 0;
91 if (MSDOS_I(inode)->i_start) {
92 int fclus, dclus;
93
94 ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
95 if (ret < 0)
96 return ret;
97 new_fclus = fclus + 1;
98 last = dclus;
99 }
100
101 /* add new one to the last of the cluster chain */
102 if (last) {
103 struct fat_entry fatent;
104
105 fatent_init(&fatent);
106 ret = fat_ent_read(inode, &fatent, last);
107 if (ret >= 0) {
108 int wait = inode_needs_sync(inode);
109 ret = fat_ent_write(inode, &fatent, new_dclus, wait);
110 fatent_brelse(&fatent);
111 }
112 if (ret < 0)
113 return ret;
114// fat_cache_add(inode, new_fclus, new_dclus);
115 } else {
116 MSDOS_I(inode)->i_start = new_dclus;
117 MSDOS_I(inode)->i_logstart = new_dclus;
118 /*
119 * Since generic_osync_inode() synchronize later if
120 * this is not directory, we don't here.
121 */
122 if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode)) {
123 ret = fat_sync_inode(inode);
124 if (ret)
125 return ret;
126 } else
127 mark_inode_dirty(inode);
128 }
129 if (new_fclus != (inode->i_blocks >> (sbi->cluster_bits - 9))) {
130 fat_fs_panic(sb, "clusters badly computed (%d != %lu)",
131 new_fclus, inode->i_blocks >> (sbi->cluster_bits - 9));
132 fat_cache_inval_inode(inode);
133 }
134 inode->i_blocks += nr_cluster << (sbi->cluster_bits - 9);
135
136 return 0;
137}
138
139extern struct timezone sys_tz;
140
141/* Linear day numbers of the respective 1sts in non-leap years. */
142static int day_n[] = {
143 /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
144 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0
145};
146
147/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
148int date_dos2unix(unsigned short time, unsigned short date)
149{
150 int month, year, secs;
151
152 /*
153 * first subtract and mask after that... Otherwise, if
154 * date == 0, bad things happen
155 */
156 month = ((date >> 5) - 1) & 15;
157 year = date >> 9;
158 secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
159 ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
160 month < 2 ? 1 : 0)+3653);
161 /* days since 1.1.70 plus 80's leap day */
162 secs += sys_tz.tz_minuteswest*60;
163 return secs;
164}
165
166/* Convert linear UNIX date to a MS-DOS time/date pair. */
167void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date)
168{
169 int day, year, nl_day, month;
170
171 unix_date -= sys_tz.tz_minuteswest*60;
172
173 /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
174 if (unix_date < 315532800)
175 unix_date = 315532800;
176
177 *time = cpu_to_le16((unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
178 (((unix_date/3600) % 24) << 11));
179 day = unix_date/86400-3652;
180 year = day/365;
181 if ((year+3)/4+365*year > day)
182 year--;
183 day -= (year+3)/4+365*year;
184 if (day == 59 && !(year & 3)) {
185 nl_day = day;
186 month = 2;
187 } else {
188 nl_day = (year & 3) || day <= 59 ? day : day-1;
189 for (month = 0; month < 12; month++) {
190 if (day_n[month] > nl_day)
191 break;
192 }
193 }
194 *date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
195}
196
197EXPORT_SYMBOL(fat_date_unix2dos);
198
199int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
200{
201 int i, e, err = 0;
202
203 for (i = 0; i < nr_bhs; i++) {
204 lock_buffer(bhs[i]);
205 if (test_clear_buffer_dirty(bhs[i])) {
206 get_bh(bhs[i]);
207 bhs[i]->b_end_io = end_buffer_write_sync;
208 e = submit_bh(WRITE, bhs[i]);
209 if (!err && e)
210 err = e;
211 } else
212 unlock_buffer(bhs[i]);
213 }
214 for (i = 0; i < nr_bhs; i++) {
215 wait_on_buffer(bhs[i]);
216 if (buffer_eopnotsupp(bhs[i])) {
217 clear_buffer_eopnotsupp(bhs[i]);
218 err = -EOPNOTSUPP;
219 } else if (!err && !buffer_uptodate(bhs[i]))
220 err = -EIO;
221 }
222 return err;
223}
224
225EXPORT_SYMBOL(fat_sync_bhs);