summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorJens Axboe <axboe@burns.home.kernel.dk>2002-02-07 10:37:19 +0100
committerJens Axboe <axboe@burns.home.kernel.dk>2002-02-07 10:37:19 +0100
commit2adf779dd193e1c8673f5896da4fef1dda830774 (patch)
treef8014bbf33b023dd09bda6f9145bb776f73389d2 /fs
parent07916eb45f4a6c63acb93e269c10490e4e623a0c (diff)
parent0ec120046dee44027a28b66a3c28d1031982a9eb (diff)
Merge http://linux.bkbits.net/linux-2.5
into burns.home.kernel.dk:/usr/local/kernel/BK/linux-2.5
Diffstat (limited to 'fs')
-rw-r--r--fs/autofs/autofs_i.h2
-rw-r--r--fs/autofs/init.c12
-rw-r--r--fs/autofs/inode.c7
-rw-r--r--fs/autofs4/autofs_i.h2
-rw-r--r--fs/autofs4/init.c12
-rw-r--r--fs/autofs4/inode.c7
-rw-r--r--fs/binfmt_misc.c26
-rw-r--r--fs/bio.c26
-rw-r--r--fs/block_dev.c20
-rw-r--r--fs/dcache.c1
-rw-r--r--fs/devfs/base.c18
-rw-r--r--fs/devpts/inode.c21
-rw-r--r--fs/driverfs/inode.c25
-rw-r--r--fs/ext2/ext2.h1
-rw-r--r--fs/ext2/super.c31
-rw-r--r--fs/fat/fatfs_syms.c7
-rw-r--r--fs/file_table.c14
-rw-r--r--fs/hfs/catalog.c12
-rw-r--r--fs/hfs/extent.c8
-rw-r--r--fs/hfs/file_cap.c1
-rw-r--r--fs/hfs/file_hdr.c1
-rw-r--r--fs/hfs/hfs.h5
-rw-r--r--fs/hfs/mdb.c3
-rw-r--r--fs/hpfs/buffer.c6
-rw-r--r--fs/hpfs/super.c4
-rw-r--r--fs/namespace.c12
-rw-r--r--fs/ncpfs/file.c3
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/ncpfs/sock.c8
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/nfs/inode.c29
-rw-r--r--fs/ntfs/fs.c2
-rw-r--r--fs/openpromfs/inode.c21
-rw-r--r--fs/pipe.c38
-rw-r--r--fs/proc/base.c103
-rw-r--r--fs/proc/generic.c14
-rw-r--r--fs/proc/inode.c50
-rw-r--r--fs/proc/root.c17
-rw-r--r--fs/ramfs/inode.c26
-rw-r--r--fs/read_write.c25
-rw-r--r--fs/reiserfs/inode.c14
-rw-r--r--fs/smbfs/file.c2
-rw-r--r--fs/smbfs/sock.c4
-rw-r--r--fs/stat.c383
-rw-r--r--fs/super.c60
-rw-r--r--fs/udf/super.c2
-rw-r--r--fs/ufs/file.c36
47 files changed, 642 insertions, 483 deletions
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 6d6a334b3717..354af8325576 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -145,7 +145,7 @@ extern struct file_operations autofs_dir_operations;
/* Initializing function */
-struct super_block *autofs_read_super(struct super_block *, void *,int);
+int autofs_fill_super(struct super_block *, void *, int);
/* Queue management functions */
diff --git a/fs/autofs/init.c b/fs/autofs/init.c
index 0e7fff94f254..b73fec09f7c2 100644
--- a/fs/autofs/init.c
+++ b/fs/autofs/init.c
@@ -14,7 +14,17 @@
#include <linux/init.h>
#include "autofs_i.h"
-static DECLARE_FSTYPE(autofs_fs_type, "autofs", autofs_read_super, 0);
+static struct super_block *autofs_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_nodev(fs_type, flags, data, autofs_fill_super);
+}
+
+static struct file_system_type autofs_fs_type = {
+ owner: THIS_MODULE,
+ name: "autofs",
+ get_sb: autofs_get_sb,
+};
static int __init init_autofs_fs(void)
{
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index d275c5f81e57..8a0f463dfaf6 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -111,8 +111,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid
return (*pipefd < 0);
}
-struct super_block *autofs_read_super(struct super_block *s, void *data,
- int silent)
+int autofs_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * root_inode;
struct dentry * root;
@@ -175,7 +174,7 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
* Success! Install the root dentry now to indicate completion.
*/
s->s_root = root;
- return s;
+ return 0;
fail_fput:
printk("autofs: pipe file descriptor does not contain proper ops\n");
@@ -189,7 +188,7 @@ fail_iput:
fail_free:
kfree(sbi);
fail_unlock:
- return NULL;
+ return -EINVAL;
}
static int autofs_statfs(struct super_block *sb, struct statfs *buf)
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 4dcdcaafcca9..7e43620bca87 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -144,7 +144,7 @@ extern struct file_operations autofs4_root_operations;
/* Initializing function */
-struct super_block *autofs4_read_super(struct super_block *, void *,int);
+int autofs4_fill_super(struct super_block *, void *, int);
struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info *sbi, mode_t mode);
/* Queue management functions */
diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c
index dbb3e5385ded..fdce6b04367c 100644
--- a/fs/autofs4/init.c
+++ b/fs/autofs4/init.c
@@ -14,7 +14,17 @@
#include <linux/init.h>
#include "autofs_i.h"
-static DECLARE_FSTYPE(autofs_fs_type, "autofs", autofs4_read_super, 0);
+static struct super_block *autofs_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_nodev(fs_type, flags, data, autofs4_fill_super);
+}
+
+static struct file_system_type autofs_fs_type = {
+ owner: THIS_MODULE,
+ name: "autofs",
+ get_sb: autofs_get_sb,
+};
static int __init init_autofs4_fs(void)
{
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 1f2d29f6d0cd..a7331fd67fa9 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -173,8 +173,7 @@ static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
return ino;
}
-struct super_block *autofs4_read_super(struct super_block *s, void *data,
- int silent)
+int autofs4_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * root_inode;
struct dentry * root;
@@ -251,7 +250,7 @@ struct super_block *autofs4_read_super(struct super_block *s, void *data,
* Success! Install the root dentry now to indicate completion.
*/
s->s_root = root;
- return s;
+ return 0;
/*
* Failure ... clean up.
@@ -278,7 +277,7 @@ fail_iput:
fail_free:
kfree(sbi);
fail_unlock:
- return NULL;
+ return -EINVAL;
}
static int autofs4_statfs(struct super_block *sb, struct statfs *buf)
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index dcbc3a688ae7..7f371ea86066 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -656,7 +656,7 @@ static struct super_operations s_ops = {
clear_inode: bm_clear_inode,
};
-static struct super_block *bm_read_super(struct super_block * sb, void * data, int silent)
+static int bm_fill_super(struct super_block * sb, void * data, int silent)
{
struct qstr names[2] = {{name:"status"}, {name:"register"}};
struct inode * inode;
@@ -675,13 +675,13 @@ static struct super_block *bm_read_super(struct super_block * sb, void * data, i
inode = bm_get_inode(sb, S_IFDIR | 0755);
if (!inode)
- return NULL;
+ return -ENOMEM;
inode->i_op = &bm_dir_inode_operations;
inode->i_fop = &bm_dir_operations;
dentry[0] = d_alloc_root(inode);
if (!dentry[0]) {
iput(inode);
- return NULL;
+ return -ENOMEM;
}
dentry[1] = d_alloc(dentry[0], &names[0]);
if (!dentry[1])
@@ -701,7 +701,7 @@ static struct super_block *bm_read_super(struct super_block * sb, void * data, i
d_add(dentry[2], inode);
sb->s_root = dentry[0];
- return sb;
+ return 0;
out3:
dput(dentry[2]);
@@ -709,14 +709,26 @@ out2:
dput(dentry[1]);
out1:
dput(dentry[0]);
- return NULL;
+ return -ENOMEM;
+}
+
+static struct super_block *bm_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_single(fs_type, flags, data, bm_fill_super);
}
static struct linux_binfmt misc_format = {
- NULL, THIS_MODULE, load_misc_binary, NULL, NULL, 0
+ module: THIS_MODULE,
+ load_binary: load_misc_binary,
};
-static DECLARE_FSTYPE(bm_fs_type, "binfmt_misc", bm_read_super, FS_SINGLE|FS_LITTER);
+static struct file_system_type bm_fs_type = {
+ owner: THIS_MODULE,
+ name: "binfmt_misc",
+ get_sb: bm_get_sb,
+ fs_flags: FS_LITTER,
+};
static int __init init_misc_binfmt(void)
{
diff --git a/fs/bio.c b/fs/bio.c
index 84752e8979e5..e39197f24166 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -33,20 +33,24 @@ static kmem_cache_t *bio_slab;
struct biovec_pool {
int size;
+ char *name;
kmem_cache_t *slab;
mempool_t *pool;
};
-static struct biovec_pool bvec_array[BIOVEC_NR_POOLS];
-
/*
* if you change this list, also change bvec_alloc or things will
* break badly! cannot be bigger than what you can fit into an
* unsigned short
*/
-static const int bvec_pool_sizes[BIOVEC_NR_POOLS] = { 1, 4, 16, 64, 128, 256 };
-#define BIO_MAX_PAGES (bvec_pool_sizes[BIOVEC_NR_POOLS - 1])
+#define BV(x) { x, "biovec-" #x }
+static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = {
+ BV(1), BV(4), BV(16), BV(64), BV(128), BV(256)
+};
+#undef BV
+
+#define BIO_MAX_PAGES (bvec_array[BIOVEC_NR_POOLS - 1].size)
static void *slab_pool_alloc(int gfp_mask, void *data)
{
@@ -64,7 +68,7 @@ static inline struct bio_vec *bvec_alloc(int gfp_mask, int nr, int *idx)
struct bio_vec *bvl;
/*
- * see comment near bvec_pool_sizes define!
+ * see comment near bvec_array define!
*/
switch (nr) {
case 1 : *idx = 0; break;
@@ -452,21 +456,17 @@ int bio_endio(struct bio *bio, int uptodate, int nr_sectors)
static void __init biovec_init_pool(void)
{
- char name[16];
int i, size;
- memset(&bvec_array, 0, sizeof(bvec_array));
-
for (i = 0; i < BIOVEC_NR_POOLS; i++) {
struct biovec_pool *bp = bvec_array + i;
- size = bvec_pool_sizes[i] * sizeof(struct bio_vec);
+ size = bp->size * sizeof(struct bio_vec);
printk("biovec: init pool %d, %d entries, %d bytes\n", i,
- bvec_pool_sizes[i], size);
+ bp->size, size);
- snprintf(name, sizeof(name) - 1,"biovec-%d",bvec_pool_sizes[i]);
- bp->slab = kmem_cache_create(name, size, 0,
+ bp->slab = kmem_cache_create(bp->name, size, 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!bp->slab)
panic("biovec: can't init slab cache\n");
@@ -474,7 +474,7 @@ static void __init biovec_init_pool(void)
slab_pool_free, bp->slab);
if (!bp->pool)
panic("biovec: can't init mempool\n");
- bp->size = size;
+ bp->size = size;
}
}
diff --git a/fs/block_dev.c b/fs/block_dev.c
index ef9fb9f89aa2..5bdffee5760e 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -220,7 +220,7 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
* pseudo-fs
*/
-static struct super_block *bd_read_super(struct super_block *sb, void *data, int silent)
+static int bd_fill_super(struct super_block *sb, void *data, int silent)
{
static struct super_operations sops = {};
struct inode *root;
@@ -232,22 +232,32 @@ static struct super_block *bd_read_super(struct super_block *sb, void *data, int
sb->s_op = &sops;
root = new_inode(sb);
if (!root)
- return NULL;
+ return -ENOMEM;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
sb->s_root = d_alloc(NULL, &(const struct qstr) { "bdev:", 5, 0 });
if (!sb->s_root) {
iput(root);
- return NULL;
+ return -ENOMEM;
}
sb->s_root->d_sb = sb;
sb->s_root->d_parent = sb->s_root;
d_instantiate(sb->s_root, root);
- return sb;
+ return 0;
}
-static DECLARE_FSTYPE(bd_type, "bdev", bd_read_super, FS_NOMOUNT);
+static struct super_block *bd_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_nodev(fs_type, flags, data, bd_fill_super);
+}
+
+static struct file_system_type bd_type = {
+ name: "bdev",
+ get_sb: bd_get_sb,
+ fs_flags: FS_NOMOUNT,
+};
static struct vfsmount *bd_mnt;
diff --git a/fs/dcache.c b/fs/dcache.c
index 7246506fff37..a421788191fb 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1283,6 +1283,7 @@ void __init vfs_caches_init(unsigned long mempages)
dcache_init(mempages);
inode_init(mempages);
+ files_init(mempages);
mnt_init(mempages);
bdev_cache_init();
cdev_cache_init();
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 89a698a63ea6..6372557356d9 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -3218,8 +3218,7 @@ static struct inode_operations devfs_symlink_iops =
setattr: devfs_notify_change,
};
-static struct super_block *devfs_read_super (struct super_block *sb,
- void *data, int silent)
+static int devfs_fill_super (struct super_block *sb, void *data, int silent)
{
struct inode *root_inode = NULL;
@@ -3238,17 +3237,24 @@ static struct super_block *devfs_read_super (struct super_block *sb,
sb->s_root = d_alloc_root (root_inode);
if (!sb->s_root) goto out_no_root;
DPRINTK (DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->u.generic_sbp);
- return sb;
+ return 0;
out_no_root:
PRINTK ("(): get root inode failed\n");
if (root_inode) iput (root_inode);
- return NULL;
+ return -EINVAL;
} /* End Function devfs_read_super */
+static struct super_block *devfs_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_single(fs_type, flags, data, devfs_fill_super);
+}
-static DECLARE_FSTYPE (devfs_fs_type, DEVFS_NAME, devfs_read_super, FS_SINGLE);
-
+static struct file_system_type devfs_fs_type = {
+ name: DEVFS_NAME,
+ get_sb: devfs_get_sb,
+};
/* File operations for devfsd follow */
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 393ca3ececc6..1816bd4137c7 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -118,9 +118,9 @@ static int devpts_remount(struct super_block * sb, int * flags, char * data)
return 0;
}
-struct super_block *devpts_read_super(struct super_block *s, void *data,
- int silent)
+static int devpts_fill_super(struct super_block *s, void *data, int silent)
{
+ int error = -ENOMEM;
struct inode * inode;
struct devpts_sb_info *sbi;
@@ -136,6 +136,7 @@ struct super_block *devpts_read_super(struct super_block *s, void *data,
memset(sbi->inodes, 0, sizeof(struct inode *) * sbi->max_ptys);
if ( devpts_parse_options(data,sbi) && !silent) {
+ error = -EINVAL;
printk("devpts: called with bogus options\n");
goto fail_free;
}
@@ -160,14 +161,14 @@ struct super_block *devpts_read_super(struct super_block *s, void *data,
s->s_root = d_alloc_root(inode);
if (s->s_root)
- return s;
+ return 0;
printk("devpts: get root dentry failed\n");
iput(inode);
fail_free:
kfree(sbi);
fail:
- return NULL;
+ return error;
}
static int devpts_statfs(struct super_block *sb, struct statfs *buf)
@@ -178,7 +179,17 @@ static int devpts_statfs(struct super_block *sb, struct statfs *buf)
return 0;
}
-static DECLARE_FSTYPE(devpts_fs_type, "devpts", devpts_read_super, FS_SINGLE);
+static struct super_block *devpts_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_single(fs_type, flags, data, devpts_fill_super);
+}
+
+static struct file_system_type devpts_fs_type = {
+ owner: THIS_MODULE,
+ name: "devpts",
+ get_sb: devpts_get_sb,
+};
void devpts_pty_new(int number, kdev_t device)
{
diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c
index 802d5f8597f9..54e35bce866d 100644
--- a/fs/driverfs/inode.c
+++ b/fs/driverfs/inode.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -341,6 +342,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig)
{
loff_t retval = -EINVAL;
+ lock_kernel();
switch(orig) {
case 0:
if (offset > 0) {
@@ -357,6 +359,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig)
default:
break;
}
+ unlock_kernel();
return retval;
}
@@ -446,8 +449,7 @@ static struct super_operations driverfs_ops = {
put_inode: force_delete,
};
-static struct super_block*
-driverfs_read_super(struct super_block *sb, void *data, int silent)
+static int driverfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode;
struct dentry *root;
@@ -460,20 +462,31 @@ driverfs_read_super(struct super_block *sb, void *data, int silent)
if (!inode) {
DBG("%s: could not get inode!\n",__FUNCTION__);
- return NULL;
+ return -ENOMEM;
}
root = d_alloc_root(inode);
if (!root) {
DBG("%s: could not get root dentry!\n",__FUNCTION__);
iput(inode);
- return NULL;
+ return -ENOMEM;
}
sb->s_root = root;
- return sb;
+ return 0;
}
-static DECLARE_FSTYPE(driverfs_fs_type, "driverfs", driverfs_read_super, FS_SINGLE | FS_LITTER);
+static struct super_block *driverfs_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_single(fs_type, flags, data, driverfs_fill_super);
+}
+
+static struct file_system_type driverfs_fs_type = {
+ owner: THIS_MODULE,
+ name: "driverfs",
+ get_sb: driverfs_get_sb,
+ fs_flags: FS_LITTER,
+};
static int get_mount(void)
{
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 09d13d60ef31..b6ffc9337824 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -96,7 +96,6 @@ extern void ext2_update_dynamic_rev (struct super_block *sb);
extern void ext2_put_super (struct super_block *);
extern void ext2_write_super (struct super_block *);
extern int ext2_remount (struct super_block *, int *, char *);
-extern struct super_block * ext2_read_super (struct super_block *,void *,int);
extern int ext2_statfs (struct super_block *, struct statfs *);
/*
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index bb14991cf85f..d46639635c61 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -441,8 +441,7 @@ static loff_t ext2_max_size(int bits)
return res;
}
-struct super_block * ext2_read_super (struct super_block * sb, void * data,
- int silent)
+static int ext2_fill_super(struct super_block *sb, void *data, int silent)
{
struct buffer_head * bh;
struct ext2_super_block * es;
@@ -465,14 +464,13 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
sb->u.ext2_sb.s_mount_opt = 0;
if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
- &sb->u.ext2_sb.s_mount_opt)) {
- return NULL;
- }
+ &sb->u.ext2_sb.s_mount_opt))
+ return -EINVAL;
blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
if (!blocksize) {
printk ("EXT2-fs: unable to set blocksize\n");
- return NULL;
+ return -EINVAL;
}
/*
@@ -487,7 +485,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
if (!(bh = sb_bread(sb, logic_sb_block))) {
printk ("EXT2-fs: unable to read superblock\n");
- return NULL;
+ return -EINVAL;
}
/*
* Note: s_es must be initialized as soon as possible because
@@ -533,7 +531,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
if (!sb_set_blocksize(sb, blocksize)) {
printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n");
- return NULL;
+ return -EINVAL;
}
logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
@@ -684,14 +682,14 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
goto failed_mount2;
}
ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
- return sb;
+ return 0;
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sb->u.ext2_sb.s_group_desc[i]);
kfree(sb->u.ext2_sb.s_group_desc);
failed_mount:
brelse(bh);
- return NULL;
+ return -EINVAL;
}
static void ext2_commit_super (struct super_block * sb,
@@ -843,7 +841,18 @@ int ext2_statfs (struct super_block * sb, struct statfs * buf)
return 0;
}
-static DECLARE_FSTYPE_DEV(ext2_fs_type, "ext2", ext2_read_super);
+static struct super_block *ext2_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
+}
+
+static struct file_system_type ext2_fs_type = {
+ owner: THIS_MODULE,
+ name: "ext2",
+ get_sb: ext2_get_sb,
+ fs_flags: FS_REQUIRES_DEV,
+};
static int __init init_ext2_fs(void)
{
diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c
index 1ebb2731f60f..8b7152af25ae 100644
--- a/fs/fat/fatfs_syms.c
+++ b/fs/fat/fatfs_syms.c
@@ -47,5 +47,10 @@ static int __init init_fat_fs(void)
return fat_init_inodecache();
}
+static void __exit exit_fat_fs(void)
+{
+ fat_destroy_inodecache();
+}
+
module_init(init_fat_fs)
-module_exit(fat_destroy_inodecache)
+module_exit(exit_fat_fs)
diff --git a/fs/file_table.c b/fs/file_table.c
index 27713eb016fc..e7248739e3d4 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -186,3 +186,17 @@ too_bad:
file_list_unlock();
return 0;
}
+
+void __init files_init(unsigned long mempages)
+{
+ int n;
+ /* One file with associated inode and dcache is very roughly 1K.
+ * Per default don't use more than 10% of our memory for files.
+ */
+
+ n = (mempages * (PAGE_SIZE / 1024)) / 10;
+ files_stat.max_files = n;
+ if (files_stat.max_files < NR_FILE)
+ files_stat.max_files = NR_FILE;
+}
+
diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
index 3bcdaae4e024..a82753c462d9 100644
--- a/fs/hfs/catalog.c
+++ b/fs/hfs/catalog.c
@@ -1346,13 +1346,6 @@ int hfs_cat_move(struct hfs_cat_entry *old_dir, struct hfs_cat_entry *new_dir,
return -EINVAL;
}
- while (mdb->rename_lock) {
- hfs_sleep_on(&mdb->rename_wait);
- }
- spin_lock(&entry_lock);
- mdb->rename_lock = 1; /* XXX: should be atomic_inc */
- spin_unlock(&entry_lock);
-
/* keep readers from getting confused by changing dir size */
start_write(new_dir);
if (old_dir != new_dir) {
@@ -1567,11 +1560,6 @@ done:
end_write(old_dir);
}
end_write(new_dir);
- spin_lock(&entry_lock);
- mdb->rename_lock = 0; /* XXX: should use atomic_dec */
- hfs_wake_up(&mdb->rename_wait);
- spin_unlock(&entry_lock);
-
return error;
}
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c
index 5df23375add4..4b7d36f5f2fb 100644
--- a/fs/hfs/extent.c
+++ b/fs/hfs/extent.c
@@ -48,10 +48,7 @@ static inline void build_key(struct hfs_ext_key *key,
* Get an exclusive lock on the B-tree bitmap.
*/
static inline void lock_bitmap(struct hfs_mdb *mdb) {
- while (mdb->bitmap_lock) {
- hfs_sleep_on(&mdb->bitmap_wait);
- }
- mdb->bitmap_lock = 1;
+ down(&mdb->bitmap_sem);
}
/*
@@ -60,8 +57,7 @@ static inline void lock_bitmap(struct hfs_mdb *mdb) {
* Relinquish an exclusive lock on the B-tree bitmap.
*/
static inline void unlock_bitmap(struct hfs_mdb *mdb) {
- mdb->bitmap_lock = 0;
- hfs_wake_up(&mdb->bitmap_wait);
+ up(&mdb->bitmap_sem);
}
/*
diff --git a/fs/hfs/file_cap.c b/fs/hfs/file_cap.c
index 494d43249c44..7a02ebaa6154 100644
--- a/fs/hfs/file_cap.c
+++ b/fs/hfs/file_cap.c
@@ -24,6 +24,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
+#include <linux/smp_lock.h>
/*================ Forward declarations ================*/
static loff_t cap_info_llseek(struct file *, loff_t,
diff --git a/fs/hfs/file_hdr.c b/fs/hfs/file_hdr.c
index 2ac3182437a7..8dad9e76d20b 100644
--- a/fs/hfs/file_hdr.c
+++ b/fs/hfs/file_hdr.c
@@ -29,6 +29,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
+#include <linux/smp_lock.h>
/* prodos types */
#define PRODOSI_FTYPE_DIR 0x0F
diff --git a/fs/hfs/hfs.h b/fs/hfs/hfs.h
index e328a14aeed7..ad9f70d74294 100644
--- a/fs/hfs/hfs.h
+++ b/fs/hfs/hfs.h
@@ -271,10 +271,7 @@ struct hfs_mdb {
512-byte blocks per
"allocation block" */
hfs_u16 attrib; /* Attribute word */
- hfs_wait_queue rename_wait;
- int rename_lock;
- hfs_wait_queue bitmap_wait;
- int bitmap_lock;
+ struct semaphore bitmap_sem;
struct list_head entry_dirty;
};
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c
index d907a632dad9..b3f8477f58cb 100644
--- a/fs/hfs/mdb.c
+++ b/fs/hfs/mdb.c
@@ -100,8 +100,7 @@ struct hfs_mdb *hfs_mdb_get(hfs_sysmdb sys_mdb, int readonly,
mdb->magic = HFS_MDB_MAGIC;
mdb->sys_mdb = sys_mdb;
INIT_LIST_HEAD(&mdb->entry_dirty);
- hfs_init_waitqueue(&mdb->rename_wait);
- hfs_init_waitqueue(&mdb->bitmap_wait);
+ init_MUTEX(&mdb->bitmap_sem);
/* See if this is an HFS filesystem */
buf = hfs_buffer_get(sys_mdb, part_start + HFS_MDB_BLK, 1);
diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c
index 0049e5ee48fa..94b663656ac4 100644
--- a/fs/hpfs/buffer.c
+++ b/fs/hpfs/buffer.c
@@ -14,8 +14,7 @@ void hpfs_lock_creation(struct super_block *s)
#ifdef DEBUG_LOCKS
printk("lock creation\n");
#endif
- while (s->s_hpfs_creation_de_lock) sleep_on(&s->s_hpfs_creation_de);
- s->s_hpfs_creation_de_lock = 1;
+ down(&s->u.hpfs_sb.hpfs_creation_de);
}
void hpfs_unlock_creation(struct super_block *s)
@@ -23,8 +22,7 @@ void hpfs_unlock_creation(struct super_block *s)
#ifdef DEBUG_LOCKS
printk("unlock creation\n");
#endif
- s->s_hpfs_creation_de_lock = 0;
- wake_up(&s->s_hpfs_creation_de);
+ up(&s->u.hpfs_sb.hpfs_creation_de);
}
void hpfs_lock_iget(struct super_block *s, int mode)
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 2483e920b597..3d59f27c82b8 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -427,8 +427,8 @@ struct super_block *hpfs_read_super(struct super_block *s, void *options,
s->s_hpfs_bmp_dir = NULL;
s->s_hpfs_cp_table = NULL;
- s->s_hpfs_creation_de_lock = s->s_hpfs_rd_inode = 0;
- init_waitqueue_head(&s->s_hpfs_creation_de);
+ s->s_hpfs_rd_inode = 0;
+ init_MUTEX(&s->u.hpfs_sb.hpfs_creation_de);
init_waitqueue_head(&s->s_hpfs_iget_q);
uid = current->uid;
diff --git a/fs/namespace.c b/fs/namespace.c
index fdcc369fbe38..1419b179c74c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1048,15 +1048,9 @@ void __init mnt_init(unsigned long mempages)
if (!mnt_cache)
panic("Cannot create vfsmount cache");
- mempages >>= (16 - PAGE_SHIFT);
- mempages *= sizeof(struct list_head);
- for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
- ;
-
- do {
- mount_hashtable = (struct list_head *)
- __get_free_pages(GFP_ATOMIC, order);
- } while (mount_hashtable == NULL && --order >= 0);
+ order = 0;
+ mount_hashtable = (struct list_head *)
+ __get_free_pages(GFP_ATOMIC, order);
if (!mount_hashtable)
panic("Failed to allocate mount hash table\n");
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 1f70ec451ce7..bc7b38e5530c 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -18,6 +18,7 @@
#include <linux/locks.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/smp_lock.h>
#include <linux/ncp_fs.h>
#include "ncplib_kernel.h"
@@ -281,7 +282,7 @@ static int ncp_release(struct inode *inode, struct file *file) {
struct file_operations ncp_file_operations =
{
- llseek: generic_file_llseek,
+ llseek: remote_llseek,
read: ncp_file_read,
write: ncp_file_write,
ioctl: ncp_ioctl,
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 32e089bd5ec0..e4ed0426d766 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -365,7 +365,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
sock_inode = ncp_filp->f_dentry->d_inode;
if (!S_ISSOCK(sock_inode->i_mode))
goto out_bad_file2;
- sock = &sock_inode->u.socket_i;
+ sock = SOCKET_I(sock_inode);
if (!sock)
goto out_bad_file2;
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index 470ea5e96ae3..095498a2b5b8 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -101,7 +101,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
struct ncp_reply_header reply;
file = server->ncp_filp;
- sock = &file->f_dentry->d_inode->u.socket_i;
+ sock = SOCKET_I(file->f_dentry->d_inode);
init_timeout = server->m.time_out;
max_timeout = NCP_MAX_RPC_TIMEOUT;
@@ -269,7 +269,7 @@ static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
int result = 0;
file = server->ncp_filp;
- sock = &file->f_dentry->d_inode->u.socket_i;
+ sock = SOCKET_I(file->f_dentry->d_inode);
dataread = 0;
@@ -348,7 +348,7 @@ static int do_ncp_tcp_rpc_call(struct ncp_server *server, int size,
*((struct ncp_request_header *) (server->packet));
file = server->ncp_filp;
- sock = &file->f_dentry->d_inode->u.socket_i;
+ sock = SOCKET_I(file->f_dentry->d_inode);
ncptcp_xmit_hdr[0] = htonl(NCP_TCP_XMIT_MAGIC);
ncptcp_xmit_hdr[1] = htonl(size + 16);
@@ -444,7 +444,7 @@ static int ncp_do_request(struct ncp_server *server, int size,
}
#endif /* CONFIG_NCPFS_PACKET_SIGNING */
file = server->ncp_filp;
- sock = &file->f_dentry->d_inode->u.socket_i;
+ sock = SOCKET_I(file->f_dentry->d_inode);
/* N.B. this isn't needed ... check socket type? */
if (!sock) {
printk(KERN_ERR "ncp_rpc_call: socki_lookup failed\n");
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 1d5e7dbde28a..d25cb4968931 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -41,7 +41,7 @@ static int nfs_file_flush(struct file *);
static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
struct file_operations nfs_file_operations = {
- llseek: generic_file_llseek,
+ llseek: remote_llseek,
read: nfs_file_read,
write: nfs_file_write,
mmap: nfs_file_mmap,
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 261cadb58635..28d57bf19bad 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -245,8 +245,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh)
* and the root file handle obtained from the server's mount
* daemon. We stash these away in the private superblock fields.
*/
-struct super_block *
-nfs_read_super(struct super_block *sb, void *raw_data, int silent)
+int nfs_fill_super(struct super_block *sb, void *raw_data, int silent)
{
struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data;
struct nfs_server *server;
@@ -455,6 +454,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
server->namelen = maxlen;
sb->s_maxbytes = fsinfo.maxfilesize;
+ if (sb->s_maxbytes > MAX_LFS_FILESIZE)
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
/* Fire up the writeback cache */
if (nfs_reqlist_alloc(server) < 0) {
@@ -467,7 +468,7 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
/* Check whether to start the lockd process */
if (!(server->flags & NFS_MOUNT_NONLM))
lockd_up();
- return sb;
+ return 0;
/* Yargs. It didn't work out. */
failure_kill_reqlist:
@@ -506,7 +507,7 @@ out_miss_args:
printk("nfs_read_super: missing data argument\n");
out_fail:
- return NULL;
+ return -EINVAL;
}
static int
@@ -1137,7 +1138,25 @@ __nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
/*
* File system information
*/
-static DECLARE_FSTYPE(nfs_fs_type, "nfs", nfs_read_super, FS_ODD_RENAME);
+
+/*
+ * Right now we are using get_sb_nodev, but we ought to switch to
+ * get_anon_super() with appropriate comparison function. The only
+ * question being, when two NFS mounts are the same? Identical IP
+ * of server + identical root fhandle? Trond?
+ */
+static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_nodev(fs_type, flags, data, nfs_fill_super);
+}
+
+static struct file_system_type nfs_fs_type = {
+ owner: THIS_MODULE,
+ name: "nfs",
+ get_sb: nfs_get_sb,
+ fs_flags: FS_ODD_RENAME,
+};
extern int nfs_init_nfspagecache(void);
extern void nfs_destroy_nfspagecache(void);
diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c
index 4fa8e2f018e4..d28ea94084a9 100644
--- a/fs/ntfs/fs.c
+++ b/fs/ntfs/fs.c
@@ -1130,7 +1130,7 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options,
/* Inform the kernel about which super operations are available. */
sb->s_op = &ntfs_super_operations;
sb->s_magic = NTFS_SUPER_MAGIC;
- sb->s_maxbytes = ~0ULL >> 1;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
ntfs_debug(DEBUG_OTHER, "Reading special files\n");
if (ntfs_load_special_files(vol)) {
ntfs_error("Error loading special files\n");
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 61c8b2b73111..fb86cd505779 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -998,8 +998,7 @@ static struct super_operations openprom_sops = {
statfs: openprom_statfs,
};
-struct super_block *openprom_read_super(struct super_block *s,void *data,
- int silent)
+static int openprom_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * root_inode;
@@ -1013,15 +1012,25 @@ struct super_block *openprom_read_super(struct super_block *s,void *data,
s->s_root = d_alloc_root(root_inode);
if (!s->s_root)
goto out_no_root;
- return s;
+ return 0;
out_no_root:
- printk("openprom_read_super: get root inode failed\n");
+ printk("openprom_fill_super: get root inode failed\n");
iput(root_inode);
- return NULL;
+ return -ENOMEM;
+}
+
+static struct super_block *openprom_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_single(fs_type, flags, data, openprom_fill_super);
}
-static DECLARE_FSTYPE(openprom_fs_type, "openpromfs", openprom_read_super, 0);
+static struct file_system_type openprom_fs_type = {
+ owner: THIS_MODULE,
+ name: "openpromfs",
+ get_sb: openprom_get_sb,
+};
static int __init init_openprom_fs(void)
{
diff --git a/fs/pipe.c b/fs/pipe.c
index 5910c168288f..90734730ca62 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -246,12 +246,6 @@ sigpipe:
return -EPIPE;
}
-static loff_t
-pipe_lseek(struct file *file, loff_t offset, int orig)
-{
- return -ESPIPE;
-}
-
static ssize_t
bad_pipe_r(struct file *filp, char *buf, size_t count, loff_t *ppos)
{
@@ -381,7 +375,7 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
* are also used in linux/fs/fifo.c to do operations on FIFOs.
*/
struct file_operations read_fifo_fops = {
- llseek: pipe_lseek,
+ llseek: no_llseek,
read: pipe_read,
write: bad_pipe_w,
poll: fifo_poll,
@@ -391,7 +385,7 @@ struct file_operations read_fifo_fops = {
};
struct file_operations write_fifo_fops = {
- llseek: pipe_lseek,
+ llseek: no_llseek,
read: bad_pipe_r,
write: pipe_write,
poll: fifo_poll,
@@ -401,7 +395,7 @@ struct file_operations write_fifo_fops = {
};
struct file_operations rdwr_fifo_fops = {
- llseek: pipe_lseek,
+ llseek: no_llseek,
read: pipe_read,
write: pipe_write,
poll: fifo_poll,
@@ -411,7 +405,7 @@ struct file_operations rdwr_fifo_fops = {
};
struct file_operations read_pipe_fops = {
- llseek: pipe_lseek,
+ llseek: no_llseek,
read: pipe_read,
write: bad_pipe_w,
poll: pipe_poll,
@@ -421,7 +415,7 @@ struct file_operations read_pipe_fops = {
};
struct file_operations write_pipe_fops = {
- llseek: pipe_lseek,
+ llseek: no_llseek,
read: bad_pipe_r,
write: pipe_write,
poll: pipe_poll,
@@ -431,7 +425,7 @@ struct file_operations write_pipe_fops = {
};
struct file_operations rdwr_pipe_fops = {
- llseek: pipe_lseek,
+ llseek: no_llseek,
read: pipe_read,
write: pipe_write,
poll: pipe_poll,
@@ -606,7 +600,7 @@ static struct super_operations pipefs_ops = {
statfs: pipefs_statfs,
};
-static struct super_block * pipefs_read_super(struct super_block *sb, void *data, int silent)
+static int pipefs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *root;
@@ -616,22 +610,32 @@ static struct super_block * pipefs_read_super(struct super_block *sb, void *data
sb->s_op = &pipefs_ops;
root = new_inode(sb);
if (!root)
- return NULL;
+ return -ENOMEM;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
sb->s_root = d_alloc(NULL, &(const struct qstr) { "pipe:", 5, 0 });
if (!sb->s_root) {
iput(root);
- return NULL;
+ return -ENOMEM;
}
sb->s_root->d_sb = sb;
sb->s_root->d_parent = sb->s_root;
d_instantiate(sb->s_root, root);
- return sb;
+ return 0;
}
-static DECLARE_FSTYPE(pipe_fs_type, "pipefs", pipefs_read_super, FS_NOMOUNT);
+static struct super_block *pipefs_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_nodev(fs_type, flags, data, pipefs_fill_super);
+}
+
+static struct file_system_type pipe_fs_type = {
+ name: "pipefs",
+ get_sb: pipefs_get_sb,
+ fs_flags: FS_NOMOUNT,
+};
static int __init init_pipe_fs(void)
{
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ed0da13a0e91..e472c395cccd 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -37,6 +37,11 @@
#define fake_ino(pid,ino) (((pid)<<16)|(ino))
+static inline struct task_struct *proc_task(struct inode *inode)
+{
+ return PROC_I(inode)->task;
+}
+
ssize_t proc_pid_read_maps(struct task_struct*,struct file*,char*,size_t,loff_t*);
int proc_pid_stat(struct task_struct*,char*);
int proc_pid_status(struct task_struct*,char*);
@@ -45,9 +50,10 @@ int proc_pid_cpu(struct task_struct*,char*);
static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
{
- if (inode->u.proc_i.file) {
- *mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
- *dentry = dget(inode->u.proc_i.file->f_dentry);
+ struct file *file = PROC_I(inode)->file;
+ if (file) {
+ *mnt = mntget(file->f_vfsmnt);
+ *dentry = dget(file->f_dentry);
return 0;
}
return -ENOENT;
@@ -58,7 +64,7 @@ static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfs
struct mm_struct * mm;
struct vm_area_struct * vma;
int result = -ENOENT;
- struct task_struct *task = inode->u.proc_i.task;
+ struct task_struct *task = proc_task(inode);
task_lock(task);
mm = task->mm;
@@ -89,11 +95,11 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
{
struct fs_struct *fs;
int result = -ENOENT;
- task_lock(inode->u.proc_i.task);
- fs = inode->u.proc_i.task->fs;
+ task_lock(proc_task(inode));
+ fs = proc_task(inode)->fs;
if(fs)
atomic_inc(&fs->count);
- task_unlock(inode->u.proc_i.task);
+ task_unlock(proc_task(inode));
if (fs) {
read_lock(&fs->lock);
*mnt = mntget(fs->pwdmnt);
@@ -109,11 +115,11 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
{
struct fs_struct *fs;
int result = -ENOENT;
- task_lock(inode->u.proc_i.task);
- fs = inode->u.proc_i.task->fs;
+ task_lock(proc_task(inode));
+ fs = proc_task(inode)->fs;
if(fs)
atomic_inc(&fs->count);
- task_unlock(inode->u.proc_i.task);
+ task_unlock(proc_task(inode));
if (fs) {
read_lock(&fs->lock);
*mnt = mntget(fs->rootmnt);
@@ -238,7 +244,7 @@ static ssize_t pid_maps_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
struct inode * inode = file->f_dentry->d_inode;
- struct task_struct *task = inode->u.proc_i.task;
+ struct task_struct *task = proc_task(inode);
ssize_t res;
res = proc_pid_read_maps(task, file, buf, count, ppos);
@@ -252,7 +258,7 @@ static struct file_operations proc_maps_operations = {
extern struct seq_operations mounts_op;
static int mounts_open(struct inode *inode, struct file *file)
{
- struct task_struct *task = inode->u.proc_i.task;
+ struct task_struct *task = proc_task(inode);
int ret = seq_open(file, &mounts_op);
if (!ret) {
@@ -298,14 +304,14 @@ static ssize_t proc_info_read(struct file * file, char * buf,
unsigned long page;
ssize_t length;
ssize_t end;
- struct task_struct *task = inode->u.proc_i.task;
+ struct task_struct *task = proc_task(inode);
if (count > PROC_BLOCK_SIZE)
count = PROC_BLOCK_SIZE;
if (!(page = __get_free_page(GFP_KERNEL)))
return -ENOMEM;
- length = inode->u.proc_i.op.proc_read(task, (char*)page);
+ length = PROC_I(inode)->op.proc_read(task, (char*)page);
if (length < 0) {
free_page(page);
@@ -342,7 +348,7 @@ static int mem_open(struct inode* inode, struct file* file)
static ssize_t mem_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
- struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
+ struct task_struct *task = proc_task(file->f_dentry->d_inode);
char *page;
unsigned long src = *ppos;
int copied = 0;
@@ -404,7 +410,7 @@ static ssize_t mem_write(struct file * file, const char * buf,
{
int copied = 0;
char *page;
- struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
+ struct task_struct *task = proc_task(file->f_dentry->d_inode);
unsigned long dst = *ppos;
if (!MAY_PTRACE(task))
@@ -463,7 +469,7 @@ static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
if (error)
goto out;
- error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
+ error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
nd->last_type = LAST_BIND;
out:
return error;
@@ -503,7 +509,7 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
if (error)
goto out;
- error = inode->u.proc_i.op.proc_get_link(inode, &de, &mnt);
+ error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
if (error)
goto out;
@@ -570,7 +576,7 @@ static struct pid_entry base_stuff[] = {
static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
{
struct inode *inode = filp->f_dentry->d_inode;
- struct task_struct *p = inode->u.proc_i.task;
+ struct task_struct *p = proc_task(inode);
unsigned int fd, pid, ino;
int retval;
char buf[NUMBUF];
@@ -598,6 +604,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
task_unlock(p);
if (!files)
goto out;
+ read_lock(&files->file_lock);
for (fd = filp->f_pos-2;
fd < files->max_fds;
fd++, filp->f_pos++) {
@@ -605,6 +612,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
if (!fcheck_files(files, fd))
continue;
+ read_unlock(&files->file_lock);
j = NUMBUF;
i = fd;
@@ -617,7 +625,9 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
ino = fake_ino(pid, PROC_PID_FD_DIR + fd);
if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0)
break;
+ read_lock(&files->file_lock);
}
+ read_unlock(&files->file_lock);
put_files_struct(files);
}
out:
@@ -632,7 +642,7 @@ static int proc_base_readdir(struct file * filp,
struct inode *inode = filp->f_dentry->d_inode;
struct pid_entry *p;
- pid = inode->u.proc_i.task->pid;
+ pid = proc_task(inode)->pid;
if (!pid)
return -ENOENT;
i = filp->f_pos;
@@ -684,6 +694,7 @@ static int task_dumpable(struct task_struct *task)
static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
{
struct inode * inode;
+ struct proc_inode *ei;
/* We need a new inode */
@@ -692,7 +703,9 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
goto out;
/* Common stuff */
-
+ ei = PROC_I(inode);
+ ei->task = NULL;
+ ei->file = NULL;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(task->pid, ino);
@@ -703,7 +716,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
* grab the reference to task.
*/
get_task_struct(task);
- inode->u.proc_i.task = task;
+ ei->task = task;
inode->i_uid = 0;
inode->i_gid = 0;
if (ino == PROC_PID_INO || task_dumpable(task)) {
@@ -733,7 +746,7 @@ static int pid_fd_revalidate(struct dentry * dentry, int flags)
*/
static int pid_base_revalidate(struct dentry * dentry, int flags)
{
- if (dentry->d_inode->u.proc_i.task->pid)
+ if (proc_task(dentry->d_inode)->pid)
return 1;
d_drop(dentry);
return 0;
@@ -767,10 +780,11 @@ static struct dentry_operations pid_base_dentry_operations =
static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
{
unsigned int fd, c;
- struct task_struct *task = dir->u.proc_i.task;
+ struct task_struct *task = proc_task(dir);
struct file * file;
struct files_struct * files;
struct inode *inode;
+ struct proc_inode *ei;
const char *name;
int len;
@@ -792,6 +806,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
if (!inode)
goto out;
+ ei = PROC_I(inode);
task_lock(task);
files = task->files;
if (files)
@@ -800,7 +815,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
if (!files)
goto out_unlock;
read_lock(&files->file_lock);
- file = inode->u.proc_i.file = fcheck_files(files, fd);
+ file = ei->file = fcheck_files(files, fd);
if (!file)
goto out_unlock2;
get_file(file);
@@ -809,7 +824,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
inode->i_mode = S_IFLNK;
- inode->u.proc_i.op.proc_get_link = proc_fd_link;
+ ei->op.proc_get_link = proc_fd_link;
if (file->f_mode & 1)
inode->i_mode |= S_IRUSR | S_IXUSR;
if (file->f_mode & 2)
@@ -844,8 +859,9 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
{
struct inode *inode;
int error;
- struct task_struct *task = dir->u.proc_i.task;
+ struct task_struct *task = proc_task(dir);
struct pid_entry *p;
+ struct proc_inode *ei;
error = -ENOENT;
inode = NULL;
@@ -864,6 +880,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
if (!inode)
goto out;
+ ei = PROC_I(inode);
inode->i_mode = p->mode;
/*
* Yes, it does not scale. And it should not. Don't add
@@ -877,35 +894,35 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
break;
case PROC_PID_EXE:
inode->i_op = &proc_pid_link_inode_operations;
- inode->u.proc_i.op.proc_get_link = proc_exe_link;
+ ei->op.proc_get_link = proc_exe_link;
break;
case PROC_PID_CWD:
inode->i_op = &proc_pid_link_inode_operations;
- inode->u.proc_i.op.proc_get_link = proc_cwd_link;
+ ei->op.proc_get_link = proc_cwd_link;
break;
case PROC_PID_ROOT:
inode->i_op = &proc_pid_link_inode_operations;
- inode->u.proc_i.op.proc_get_link = proc_root_link;
+ ei->op.proc_get_link = proc_root_link;
break;
case PROC_PID_ENVIRON:
inode->i_fop = &proc_info_file_operations;
- inode->u.proc_i.op.proc_read = proc_pid_environ;
+ ei->op.proc_read = proc_pid_environ;
break;
case PROC_PID_STATUS:
inode->i_fop = &proc_info_file_operations;
- inode->u.proc_i.op.proc_read = proc_pid_status;
+ ei->op.proc_read = proc_pid_status;
break;
case PROC_PID_STAT:
inode->i_fop = &proc_info_file_operations;
- inode->u.proc_i.op.proc_read = proc_pid_stat;
+ ei->op.proc_read = proc_pid_stat;
break;
case PROC_PID_CMDLINE:
inode->i_fop = &proc_info_file_operations;
- inode->u.proc_i.op.proc_read = proc_pid_cmdline;
+ ei->op.proc_read = proc_pid_cmdline;
break;
case PROC_PID_STATM:
inode->i_fop = &proc_info_file_operations;
- inode->u.proc_i.op.proc_read = proc_pid_statm;
+ ei->op.proc_read = proc_pid_statm;
break;
case PROC_PID_MAPS:
inode->i_fop = &proc_maps_operations;
@@ -913,7 +930,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
#ifdef CONFIG_SMP
case PROC_PID_CPU:
inode->i_fop = &proc_info_file_operations;
- inode->u.proc_i.op.proc_read = proc_pid_cpu;
+ ei->op.proc_read = proc_pid_cpu;
break;
#endif
case PROC_PID_MEM:
@@ -973,6 +990,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
struct task_struct *task;
const char *name;
struct inode *inode;
+ struct proc_inode *ei;
int len;
pid = 0;
@@ -982,10 +1000,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
inode = new_inode(dir->i_sb);
if (!inode)
return ERR_PTR(-ENOMEM);
+ ei = PROC_I(inode);
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(0, PROC_PID_INO);
- inode->u.proc_i.file = NULL;
- inode->u.proc_i.task = NULL;
+ ei->file = NULL;
+ ei->task = NULL;
inode->i_mode = S_IFLNK|S_IRWXUGO;
inode->i_uid = inode->i_gid = 0;
inode->i_size = 64;
@@ -1035,10 +1054,10 @@ out:
void proc_pid_delete_inode(struct inode *inode)
{
- if (inode->u.proc_i.file)
- fput(inode->u.proc_i.file);
- if (inode->u.proc_i.task)
- free_task_struct(inode->u.proc_i.task);
+ if (PROC_I(inode)->file)
+ fput(PROC_I(inode)->file);
+ if (proc_task(inode))
+ free_task_struct(proc_task(inode));
}
#define PROC_NUMBUF 10
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 3e31f65e266b..f50b13026f27 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -58,7 +58,7 @@ proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
char *start;
struct proc_dir_entry * dp;
- dp = (struct proc_dir_entry *) inode->u.generic_ip;
+ dp = PDE(inode);
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
@@ -128,7 +128,7 @@ proc_file_write(struct file * file, const char * buffer,
struct inode *inode = file->f_dentry->d_inode;
struct proc_dir_entry * dp;
- dp = (struct proc_dir_entry *) inode->u.generic_ip;
+ dp = PDE(inode);
if (!dp->write_proc)
return -EIO;
@@ -221,13 +221,13 @@ out:
static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
{
- char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
+ char *s=PDE(dentry->d_inode)->data;
return vfs_readlink(dentry, buffer, buflen, s);
}
static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
+ char *s=PDE(dentry->d_inode)->data;
return vfs_follow_link(nd, s);
}
@@ -264,7 +264,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
error = -ENOENT;
inode = NULL;
- de = (struct proc_dir_entry *) dir->u.generic_ip;
+ de = PDE(dir);
if (de) {
for (de = de->subdir; de ; de = de->next) {
if (!de || !de->low_ino)
@@ -306,7 +306,7 @@ int proc_readdir(struct file * filp,
struct inode *inode = filp->f_dentry->d_inode;
ino = inode->i_ino;
- de = (struct proc_dir_entry *) inode->u.generic_ip;
+ de = PDE(inode);
if (!de)
return -EINVAL;
i = filp->f_pos;
@@ -413,7 +413,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
if (dentry->d_op != &proc_dentry_operations)
continue;
inode = dentry->d_inode;
- if (inode->u.generic_ip != de)
+ if (PDE(inode) != de)
continue;
fops = filp->f_op;
filp->f_op = NULL;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 8af8a6868e92..c96bde47f090 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -58,7 +58,7 @@ void de_put(struct proc_dir_entry *de)
*/
static void proc_delete_inode(struct inode *inode)
{
- struct proc_dir_entry *de = inode->u.generic_ip;
+ struct proc_dir_entry *de = PDE(inode);
inode->i_state = I_CLEAR;
@@ -91,14 +91,51 @@ static int proc_statfs(struct super_block *sb, struct statfs *buf)
return 0;
}
+static kmem_cache_t * proc_inode_cachep;
+
+static struct inode *proc_alloc_inode(struct super_block *sb)
+{
+ struct proc_inode *ei;
+ ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, SLAB_KERNEL);
+ if (!ei)
+ return NULL;
+ return &ei->vfs_inode;
+}
+
+static void proc_destroy_inode(struct inode *inode)
+{
+ kmem_cache_free(proc_inode_cachep, PROC_I(inode));
+}
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+ struct proc_inode *ei = (struct proc_inode *) foo;
+
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR)
+ inode_init_once(&ei->vfs_inode);
+}
+
+int __init proc_init_inodecache(void)
+{
+ proc_inode_cachep = kmem_cache_create("proc_inode_cache",
+ sizeof(struct proc_inode),
+ 0, SLAB_HWCACHE_ALIGN,
+ init_once, NULL);
+ if (proc_inode_cachep == NULL)
+ return -ENOMEM;
+ return 0;
+}
+
static struct super_operations proc_sops = {
+ alloc_inode: proc_alloc_inode,
+ destroy_inode: proc_destroy_inode,
read_inode: proc_read_inode,
put_inode: force_delete,
delete_inode: proc_delete_inode,
statfs: proc_statfs,
};
-
static int parse_options(char *options,uid_t *uid,gid_t *gid)
{
char *this_char,*value;
@@ -147,7 +184,7 @@ printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&d
if (!inode)
goto out_fail;
- inode->u.generic_ip = (void *) de;
+ PROC_I(inode)->pde = de;
if (de) {
if (de->mode) {
inode->i_mode = de->mode;
@@ -176,8 +213,7 @@ out_fail:
goto out;
}
-struct super_block *proc_read_super(struct super_block *s,void *data,
- int silent)
+int proc_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * root_inode;
struct task_struct *p;
@@ -200,11 +236,11 @@ struct super_block *proc_read_super(struct super_block *s,void *data,
if (!s->s_root)
goto out_no_root;
parse_options(data, &root_inode->i_uid, &root_inode->i_gid);
- return s;
+ return 0;
out_no_root:
printk("proc_read_super: get root inode failed\n");
iput(root_inode);
- return NULL;
+ return -ENOMEM;
}
MODULE_LICENSE("GPL");
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 3db40a53bc0f..666166bfcf57 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -23,11 +23,24 @@ struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver;
struct proc_dir_entry *proc_sys_root;
#endif
-static DECLARE_FSTYPE(proc_fs_type, "proc", proc_read_super, FS_SINGLE);
+static struct super_block *proc_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_single(fs_type, flags, data, proc_fill_super);
+}
+
+static struct file_system_type proc_fs_type = {
+ name: "proc",
+ get_sb: proc_get_sb,
+};
+extern int __init proc_init_inodecache(void);
void __init proc_root_init(void)
{
- int err = register_filesystem(&proc_fs_type);
+ int err = proc_init_inodecache();
+ if (err)
+ return;
+ err = register_filesystem(&proc_fs_type);
if (err)
return;
proc_mnt = kern_mount(&proc_fs_type);
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index b8994583f13a..3bed425ec3b8 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -302,7 +302,7 @@ static struct super_operations ramfs_ops = {
put_inode: force_delete,
};
-static struct super_block *ramfs_read_super(struct super_block * sb, void * data, int silent)
+static int ramfs_fill_super(struct super_block * sb, void * data, int silent)
{
struct inode * inode;
struct dentry * root;
@@ -313,19 +313,33 @@ static struct super_block *ramfs_read_super(struct super_block * sb, void * data
sb->s_op = &ramfs_ops;
inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);
if (!inode)
- return NULL;
+ return -ENOMEM;
root = d_alloc_root(inode);
if (!root) {
iput(inode);
- return NULL;
+ return -ENOMEM;
}
sb->s_root = root;
- return sb;
+ return 0;
+}
+
+static struct super_block *ramfs_get_sb(struct file_system_type *fs_type,
+ int flags, char *dev_name, void *data)
+{
+ return get_sb_nodev(fs_type, flags, data, ramfs_fill_super);
}
-static DECLARE_FSTYPE(ramfs_fs_type, "ramfs", ramfs_read_super, FS_LITTER);
-static DECLARE_FSTYPE(rootfs_fs_type, "rootfs", ramfs_read_super, FS_NOMOUNT|FS_LITTER);
+static struct file_system_type ramfs_fs_type = {
+ name: "ramfs",
+ get_sb: ramfs_get_sb,
+ fs_flags: FS_LITTER,
+};
+static struct file_system_type rootfs_fs_type = {
+ name: "rootfs",
+ get_sb: ramfs_get_sb,
+ fs_flags: FS_NOMOUNT|FS_LITTER,
+};
static int __init init_ramfs_fs(void)
{
diff --git a/fs/read_write.c b/fs/read_write.c
index 31cee2a6aa4e..ce5230669579 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -51,6 +51,31 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
return retval;
}
+loff_t remote_llseek(struct file *file, loff_t offset, int origin)
+{
+ long long retval;
+
+ lock_kernel();
+ switch (origin) {
+ case 2:
+ offset += file->f_dentry->d_inode->i_size;
+ break;
+ case 1:
+ offset += file->f_pos;
+ }
+ retval = -EINVAL;
+ if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ file->f_reada = 0;
+ file->f_version = ++event;
+ }
+ retval = offset;
+ }
+ unlock_kernel();
+ return retval;
+}
+
loff_t no_llseek(struct file *file, loff_t offset, int origin)
{
return -ESPIPE;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 4fe8843c5899..c35cb51a9a48 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -890,6 +890,13 @@ static void init_inode (struct inode * inode, struct path * path)
inode->i_blksize = PAGE_SIZE;
INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list ));
+ REISERFS_I(inode)->i_flags = 0;
+ REISERFS_I(inode)->i_prealloc_block = 0;
+ REISERFS_I(inode)->i_prealloc_count = 0;
+ REISERFS_I(inode)->i_trans_id = 0;
+ REISERFS_I(inode)->i_trans_index = 0;
+ /* nopack = 0, by default */
+ REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
if (stat_data_v1 (ih)) {
struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
@@ -950,13 +957,6 @@ static void init_inode (struct inode * inode, struct path * path)
set_inode_item_key_version (inode, KEY_FORMAT_3_6);
REISERFS_I(inode)->i_first_direct_byte = 0;
}
- REISERFS_I(inode)->i_flags = 0;
- REISERFS_I(inode)->i_prealloc_block = 0;
- REISERFS_I(inode)->i_prealloc_count = 0;
- REISERFS_I(inode)->i_trans_id = 0;
- REISERFS_I(inode)->i_trans_index = 0;
- /* nopack = 0, by default */
- REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
pathrelse (path);
if (S_ISREG (inode->i_mode)) {
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index b3feaa56924a..39badd71692f 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -381,7 +381,7 @@ smb_file_permission(struct inode *inode, int mask)
struct file_operations smb_file_operations =
{
- llseek: generic_file_llseek,
+ llseek: remote_llseek,
read: smb_file_read,
write: smb_file_write,
ioctl: smb_ioctl,
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c
index 46313b623c7b..8c66f4c5e655 100644
--- a/fs/smbfs/sock.c
+++ b/fs/smbfs/sock.c
@@ -176,7 +176,7 @@ int
smb_valid_socket(struct inode * inode)
{
return (inode && S_ISSOCK(inode->i_mode) &&
- inode->u.socket_i.type == SOCK_STREAM);
+ SOCKET_I(inode)->type == SOCK_STREAM);
}
static struct socket *
@@ -190,7 +190,7 @@ server_sock(struct smb_sb_info *server)
if (!smb_valid_socket(file->f_dentry->d_inode))
PARANOIA("bad socket!\n");
#endif
- return &file->f_dentry->d_inode->u.socket_i;
+ return SOCKET_I(file->f_dentry->d_inode);
}
return NULL;
}
diff --git a/fs/stat.c b/fs/stat.c
index d7ed42c77f59..20bd373580c5 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -25,68 +25,28 @@ do_revalidate(struct dentry *dentry)
return 0;
}
-
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
-
-/*
- * For backward compatibility? Maybe this should be moved
- * into arch/i386 instead?
- */
-static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
+static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
- static int warncount = 5;
- struct __old_kernel_stat tmp;
-
- if (warncount > 0) {
- warncount--;
- printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
- current->comm);
- } else if (warncount < 0) {
- /* it's laughable, but... */
- warncount = 0;
- }
-
- tmp.st_dev = kdev_t_to_nr(inode->i_dev);
- tmp.st_ino = inode->i_ino;
- tmp.st_mode = inode->i_mode;
- tmp.st_nlink = inode->i_nlink;
- SET_OLDSTAT_UID(tmp, inode->i_uid);
- SET_OLDSTAT_GID(tmp, inode->i_gid);
- tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-#if BITS_PER_LONG == 32
- if (inode->i_size > MAX_NON_LFS)
- return -EOVERFLOW;
-#endif
- tmp.st_size = inode->i_size;
- tmp.st_atime = inode->i_atime;
- tmp.st_mtime = inode->i_mtime;
- tmp.st_ctime = inode->i_ctime;
- return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
-}
-
-#endif
-
-static int cp_new_stat(struct inode * inode, struct stat * statbuf)
-{
- struct stat tmp;
+ int res = 0;
unsigned int blocks, indirect;
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.st_dev = kdev_t_to_nr(inode->i_dev);
- tmp.st_ino = inode->i_ino;
- tmp.st_mode = inode->i_mode;
- tmp.st_nlink = inode->i_nlink;
- SET_STAT_UID(tmp, inode->i_uid);
- SET_STAT_GID(tmp, inode->i_gid);
- tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-#if BITS_PER_LONG == 32
- if (inode->i_size > MAX_NON_LFS)
- return -EOVERFLOW;
-#endif
- tmp.st_size = inode->i_size;
- tmp.st_atime = inode->i_atime;
- tmp.st_mtime = inode->i_mtime;
- tmp.st_ctime = inode->i_ctime;
+ struct inode *inode = dentry->d_inode;
+
+ res = do_revalidate(dentry);
+ if (res)
+ return res;
+
+ stat->dev = kdev_t_to_nr(inode->i_dev);
+ stat->ino = inode->i_ino;
+ stat->mode = inode->i_mode;
+ stat->nlink = inode->i_nlink;
+ stat->uid = inode->i_uid;
+ stat->gid = inode->i_gid;
+ stat->rdev = kdev_t_to_nr(inode->i_rdev);
+ stat->atime = inode->i_atime;
+ stat->mtime = inode->i_mtime;
+ stat->ctime = inode->i_ctime;
+ stat->ctime = inode->i_ctime;
+ stat->size = inode->i_size;
/*
* st_blocks and st_blksize are approximated with a simple algorithm if
* they aren't supported directly by the filesystem. The minix and msdos
@@ -106,7 +66,7 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf)
#define I_B (BLOCK_SIZE / sizeof(unsigned short))
if (!inode->i_blksize) {
- blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ blocks = (stat->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
if (blocks > D_B) {
indirect = (blocks - D_B + I_B - 1) / I_B;
blocks += indirect;
@@ -117,130 +77,178 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf)
blocks++;
}
}
- tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
- tmp.st_blksize = BLOCK_SIZE;
+ stat->blocks = (BLOCK_SIZE / 512) * blocks;
+ stat->blksize = BLOCK_SIZE;
} else {
- tmp.st_blocks = inode->i_blocks;
- tmp.st_blksize = inode->i_blksize;
+ stat->blocks = inode->i_blocks;
+ stat->blksize = inode->i_blksize;
}
- return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+ return 0;
}
-
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
-/*
- * For backward compatibility? Maybe this should be moved
- * into arch/i386 instead?
- */
-asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
+int vfs_stat(char *name, struct kstat *stat)
{
struct nameidata nd;
int error;
- error = user_path_walk(filename, &nd);
+ error = user_path_walk(name, &nd);
if (!error) {
- error = do_revalidate(nd.dentry);
- if (!error)
- error = cp_old_stat(nd.dentry->d_inode, statbuf);
+ error = do_getattr(nd.mnt, nd.dentry, stat);
path_release(&nd);
}
return error;
}
-#endif
-asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
+int vfs_lstat(char *name, struct kstat *stat)
{
struct nameidata nd;
int error;
- error = user_path_walk(filename, &nd);
+ error = user_path_walk_link(name, &nd);
if (!error) {
- error = do_revalidate(nd.dentry);
- if (!error)
- error = cp_new_stat(nd.dentry->d_inode, statbuf);
+ error = do_getattr(nd.mnt, nd.dentry, stat);
path_release(&nd);
}
return error;
}
+int vfs_fstat(unsigned int fd, struct kstat *stat)
+{
+ struct file *f = fget(fd);
+ int error = -EBADF;
+
+ if (f) {
+ error = do_getattr(f->f_vfsmnt, f->f_dentry, stat);
+ fput(f);
+ }
+ return error;
+}
+
#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
/*
* For backward compatibility? Maybe this should be moved
* into arch/i386 instead?
*/
-asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
+static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat * statbuf)
{
- struct nameidata nd;
- int error;
+ static int warncount = 5;
+ struct __old_kernel_stat tmp;
- error = user_path_walk_link(filename, &nd);
- if (!error) {
- error = do_revalidate(nd.dentry);
- if (!error)
- error = cp_old_stat(nd.dentry->d_inode, statbuf);
- path_release(&nd);
+ if (warncount > 0) {
+ warncount--;
+ printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
+ current->comm);
+ } else if (warncount < 0) {
+ /* it's laughable, but... */
+ warncount = 0;
}
- return error;
-}
-#endif
+ tmp.st_dev = stat->dev;
+ tmp.st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ SET_OLDSTAT_UID(tmp, stat->uid);
+ SET_OLDSTAT_GID(tmp, stat->gid);
+ tmp.st_rdev = stat->rdev;
+#if BITS_PER_LONG == 32
+ if (stat->size > MAX_NON_LFS)
+ return -EOVERFLOW;
+#endif
+ tmp.st_size = stat->size;
+ tmp.st_atime = stat->atime;
+ tmp.st_mtime = stat->mtime;
+ tmp.st_ctime = stat->ctime;
+ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
-asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
+asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
{
- struct nameidata nd;
- int error;
+ struct kstat stat;
+ int error = vfs_stat(filename, &stat);
+
+ if (!error)
+ error = cp_old_stat(&stat, statbuf);
- error = user_path_walk_link(filename, &nd);
- if (!error) {
- error = do_revalidate(nd.dentry);
- if (!error)
- error = cp_new_stat(nd.dentry->d_inode, statbuf);
- path_release(&nd);
- }
return error;
}
+asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_lstat(filename, &stat);
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
+ if (!error)
+ error = cp_old_stat(&stat, statbuf);
-/*
- * For backward compatibility? Maybe this should be moved
- * into arch/i386 instead?
- */
+ return error;
+}
asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat * statbuf)
{
- struct file * f;
- int err = -EBADF;
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
- f = fget(fd);
- if (f) {
- struct dentry * dentry = f->f_dentry;
+ if (!error)
+ error = cp_old_stat(&stat, statbuf);
- err = do_revalidate(dentry);
- if (!err)
- err = cp_old_stat(dentry->d_inode, statbuf);
- fput(f);
- }
- return err;
+ return error;
}
#endif
+static int cp_new_stat(struct kstat *stat, struct stat *statbuf)
+{
+ struct stat tmp;
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.st_dev = stat->dev;
+ tmp.st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ SET_STAT_UID(tmp, stat->uid);
+ SET_STAT_GID(tmp, stat->gid);
+ tmp.st_rdev = stat->rdev;
+#if BITS_PER_LONG == 32
+ if (stat->size > MAX_NON_LFS)
+ return -EOVERFLOW;
+#endif
+ tmp.st_size = stat->size;
+ tmp.st_atime = stat->atime;
+ tmp.st_mtime = stat->mtime;
+ tmp.st_ctime = stat->ctime;
+ tmp.st_blocks = stat->blocks;
+ tmp.st_blksize = stat->blksize;
+ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_stat(filename, &stat);
+
+ if (!error)
+ error = cp_new_stat(&stat, statbuf);
+
+ return error;
+}
+asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_lstat(filename, &stat);
+
+ if (!error)
+ error = cp_new_stat(&stat, statbuf);
+
+ return error;
+}
asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf)
{
- struct file * f;
- int err = -EBADF;
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
- f = fget(fd);
- if (f) {
- struct dentry * dentry = f->f_dentry;
+ if (!error)
+ error = cp_new_stat(&stat, statbuf);
- err = do_revalidate(dentry);
- if (!err)
- err = cp_new_stat(dentry->d_inode, statbuf);
- fput(f);
- }
- return err;
+ return error;
}
asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz)
@@ -270,110 +278,59 @@ asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz)
/* ---------- LFS-64 ----------- */
#if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips64) && !defined(__x86_64__) && !defined(CONFIG_ARCH_S390X)
-static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf)
+static long cp_new_stat64(struct kstat *stat, struct stat64 *statbuf)
{
struct stat64 tmp;
- unsigned int blocks, indirect;
memset(&tmp, 0, sizeof(tmp));
- tmp.st_dev = kdev_t_to_nr(inode->i_dev);
- tmp.st_ino = inode->i_ino;
+ tmp.st_dev = stat->dev;
+ tmp.st_ino = stat->ino;
#ifdef STAT64_HAS_BROKEN_ST_INO
- tmp.__st_ino = inode->i_ino;
+ tmp.__st_ino = stat->ino;
#endif
- tmp.st_mode = inode->i_mode;
- tmp.st_nlink = inode->i_nlink;
- tmp.st_uid = inode->i_uid;
- tmp.st_gid = inode->i_gid;
- tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
- tmp.st_atime = inode->i_atime;
- tmp.st_mtime = inode->i_mtime;
- tmp.st_ctime = inode->i_ctime;
- tmp.st_size = inode->i_size;
-/*
- * st_blocks and st_blksize are approximated with a simple algorithm if
- * they aren't supported directly by the filesystem. The minix and msdos
- * filesystems don't keep track of blocks, so they would either have to
- * be counted explicitly (by delving into the file itself), or by using
- * this simple algorithm to get a reasonable (although not 100% accurate)
- * value.
- */
-
-/*
- * Use minix fs values for the number of direct and indirect blocks. The
- * count is now exact for the minix fs except that it counts zero blocks.
- * Everything is in units of BLOCK_SIZE until the assignment to
- * tmp.st_blksize.
- */
-#define D_B 7
-#define I_B (BLOCK_SIZE / sizeof(unsigned short))
-
- if (!inode->i_blksize) {
- blocks = (tmp.st_size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
- if (blocks > D_B) {
- indirect = (blocks - D_B + I_B - 1) / I_B;
- blocks += indirect;
- if (indirect > 1) {
- indirect = (indirect - 1 + I_B - 1) / I_B;
- blocks += indirect;
- if (indirect > 1)
- blocks++;
- }
- }
- tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
- tmp.st_blksize = BLOCK_SIZE;
- } else {
- tmp.st_blocks = inode->i_blocks;
- tmp.st_blksize = inode->i_blksize;
- }
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ tmp.st_uid = stat->uid;
+ tmp.st_gid = stat->gid;
+ tmp.st_rdev = stat->rdev;
+ tmp.st_atime = stat->atime;
+ tmp.st_mtime = stat->mtime;
+ tmp.st_ctime = stat->ctime;
+ tmp.st_size = stat->size;
+ tmp.st_blocks = stat->blocks;
+ tmp.st_blksize = stat->blksize;
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
asmlinkage long sys_stat64(char * filename, struct stat64 * statbuf, long flags)
{
- struct nameidata nd;
- int error;
+ struct kstat stat;
+ int error = vfs_stat(filename, &stat);
+
+ if (!error)
+ error = cp_new_stat64(&stat, statbuf);
- error = user_path_walk(filename, &nd);
- if (!error) {
- error = do_revalidate(nd.dentry);
- if (!error)
- error = cp_new_stat64(nd.dentry->d_inode, statbuf);
- path_release(&nd);
- }
return error;
}
-
asmlinkage long sys_lstat64(char * filename, struct stat64 * statbuf, long flags)
{
- struct nameidata nd;
- int error;
+ struct kstat stat;
+ int error = vfs_lstat(filename, &stat);
+
+ if (!error)
+ error = cp_new_stat64(&stat, statbuf);
- error = user_path_walk_link(filename, &nd);
- if (!error) {
- error = do_revalidate(nd.dentry);
- if (!error)
- error = cp_new_stat64(nd.dentry->d_inode, statbuf);
- path_release(&nd);
- }
return error;
}
-
asmlinkage long sys_fstat64(unsigned long fd, struct stat64 * statbuf, long flags)
{
- struct file * f;
- int err = -EBADF;
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
- f = fget(fd);
- if (f) {
- struct dentry * dentry = f->f_dentry;
+ if (!error)
+ error = cp_new_stat64(&stat, statbuf);
- err = do_revalidate(dentry);
- if (!err)
- err = cp_new_stat64(dentry->d_inode, statbuf);
- fput(f);
- }
- return err;
+ return error;
}
#endif /* LFS-64 */
diff --git a/fs/super.c b/fs/super.c
index fb70602790ae..f9f6a9802ad4 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -641,8 +641,9 @@ retry:
return s;
}
-static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
- int flags, char *dev_name, void * data)
+struct super_block *get_sb_bdev(struct file_system_type *fs_type,
+ int flags, char *dev_name, void * data,
+ int (*fill_super)(struct super_block *, void *, int))
{
struct inode *inode;
struct block_device *bdev;
@@ -698,7 +699,7 @@ restart:
list_for_each(p, &super_blocks) {
struct super_block *old = sb_entry(p);
- if (!kdev_same(old->s_dev, dev))
+ if (old->s_bdev != bdev)
continue;
if (old->s_type != fs_type ||
((flags ^ old->s_flags) & MS_RDONLY)) {
@@ -718,8 +719,8 @@ restart:
s->s_flags = flags;
insert_super(s, fs_type);
strncpy(s->s_id, bdevname(dev), sizeof(s->s_id));
- error = -EINVAL;
- if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
+ error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+ if (error)
goto failed;
s->s_flags |= MS_ACTIVE;
path_release(&nd);
@@ -736,19 +737,23 @@ out:
return ERR_PTR(error);
}
-static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
- int flags, char *dev_name, void *data)
+struct super_block *get_sb_nodev(struct file_system_type *fs_type,
+ int flags, void *data,
+ int (*fill_super)(struct super_block *, void *, int))
{
+ int error;
struct super_block *s = get_anon_super(fs_type, NULL, NULL);
if (IS_ERR(s))
return s;
s->s_flags = flags;
- if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
+
+ error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+ if (error) {
deactivate_super(s);
remove_super(s);
- return ERR_PTR(-EINVAL);
+ return ERR_PTR(error);
}
s->s_flags |= MS_ACTIVE;
return s;
@@ -759,19 +764,22 @@ static int compare_single(struct super_block *s, void *p)
return 1;
}
-static struct super_block *get_sb_single(struct file_system_type *fs_type,
- int flags, char *dev_name, void *data)
+struct super_block *get_sb_single(struct file_system_type *fs_type,
+ int flags, void *data,
+ int (*fill_super)(struct super_block *, void *, int))
{
+ int error;
struct super_block *s = get_anon_super(fs_type, compare_single, NULL);
if (IS_ERR(s))
return s;
if (!s->s_root) {
s->s_flags = flags;
- if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
+ error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+ if (error) {
deactivate_super(s);
remove_super(s);
- return ERR_PTR(-EINVAL);
+ return ERR_PTR(error);
}
s->s_flags |= MS_ACTIVE;
}
@@ -779,6 +787,22 @@ static struct super_block *get_sb_single(struct file_system_type *fs_type,
return s;
}
+/* Will go away */
+static int fill_super(struct super_block *sb, void *data, int verbose)
+{
+ return sb->s_type->read_super(sb, data, verbose) ? 0 : -EINVAL;
+}
+static struct super_block *__get_sb_bdev(struct file_system_type *fs_type,
+ int flags, char *dev_name, void * data)
+{
+ return get_sb_bdev(fs_type, flags, dev_name, data, fill_super);
+}
+static struct super_block *__get_sb_nodev(struct file_system_type *fs_type,
+ int flags, char *dev_name, void * data)
+{
+ return get_sb_nodev(fs_type, flags, data, fill_super);
+}
+
struct vfsmount *
do_kern_mount(const char *fstype, int flags, char *name, void *data)
{
@@ -792,12 +816,12 @@ do_kern_mount(const char *fstype, int flags, char *name, void *data)
mnt = alloc_vfsmnt(name);
if (!mnt)
goto out;
- if (type->fs_flags & FS_REQUIRES_DEV)
- sb = get_sb_bdev(type, flags, name, data);
- else if (type->fs_flags & FS_SINGLE)
- sb = get_sb_single(type, flags, name, data);
+ if (type->get_sb)
+ sb = type->get_sb(type, flags, name, data);
+ else if (type->fs_flags & FS_REQUIRES_DEV)
+ sb = __get_sb_bdev(type, flags, name, data);
else
- sb = get_sb_nodev(type, flags, name, data);
+ sb = __get_sb_nodev(type, flags, name, data);
if (IS_ERR(sb))
goto out_mnt;
if (type->fs_flags & FS_NOMOUNT)
diff --git a/fs/udf/super.c b/fs/udf/super.c
index a4984734a384..cf78cf53cc76 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1544,7 +1544,7 @@ udf_read_super(struct super_block *sb, void *options, int silent)
iput(inode);
goto error_out;
}
- sb->s_maxbytes = ~0ULL;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
return sb;
error_out:
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 7af092555ad0..819e6945b112 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -38,46 +38,12 @@
#include <linux/smp_lock.h>
/*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
-static long long ufs_file_lseek(
- struct file *file,
- long long offset,
- int origin )
-{
- long long retval;
- struct inode *inode = file->f_dentry->d_inode;
-
- lock_kernel();
-
- switch (origin) {
- case 2:
- offset += inode->i_size;
- break;
- case 1:
- offset += file->f_pos;
- }
- retval = -EINVAL;
- /* make sure the offset fits in 32 bits */
- if (((unsigned long long) offset >> 32) == 0) {
- if (offset != file->f_pos) {
- file->f_pos = offset;
- file->f_reada = 0;
- file->f_version = ++event;
- }
- retval = offset;
- }
- unlock_kernel();
- return retval;
-}
-
-/*
* We have mostly NULL's here: the current defaults are ok for
* the ufs filesystem.
*/
struct file_operations ufs_file_operations = {
- llseek: ufs_file_lseek,
+ llseek: generic_file_llseek,
read: generic_file_read,
write: generic_file_write,
mmap: generic_file_mmap,