block: bd_start_claiming fix module refcount
[safe/jmp/linux-2.6] / fs / ufs / inode.c
index 4320782..73fe773 100644 (file)
 
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/ufs_fs.h>
 #include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
+#include <linux/writeback.h>
 
+#include "ufs_fs.h"
 #include "ufs.h"
 #include "swab.h"
 #include "util.h"
@@ -56,9 +57,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off
 
 
        UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
-       if (i_block < 0) {
-               ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
-       } else if (i_block < direct_blocks) {
+       if (i_block < direct_blocks) {
                offsets[n++] = i_block;
        } else if ((i_block -= direct_blocks) < indirect_blocks) {
                offsets[n++] = UFS_IND_BLOCK;
@@ -440,8 +439,6 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head
        lock_kernel();
 
        UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
-       if (fragment < 0)
-               goto abort_negative;
        if (fragment >
            ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
             << uspi->s_fpbshift))
@@ -504,10 +501,6 @@ abort:
        unlock_kernel();
        return err;
 
-abort_negative:
-       ufs_warning(sb, "ufs_get_block", "block < 0");
-       goto abort;
-
 abort_too_big:
        ufs_warning(sb, "ufs_get_block", "block > big");
        goto abort;
@@ -609,7 +602,7 @@ static void ufs_set_inode_ops(struct inode *inode)
                if (!inode->i_blocks)
                        inode->i_op = &ufs_fast_symlink_inode_operations;
                else {
-                       inode->i_op = &page_symlink_inode_operations;
+                       inode->i_op = &ufs_symlink_inode_operations;
                        inode->i_mapping->a_ops = &ufs_aops;
                }
        } else
@@ -622,7 +615,6 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
        struct ufs_inode_info *ufsi = UFS_I(inode);
        struct super_block *sb = inode->i_sb;
        mode_t mode;
-       unsigned i;
 
        /*
         * Copy data to the in-core inode.
@@ -655,11 +647,12 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
 
        
        if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
-                       ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i];
+               memcpy(ufsi->i_u1.i_data, &ufs_inode->ui_u2.ui_addr,
+                      sizeof(ufs_inode->ui_u2.ui_addr));
        } else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i];
+               memcpy(ufsi->i_u1.i_symlink, ufs_inode->ui_u2.ui_symlink,
+                      sizeof(ufs_inode->ui_u2.ui_symlink) - 1);
+               ufsi->i_u1.i_symlink[sizeof(ufs_inode->ui_u2.ui_symlink) - 1] = 0;
        }
        return 0;
 }
@@ -669,7 +662,6 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
        struct ufs_inode_info *ufsi = UFS_I(inode);
        struct super_block *sb = inode->i_sb;
        mode_t mode;
-       unsigned i;
 
        UFSD("Reading ufs2 inode, ino %lu\n", inode->i_ino);
        /*
@@ -704,36 +696,40 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
        */
 
        if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
-                       ufsi->i_u1.u2_i_data[i] =
-                               ufs2_inode->ui_u2.ui_addr.ui_db[i];
+               memcpy(ufsi->i_u1.u2_i_data, &ufs2_inode->ui_u2.ui_addr,
+                      sizeof(ufs2_inode->ui_u2.ui_addr));
        } else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufsi->i_u1.i_symlink[i] = ufs2_inode->ui_u2.ui_symlink[i];
+               memcpy(ufsi->i_u1.i_symlink, ufs2_inode->ui_u2.ui_symlink,
+                      sizeof(ufs2_inode->ui_u2.ui_symlink) - 1);
+               ufsi->i_u1.i_symlink[sizeof(ufs2_inode->ui_u2.ui_symlink) - 1] = 0;
        }
        return 0;
 }
 
-void ufs_read_inode(struct inode * inode)
+struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
 {
-       struct ufs_inode_info *ufsi = UFS_I(inode);
-       struct super_block * sb;
-       struct ufs_sb_private_info * uspi;
+       struct ufs_inode_info *ufsi;
+       struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        struct buffer_head * bh;
+       struct inode *inode;
        int err;
 
-       UFSD("ENTER, ino %lu\n", inode->i_ino);
-
-       sb = inode->i_sb;
-       uspi = UFS_SB(sb)->s_uspi;
+       UFSD("ENTER, ino %lu\n", ino);
 
-       if (inode->i_ino < UFS_ROOTINO ||
-           inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) {
+       if (ino < UFS_ROOTINO || ino > (uspi->s_ncg * uspi->s_ipg)) {
                ufs_warning(sb, "ufs_read_inode", "bad inode number (%lu)\n",
-                           inode->i_ino);
-               goto bad_inode;
+                           ino);
+               return ERR_PTR(-EIO);
        }
 
+       inode = iget_locked(sb, ino);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
+
+       ufsi = UFS_I(inode);
+
        bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino));
        if (!bh) {
                ufs_warning(sb, "ufs_read_inode", "unable to read inode %lu\n",
@@ -765,17 +761,18 @@ void ufs_read_inode(struct inode * inode)
        brelse(bh);
 
        UFSD("EXIT\n");
-       return;
+       unlock_new_inode(inode);
+       return inode;
 
 bad_inode:
-       make_bad_inode(inode);
+       iget_failed(inode);
+       return ERR_PTR(-EIO);
 }
 
 static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)
 {
        struct super_block *sb = inode->i_sb;
        struct ufs_inode_info *ufsi = UFS_I(inode);
-       unsigned i;
 
        ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode);
        ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink);
@@ -803,12 +800,12 @@ static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)
                /* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */
                ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.i_data[0];
        } else if (inode->i_blocks) {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
-                       ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.i_data[i];
+               memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.i_data,
+                      sizeof(ufs_inode->ui_u2.ui_addr));
        }
        else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufs_inode->ui_u2.ui_symlink[i] = ufsi->i_u1.i_symlink[i];
+               memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink,
+                      sizeof(ufs_inode->ui_u2.ui_symlink));
        }
 
        if (!inode->i_nlink)
@@ -819,7 +816,6 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode)
 {
        struct super_block *sb = inode->i_sb;
        struct ufs_inode_info *ufsi = UFS_I(inode);
-       unsigned i;
 
        UFSD("ENTER\n");
        ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode);
@@ -844,11 +840,11 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode)
                /* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */
                ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.u2_i_data[0];
        } else if (inode->i_blocks) {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
-                       ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.u2_i_data[i];
+               memcpy(&ufs_inode->ui_u2.ui_addr, ufsi->i_u1.u2_i_data,
+                      sizeof(ufs_inode->ui_u2.ui_addr));
        } else {
-               for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
-                       ufs_inode->ui_u2.ui_symlink[i] = ufsi->i_u1.i_symlink[i];
+               memcpy(&ufs_inode->ui_u2.ui_symlink, ufsi->i_u1.i_symlink,
+                      sizeof(ufs_inode->ui_u2.ui_symlink));
        }
 
        if (!inode->i_nlink)
@@ -895,11 +891,11 @@ static int ufs_update_inode(struct inode * inode, int do_sync)
        return 0;
 }
 
-int ufs_write_inode (struct inode * inode, int wait)
+int ufs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        int ret;
        lock_kernel();
-       ret = ufs_update_inode (inode, wait);
+       ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
        unlock_kernel();
        return ret;
 }
@@ -923,7 +919,7 @@ void ufs_delete_inode (struct inode * inode)
        old_i_size = inode->i_size;
        inode->i_size = 0;
        if (inode->i_blocks && ufs_truncate(inode, old_i_size))
-               ufs_warning(inode->i_sb, __FUNCTION__, "ufs_truncate failed\n");
+               ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n");
        ufs_free_inode (inode);
        unlock_kernel();
        return;