diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-03-25 11:41:20 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-03-25 11:41:20 -0400 |
commit | 7bf7e370d5919112c223a269462cd0b546903829 (patch) | |
tree | 03ccc715239df14ae168277dbccc9d9cf4d8a2c8 /fs/ufs/inode.c | |
parent | 68b1a1e786f29c900fa1c516a402e24f0ece622a (diff) | |
parent | d39dd11c3e6a7af5c20bfac40594db36cf270f42 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus-1
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6: (9356 commits)
[media] rc: update for bitop name changes
fs: simplify iget & friends
fs: pull inode->i_lock up out of writeback_single_inode
fs: rename inode_lock to inode_hash_lock
fs: move i_wb_list out from under inode_lock
fs: move i_sb_list out from under inode_lock
fs: remove inode_lock from iput_final and prune_icache
fs: Lock the inode LRU list separately
fs: factor inode disposal
fs: protect inode->i_state with inode->i_lock
lib, arch: add filter argument to show_mem and fix private implementations
SLUB: Write to per cpu data when allocating it
slub: Fix debugobjects with lockless fastpath
autofs4: Do not potentially dereference NULL pointer returned by fget() in autofs_dev_ioctl_setpipefd()
autofs4 - remove autofs4_lock
autofs4 - fix d_manage() return on rcu-walk
autofs4 - fix autofs4_expire_indirect() traversal
autofs4 - fix dentry leak in autofs4_expire_direct()
autofs4 - reinstate last used update on access
vfs - check non-mountpoint dentry might block in __follow_mount_rcu()
...
NOTE!
This merge commit was created to fix compilation error. The block
tree was merged upstream and removed the 'elv_queue_empty()'
function which the new 'mtdswap' driver is using. So a simple
merge of the mtd tree with upstream does not compile. And the
mtd tree has already be published, so re-basing it is not an option.
To fix this unfortunate situation, I had to merge upstream into the
mtd-2.6.git tree without committing, put the fixup patch on top of
this, and then commit this. The result is that we do not have commits
which do not compile.
In other words, this merge commit "merges" 3 things: the MTD tree, the
upstream tree, and the fixup patch.
Diffstat (limited to 'fs/ufs/inode.c')
-rw-r--r-- | fs/ufs/inode.c | 79 |
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 | ||
46 | static u64 ufs_frag_map(struct inode *inode, sector_t frag); | 45 | static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock); |
47 | 46 | ||
48 | static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) | 47 | static 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 | ||
85 | static u64 ufs_frag_map(struct inode *inode, sector_t frag) | 84 | static 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 | ||
154 | out: | 154 | out: |
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: | |||
415 | int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) | 416 | int 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); |
500 | abort: | 504 | abort: |
501 | unlock_kernel(); | 505 | if (needs_lock) |
506 | unlock_ufs(sb); | ||
507 | |||
502 | return err; | 508 | return err; |
503 | 509 | ||
504 | abort_too_big: | 510 | abort_too_big: |
@@ -506,48 +512,6 @@ abort_too_big: | |||
506 | goto abort; | 512 | goto abort; |
507 | } | 513 | } |
508 | 514 | ||
509 | static 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 | |||
533 | struct 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 | |||
551 | static int ufs_writepage(struct page *page, struct writeback_control *wbc) | 515 | static 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) | |||
588 | const struct address_space_operations ufs_aops = { | 552 | const 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) | |||
900 | int ufs_write_inode(struct inode *inode, struct writeback_control *wbc) | 863 | int 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 | } |