#include <linux/string.h>
#include <linux/blkdev.h>
#include <linux/cramfs_fs.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/cramfs_fs_sb.h>
#include <linux/buffer_head.h>
sb_set_blocksize(sb, PAGE_CACHE_SIZE);
/* Invalidate the read buffers on mount: think disk change.. */
+ down(&read_mutex);
for (i = 0; i < READ_BUFFERS; i++)
buffer_blocknr[i] = -1;
- down(&read_mutex);
/* Read the first block and get the superblock from it */
memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super));
up(&read_mutex);
/* Do sanity checks on the superblock */
if (super.magic != CRAMFS_MAGIC) {
/* check at 512 byte offset */
+ down(&read_mutex);
memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super));
+ up(&read_mutex);
if (super.magic != CRAMFS_MAGIC) {
if (!silent)
printk(KERN_ERR "cramfs: wrong magic\n");
{
struct inode *inode = filp->f_dentry->d_inode;
struct super_block *sb = inode->i_sb;
+ char *buf;
unsigned int offset;
int copied;
if (offset & 3)
return -EINVAL;
- lock_kernel();
+ buf = kmalloc(256, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
copied = 0;
while (offset < inode->i_size) {
struct cramfs_inode *de;
unsigned long nextoffset;
char *name;
+ ino_t ino;
+ mode_t mode;
int namelen, error;
down(&read_mutex);
de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256);
- up(&read_mutex);
name = (char *)(de+1);
/*
* with zeroes.
*/
namelen = de->namelen << 2;
+ memcpy(buf, name, namelen);
+ ino = CRAMINO(de);
+ mode = de->mode;
+ up(&read_mutex);
nextoffset = offset + sizeof(*de) + namelen;
for (;;) {
if (!namelen) {
- unlock_kernel();
+ kfree(buf);
return -EIO;
}
- if (name[namelen-1])
+ if (buf[namelen-1])
break;
namelen--;
}
- error = filldir(dirent, name, namelen, offset, CRAMINO(de), de->mode >> 12);
+ error = filldir(dirent, buf, namelen, offset, ino, mode >> 12);
if (error)
break;
filp->f_pos = offset;
copied++;
}
- unlock_kernel();
+ kfree(buf);
return 0;
}
unsigned int offset = 0;
int sorted;
- lock_kernel();
+ down(&read_mutex);
sorted = CRAMFS_SB(dir->i_sb)->flags & CRAMFS_FLAG_SORTED_DIRS;
while (offset < dir->i_size) {
struct cramfs_inode *de;
char *name;
int namelen, retval;
- down(&read_mutex);
de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256);
- up(&read_mutex);
name = (char *)(de+1);
/* Try to take advantage of sorted directories */
for (;;) {
if (!namelen) {
- unlock_kernel();
+ up(&read_mutex);
return ERR_PTR(-EIO);
}
if (name[namelen-1])
if (retval > 0)
continue;
if (!retval) {
- d_add(dentry, get_cramfs_inode(dir->i_sb, de));
- unlock_kernel();
+ struct cramfs_inode entry = *de;
+ up(&read_mutex);
+ d_add(dentry, get_cramfs_inode(dir->i_sb, &entry));
return NULL;
}
/* else (retval < 0) */
if (sorted)
break;
}
- unlock_kernel();
+ up(&read_mutex);
d_add(dentry, NULL);
return NULL;
}
* A directory can only readdir
*/
static struct file_operations cramfs_directory_operations = {
+ .llseek = generic_file_llseek,
.read = generic_read_dir,
.readdir = cramfs_readdir,
};