aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ufs/inode.c')
-rw-r--r--fs/ufs/inode.c79
1 files changed, 21 insertions, 58 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 2b251f2093af..27a4babe7df0 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -34,7 +34,6 @@
34#include <linux/stat.h> 34#include <linux/stat.h>
35#include <linux/string.h> 35#include <linux/string.h>
36#include <linux/mm.h> 36#include <linux/mm.h>
37#include <linux/smp_lock.h>
38#include <linux/buffer_head.h> 37#include <linux/buffer_head.h>
39#include <linux/writeback.h> 38#include <linux/writeback.h>
40 39
@@ -43,7 +42,7 @@
43#include "swab.h" 42#include "swab.h"
44#include "util.h" 43#include "util.h"
45 44
46static u64 ufs_frag_map(struct inode *inode, sector_t frag); 45static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock);
47 46
48static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) 47static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4])
49{ 48{
@@ -82,7 +81,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off
82 * the begining of the filesystem. 81 * the begining of the filesystem.
83 */ 82 */
84 83
85static u64 ufs_frag_map(struct inode *inode, sector_t frag) 84static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock)
86{ 85{
87 struct ufs_inode_info *ufsi = UFS_I(inode); 86 struct ufs_inode_info *ufsi = UFS_I(inode);
88 struct super_block *sb = inode->i_sb; 87 struct super_block *sb = inode->i_sb;
@@ -107,7 +106,8 @@ static u64 ufs_frag_map(struct inode *inode, sector_t frag)
107 106
108 p = offsets; 107 p = offsets;
109 108
110 lock_kernel(); 109 if (needs_lock)
110 lock_ufs(sb);
111 if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) 111 if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2)
112 goto ufs2; 112 goto ufs2;
113 113
@@ -152,7 +152,8 @@ ufs2:
152 ret = temp + (u64) (frag & uspi->s_fpbmask); 152 ret = temp + (u64) (frag & uspi->s_fpbmask);
153 153
154out: 154out:
155 unlock_kernel(); 155 if (needs_lock)
156 unlock_ufs(sb);
156 return ret; 157 return ret;
157} 158}
158 159
@@ -415,14 +416,16 @@ out:
415int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) 416int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create)
416{ 417{
417 struct super_block * sb = inode->i_sb; 418 struct super_block * sb = inode->i_sb;
418 struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; 419 struct ufs_sb_info * sbi = UFS_SB(sb);
420 struct ufs_sb_private_info * uspi = sbi->s_uspi;
419 struct buffer_head * bh; 421 struct buffer_head * bh;
420 int ret, err, new; 422 int ret, err, new;
421 unsigned long ptr,phys; 423 unsigned long ptr,phys;
422 u64 phys64 = 0; 424 u64 phys64 = 0;
425 bool needs_lock = (sbi->mutex_owner != current);
423 426
424 if (!create) { 427 if (!create) {
425 phys64 = ufs_frag_map(inode, fragment); 428 phys64 = ufs_frag_map(inode, fragment, needs_lock);
426 UFSD("phys64 = %llu\n", (unsigned long long)phys64); 429 UFSD("phys64 = %llu\n", (unsigned long long)phys64);
427 if (phys64) 430 if (phys64)
428 map_bh(bh_result, sb, phys64); 431 map_bh(bh_result, sb, phys64);
@@ -436,7 +439,8 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head
436 ret = 0; 439 ret = 0;
437 bh = NULL; 440 bh = NULL;
438 441
439 lock_kernel(); 442 if (needs_lock)
443 lock_ufs(sb);
440 444
441 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); 445 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
442 if (fragment > 446 if (fragment >
@@ -498,7 +502,9 @@ out:
498 set_buffer_new(bh_result); 502 set_buffer_new(bh_result);
499 map_bh(bh_result, sb, phys); 503 map_bh(bh_result, sb, phys);
500abort: 504abort:
501 unlock_kernel(); 505 if (needs_lock)
506 unlock_ufs(sb);
507
502 return err; 508 return err;
503 509
504abort_too_big: 510abort_too_big:
@@ -506,48 +512,6 @@ abort_too_big:
506 goto abort; 512 goto abort;
507} 513}
508 514
509static struct buffer_head *ufs_getfrag(struct inode *inode,
510 unsigned int fragment,
511 int create, int *err)
512{
513 struct buffer_head dummy;
514 int error;
515
516 dummy.b_state = 0;
517 dummy.b_blocknr = -1000;
518 error = ufs_getfrag_block(inode, fragment, &dummy, create);
519 *err = error;
520 if (!error && buffer_mapped(&dummy)) {
521 struct buffer_head *bh;
522 bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
523 if (buffer_new(&dummy)) {
524 memset(bh->b_data, 0, inode->i_sb->s_blocksize);
525 set_buffer_uptodate(bh);
526 mark_buffer_dirty(bh);
527 }
528 return bh;
529 }
530 return NULL;
531}
532
533struct buffer_head * ufs_bread (struct inode * inode, unsigned fragment,
534 int create, int * err)
535{
536 struct buffer_head * bh;
537
538 UFSD("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment);
539 bh = ufs_getfrag (inode, fragment, create, err);
540 if (!bh || buffer_uptodate(bh))
541 return bh;
542 ll_rw_block (READ, 1, &bh);
543 wait_on_buffer (bh);
544 if (buffer_uptodate(bh))
545 return bh;
546 brelse (bh);
547 *err = -EIO;
548 return NULL;
549}
550
551static int ufs_writepage(struct page *page, struct writeback_control *wbc) 515static int ufs_writepage(struct page *page, struct writeback_control *wbc)
552{ 516{
553 return block_write_full_page(page,ufs_getfrag_block,wbc); 517 return block_write_full_page(page,ufs_getfrag_block,wbc);
@@ -588,7 +552,6 @@ static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
588const struct address_space_operations ufs_aops = { 552const struct address_space_operations ufs_aops = {
589 .readpage = ufs_readpage, 553 .readpage = ufs_readpage,
590 .writepage = ufs_writepage, 554 .writepage = ufs_writepage,
591 .sync_page = block_sync_page,
592 .write_begin = ufs_write_begin, 555 .write_begin = ufs_write_begin,
593 .write_end = generic_write_end, 556 .write_end = generic_write_end,
594 .bmap = ufs_bmap 557 .bmap = ufs_bmap
@@ -900,9 +863,9 @@ static int ufs_update_inode(struct inode * inode, int do_sync)
900int ufs_write_inode(struct inode *inode, struct writeback_control *wbc) 863int ufs_write_inode(struct inode *inode, struct writeback_control *wbc)
901{ 864{
902 int ret; 865 int ret;
903 lock_kernel(); 866 lock_ufs(inode->i_sb);
904 ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 867 ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
905 unlock_kernel(); 868 unlock_ufs(inode->i_sb);
906 return ret; 869 return ret;
907} 870}
908 871
@@ -922,22 +885,22 @@ void ufs_evict_inode(struct inode * inode)
922 if (want_delete) { 885 if (want_delete) {
923 loff_t old_i_size; 886 loff_t old_i_size;
924 /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/ 887 /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
925 lock_kernel(); 888 lock_ufs(inode->i_sb);
926 mark_inode_dirty(inode); 889 mark_inode_dirty(inode);
927 ufs_update_inode(inode, IS_SYNC(inode)); 890 ufs_update_inode(inode, IS_SYNC(inode));
928 old_i_size = inode->i_size; 891 old_i_size = inode->i_size;
929 inode->i_size = 0; 892 inode->i_size = 0;
930 if (inode->i_blocks && ufs_truncate(inode, old_i_size)) 893 if (inode->i_blocks && ufs_truncate(inode, old_i_size))
931 ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n"); 894 ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n");
932 unlock_kernel(); 895 unlock_ufs(inode->i_sb);
933 } 896 }
934 897
935 invalidate_inode_buffers(inode); 898 invalidate_inode_buffers(inode);
936 end_writeback(inode); 899 end_writeback(inode);
937 900
938 if (want_delete) { 901 if (want_delete) {
939 lock_kernel(); 902 lock_ufs(inode->i_sb);
940 ufs_free_inode (inode); 903 ufs_free_inode (inode);
941 unlock_kernel(); 904 unlock_ufs(inode->i_sb);
942 } 905 }
943} 906}