diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 19:12:19 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 19:12:19 -0800 |
| commit | 7b4d3039dfd2cbfa15127c29dcb557f314d13db1 (patch) | |
| tree | 31d8a48158c92b967fd4acec936cb19ee847f531 /fs | |
| parent | fff10634980710b1edd0c849b8478d3f5ec5ee95 (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.c | 2 | ||||
| -rw-r--r-- | fs/binfmt_aout.c | 2 | ||||
| -rw-r--r-- | fs/cramfs/README | 4 | ||||
| -rw-r--r-- | fs/cramfs/cramfs.h | 52 | ||||
| -rw-r--r-- | fs/cramfs/inode.c | 109 | ||||
| -rw-r--r-- | fs/exec.c | 10 | ||||
| -rw-r--r-- | fs/nfs/nfsroot.c | 2 | ||||
| -rw-r--r-- | fs/proc/base.c | 2 |
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; } |
