import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / fs / cramfs / inode.c
1 /*
2  * inode.c
3  *
4  * Copyright (C) 1999 Linus Torvalds
5  * Copyright (C) 2000-2002 Transmeta Corporation
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License (Version 2) as
9  * published by the Free Software Foundation.
10  *
11  * Compressed ROM filesystem for Linux.
12  */
13
14 /*
15  * These are the VFS interfaces to the compressed ROM filesystem.
16  * The actual compression is based on zlib, see the other files.
17  */
18
19 #include <linux/module.h>
20 #include <linux/fs.h>
21 #include <linux/pagemap.h>
22 #include <linux/init.h>
23 #include <linux/string.h>
24 #include <linux/locks.h>
25 #include <linux/blkdev.h>
26 #include <linux/cramfs_fs.h>
27 #include <asm/semaphore.h>
28
29 #include <asm/uaccess.h>
30
31 #define CRAMFS_SB_MAGIC u.cramfs_sb.magic
32 #define CRAMFS_SB_SIZE u.cramfs_sb.size
33 #define CRAMFS_SB_BLOCKS u.cramfs_sb.blocks
34 #define CRAMFS_SB_FILES u.cramfs_sb.files
35 #define CRAMFS_SB_FLAGS u.cramfs_sb.flags
36
37 static struct super_operations cramfs_ops;
38 static struct inode_operations cramfs_dir_inode_operations;
39 static struct file_operations cramfs_directory_operations;
40 static struct address_space_operations cramfs_aops;
41
42 static DECLARE_MUTEX(read_mutex);
43
44
45 /* These two macros may change in future, to provide better st_ino
46    semantics. */
47 #define CRAMINO(x)      (CRAMFS_GET_OFFSET(x) ? CRAMFS_GET_OFFSET(x)<<2 : 1)
48 #define OFFSET(x)       ((x)->i_ino)
49
50 static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode)
51 {
52         struct inode * inode = new_inode(sb);
53
54         if (inode) {
55                 inode->i_mode = CRAMFS_16(cramfs_inode->mode);
56                 inode->i_uid = CRAMFS_16(cramfs_inode->uid);
57                 inode->i_size = CRAMFS_24(cramfs_inode->size);
58                 inode->i_blocks = (CRAMFS_24(cramfs_inode->size) - 1)/512 + 1;
59                 inode->i_blksize = PAGE_CACHE_SIZE;
60                 inode->i_gid = cramfs_inode->gid;
61                 inode->i_ino = CRAMINO(cramfs_inode);
62                 /* inode->i_nlink is left 1 - arguably wrong for directories,
63                    but it's the best we can do without reading the directory
64                    contents.  1 yields the right result in GNU find, even
65                    without -noleaf option. */
66                 insert_inode_hash(inode);
67                 if (S_ISREG(inode->i_mode)) {
68                         inode->i_fop = &generic_ro_fops;
69                         inode->i_data.a_ops = &cramfs_aops;
70                 } else if (S_ISDIR(inode->i_mode)) {
71                         inode->i_op = &cramfs_dir_inode_operations;
72                         inode->i_fop = &cramfs_directory_operations;
73                 } else if (S_ISLNK(inode->i_mode)) {
74                         inode->i_op = &page_symlink_inode_operations;
75                         inode->i_data.a_ops = &cramfs_aops;
76                 } else {
77                         inode->i_size = 0;
78                         init_special_inode(inode, inode->i_mode, CRAMFS_24(cramfs_inode->size));
79                 }
80         }
81         return inode;
82 }
83
84 /*
85  * We have our own block cache: don't fill up the buffer cache
86  * with the ROM image, because the way the filesystem is set
87  * up the accesses should be fairly regular and cached in the
88  * page cache and dentry tree anyway..
89  *
90  * This also acts as a way to guarantee contiguous areas of up to
91  * BLKS_PER_BUF*PAGE_CACHE_SIZE, so that the caller doesn't need to
92  * worry about end-of-buffer issues even when decompressing a full
93  * page cache.
94  */
95 #define READ_BUFFERS (2)
96 /* NEXT_BUFFER(): Loop over [0..(READ_BUFFERS-1)]. */
97 #define NEXT_BUFFER(_ix) ((_ix) ^ 1)
98
99 /*
100  * BLKS_PER_BUF_SHIFT should be at least 2 to allow for "compressed"
101  * data that takes up more space than the original and with unlucky
102  * alignment.
103  */
104 #define BLKS_PER_BUF_SHIFT      (2)
105 #define BLKS_PER_BUF            (1 << BLKS_PER_BUF_SHIFT)
106 #define BUFFER_SIZE             (BLKS_PER_BUF*PAGE_CACHE_SIZE)
107
108 static unsigned char read_buffers[READ_BUFFERS][BUFFER_SIZE];
109 static unsigned buffer_blocknr[READ_BUFFERS];
110 static struct super_block * buffer_dev[READ_BUFFERS];
111 static int next_buffer;
112
113 /*
114  * Returns a pointer to a buffer containing at least LEN bytes of
115  * filesystem starting at byte offset OFFSET into the filesystem.
116  */
117 static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len)
118 {
119         struct buffer_head * bh_array[BLKS_PER_BUF];
120         struct buffer_head * read_array[BLKS_PER_BUF];
121         unsigned i, blocknr, buffer, unread;
122         unsigned long devsize;
123         int major, minor;
124
125         char *data;
126
127         if (!len)
128                 return NULL;
129         blocknr = offset >> PAGE_CACHE_SHIFT;
130         offset &= PAGE_CACHE_SIZE - 1;
131
132         /* Check if an existing buffer already has the data.. */
133         for (i = 0; i < READ_BUFFERS; i++) {
134                 unsigned int blk_offset;
135
136                 if (buffer_dev[i] != sb)
137                         continue;
138                 if (blocknr < buffer_blocknr[i])
139                         continue;
140                 blk_offset = (blocknr - buffer_blocknr[i]) << PAGE_CACHE_SHIFT;
141                 blk_offset += offset;
142                 if (blk_offset + len > BUFFER_SIZE)
143                         continue;
144                 return read_buffers[i] + blk_offset;
145         }
146
147         devsize = ~0UL;
148         major = MAJOR(sb->s_dev);
149         minor = MINOR(sb->s_dev);
150
151         if (blk_size[major])
152                 devsize = blk_size[major][minor] >> 2;
153
154         /* Ok, read in BLKS_PER_BUF pages completely first. */
155         unread = 0;
156         for (i = 0; i < BLKS_PER_BUF; i++) {
157                 struct buffer_head *bh;
158
159                 bh = NULL;
160                 if (blocknr + i < devsize) {
161                         bh = sb_getblk(sb, blocknr + i);
162                         if (!buffer_uptodate(bh))
163                                 read_array[unread++] = bh;
164                 }
165                 bh_array[i] = bh;
166         }
167
168         if (unread) {
169                 ll_rw_block(READ, unread, read_array);
170                 do {
171                         unread--;
172                         wait_on_buffer(read_array[unread]);
173                 } while (unread);
174         }
175
176         /* Ok, copy them to the staging area without sleeping. */
177         buffer = next_buffer;
178         next_buffer = NEXT_BUFFER(buffer);
179         buffer_blocknr[buffer] = blocknr;
180         buffer_dev[buffer] = sb;
181
182         data = read_buffers[buffer];
183         for (i = 0; i < BLKS_PER_BUF; i++) {
184                 struct buffer_head * bh = bh_array[i];
185                 if (bh) {
186                         memcpy(data, bh->b_data, PAGE_CACHE_SIZE);
187                         brelse(bh);
188                 } else
189                         memset(data, 0, PAGE_CACHE_SIZE);
190                 data += PAGE_CACHE_SIZE;
191         }
192         return read_buffers[buffer] + offset;
193 }
194
195
196 static struct super_block * cramfs_read_super(struct super_block *sb, void *data, int silent)
197 {
198         int i;
199         struct cramfs_super super;
200         unsigned long root_offset;
201         struct super_block * retval = NULL;
202
203         set_blocksize(sb->s_dev, PAGE_CACHE_SIZE);
204         sb->s_blocksize = PAGE_CACHE_SIZE;
205         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
206
207         /* Invalidate the read buffers on mount: think disk change.. */
208         for (i = 0; i < READ_BUFFERS; i++)
209                 buffer_blocknr[i] = -1;
210
211         down(&read_mutex);
212         /* Read the first block and get the superblock from it */
213         memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super));
214         up(&read_mutex);
215
216         /* Do sanity checks on the superblock */
217         if (super.magic != CRAMFS_32(CRAMFS_MAGIC)) {
218                 /* check at 512 byte offset */
219                 memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super));
220                 if (super.magic != CRAMFS_32(CRAMFS_MAGIC)) {
221                         printk(KERN_ERR "cramfs: wrong magic\n");
222                         goto out;
223                 }
224         }
225
226         /* flags is reused several times, so swab it once */
227         super.flags = CRAMFS_32(super.flags);
228
229         /* get feature flags first */
230         if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
231                 printk(KERN_ERR "cramfs: unsupported filesystem features\n");
232                 goto out;
233         }
234
235         /* Check that the root inode is in a sane state */
236         if (!S_ISDIR(CRAMFS_16(super.root.mode))) {
237                 printk(KERN_ERR "cramfs: root is not a directory\n");
238                 goto out;
239         }
240         root_offset = CRAMFS_GET_OFFSET(&(super.root)) << 2;
241         if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
242                 sb->CRAMFS_SB_SIZE = CRAMFS_32(super.size);
243                 sb->CRAMFS_SB_BLOCKS = CRAMFS_32(super.fsid.blocks);
244                 sb->CRAMFS_SB_FILES = CRAMFS_32(super.fsid.files);
245         } else {
246                 sb->CRAMFS_SB_SIZE = 1 << 28;
247                 sb->CRAMFS_SB_BLOCKS = 0;
248                 sb->CRAMFS_SB_FILES = 0;
249         }
250         sb->CRAMFS_SB_MAGIC = CRAMFS_MAGIC;
251         sb->CRAMFS_SB_FLAGS = super.flags;
252         if (root_offset == 0)
253                 printk(KERN_INFO "cramfs: empty filesystem");
254         else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
255                  ((root_offset != sizeof(struct cramfs_super)) &&
256                   (root_offset != 512 + sizeof(struct cramfs_super))))
257         {
258                 printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset);
259                 goto out;
260         }
261
262         /* Set it all up.. */
263         sb->s_op = &cramfs_ops;
264         sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root));
265         retval = sb;
266 out:
267         return retval;
268 }
269
270 static int cramfs_statfs(struct super_block *sb, struct statfs *buf)
271 {
272         buf->f_type = CRAMFS_MAGIC;
273         buf->f_bsize = PAGE_CACHE_SIZE;
274         buf->f_blocks = sb->CRAMFS_SB_BLOCKS;
275         buf->f_bfree = 0;
276         buf->f_bavail = 0;
277         buf->f_files = sb->CRAMFS_SB_FILES;
278         buf->f_ffree = 0;
279         buf->f_namelen = CRAMFS_MAXPATHLEN;
280         return 0;
281 }
282
283 /*
284  * Read a cramfs directory entry.
285  */
286 static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
287 {
288         struct inode *inode = filp->f_dentry->d_inode;
289         struct super_block *sb = inode->i_sb;
290         unsigned int offset;
291         int copied;
292
293         /* Offset within the thing. */
294         offset = filp->f_pos;
295         if (offset >= inode->i_size)
296                 return 0;
297         /* Directory entries are always 4-byte aligned */
298         if (offset & 3)
299                 return -EINVAL;
300
301         copied = 0;
302         while (offset < inode->i_size) {
303                 struct cramfs_inode *de;
304                 unsigned long nextoffset;
305                 char *name;
306                 int namelen, error;
307
308                 down(&read_mutex);
309                 de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256);
310                 up(&read_mutex);
311                 name = (char *)(de+1);
312
313                 /*
314                  * Namelengths on disk are shifted by two
315                  * and the name padded out to 4-byte boundaries
316                  * with zeroes.
317                  */
318                 namelen = CRAMFS_GET_NAMELEN(de) << 2;
319                 nextoffset = offset + sizeof(*de) + namelen;
320                 for (;;) {
321                         if (!namelen)
322                                 return -EIO;
323                         if (name[namelen-1])
324                                 break;
325                         namelen--;
326                 }
327                 error = filldir(dirent, name, namelen, offset, CRAMINO(de), CRAMFS_16(de->mode) >> 12);
328                 if (error)
329                         break;
330
331                 offset = nextoffset;
332                 filp->f_pos = offset;
333                 copied++;
334         }
335         return 0;
336 }
337
338 /*
339  * Lookup and fill in the inode data..
340  */
341 static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
342 {
343         unsigned int offset = 0;
344         int sorted = dir->i_sb->CRAMFS_SB_FLAGS & CRAMFS_FLAG_SORTED_DIRS;
345
346         while (offset < dir->i_size) {
347                 struct cramfs_inode *de;
348                 char *name;
349                 int namelen, retval;
350
351                 down(&read_mutex);
352                 de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256);
353                 up(&read_mutex);
354                 name = (char *)(de+1);
355
356                 /* Try to take advantage of sorted directories */
357                 if (sorted && (dentry->d_name.name[0] < name[0]))
358                         break;
359
360                 namelen = CRAMFS_GET_NAMELEN(de) << 2;
361                 offset += sizeof(*de) + namelen;
362
363                 /* Quick check that the name is roughly the right length */
364                 if (((dentry->d_name.len + 3) & ~3) != namelen)
365                         continue;
366
367                 for (;;) {
368                         if (!namelen)
369                                 return ERR_PTR(-EIO);
370                         if (name[namelen-1])
371                                 break;
372                         namelen--;
373                 }
374                 if (namelen != dentry->d_name.len)
375                         continue;
376                 retval = memcmp(dentry->d_name.name, name, namelen);
377                 if (retval > 0)
378                         continue;
379                 if (!retval) {
380                         d_add(dentry, get_cramfs_inode(dir->i_sb, de));
381                         return NULL;
382                 }
383                 /* else (retval < 0) */
384                 if (sorted)
385                         break;
386         }
387         d_add(dentry, NULL);
388         return NULL;
389 }
390
391 static int cramfs_readpage(struct file *file, struct page * page)
392 {
393         struct inode *inode = page->mapping->host;
394         u32 maxblock, bytes_filled;
395         void *pgdata;
396
397         maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
398         bytes_filled = 0;
399         if (page->index < maxblock) {
400                 struct super_block *sb = inode->i_sb;
401                 u32 blkptr_offset = OFFSET(inode) + page->index*4;
402                 u32 start_offset, compr_len;
403
404                 start_offset = OFFSET(inode) + maxblock*4;
405                 down(&read_mutex);
406                 if (page->index)
407                         start_offset = CRAMFS_32(*(u32 *) cramfs_read(sb, blkptr_offset-4, 4));
408                 compr_len = CRAMFS_32(*(u32 *) cramfs_read(sb, blkptr_offset, 4)) - start_offset;
409                 up(&read_mutex);
410                 pgdata = kmap(page);
411                 if (compr_len == 0)
412                         ; /* hole */
413                 else {
414                         down(&read_mutex);
415                         bytes_filled = cramfs_uncompress_block(pgdata,
416                                  PAGE_CACHE_SIZE,
417                                  cramfs_read(sb, start_offset, compr_len),
418                                  compr_len);
419                         up(&read_mutex);
420                 }
421         } else
422                 pgdata = kmap(page);
423         memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled);
424         kunmap(page);
425         flush_dcache_page(page);
426         SetPageUptodate(page);
427         UnlockPage(page);
428         return 0;
429 }
430
431 static struct address_space_operations cramfs_aops = {
432         readpage: cramfs_readpage
433 };
434
435 /*
436  * Our operations:
437  */
438
439 /*
440  * A directory can only readdir
441  */
442 static struct file_operations cramfs_directory_operations = {
443         read:           generic_read_dir,
444         readdir:        cramfs_readdir,
445 };
446
447 static struct inode_operations cramfs_dir_inode_operations = {
448         lookup:         cramfs_lookup,
449 };
450
451 static struct super_operations cramfs_ops = {
452         statfs:         cramfs_statfs,
453 };
454
455 static DECLARE_FSTYPE_DEV(cramfs_fs_type, "cramfs", cramfs_read_super);
456
457 static int __init init_cramfs_fs(void)
458 {
459         cramfs_uncompress_init();
460         return register_filesystem(&cramfs_fs_type);
461 }
462
463 static void __exit exit_cramfs_fs(void)
464 {
465         cramfs_uncompress_exit();
466         unregister_filesystem(&cramfs_fs_type);
467 }
468
469 module_init(init_cramfs_fs)
470 module_exit(exit_cramfs_fs)
471 MODULE_LICENSE("GPL");