14 #include <linux/module.h>
18 #include <linux/string.h>
20 #include <linux/cramfs_fs.h>
21 #include <linux/slab.h>
26 #include <asm/uaccess.h>
37 #define OFFSET(x) ((x)->i_ino)
68 inode =
iget_locked(sb, cramino(cramfs_inode, offset));
71 if (!(inode->i_state &
I_NEW))
77 inode->i_data.a_ops = &cramfs_aops;
80 inode->i_op = &cramfs_dir_inode_operations;
81 inode->i_fop = &cramfs_directory_operations;
85 inode->i_data.a_ops = &cramfs_aops;
89 old_decode_dev(cramfs_inode->
size));
92 inode->i_mode = cramfs_inode->
mode;
93 i_uid_write(inode, cramfs_inode->
uid);
94 i_gid_write(inode, cramfs_inode->
gid);
97 if (!(inode->i_ino & 3)) {
98 inode->i_size = cramfs_inode->
size;
99 inode->i_blocks = (cramfs_inode->
size - 1) / 512 + 1;
103 inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
125 #define READ_BUFFERS (2)
127 #define NEXT_BUFFER(_ix) ((_ix) ^ 1)
134 #define BLKS_PER_BUF_SHIFT (2)
135 #define BLKS_PER_BUF (1 << BLKS_PER_BUF_SHIFT)
136 #define BUFFER_SIZE (BLKS_PER_BUF*PAGE_CACHE_SIZE)
141 static int next_buffer;
147 static void *cramfs_read(
struct super_block *sb,
unsigned int offset,
unsigned int len)
152 unsigned long devsize;
162 unsigned int blk_offset;
164 if (buffer_dev[i] != sb)
166 if (blocknr < buffer_blocknr[i])
168 blk_offset = (blocknr - buffer_blocknr[
i]) << PAGE_CACHE_SHIFT;
172 return read_buffers[
i] + blk_offset;
181 if (blocknr + i < devsize) {
182 page = read_mapping_page_async(mapping, blocknr + i,
194 wait_on_page_locked(page);
195 if (!PageUptodate(page)) {
203 buffer = next_buffer;
208 data = read_buffers[
buffer];
222 static void cramfs_put_super(
struct super_block *sb)
234 static int cramfs_fill_super(
struct super_block *sb,
void *
data,
int silent)
238 unsigned long root_offset;
252 buffer_blocknr[i] = -1;
255 memcpy(&super, cramfs_read(sb, 0,
sizeof(super)),
sizeof(super));
269 memcpy(&super, cramfs_read(sb, 512,
sizeof(super)),
sizeof(super));
287 if (!
S_ISDIR(super.root.mode)) {
294 root_offset = super.root.offset << 2;
296 sbi->
size=super.size;
297 sbi->
blocks=super.fsid.blocks;
298 sbi->
files=super.fsid.files;
304 sbi->
magic=super.magic;
305 sbi->
flags=super.flags;
306 if (root_offset == 0)
317 sb->
s_op = &cramfs_ops;
318 root = get_cramfs_inode(sb, &super.root, 0);
334 u64 id = huge_encode_dev(sb->
s_bdev->bd_dev);
338 buf->
f_blocks = CRAMFS_SB(sb)->blocks;
341 buf->
f_files = CRAMFS_SB(sb)->files;
354 struct inode *inode = filp->
f_path.dentry->d_inode;
361 offset = filp->
f_pos;
362 if (offset >= inode->
i_size)
374 struct cramfs_inode *de;
375 unsigned long nextoffset;
383 name = (
char *)(de+1);
391 memcpy(buf, name, namelen);
392 ino = cramino(de,
OFFSET(inode) + offset);
395 nextoffset = offset +
sizeof(*de) +
namelen;
405 error = filldir(dirent, buf, namelen, offset, ino, mode >> 12);
420 static struct dentry * cramfs_lookup(
struct inode *dir,
struct dentry *dentry,
unsigned int flags)
422 unsigned int offset = 0;
423 struct inode *inode =
NULL;
429 struct cramfs_inode *de;
435 name = (
char *)(de+1);
438 if (sorted && (dentry->
d_name.name[0] < name[0]))
442 offset +=
sizeof(*de) +
namelen;
450 inode = ERR_PTR(-
EIO);
457 if (namelen != dentry->
d_name.len)
463 inode = get_cramfs_inode(dir->
i_sb, de, dir_off);
473 return ERR_CAST(inode);
474 d_add(dentry, inode);
480 struct inode *inode = page->
mapping->host;
489 if (page->
index < maxblock) {
494 start_offset =
OFFSET(inode) + maxblock*4;
497 start_offset = *(
u32 *) cramfs_read(sb, blkptr_offset-4,
499 compr_len = (*(
u32 *) cramfs_read(sb, blkptr_offset, 4) -
506 pr_err(
"cramfs: bad compressed blocksize %u\n",
513 cramfs_read(sb, start_offset, compr_len),
524 SetPageUptodate(page);
530 ClearPageUptodate(page);
537 .readpage = cramfs_readpage
550 .readdir = cramfs_readdir,
554 .lookup = cramfs_lookup,
558 .put_super = cramfs_put_super,
559 .remount_fs = cramfs_remount,
560 .statfs = cramfs_statfs,
564 int flags,
const char *dev_name,
void *data)
566 return mount_bdev(fs_type, flags, dev_name, data, cramfs_fill_super);
572 .mount = cramfs_mount,
577 static int __init init_cramfs_fs(
void)
590 static void __exit exit_cramfs_fs(
void)