summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 19:12:19 -0800
committerLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 19:12:19 -0800
commit7b4d3039dfd2cbfa15127c29dcb557f314d13db1 (patch)
tree31d8a48158c92b967fd4acec936cb19ee847f531 /fs
parentfff10634980710b1edd0c849b8478d3f5ec5ee95 (diff)
v2.4.6.8 -> v2.4.6.9
- Dan Quinlan: cramfs update - Ben Collins: IEEE 1394 update - David Miller: network update (pppoe, routing cache stats), sparc32 update - me: only dump core once per threaded app (first one wins) - me: use new completion handlers for block device requests (same race as with vfork, see -pre7)
Diffstat (limited to 'fs')
-rw-r--r--fs/affs/amigaffs.c2
-rw-r--r--fs/binfmt_aout.c2
-rw-r--r--fs/cramfs/README4
-rw-r--r--fs/cramfs/cramfs.h52
-rw-r--r--fs/cramfs/inode.c109
-rw-r--r--fs/exec.c10
-rw-r--r--fs/nfs/nfsroot.c2
-rw-r--r--fs/proc/base.c2
8 files changed, 99 insertions, 84 deletions
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index acb2fd102adf..0c09806d2d31 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -284,7 +284,7 @@ affs_remove_header(struct dentry *dentry)
pr_debug("AFFS: remove_header(key=%ld)\n", inode->i_ino);
retval = -EIO;
- bh = affs_bread(sb, (u32)dentry->d_fsdata);
+ bh = affs_bread(sb, (u32)(long)dentry->d_fsdata);
if (!bh)
goto done;
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 8a907e0371ba..2b943f5ca539 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -73,7 +73,7 @@ if (file->f_op->llseek) { \
* Currently only a stub-function.
*
* Note that setuid/setgid files won't make a core-dump if the uid/gid
- * changed due to the set[u|g]id. It's enforced by the "current->dumpable"
+ * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable"
* field, which also makes sure the core-dumps won't be recursive if the
* dumping of the process results in another error..
*/
diff --git a/fs/cramfs/README b/fs/cramfs/README
index a04f41b1f267..d5ff1832dbc2 100644
--- a/fs/cramfs/README
+++ b/fs/cramfs/README
@@ -14,11 +14,11 @@ ever do swabbing. (See section `Block Size' below.)
<directory_structure>
<data>
-<superblock>: struct cramfs_super (see cramfs.h).
+<superblock>: struct cramfs_super (see cramfs_fs.h).
<directory_structure>:
For each file:
- struct cramfs_inode (see cramfs.h).
+ struct cramfs_inode (see cramfs_fs.h).
Filename. Not generally null-terminated, but it is
null-padded to a multiple of 4 bytes.
diff --git a/fs/cramfs/cramfs.h b/fs/cramfs/cramfs.h
deleted file mode 100644
index b7e4e76003ff..000000000000
--- a/fs/cramfs/cramfs.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __CRAMFS_H
-#define __CRAMFS_H
-
-#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */
-#define CRAMFS_SIGNATURE "Compressed ROMFS"
-
-/*
- * Reasonably terse representation of the inode data.
- */
-struct cramfs_inode {
- u32 mode:16, uid:16;
- /* SIZE for device files is i_rdev */
- u32 size:24, gid:8;
- /* NAMELEN is the length of the file name, divided by 4 and
- rounded up. (cramfs doesn't support hard links.) */
- /* OFFSET: For symlinks and non-empty regular files, this
- contains the offset (divided by 4) of the file data in
- compressed form (starting with an array of block pointers;
- see README). For non-empty directories it is the offset
- (divided by 4) of the inode of the first file in that
- directory. For anything else, offset is zero. */
- u32 namelen:6, offset:26;
-};
-
-/*
- * Superblock information at the beginning of the FS.
- */
-struct cramfs_super {
- u32 magic; /* 0x28cd3d45 - random number */
- u32 size; /* Not used. mkcramfs currently
- writes a constant 1<<16 here. */
- u32 flags; /* 0 */
- u32 future; /* 0 */
- u8 signature[16]; /* "Compressed ROMFS" */
- u8 fsid[16]; /* random number */
- u8 name[16]; /* user-defined name */
- struct cramfs_inode root; /* Root inode data */
-};
-
-/*
- * Valid values in super.flags. Currently we refuse to mount
- * if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be
- * changed to test super.future instead.
- */
-#define CRAMFS_SUPPORTED_FLAGS (0xff)
-
-/* Uncompression interfaces to the underlying zlib */
-int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
-int cramfs_uncompress_init(void);
-int cramfs_uncompress_exit(void);
-
-#endif
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 22deb7d31a55..ee5d4d367822 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -17,10 +17,16 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/locks.h>
+#include <linux/blkdev.h>
+#include <linux/cramfs_fs.h>
#include <asm/uaccess.h>
-#include "cramfs.h"
+#define CRAMFS_SB_MAGIC u.cramfs_sb.magic
+#define CRAMFS_SB_SIZE u.cramfs_sb.size
+#define CRAMFS_SB_BLOCKS u.cramfs_sb.blocks
+#define CRAMFS_SB_FILES u.cramfs_sb.files
+#define CRAMFS_SB_FLAGS u.cramfs_sb.flags
static struct super_operations cramfs_ops;
static struct inode_operations cramfs_dir_inode_operations;
@@ -40,6 +46,8 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod
inode->i_mode = cramfs_inode->mode;
inode->i_uid = cramfs_inode->uid;
inode->i_size = cramfs_inode->size;
+ inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
+ inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_gid = cramfs_inode->gid;
inode->i_ino = CRAMINO(cramfs_inode);
/* inode->i_nlink is left 1 - arguably wrong for directories,
@@ -100,7 +108,11 @@ static int next_buffer;
static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len)
{
struct buffer_head * bh_array[BLKS_PER_BUF];
- unsigned i, blocknr, buffer;
+ struct buffer_head * read_array[BLKS_PER_BUF];
+ unsigned i, blocknr, buffer, unread;
+ unsigned long devsize;
+ int major, minor;
+
char *data;
if (!len)
@@ -123,9 +135,34 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
return read_buffers[i] + blk_offset;
}
+ devsize = ~0UL;
+ major = MAJOR(sb->s_dev);
+ minor = MINOR(sb->s_dev);
+
+ if (blk_size[major])
+ devsize = blk_size[major][minor] >> 2;
+
/* Ok, read in BLKS_PER_BUF pages completely first. */
- for (i = 0; i < BLKS_PER_BUF; i++)
- bh_array[i] = bread(sb->s_dev, blocknr + i, PAGE_CACHE_SIZE);
+ unread = 0;
+ for (i = 0; i < BLKS_PER_BUF; i++) {
+ struct buffer_head *bh;
+
+ bh = NULL;
+ if (blocknr + i < devsize) {
+ bh = getblk(sb->s_dev, blocknr + i, PAGE_CACHE_SIZE);
+ if (!buffer_uptodate(bh))
+ read_array[unread++] = bh;
+ }
+ bh_array[i] = bh;
+ }
+
+ if (unread) {
+ ll_rw_block(READ, unread, read_array);
+ do {
+ unread--;
+ wait_on_buffer(read_array[unread]);
+ } while (unread);
+ }
/* Ok, copy them to the staging area without sleeping. */
buffer = next_buffer;
@@ -167,34 +204,50 @@ static struct super_block * cramfs_read_super(struct super_block *sb, void *data
/* Do sanity checks on the superblock */
if (super.magic != CRAMFS_MAGIC) {
- printk("wrong magic\n");
- goto out;
- }
- if (memcmp(super.signature, CRAMFS_SIGNATURE, sizeof(super.signature))) {
- printk("wrong signature\n");
- goto out;
+ /* check at 512 byte offset */
+ memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super));
+ if (super.magic != CRAMFS_MAGIC) {
+ printk(KERN_ERR "cramfs: wrong magic\n");
+ goto out;
+ }
}
+
+ /* get feature flags first */
if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
- printk("unsupported filesystem features\n");
+ printk(KERN_ERR "cramfs: unsupported filesystem features\n");
goto out;
}
/* Check that the root inode is in a sane state */
if (!S_ISDIR(super.root.mode)) {
- printk("root is not a directory\n");
+ printk(KERN_ERR "cramfs: root is not a directory\n");
goto out;
}
root_offset = super.root.offset << 2;
+ if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
+ sb->CRAMFS_SB_SIZE=super.size;
+ sb->CRAMFS_SB_BLOCKS=super.fsid.blocks;
+ sb->CRAMFS_SB_FILES=super.fsid.files;
+ } else {
+ sb->CRAMFS_SB_SIZE=1<<28;
+ sb->CRAMFS_SB_BLOCKS=0;
+ sb->CRAMFS_SB_FILES=0;
+ }
+ sb->CRAMFS_SB_MAGIC=super.magic;
+ sb->CRAMFS_SB_FLAGS=super.flags;
if (root_offset == 0)
- printk(KERN_INFO "cramfs: note: empty filesystem");
- else if (root_offset != sizeof(struct cramfs_super)) {
- printk("bad root offset %lu\n", root_offset);
+ printk(KERN_INFO "cramfs: empty filesystem");
+ else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
+ ((root_offset != sizeof(struct cramfs_super)) &&
+ (root_offset != 512 + sizeof(struct cramfs_super))))
+ {
+ printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset);
goto out;
}
/* Set it all up.. */
- sb->s_op = &cramfs_ops;
- sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root));
+ sb->s_op = &cramfs_ops;
+ sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root));
retval = sb;
out:
return retval;
@@ -204,8 +257,10 @@ static int cramfs_statfs(struct super_block *sb, struct statfs *buf)
{
buf->f_type = CRAMFS_MAGIC;
buf->f_bsize = PAGE_CACHE_SIZE;
+ buf->f_blocks = sb->CRAMFS_SB_BLOCKS;
buf->f_bfree = 0;
buf->f_bavail = 0;
+ buf->f_files = sb->CRAMFS_SB_FILES;
buf->f_ffree = 0;
buf->f_namelen = 255;
return 0;
@@ -270,14 +325,20 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
{
unsigned int offset = 0;
+ int sorted = dir->i_sb->CRAMFS_SB_FLAGS & CRAMFS_FLAG_SORTED_DIRS;
while (offset < dir->i_size) {
struct cramfs_inode *de;
char *name;
- int namelen;
+ int namelen, retval;
de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256);
name = (char *)(de+1);
+
+ /* Try to take advantage of sorted directories */
+ if (sorted && (dentry->d_name.name[0] < name[0]))
+ break;
+
namelen = de->namelen << 2;
offset += sizeof(*de) + namelen;
@@ -294,10 +355,16 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
}
if (namelen != dentry->d_name.len)
continue;
- if (memcmp(dentry->d_name.name, name, namelen))
+ retval = memcmp(dentry->d_name.name, name, namelen);
+ if (retval > 0)
continue;
- d_add(dentry, get_cramfs_inode(dir->i_sb, de));
- return NULL;
+ if (!retval) {
+ d_add(dentry, get_cramfs_inode(dir->i_sb, de));
+ return NULL;
+ }
+ /* else (retval < 0) */
+ if (sorted)
+ break;
}
d_add(dentry, NULL);
return NULL;
diff --git a/fs/exec.c b/fs/exec.c
index 3e143bc2ac10..012b1a02319a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -548,7 +548,7 @@ int flush_old_exec(struct linux_binprm * bprm)
current->sas_ss_sp = current->sas_ss_size = 0;
if (current->euid == current->uid && current->egid == current->gid)
- current->dumpable = 1;
+ current->mm->dumpable = 1;
name = bprm->filename;
for (i=0; (ch = *(name++)) != '\0';) {
if (ch == '/')
@@ -565,7 +565,7 @@ int flush_old_exec(struct linux_binprm * bprm)
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
permission(bprm->file->f_dentry->d_inode,MAY_READ))
- current->dumpable = 0;
+ current->mm->dumpable = 0;
/* An exec changes our domain. We are no longer part of the thread
group */
@@ -683,7 +683,7 @@ void compute_creds(struct linux_binprm *bprm)
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
!cap_issubset(new_permitted, current->cap_permitted)) {
- current->dumpable = 0;
+ current->mm->dumpable = 0;
lock_kernel();
if (must_not_trace_exec(current)
@@ -933,9 +933,9 @@ int do_coredump(long signr, struct pt_regs * regs)
binfmt = current->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
- if (!current->dumpable)
+ if (!current->mm->dumpable)
goto fail;
- current->dumpable = 0;
+ current->mm->dumpable = 0;
if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
goto fail;
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index ce05e1843b4b..a2373467d5e4 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -418,7 +418,7 @@ static int __init root_nfs_ports(void)
"as nfsd port\n", port);
}
- if ((port = root_nfs_getport(NFS_MNT_PROGRAM, nfsd_ver, proto)) < 0) {
+ if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
printk(KERN_ERR "Root-NFS: Unable to get mountd port "
"number from server, using default\n");
port = mountd_port;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f6cce3b126c5..969b91d8981e 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -670,7 +670,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
inode->u.proc_i.task = task;
inode->i_uid = 0;
inode->i_gid = 0;
- if (ino == PROC_PID_INO || task->dumpable) {
+ if (ino == PROC_PID_INO || task->mm->dumpable) {
inode->i_uid = task->euid;
inode->i_gid = task->egid;
}