remove ->write_super call in generic_shutdown_super
[safe/jmp/linux-2.6] / fs / sysv / inode.c
index a6ca12b..cd80316 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
+#include <linux/namei.h>
 #include <asm/byteorder.h>
 #include "sysv.h"
 
@@ -71,6 +72,9 @@ static void sysv_put_super(struct super_block *sb)
 {
        struct sysv_sb_info *sbi = SYSV_SB(sb);
 
+       if (sb->s_dirt)
+               sysv_write_super(sb);
+
        if (!(sb->s_flags & MS_RDONLY)) {
                /* XXX ext2 also updates the state here */
                mark_buffer_dirty(sbi->s_bh1);
@@ -89,6 +93,7 @@ static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct super_block *sb = dentry->d_sb;
        struct sysv_sb_info *sbi = SYSV_SB(sb);
+       u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
 
        buf->f_type = sb->s_magic;
        buf->f_bsize = sb->s_blocksize;
@@ -97,6 +102,8 @@ static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_files = sbi->s_ninodes;
        buf->f_ffree = sysv_count_free_inodes(sb);
        buf->f_namelen = SYSV_NAMELEN;
+       buf->f_fsid.val[0] = (u32)id;
+       buf->f_fsid.val[1] = (u32)(id >> 32);
        return 0;
 }
 
@@ -142,7 +149,7 @@ static inline void write3byte(struct sysv_sb_info *sbi,
        }
 }
 
-static struct inode_operations sysv_symlink_inode_operations = {
+static const struct inode_operations sysv_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
@@ -163,26 +170,36 @@ void sysv_set_inode(struct inode *inode, dev_t rdev)
                if (inode->i_blocks) {
                        inode->i_op = &sysv_symlink_inode_operations;
                        inode->i_mapping->a_ops = &sysv_aops;
-               } else
+               } else {
                        inode->i_op = &sysv_fast_symlink_inode_operations;
+                       nd_terminate_link(SYSV_I(inode)->i_data, inode->i_size,
+                               sizeof(SYSV_I(inode)->i_data) - 1);
+               }
        } else
                init_special_inode(inode, inode->i_mode, rdev);
 }
 
-static void sysv_read_inode(struct inode *inode)
+struct inode *sysv_iget(struct super_block *sb, unsigned int ino)
 {
-       struct super_block * sb = inode->i_sb;
        struct sysv_sb_info * sbi = SYSV_SB(sb);
        struct buffer_head * bh;
        struct sysv_inode * raw_inode;
        struct sysv_inode_info * si;
-       unsigned int block, ino = inode->i_ino;
+       struct inode *inode;
+       unsigned int block;
 
        if (!ino || ino > sbi->s_ninodes) {
                printk("Bad inode number on dev %s: %d is out of range\n",
-                      inode->i_sb->s_id, ino);
-               goto bad_inode;
+                      sb->s_id, ino);
+               return ERR_PTR(-EIO);
        }
+
+       inode = iget_locked(sb, ino);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
+
        raw_inode = sysv_raw_inode(sb, ino, &bh);
        if (!raw_inode) {
                printk("Major problem: unable to read inode from dev %s\n",
@@ -214,11 +231,12 @@ static void sysv_read_inode(struct inode *inode)
                               old_decode_dev(fs32_to_cpu(sbi, si->i_data[0])));
        else
                sysv_set_inode(inode, 0);
-       return;
+       unlock_new_inode(inode);
+       return inode;
 
 bad_inode:
-       make_bad_inode(inode);
-       return;
+       iget_failed(inode);
+       return ERR_PTR(-EIO);
 }
 
 static struct buffer_head * sysv_update_inode(struct inode * inode)
@@ -301,7 +319,7 @@ static void sysv_delete_inode(struct inode *inode)
        unlock_kernel();
 }
 
-static kmem_cache_t *sysv_inode_cachep;
+static struct kmem_cache *sysv_inode_cachep;
 
 static struct inode *sysv_alloc_inode(struct super_block *sb)
 {
@@ -318,19 +336,16 @@ static void sysv_destroy_inode(struct inode *inode)
        kmem_cache_free(sysv_inode_cachep, SYSV_I(inode));
 }
 
-static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags)
+static void init_once(void *p)
 {
        struct sysv_inode_info *si = (struct sysv_inode_info *)p;
 
-       if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-                       SLAB_CTOR_CONSTRUCTOR)
-               inode_init_once(&si->vfs_inode);
+       inode_init_once(&si->vfs_inode);
 }
 
-struct super_operations sysv_sops = {
+const struct super_operations sysv_sops = {
        .alloc_inode    = sysv_alloc_inode,
        .destroy_inode  = sysv_destroy_inode,
-       .read_inode     = sysv_read_inode,
        .write_inode    = sysv_write_inode,
        .delete_inode   = sysv_delete_inode,
        .put_super      = sysv_put_super,
@@ -344,7 +359,7 @@ int __init sysv_init_icache(void)
        sysv_inode_cachep = kmem_cache_create("sysv_inode_cache",
                        sizeof(struct sysv_inode_info), 0,
                        SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
-                       init_once, NULL);
+                       init_once);
        if (!sysv_inode_cachep)
                return -ENOMEM;
        return 0;