Merge branch 'for-2.6.39/core' of git://git.kernel.dk/linux-2.6-block
[sfrench/cifs-2.6.git] / fs / ufs / inode.c
index 83b28444eb17c6b87cbb37a721faaa98071a5372..27a4babe7df0bcaf406e260631d86e44abb5ba51 100644 (file)
@@ -34,7 +34,6 @@
 #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>
 
@@ -43,7 +42,7 @@
 #include "swab.h"
 #include "util.h"
 
-static u64 ufs_frag_map(struct inode *inode, sector_t frag);
+static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock);
 
 static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4])
 {
@@ -82,7 +81,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off
  * the begining of the filesystem.
  */
 
-static u64 ufs_frag_map(struct inode *inode, sector_t frag)
+static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock)
 {
        struct ufs_inode_info *ufsi = UFS_I(inode);
        struct super_block *sb = inode->i_sb;
@@ -107,7 +106,8 @@ static u64 ufs_frag_map(struct inode *inode, sector_t frag)
 
        p = offsets;
 
-       lock_kernel();
+       if (needs_lock)
+               lock_ufs(sb);
        if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
                goto ufs2;
 
@@ -152,7 +152,8 @@ ufs2:
        ret = temp + (u64) (frag & uspi->s_fpbmask);
 
 out:
-       unlock_kernel();
+       if (needs_lock)
+               unlock_ufs(sb);
        return ret;
 }
 
@@ -415,14 +416,16 @@ out:
 int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
 {
        struct super_block * sb = inode->i_sb;
-       struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi;
+       struct ufs_sb_info * sbi = UFS_SB(sb);
+       struct ufs_sb_private_info * uspi = sbi->s_uspi;
        struct buffer_head * bh;
        int ret, err, new;
        unsigned long ptr,phys;
        u64 phys64 = 0;
+       bool needs_lock = (sbi->mutex_owner != current);
        
        if (!create) {
-               phys64 = ufs_frag_map(inode, fragment);
+               phys64 = ufs_frag_map(inode, fragment, needs_lock);
                UFSD("phys64 = %llu\n", (unsigned long long)phys64);
                if (phys64)
                        map_bh(bh_result, sb, phys64);
@@ -436,7 +439,8 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head
        ret = 0;
        bh = NULL;
 
-       lock_kernel();
+       if (needs_lock)
+               lock_ufs(sb);
 
        UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
        if (fragment >
@@ -498,7 +502,9 @@ out:
                set_buffer_new(bh_result);
        map_bh(bh_result, sb, phys);
 abort:
-       unlock_kernel();
+       if (needs_lock)
+               unlock_ufs(sb);
+
        return err;
 
 abort_too_big:
@@ -506,48 +512,6 @@ abort_too_big:
        goto abort;
 }
 
-static struct buffer_head *ufs_getfrag(struct inode *inode,
-                                      unsigned int fragment,
-                                      int create, int *err)
-{
-       struct buffer_head dummy;
-       int error;
-
-       dummy.b_state = 0;
-       dummy.b_blocknr = -1000;
-       error = ufs_getfrag_block(inode, fragment, &dummy, create);
-       *err = error;
-       if (!error && buffer_mapped(&dummy)) {
-               struct buffer_head *bh;
-               bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
-               if (buffer_new(&dummy)) {
-                       memset(bh->b_data, 0, inode->i_sb->s_blocksize);
-                       set_buffer_uptodate(bh);
-                       mark_buffer_dirty(bh);
-               }
-               return bh;
-       }
-       return NULL;
-}
-
-struct buffer_head * ufs_bread (struct inode * inode, unsigned fragment,
-       int create, int * err)
-{
-       struct buffer_head * bh;
-
-       UFSD("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment);
-       bh = ufs_getfrag (inode, fragment, create, err);
-       if (!bh || buffer_uptodate(bh))                 
-               return bh;
-       ll_rw_block (READ, 1, &bh);
-       wait_on_buffer (bh);
-       if (buffer_uptodate(bh))
-               return bh;
-       brelse (bh);
-       *err = -EIO;
-       return NULL;
-}
-
 static int ufs_writepage(struct page *page, struct writeback_control *wbc)
 {
        return block_write_full_page(page,ufs_getfrag_block,wbc);
@@ -899,9 +863,9 @@ static int ufs_update_inode(struct inode * inode, int do_sync)
 int ufs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        int ret;
-       lock_kernel();
+       lock_ufs(inode->i_sb);
        ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
-       unlock_kernel();
+       unlock_ufs(inode->i_sb);
        return ret;
 }
 
@@ -921,22 +885,22 @@ void ufs_evict_inode(struct inode * inode)
        if (want_delete) {
                loff_t old_i_size;
                /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
-               lock_kernel();
+               lock_ufs(inode->i_sb);
                mark_inode_dirty(inode);
                ufs_update_inode(inode, IS_SYNC(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, __func__, "ufs_truncate failed\n");
-               unlock_kernel();
+               unlock_ufs(inode->i_sb);
        }
 
        invalidate_inode_buffers(inode);
        end_writeback(inode);
 
        if (want_delete) {
-               lock_kernel();
+               lock_ufs(inode->i_sb);
                ufs_free_inode (inode);
-               unlock_kernel();
+               unlock_ufs(inode->i_sb);
        }
 }