diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/cifs/CHANGES | 4 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 3 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 13 | ||||
| -rw-r--r-- | fs/ext4/Kconfig | 1 | ||||
| -rw-r--r-- | fs/ext4/block_validity.c | 1 | ||||
| -rw-r--r-- | fs/ext4/ext4.h | 2 | ||||
| -rw-r--r-- | fs/ext4/ext4_extents.h | 3 | ||||
| -rw-r--r-- | fs/ext4/extents.c | 77 | ||||
| -rw-r--r-- | fs/ext4/fsync.c | 16 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 225 | ||||
| -rw-r--r-- | fs/ext4/mballoc.h | 1 | ||||
| -rw-r--r-- | fs/ext4/super.c | 7 | ||||
| -rw-r--r-- | fs/ext4/xattr.c | 2 | ||||
| -rw-r--r-- | fs/fs-writeback.c | 18 | ||||
| -rw-r--r-- | fs/jbd2/checkpoint.c | 15 | ||||
| -rw-r--r-- | fs/jbd2/commit.c | 19 | ||||
| -rw-r--r-- | fs/jbd2/journal.c | 2 | ||||
| -rw-r--r-- | fs/namei.c | 1 | ||||
| -rw-r--r-- | fs/nilfs2/bmap.c | 4 | ||||
| -rw-r--r-- | fs/nilfs2/cpfile.c | 31 | ||||
| -rw-r--r-- | fs/nilfs2/direct.c | 17 | ||||
| -rw-r--r-- | fs/nilfs2/ioctl.c | 2 | ||||
| -rw-r--r-- | fs/reiserfs/bitmap.c | 3 | ||||
| -rw-r--r-- | fs/reiserfs/inode.c | 5 | ||||
| -rw-r--r-- | fs/reiserfs/journal.c | 18 | ||||
| -rw-r--r-- | fs/reiserfs/lock.c | 9 | ||||
| -rw-r--r-- | fs/reiserfs/namei.c | 7 | ||||
| -rw-r--r-- | fs/reiserfs/xattr.c | 26 |
28 files changed, 354 insertions, 178 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 094ea65afc85..7b2600b380d7 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -5,7 +5,9 @@ have duplicated data). Fix oops in cifs_lookup. Workaround problem | |||
| 5 | mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session. | 5 | mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session. |
| 6 | Disable use of server inode numbers when server only | 6 | Disable use of server inode numbers when server only |
| 7 | partially supports them (e.g. for one server querying inode numbers on | 7 | partially supports them (e.g. for one server querying inode numbers on |
| 8 | FindFirst fails but QPathInfo queries works). | 8 | FindFirst fails but QPathInfo queries works). Fix oops with dfs in |
| 9 | cifs_put_smb_ses. Fix mmap to work on directio mounts (needed | ||
| 10 | for OpenOffice when on forcedirectio mount e.g.) | ||
| 9 | 11 | ||
| 10 | Version 1.60 | 12 | Version 1.60 |
| 11 | ------------- | 13 | ------------- |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 29f1da761bbf..8c6a03627176 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -758,7 +758,7 @@ const struct file_operations cifs_file_ops = { | |||
| 758 | }; | 758 | }; |
| 759 | 759 | ||
| 760 | const struct file_operations cifs_file_direct_ops = { | 760 | const struct file_operations cifs_file_direct_ops = { |
| 761 | /* no mmap, no aio, no readv - | 761 | /* no aio, no readv - |
| 762 | BB reevaluate whether they can be done with directio, no cache */ | 762 | BB reevaluate whether they can be done with directio, no cache */ |
| 763 | .read = cifs_user_read, | 763 | .read = cifs_user_read, |
| 764 | .write = cifs_user_write, | 764 | .write = cifs_user_write, |
| @@ -767,6 +767,7 @@ const struct file_operations cifs_file_direct_ops = { | |||
| 767 | .lock = cifs_lock, | 767 | .lock = cifs_lock, |
| 768 | .fsync = cifs_fsync, | 768 | .fsync = cifs_fsync, |
| 769 | .flush = cifs_flush, | 769 | .flush = cifs_flush, |
| 770 | .mmap = cifs_file_mmap, | ||
| 770 | .splice_read = generic_file_splice_read, | 771 | .splice_read = generic_file_splice_read, |
| 771 | #ifdef CONFIG_CIFS_POSIX | 772 | #ifdef CONFIG_CIFS_POSIX |
| 772 | .unlocked_ioctl = cifs_ioctl, | 773 | .unlocked_ioctl = cifs_ioctl, |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 63ea83ff687f..3bbcaa716b3c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -2287,12 +2287,12 @@ int | |||
| 2287 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | 2287 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, |
| 2288 | char *mount_data_global, const char *devname) | 2288 | char *mount_data_global, const char *devname) |
| 2289 | { | 2289 | { |
| 2290 | int rc = 0; | 2290 | int rc; |
| 2291 | int xid; | 2291 | int xid; |
| 2292 | struct smb_vol *volume_info; | 2292 | struct smb_vol *volume_info; |
| 2293 | struct cifsSesInfo *pSesInfo = NULL; | 2293 | struct cifsSesInfo *pSesInfo; |
| 2294 | struct cifsTconInfo *tcon = NULL; | 2294 | struct cifsTconInfo *tcon; |
| 2295 | struct TCP_Server_Info *srvTcp = NULL; | 2295 | struct TCP_Server_Info *srvTcp; |
| 2296 | char *full_path; | 2296 | char *full_path; |
| 2297 | char *mount_data = mount_data_global; | 2297 | char *mount_data = mount_data_global; |
| 2298 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2298 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| @@ -2301,6 +2301,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2301 | int referral_walks_count = 0; | 2301 | int referral_walks_count = 0; |
| 2302 | try_mount_again: | 2302 | try_mount_again: |
| 2303 | #endif | 2303 | #endif |
| 2304 | rc = 0; | ||
| 2305 | tcon = NULL; | ||
| 2306 | pSesInfo = NULL; | ||
| 2307 | srvTcp = NULL; | ||
| 2304 | full_path = NULL; | 2308 | full_path = NULL; |
| 2305 | 2309 | ||
| 2306 | xid = GetXid(); | 2310 | xid = GetXid(); |
| @@ -2597,6 +2601,7 @@ remote_path_check: | |||
| 2597 | 2601 | ||
| 2598 | cleanup_volume_info(&volume_info); | 2602 | cleanup_volume_info(&volume_info); |
| 2599 | referral_walks_count++; | 2603 | referral_walks_count++; |
| 2604 | FreeXid(xid); | ||
| 2600 | goto try_mount_again; | 2605 | goto try_mount_again; |
| 2601 | } | 2606 | } |
| 2602 | #else /* No DFS support, return error on mount */ | 2607 | #else /* No DFS support, return error on mount */ |
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index 9acf7e808139..9ed1bb1f319f 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig | |||
| @@ -28,6 +28,7 @@ config EXT4_FS | |||
| 28 | 28 | ||
| 29 | config EXT4_USE_FOR_EXT23 | 29 | config EXT4_USE_FOR_EXT23 |
| 30 | bool "Use ext4 for ext2/ext3 file systems" | 30 | bool "Use ext4 for ext2/ext3 file systems" |
| 31 | depends on EXT4_FS | ||
| 31 | depends on EXT3_FS=n || EXT2_FS=n | 32 | depends on EXT3_FS=n || EXT2_FS=n |
| 32 | default y | 33 | default y |
| 33 | help | 34 | help |
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index 4df8621ec31c..a60ab9aad57d 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/swap.h> | 17 | #include <linux/swap.h> |
| 18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
| 19 | #include <linux/version.h> | ||
| 20 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
| 21 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
| 22 | #include "ext4.h" | 21 | #include "ext4.h" |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 56f9271ee8cc..af7b62699ea9 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -699,6 +699,8 @@ struct ext4_inode_info { | |||
| 699 | unsigned int i_reserved_meta_blocks; | 699 | unsigned int i_reserved_meta_blocks; |
| 700 | unsigned int i_allocated_meta_blocks; | 700 | unsigned int i_allocated_meta_blocks; |
| 701 | unsigned short i_delalloc_reserved_flag; | 701 | unsigned short i_delalloc_reserved_flag; |
| 702 | sector_t i_da_metadata_calc_last_lblock; | ||
| 703 | int i_da_metadata_calc_len; | ||
| 702 | 704 | ||
| 703 | /* on-disk additional length */ | 705 | /* on-disk additional length */ |
| 704 | __u16 i_extra_isize; | 706 | __u16 i_extra_isize; |
diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h index 2ca686454e87..bdb6ce7e2eb4 100644 --- a/fs/ext4/ext4_extents.h +++ b/fs/ext4/ext4_extents.h | |||
| @@ -225,7 +225,8 @@ static inline void ext4_ext_mark_initialized(struct ext4_extent *ext) | |||
| 225 | ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext)); | 225 | ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext)); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks); | 228 | extern int ext4_ext_calc_metadata_amount(struct inode *inode, |
| 229 | sector_t lblocks); | ||
| 229 | extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex); | 230 | extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex); |
| 230 | extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *); | 231 | extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *); |
| 231 | extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t); | 232 | extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t); |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3a7928f825e4..7d7b74e94687 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -296,29 +296,44 @@ static inline int ext4_ext_space_root_idx(struct inode *inode, int check) | |||
| 296 | * to allocate @blocks | 296 | * to allocate @blocks |
| 297 | * Worse case is one block per extent | 297 | * Worse case is one block per extent |
| 298 | */ | 298 | */ |
| 299 | int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks) | 299 | int ext4_ext_calc_metadata_amount(struct inode *inode, sector_t lblock) |
| 300 | { | 300 | { |
| 301 | int lcap, icap, rcap, leafs, idxs, num; | 301 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 302 | int newextents = blocks; | 302 | int idxs, num = 0; |
| 303 | |||
| 304 | rcap = ext4_ext_space_root_idx(inode, 0); | ||
| 305 | lcap = ext4_ext_space_block(inode, 0); | ||
| 306 | icap = ext4_ext_space_block_idx(inode, 0); | ||
| 307 | 303 | ||
| 308 | /* number of new leaf blocks needed */ | 304 | idxs = ((inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) |
| 309 | num = leafs = (newextents + lcap - 1) / lcap; | 305 | / sizeof(struct ext4_extent_idx)); |
| 310 | 306 | ||
| 311 | /* | 307 | /* |
| 312 | * Worse case, we need separate index block(s) | 308 | * If the new delayed allocation block is contiguous with the |
| 313 | * to link all new leaf blocks | 309 | * previous da block, it can share index blocks with the |
| 310 | * previous block, so we only need to allocate a new index | ||
| 311 | * block every idxs leaf blocks. At ldxs**2 blocks, we need | ||
| 312 | * an additional index block, and at ldxs**3 blocks, yet | ||
| 313 | * another index blocks. | ||
| 314 | */ | 314 | */ |
| 315 | idxs = (leafs + icap - 1) / icap; | 315 | if (ei->i_da_metadata_calc_len && |
| 316 | do { | 316 | ei->i_da_metadata_calc_last_lblock+1 == lblock) { |
| 317 | num += idxs; | 317 | if ((ei->i_da_metadata_calc_len % idxs) == 0) |
| 318 | idxs = (idxs + icap - 1) / icap; | 318 | num++; |
| 319 | } while (idxs > rcap); | 319 | if ((ei->i_da_metadata_calc_len % (idxs*idxs)) == 0) |
| 320 | num++; | ||
| 321 | if ((ei->i_da_metadata_calc_len % (idxs*idxs*idxs)) == 0) { | ||
| 322 | num++; | ||
| 323 | ei->i_da_metadata_calc_len = 0; | ||
| 324 | } else | ||
| 325 | ei->i_da_metadata_calc_len++; | ||
| 326 | ei->i_da_metadata_calc_last_lblock++; | ||
| 327 | return num; | ||
| 328 | } | ||
| 320 | 329 | ||
| 321 | return num; | 330 | /* |
| 331 | * In the worst case we need a new set of index blocks at | ||
| 332 | * every level of the inode's extent tree. | ||
| 333 | */ | ||
| 334 | ei->i_da_metadata_calc_len = 1; | ||
| 335 | ei->i_da_metadata_calc_last_lblock = lblock; | ||
| 336 | return ext_depth(inode) + 1; | ||
| 322 | } | 337 | } |
| 323 | 338 | ||
| 324 | static int | 339 | static int |
| @@ -3023,6 +3038,14 @@ out: | |||
| 3023 | return err; | 3038 | return err; |
| 3024 | } | 3039 | } |
| 3025 | 3040 | ||
| 3041 | static void unmap_underlying_metadata_blocks(struct block_device *bdev, | ||
| 3042 | sector_t block, int count) | ||
| 3043 | { | ||
| 3044 | int i; | ||
| 3045 | for (i = 0; i < count; i++) | ||
| 3046 | unmap_underlying_metadata(bdev, block + i); | ||
| 3047 | } | ||
| 3048 | |||
| 3026 | static int | 3049 | static int |
| 3027 | ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | 3050 | ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, |
| 3028 | ext4_lblk_t iblock, unsigned int max_blocks, | 3051 | ext4_lblk_t iblock, unsigned int max_blocks, |
| @@ -3098,6 +3121,18 @@ out: | |||
| 3098 | } else | 3121 | } else |
| 3099 | allocated = ret; | 3122 | allocated = ret; |
| 3100 | set_buffer_new(bh_result); | 3123 | set_buffer_new(bh_result); |
| 3124 | /* | ||
| 3125 | * if we allocated more blocks than requested | ||
| 3126 | * we need to make sure we unmap the extra block | ||
| 3127 | * allocated. The actual needed block will get | ||
| 3128 | * unmapped later when we find the buffer_head marked | ||
| 3129 | * new. | ||
| 3130 | */ | ||
| 3131 | if (allocated > max_blocks) { | ||
| 3132 | unmap_underlying_metadata_blocks(inode->i_sb->s_bdev, | ||
| 3133 | newblock + max_blocks, | ||
| 3134 | allocated - max_blocks); | ||
| 3135 | } | ||
| 3101 | map_out: | 3136 | map_out: |
| 3102 | set_buffer_mapped(bh_result); | 3137 | set_buffer_mapped(bh_result); |
| 3103 | out1: | 3138 | out1: |
| @@ -3190,7 +3225,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 3190 | * this situation is possible, though, _during_ tree modification; | 3225 | * this situation is possible, though, _during_ tree modification; |
| 3191 | * this is why assert can't be put in ext4_ext_find_extent() | 3226 | * this is why assert can't be put in ext4_ext_find_extent() |
| 3192 | */ | 3227 | */ |
| 3193 | BUG_ON(path[depth].p_ext == NULL && depth != 0); | 3228 | if (path[depth].p_ext == NULL && depth != 0) { |
| 3229 | ext4_error(inode->i_sb, __func__, "bad extent address " | ||
| 3230 | "inode: %lu, iblock: %d, depth: %d", | ||
| 3231 | inode->i_ino, iblock, depth); | ||
| 3232 | err = -EIO; | ||
| 3233 | goto out2; | ||
| 3234 | } | ||
| 3194 | eh = path[depth].p_hdr; | 3235 | eh = path[depth].p_hdr; |
| 3195 | 3236 | ||
| 3196 | ex = path[depth].p_ext; | 3237 | ex = path[depth].p_ext; |
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 0b22497d92e1..98bd140aad01 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
| @@ -88,9 +88,21 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 88 | return ext4_force_commit(inode->i_sb); | 88 | return ext4_force_commit(inode->i_sb); |
| 89 | 89 | ||
| 90 | commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid; | 90 | commit_tid = datasync ? ei->i_datasync_tid : ei->i_sync_tid; |
| 91 | if (jbd2_log_start_commit(journal, commit_tid)) | 91 | if (jbd2_log_start_commit(journal, commit_tid)) { |
| 92 | /* | ||
| 93 | * When the journal is on a different device than the | ||
| 94 | * fs data disk, we need to issue the barrier in | ||
| 95 | * writeback mode. (In ordered mode, the jbd2 layer | ||
| 96 | * will take care of issuing the barrier. In | ||
| 97 | * data=journal, all of the data blocks are written to | ||
| 98 | * the journal device.) | ||
| 99 | */ | ||
| 100 | if (ext4_should_writeback_data(inode) && | ||
| 101 | (journal->j_fs_dev != journal->j_dev) && | ||
| 102 | (journal->j_flags & JBD2_BARRIER)) | ||
| 103 | blkdev_issue_flush(inode->i_sb->s_bdev, NULL); | ||
| 92 | jbd2_log_wait_commit(journal, commit_tid); | 104 | jbd2_log_wait_commit(journal, commit_tid); |
| 93 | else if (journal->j_flags & JBD2_BARRIER) | 105 | } else if (journal->j_flags & JBD2_BARRIER) |
| 94 | blkdev_issue_flush(inode->i_sb->s_bdev, NULL); | 106 | blkdev_issue_flush(inode->i_sb->s_bdev, NULL); |
| 95 | return ret; | 107 | return ret; |
| 96 | } | 108 | } |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ab807963a614..c818972c8302 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -1009,77 +1009,88 @@ qsize_t *ext4_get_reserved_space(struct inode *inode) | |||
| 1009 | return &EXT4_I(inode)->i_reserved_quota; | 1009 | return &EXT4_I(inode)->i_reserved_quota; |
| 1010 | } | 1010 | } |
| 1011 | #endif | 1011 | #endif |
| 1012 | |||
| 1012 | /* | 1013 | /* |
| 1013 | * Calculate the number of metadata blocks need to reserve | 1014 | * Calculate the number of metadata blocks need to reserve |
| 1014 | * to allocate @blocks for non extent file based file | 1015 | * to allocate a new block at @lblocks for non extent file based file |
| 1015 | */ | 1016 | */ |
| 1016 | static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks) | 1017 | static int ext4_indirect_calc_metadata_amount(struct inode *inode, |
| 1018 | sector_t lblock) | ||
| 1017 | { | 1019 | { |
| 1018 | int icap = EXT4_ADDR_PER_BLOCK(inode->i_sb); | 1020 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 1019 | int ind_blks, dind_blks, tind_blks; | 1021 | int dind_mask = EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1; |
| 1020 | 1022 | int blk_bits; | |
| 1021 | /* number of new indirect blocks needed */ | ||
| 1022 | ind_blks = (blocks + icap - 1) / icap; | ||
| 1023 | 1023 | ||
| 1024 | dind_blks = (ind_blks + icap - 1) / icap; | 1024 | if (lblock < EXT4_NDIR_BLOCKS) |
| 1025 | return 0; | ||
| 1025 | 1026 | ||
| 1026 | tind_blks = 1; | 1027 | lblock -= EXT4_NDIR_BLOCKS; |
| 1027 | 1028 | ||
| 1028 | return ind_blks + dind_blks + tind_blks; | 1029 | if (ei->i_da_metadata_calc_len && |
| 1030 | (lblock & dind_mask) == ei->i_da_metadata_calc_last_lblock) { | ||
| 1031 | ei->i_da_metadata_calc_len++; | ||
| 1032 | return 0; | ||
| 1033 | } | ||
| 1034 | ei->i_da_metadata_calc_last_lblock = lblock & dind_mask; | ||
| 1035 | ei->i_da_metadata_calc_len = 1; | ||
| 1036 | blk_bits = roundup_pow_of_two(lblock + 1); | ||
| 1037 | return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1; | ||
| 1029 | } | 1038 | } |
| 1030 | 1039 | ||
| 1031 | /* | 1040 | /* |
| 1032 | * Calculate the number of metadata blocks need to reserve | 1041 | * Calculate the number of metadata blocks need to reserve |
| 1033 | * to allocate given number of blocks | 1042 | * to allocate a block located at @lblock |
| 1034 | */ | 1043 | */ |
| 1035 | static int ext4_calc_metadata_amount(struct inode *inode, int blocks) | 1044 | static int ext4_calc_metadata_amount(struct inode *inode, sector_t lblock) |
| 1036 | { | 1045 | { |
| 1037 | if (!blocks) | ||
| 1038 | return 0; | ||
| 1039 | |||
| 1040 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) | 1046 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) |
| 1041 | return ext4_ext_calc_metadata_amount(inode, blocks); | 1047 | return ext4_ext_calc_metadata_amount(inode, lblock); |
| 1042 | 1048 | ||
| 1043 | return ext4_indirect_calc_metadata_amount(inode, blocks); | 1049 | return ext4_indirect_calc_metadata_amount(inode, lblock); |
| 1044 | } | 1050 | } |
| 1045 | 1051 | ||
| 1052 | /* | ||
| 1053 | * Called with i_data_sem down, which is important since we can call | ||
| 1054 | * ext4_discard_preallocations() from here. | ||
| 1055 | */ | ||
| 1046 | static void ext4_da_update_reserve_space(struct inode *inode, int used) | 1056 | static void ext4_da_update_reserve_space(struct inode *inode, int used) |
| 1047 | { | 1057 | { |
| 1048 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1058 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
| 1049 | int total, mdb, mdb_free, mdb_claim = 0; | 1059 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 1050 | 1060 | int mdb_free = 0; | |
| 1051 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 1061 | |
| 1052 | /* recalculate the number of metablocks still need to be reserved */ | 1062 | spin_lock(&ei->i_block_reservation_lock); |
| 1053 | total = EXT4_I(inode)->i_reserved_data_blocks - used; | 1063 | if (unlikely(used > ei->i_reserved_data_blocks)) { |
| 1054 | mdb = ext4_calc_metadata_amount(inode, total); | 1064 | ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, used %d " |
| 1055 | 1065 | "with only %d reserved data blocks\n", | |
| 1056 | /* figure out how many metablocks to release */ | 1066 | __func__, inode->i_ino, used, |
| 1057 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); | 1067 | ei->i_reserved_data_blocks); |
| 1058 | mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; | 1068 | WARN_ON(1); |
| 1059 | 1069 | used = ei->i_reserved_data_blocks; | |
| 1060 | if (mdb_free) { | 1070 | } |
| 1061 | /* Account for allocated meta_blocks */ | 1071 | |
| 1062 | mdb_claim = EXT4_I(inode)->i_allocated_meta_blocks; | 1072 | /* Update per-inode reservations */ |
| 1063 | BUG_ON(mdb_free < mdb_claim); | 1073 | ei->i_reserved_data_blocks -= used; |
| 1064 | mdb_free -= mdb_claim; | 1074 | used += ei->i_allocated_meta_blocks; |
| 1065 | 1075 | ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; | |
| 1066 | /* update fs dirty blocks counter */ | 1076 | ei->i_allocated_meta_blocks = 0; |
| 1077 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, used); | ||
| 1078 | |||
| 1079 | if (ei->i_reserved_data_blocks == 0) { | ||
| 1080 | /* | ||
| 1081 | * We can release all of the reserved metadata blocks | ||
| 1082 | * only when we have written all of the delayed | ||
| 1083 | * allocation blocks. | ||
| 1084 | */ | ||
| 1085 | mdb_free = ei->i_reserved_meta_blocks; | ||
| 1086 | ei->i_reserved_meta_blocks = 0; | ||
| 1087 | ei->i_da_metadata_calc_len = 0; | ||
| 1067 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); | 1088 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); |
| 1068 | EXT4_I(inode)->i_allocated_meta_blocks = 0; | ||
| 1069 | EXT4_I(inode)->i_reserved_meta_blocks = mdb; | ||
| 1070 | } | 1089 | } |
| 1071 | |||
| 1072 | /* update per-inode reservations */ | ||
| 1073 | BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); | ||
| 1074 | EXT4_I(inode)->i_reserved_data_blocks -= used; | ||
| 1075 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, used + mdb_claim); | ||
| 1076 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 1090 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
| 1077 | 1091 | ||
| 1078 | vfs_dq_claim_block(inode, used + mdb_claim); | 1092 | /* Update quota subsystem */ |
| 1079 | 1093 | vfs_dq_claim_block(inode, used); | |
| 1080 | /* | ||
| 1081 | * free those over-booking quota for metadata blocks | ||
| 1082 | */ | ||
| 1083 | if (mdb_free) | 1094 | if (mdb_free) |
| 1084 | vfs_dq_release_reservation_block(inode, mdb_free); | 1095 | vfs_dq_release_reservation_block(inode, mdb_free); |
| 1085 | 1096 | ||
| @@ -1088,7 +1099,8 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) | |||
| 1088 | * there aren't any writers on the inode, we can discard the | 1099 | * there aren't any writers on the inode, we can discard the |
| 1089 | * inode's preallocations. | 1100 | * inode's preallocations. |
| 1090 | */ | 1101 | */ |
| 1091 | if (!total && (atomic_read(&inode->i_writecount) == 0)) | 1102 | if ((ei->i_reserved_data_blocks == 0) && |
| 1103 | (atomic_read(&inode->i_writecount) == 0)) | ||
| 1092 | ext4_discard_preallocations(inode); | 1104 | ext4_discard_preallocations(inode); |
| 1093 | } | 1105 | } |
| 1094 | 1106 | ||
| @@ -1797,11 +1809,15 @@ static int ext4_journalled_write_end(struct file *file, | |||
| 1797 | return ret ? ret : copied; | 1809 | return ret ? ret : copied; |
| 1798 | } | 1810 | } |
| 1799 | 1811 | ||
| 1800 | static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | 1812 | /* |
| 1813 | * Reserve a single block located at lblock | ||
| 1814 | */ | ||
| 1815 | static int ext4_da_reserve_space(struct inode *inode, sector_t lblock) | ||
| 1801 | { | 1816 | { |
| 1802 | int retries = 0; | 1817 | int retries = 0; |
| 1803 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1818 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
| 1804 | unsigned long md_needed, mdblocks, total = 0; | 1819 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 1820 | unsigned long md_needed, md_reserved; | ||
| 1805 | 1821 | ||
| 1806 | /* | 1822 | /* |
| 1807 | * recalculate the amount of metadata blocks to reserve | 1823 | * recalculate the amount of metadata blocks to reserve |
| @@ -1809,35 +1825,43 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) | |||
| 1809 | * worse case is one extent per block | 1825 | * worse case is one extent per block |
| 1810 | */ | 1826 | */ |
| 1811 | repeat: | 1827 | repeat: |
| 1812 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 1828 | spin_lock(&ei->i_block_reservation_lock); |
| 1813 | total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; | 1829 | md_reserved = ei->i_reserved_meta_blocks; |
| 1814 | mdblocks = ext4_calc_metadata_amount(inode, total); | 1830 | md_needed = ext4_calc_metadata_amount(inode, lblock); |
| 1815 | BUG_ON(mdblocks < EXT4_I(inode)->i_reserved_meta_blocks); | 1831 | spin_unlock(&ei->i_block_reservation_lock); |
| 1816 | |||
| 1817 | md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; | ||
| 1818 | total = md_needed + nrblocks; | ||
| 1819 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | ||
| 1820 | 1832 | ||
| 1821 | /* | 1833 | /* |
| 1822 | * Make quota reservation here to prevent quota overflow | 1834 | * Make quota reservation here to prevent quota overflow |
| 1823 | * later. Real quota accounting is done at pages writeout | 1835 | * later. Real quota accounting is done at pages writeout |
| 1824 | * time. | 1836 | * time. |
| 1825 | */ | 1837 | */ |
| 1826 | if (vfs_dq_reserve_block(inode, total)) | 1838 | if (vfs_dq_reserve_block(inode, md_needed + 1)) { |
| 1839 | /* | ||
| 1840 | * We tend to badly over-estimate the amount of | ||
| 1841 | * metadata blocks which are needed, so if we have | ||
| 1842 | * reserved any metadata blocks, try to force out the | ||
| 1843 | * inode and see if we have any better luck. | ||
| 1844 | */ | ||
| 1845 | if (md_reserved && retries++ <= 3) | ||
| 1846 | goto retry; | ||
| 1827 | return -EDQUOT; | 1847 | return -EDQUOT; |
| 1848 | } | ||
| 1828 | 1849 | ||
| 1829 | if (ext4_claim_free_blocks(sbi, total)) { | 1850 | if (ext4_claim_free_blocks(sbi, md_needed + 1)) { |
| 1830 | vfs_dq_release_reservation_block(inode, total); | 1851 | vfs_dq_release_reservation_block(inode, md_needed + 1); |
| 1831 | if (ext4_should_retry_alloc(inode->i_sb, &retries)) { | 1852 | if (ext4_should_retry_alloc(inode->i_sb, &retries)) { |
| 1853 | retry: | ||
| 1854 | if (md_reserved) | ||
| 1855 | write_inode_now(inode, (retries == 3)); | ||
| 1832 | yield(); | 1856 | yield(); |
| 1833 | goto repeat; | 1857 | goto repeat; |
| 1834 | } | 1858 | } |
| 1835 | return -ENOSPC; | 1859 | return -ENOSPC; |
| 1836 | } | 1860 | } |
| 1837 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 1861 | spin_lock(&ei->i_block_reservation_lock); |
| 1838 | EXT4_I(inode)->i_reserved_data_blocks += nrblocks; | 1862 | ei->i_reserved_data_blocks++; |
| 1839 | EXT4_I(inode)->i_reserved_meta_blocks += md_needed; | 1863 | ei->i_reserved_meta_blocks += md_needed; |
| 1840 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 1864 | spin_unlock(&ei->i_block_reservation_lock); |
| 1841 | 1865 | ||
| 1842 | return 0; /* success */ | 1866 | return 0; /* success */ |
| 1843 | } | 1867 | } |
| @@ -1845,49 +1869,46 @@ repeat: | |||
| 1845 | static void ext4_da_release_space(struct inode *inode, int to_free) | 1869 | static void ext4_da_release_space(struct inode *inode, int to_free) |
| 1846 | { | 1870 | { |
| 1847 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1871 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
| 1848 | int total, mdb, mdb_free, release; | 1872 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 1849 | 1873 | ||
| 1850 | if (!to_free) | 1874 | if (!to_free) |
| 1851 | return; /* Nothing to release, exit */ | 1875 | return; /* Nothing to release, exit */ |
| 1852 | 1876 | ||
| 1853 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | 1877 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); |
| 1854 | 1878 | ||
| 1855 | if (!EXT4_I(inode)->i_reserved_data_blocks) { | 1879 | if (unlikely(to_free > ei->i_reserved_data_blocks)) { |
| 1856 | /* | 1880 | /* |
| 1857 | * if there is no reserved blocks, but we try to free some | 1881 | * if there aren't enough reserved blocks, then the |
| 1858 | * then the counter is messed up somewhere. | 1882 | * counter is messed up somewhere. Since this |
| 1859 | * but since this function is called from invalidate | 1883 | * function is called from invalidate page, it's |
| 1860 | * page, it's harmless to return without any action | 1884 | * harmless to return without any action. |
| 1861 | */ | 1885 | */ |
| 1862 | printk(KERN_INFO "ext4 delalloc try to release %d reserved " | 1886 | ext4_msg(inode->i_sb, KERN_NOTICE, "ext4_da_release_space: " |
| 1863 | "blocks for inode %lu, but there is no reserved " | 1887 | "ino %lu, to_free %d with only %d reserved " |
| 1864 | "data blocks\n", to_free, inode->i_ino); | 1888 | "data blocks\n", inode->i_ino, to_free, |
| 1865 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 1889 | ei->i_reserved_data_blocks); |
| 1866 | return; | 1890 | WARN_ON(1); |
| 1891 | to_free = ei->i_reserved_data_blocks; | ||
| 1867 | } | 1892 | } |
| 1893 | ei->i_reserved_data_blocks -= to_free; | ||
| 1868 | 1894 | ||
| 1869 | /* recalculate the number of metablocks still need to be reserved */ | 1895 | if (ei->i_reserved_data_blocks == 0) { |
| 1870 | total = EXT4_I(inode)->i_reserved_data_blocks - to_free; | 1896 | /* |
| 1871 | mdb = ext4_calc_metadata_amount(inode, total); | 1897 | * We can release all of the reserved metadata blocks |
| 1872 | 1898 | * only when we have written all of the delayed | |
| 1873 | /* figure out how many metablocks to release */ | 1899 | * allocation blocks. |
| 1874 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); | 1900 | */ |
| 1875 | mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; | 1901 | to_free += ei->i_reserved_meta_blocks; |
| 1876 | 1902 | ei->i_reserved_meta_blocks = 0; | |
| 1877 | release = to_free + mdb_free; | 1903 | ei->i_da_metadata_calc_len = 0; |
| 1878 | 1904 | } | |
| 1879 | /* update fs dirty blocks counter for truncate case */ | ||
| 1880 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, release); | ||
| 1881 | 1905 | ||
| 1882 | /* update per-inode reservations */ | 1906 | /* update fs dirty blocks counter */ |
| 1883 | BUG_ON(to_free > EXT4_I(inode)->i_reserved_data_blocks); | 1907 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, to_free); |
| 1884 | EXT4_I(inode)->i_reserved_data_blocks -= to_free; | ||
| 1885 | 1908 | ||
| 1886 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); | ||
| 1887 | EXT4_I(inode)->i_reserved_meta_blocks = mdb; | ||
| 1888 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | 1909 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
| 1889 | 1910 | ||
| 1890 | vfs_dq_release_reservation_block(inode, release); | 1911 | vfs_dq_release_reservation_block(inode, to_free); |
| 1891 | } | 1912 | } |
| 1892 | 1913 | ||
| 1893 | static void ext4_da_page_release_reservation(struct page *page, | 1914 | static void ext4_da_page_release_reservation(struct page *page, |
| @@ -2493,7 +2514,7 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, | |||
| 2493 | * XXX: __block_prepare_write() unmaps passed block, | 2514 | * XXX: __block_prepare_write() unmaps passed block, |
| 2494 | * is it OK? | 2515 | * is it OK? |
| 2495 | */ | 2516 | */ |
| 2496 | ret = ext4_da_reserve_space(inode, 1); | 2517 | ret = ext4_da_reserve_space(inode, iblock); |
| 2497 | if (ret) | 2518 | if (ret) |
| 2498 | /* not enough space to reserve */ | 2519 | /* not enough space to reserve */ |
| 2499 | return ret; | 2520 | return ret; |
| @@ -2967,8 +2988,7 @@ retry: | |||
| 2967 | out_writepages: | 2988 | out_writepages: |
| 2968 | if (!no_nrwrite_index_update) | 2989 | if (!no_nrwrite_index_update) |
| 2969 | wbc->no_nrwrite_index_update = 0; | 2990 | wbc->no_nrwrite_index_update = 0; |
| 2970 | if (wbc->nr_to_write > nr_to_writebump) | 2991 | wbc->nr_to_write -= nr_to_writebump; |
| 2971 | wbc->nr_to_write -= nr_to_writebump; | ||
| 2972 | wbc->range_start = range_start; | 2992 | wbc->range_start = range_start; |
| 2973 | trace_ext4_da_writepages_result(inode, wbc, ret, pages_written); | 2993 | trace_ext4_da_writepages_result(inode, wbc, ret, pages_written); |
| 2974 | return ret; | 2994 | return ret; |
| @@ -2993,11 +3013,18 @@ static int ext4_nonda_switch(struct super_block *sb) | |||
| 2993 | if (2 * free_blocks < 3 * dirty_blocks || | 3013 | if (2 * free_blocks < 3 * dirty_blocks || |
| 2994 | free_blocks < (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) { | 3014 | free_blocks < (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) { |
| 2995 | /* | 3015 | /* |
| 2996 | * free block count is less that 150% of dirty blocks | 3016 | * free block count is less than 150% of dirty blocks |
| 2997 | * or free blocks is less that watermark | 3017 | * or free blocks is less than watermark |
| 2998 | */ | 3018 | */ |
| 2999 | return 1; | 3019 | return 1; |
| 3000 | } | 3020 | } |
| 3021 | /* | ||
| 3022 | * Even if we don't switch but are nearing capacity, | ||
| 3023 | * start pushing delalloc when 1/2 of free blocks are dirty. | ||
| 3024 | */ | ||
| 3025 | if (free_blocks < 2 * dirty_blocks) | ||
| 3026 | writeback_inodes_sb_if_idle(sb); | ||
| 3027 | |||
| 3001 | return 0; | 3028 | return 0; |
| 3002 | } | 3029 | } |
| 3003 | 3030 | ||
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index 0ca811061bc7..436521cae456 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
| 18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
| 19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
| 20 | #include <linux/version.h> | ||
| 21 | #include <linux/blkdev.h> | 20 | #include <linux/blkdev.h> |
| 22 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
| 23 | #include "ext4_jbd2.h" | 22 | #include "ext4_jbd2.h" |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6ed9aa91f27d..735c20d5fd56 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -702,6 +702,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
| 702 | ei->i_reserved_data_blocks = 0; | 702 | ei->i_reserved_data_blocks = 0; |
| 703 | ei->i_reserved_meta_blocks = 0; | 703 | ei->i_reserved_meta_blocks = 0; |
| 704 | ei->i_allocated_meta_blocks = 0; | 704 | ei->i_allocated_meta_blocks = 0; |
| 705 | ei->i_da_metadata_calc_len = 0; | ||
| 705 | ei->i_delalloc_reserved_flag = 0; | 706 | ei->i_delalloc_reserved_flag = 0; |
| 706 | spin_lock_init(&(ei->i_block_reservation_lock)); | 707 | spin_lock_init(&(ei->i_block_reservation_lock)); |
| 707 | #ifdef CONFIG_QUOTA | 708 | #ifdef CONFIG_QUOTA |
| @@ -2174,9 +2175,9 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, | |||
| 2174 | struct super_block *sb = sbi->s_buddy_cache->i_sb; | 2175 | struct super_block *sb = sbi->s_buddy_cache->i_sb; |
| 2175 | 2176 | ||
| 2176 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 2177 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
| 2177 | sbi->s_kbytes_written + | 2178 | (unsigned long long)(sbi->s_kbytes_written + |
| 2178 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - | 2179 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - |
| 2179 | EXT4_SB(sb)->s_sectors_written_start) >> 1)); | 2180 | EXT4_SB(sb)->s_sectors_written_start) >> 1))); |
| 2180 | } | 2181 | } |
| 2181 | 2182 | ||
| 2182 | static ssize_t inode_readahead_blks_store(struct ext4_attr *a, | 2183 | static ssize_t inode_readahead_blks_store(struct ext4_attr *a, |
| @@ -4005,6 +4006,7 @@ static inline void unregister_as_ext2(void) | |||
| 4005 | { | 4006 | { |
| 4006 | unregister_filesystem(&ext2_fs_type); | 4007 | unregister_filesystem(&ext2_fs_type); |
| 4007 | } | 4008 | } |
| 4009 | MODULE_ALIAS("ext2"); | ||
| 4008 | #else | 4010 | #else |
| 4009 | static inline void register_as_ext2(void) { } | 4011 | static inline void register_as_ext2(void) { } |
| 4010 | static inline void unregister_as_ext2(void) { } | 4012 | static inline void unregister_as_ext2(void) { } |
| @@ -4031,6 +4033,7 @@ static inline void unregister_as_ext3(void) | |||
| 4031 | { | 4033 | { |
| 4032 | unregister_filesystem(&ext3_fs_type); | 4034 | unregister_filesystem(&ext3_fs_type); |
| 4033 | } | 4035 | } |
| 4036 | MODULE_ALIAS("ext3"); | ||
| 4034 | #else | 4037 | #else |
| 4035 | static inline void register_as_ext3(void) { } | 4038 | static inline void register_as_ext3(void) { } |
| 4036 | static inline void unregister_as_ext3(void) { } | 4039 | static inline void unregister_as_ext3(void) { } |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 83218bebbc7c..f3a2f7ed45aa 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
| @@ -1332,6 +1332,8 @@ retry: | |||
| 1332 | goto cleanup; | 1332 | goto cleanup; |
| 1333 | kfree(b_entry_name); | 1333 | kfree(b_entry_name); |
| 1334 | kfree(buffer); | 1334 | kfree(buffer); |
| 1335 | b_entry_name = NULL; | ||
| 1336 | buffer = NULL; | ||
| 1335 | brelse(is->iloc.bh); | 1337 | brelse(is->iloc.bh); |
| 1336 | kfree(is); | 1338 | kfree(is); |
| 1337 | kfree(bs); | 1339 | kfree(bs); |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 49bc1b8e8f19..1a7c42c64ff4 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -242,6 +242,7 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi, | |||
| 242 | /** | 242 | /** |
| 243 | * bdi_start_writeback - start writeback | 243 | * bdi_start_writeback - start writeback |
| 244 | * @bdi: the backing device to write from | 244 | * @bdi: the backing device to write from |
| 245 | * @sb: write inodes from this super_block | ||
| 245 | * @nr_pages: the number of pages to write | 246 | * @nr_pages: the number of pages to write |
| 246 | * | 247 | * |
| 247 | * Description: | 248 | * Description: |
| @@ -1187,6 +1188,23 @@ void writeback_inodes_sb(struct super_block *sb) | |||
| 1187 | EXPORT_SYMBOL(writeback_inodes_sb); | 1188 | EXPORT_SYMBOL(writeback_inodes_sb); |
| 1188 | 1189 | ||
| 1189 | /** | 1190 | /** |
| 1191 | * writeback_inodes_sb_if_idle - start writeback if none underway | ||
| 1192 | * @sb: the superblock | ||
| 1193 | * | ||
| 1194 | * Invoke writeback_inodes_sb if no writeback is currently underway. | ||
| 1195 | * Returns 1 if writeback was started, 0 if not. | ||
| 1196 | */ | ||
| 1197 | int writeback_inodes_sb_if_idle(struct super_block *sb) | ||
| 1198 | { | ||
| 1199 | if (!writeback_in_progress(sb->s_bdi)) { | ||
| 1200 | writeback_inodes_sb(sb); | ||
| 1201 | return 1; | ||
| 1202 | } else | ||
| 1203 | return 0; | ||
| 1204 | } | ||
| 1205 | EXPORT_SYMBOL(writeback_inodes_sb_if_idle); | ||
| 1206 | |||
| 1207 | /** | ||
| 1190 | * sync_inodes_sb - sync sb inode pages | 1208 | * sync_inodes_sb - sync sb inode pages |
| 1191 | * @sb: the superblock | 1209 | * @sb: the superblock |
| 1192 | * | 1210 | * |
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index ca0f5eb62b20..886849370950 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/jbd2.h> | 22 | #include <linux/jbd2.h> |
| 23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
| 24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <linux/blkdev.h> | ||
| 25 | #include <trace/events/jbd2.h> | 26 | #include <trace/events/jbd2.h> |
| 26 | 27 | ||
| 27 | /* | 28 | /* |
| @@ -515,6 +516,20 @@ int jbd2_cleanup_journal_tail(journal_t *journal) | |||
| 515 | journal->j_tail_sequence = first_tid; | 516 | journal->j_tail_sequence = first_tid; |
| 516 | journal->j_tail = blocknr; | 517 | journal->j_tail = blocknr; |
| 517 | spin_unlock(&journal->j_state_lock); | 518 | spin_unlock(&journal->j_state_lock); |
| 519 | |||
| 520 | /* | ||
| 521 | * If there is an external journal, we need to make sure that | ||
| 522 | * any data blocks that were recently written out --- perhaps | ||
| 523 | * by jbd2_log_do_checkpoint() --- are flushed out before we | ||
| 524 | * drop the transactions from the external journal. It's | ||
| 525 | * unlikely this will be necessary, especially with a | ||
| 526 | * appropriately sized journal, but we need this to guarantee | ||
| 527 | * correctness. Fortunately jbd2_cleanup_journal_tail() | ||
| 528 | * doesn't get called all that often. | ||
| 529 | */ | ||
| 530 | if ((journal->j_fs_dev != journal->j_dev) && | ||
| 531 | (journal->j_flags & JBD2_BARRIER)) | ||
| 532 | blkdev_issue_flush(journal->j_fs_dev, NULL); | ||
| 518 | if (!(journal->j_flags & JBD2_ABORT)) | 533 | if (!(journal->j_flags & JBD2_ABORT)) |
| 519 | jbd2_journal_update_superblock(journal, 1); | 534 | jbd2_journal_update_superblock(journal, 1); |
| 520 | return 0; | 535 | return 0; |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 6a10238d2c63..1bc74b6f26d2 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
| @@ -259,6 +259,7 @@ static int journal_submit_data_buffers(journal_t *journal, | |||
| 259 | ret = err; | 259 | ret = err; |
| 260 | spin_lock(&journal->j_list_lock); | 260 | spin_lock(&journal->j_list_lock); |
| 261 | J_ASSERT(jinode->i_transaction == commit_transaction); | 261 | J_ASSERT(jinode->i_transaction == commit_transaction); |
| 262 | commit_transaction->t_flushed_data_blocks = 1; | ||
| 262 | jinode->i_flags &= ~JI_COMMIT_RUNNING; | 263 | jinode->i_flags &= ~JI_COMMIT_RUNNING; |
| 263 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); | 264 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); |
| 264 | } | 265 | } |
| @@ -708,8 +709,17 @@ start_journal_io: | |||
| 708 | } | 709 | } |
| 709 | } | 710 | } |
| 710 | 711 | ||
| 711 | /* Done it all: now write the commit record asynchronously. */ | 712 | /* |
| 713 | * If the journal is not located on the file system device, | ||
| 714 | * then we must flush the file system device before we issue | ||
| 715 | * the commit record | ||
| 716 | */ | ||
| 717 | if (commit_transaction->t_flushed_data_blocks && | ||
| 718 | (journal->j_fs_dev != journal->j_dev) && | ||
| 719 | (journal->j_flags & JBD2_BARRIER)) | ||
| 720 | blkdev_issue_flush(journal->j_fs_dev, NULL); | ||
| 712 | 721 | ||
| 722 | /* Done it all: now write the commit record asynchronously. */ | ||
| 713 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, | 723 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, |
| 714 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { | 724 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { |
| 715 | err = journal_submit_commit_record(journal, commit_transaction, | 725 | err = journal_submit_commit_record(journal, commit_transaction, |
| @@ -720,13 +730,6 @@ start_journal_io: | |||
| 720 | blkdev_issue_flush(journal->j_dev, NULL); | 730 | blkdev_issue_flush(journal->j_dev, NULL); |
| 721 | } | 731 | } |
| 722 | 732 | ||
| 723 | /* | ||
| 724 | * This is the right place to wait for data buffers both for ASYNC | ||
| 725 | * and !ASYNC commit. If commit is ASYNC, we need to wait only after | ||
| 726 | * the commit block went to disk (which happens above). If commit is | ||
| 727 | * SYNC, we need to wait for data buffers before we start writing | ||
| 728 | * commit block, which happens below in such setting. | ||
| 729 | */ | ||
| 730 | err = journal_finish_inode_data_buffers(journal, commit_transaction); | 733 | err = journal_finish_inode_data_buffers(journal, commit_transaction); |
| 731 | if (err) { | 734 | if (err) { |
| 732 | printk(KERN_WARNING | 735 | printk(KERN_WARNING |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 17af879e6e9e..ac0d027595d0 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -814,7 +814,7 @@ static journal_t * journal_init_common (void) | |||
| 814 | journal_t *journal; | 814 | journal_t *journal; |
| 815 | int err; | 815 | int err; |
| 816 | 816 | ||
| 817 | journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL); | 817 | journal = kzalloc(sizeof(*journal), GFP_KERNEL); |
| 818 | if (!journal) | 818 | if (!journal) |
| 819 | goto fail; | 819 | goto fail; |
| 820 | 820 | ||
diff --git a/fs/namei.c b/fs/namei.c index 68921d9b5302..b55440baf7ab 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -232,6 +232,7 @@ int generic_permission(struct inode *inode, int mask, | |||
| 232 | /* | 232 | /* |
| 233 | * Searching includes executable on directories, else just read. | 233 | * Searching includes executable on directories, else just read. |
| 234 | */ | 234 | */ |
| 235 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; | ||
| 235 | if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) | 236 | if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) |
| 236 | if (capable(CAP_DAC_READ_SEARCH)) | 237 | if (capable(CAP_DAC_READ_SEARCH)) |
| 237 | return 0; | 238 | return 0; |
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index f4a14ea2ed9c..effdbdbe6c11 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
| @@ -417,8 +417,8 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap, | |||
| 417 | 417 | ||
| 418 | key = page_index(bh->b_page) << (PAGE_CACHE_SHIFT - | 418 | key = page_index(bh->b_page) << (PAGE_CACHE_SHIFT - |
| 419 | bmap->b_inode->i_blkbits); | 419 | bmap->b_inode->i_blkbits); |
| 420 | for (pbh = page_buffers(bh->b_page); pbh != bh; | 420 | for (pbh = page_buffers(bh->b_page); pbh != bh; pbh = pbh->b_this_page) |
| 421 | pbh = pbh->b_this_page, key++); | 421 | key++; |
| 422 | 422 | ||
| 423 | return key; | 423 | return key; |
| 424 | } | 424 | } |
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index d5ad54e204a5..18737818db63 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
| @@ -328,19 +328,24 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
| 328 | tnicps += nicps; | 328 | tnicps += nicps; |
| 329 | nilfs_mdt_mark_buffer_dirty(cp_bh); | 329 | nilfs_mdt_mark_buffer_dirty(cp_bh); |
| 330 | nilfs_mdt_mark_dirty(cpfile); | 330 | nilfs_mdt_mark_dirty(cpfile); |
| 331 | if (!nilfs_cpfile_is_in_first(cpfile, cno) && | 331 | if (!nilfs_cpfile_is_in_first(cpfile, cno)) { |
| 332 | (count = nilfs_cpfile_block_sub_valid_checkpoints( | 332 | count = |
| 333 | cpfile, cp_bh, kaddr, nicps)) == 0) { | 333 | nilfs_cpfile_block_sub_valid_checkpoints( |
| 334 | /* make hole */ | 334 | cpfile, cp_bh, kaddr, nicps); |
| 335 | kunmap_atomic(kaddr, KM_USER0); | 335 | if (count == 0) { |
| 336 | brelse(cp_bh); | 336 | /* make hole */ |
| 337 | ret = nilfs_cpfile_delete_checkpoint_block( | 337 | kunmap_atomic(kaddr, KM_USER0); |
| 338 | cpfile, cno); | 338 | brelse(cp_bh); |
| 339 | if (ret == 0) | 339 | ret = |
| 340 | continue; | 340 | nilfs_cpfile_delete_checkpoint_block( |
| 341 | printk(KERN_ERR "%s: cannot delete block\n", | 341 | cpfile, cno); |
| 342 | __func__); | 342 | if (ret == 0) |
| 343 | break; | 343 | continue; |
| 344 | printk(KERN_ERR | ||
| 345 | "%s: cannot delete block\n", | ||
| 346 | __func__); | ||
| 347 | break; | ||
| 348 | } | ||
| 344 | } | 349 | } |
| 345 | } | 350 | } |
| 346 | 351 | ||
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c index d369ac718277..236753df5cdf 100644 --- a/fs/nilfs2/direct.c +++ b/fs/nilfs2/direct.c | |||
| @@ -51,11 +51,11 @@ static int nilfs_direct_lookup(const struct nilfs_bmap *bmap, | |||
| 51 | struct nilfs_direct *direct; | 51 | struct nilfs_direct *direct; |
| 52 | __u64 ptr; | 52 | __u64 ptr; |
| 53 | 53 | ||
| 54 | direct = (struct nilfs_direct *)bmap; | 54 | direct = (struct nilfs_direct *)bmap; /* XXX: use macro for level 1 */ |
| 55 | if ((key > NILFS_DIRECT_KEY_MAX) || | 55 | if (key > NILFS_DIRECT_KEY_MAX || level != 1) |
| 56 | (level != 1) || /* XXX: use macro for level 1 */ | 56 | return -ENOENT; |
| 57 | ((ptr = nilfs_direct_get_ptr(direct, key)) == | 57 | ptr = nilfs_direct_get_ptr(direct, key); |
| 58 | NILFS_BMAP_INVALID_PTR)) | 58 | if (ptr == NILFS_BMAP_INVALID_PTR) |
| 59 | return -ENOENT; | 59 | return -ENOENT; |
| 60 | 60 | ||
| 61 | if (ptrp != NULL) | 61 | if (ptrp != NULL) |
| @@ -73,9 +73,10 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap, | |||
| 73 | sector_t blocknr; | 73 | sector_t blocknr; |
| 74 | int ret, cnt; | 74 | int ret, cnt; |
| 75 | 75 | ||
| 76 | if (key > NILFS_DIRECT_KEY_MAX || | 76 | if (key > NILFS_DIRECT_KEY_MAX) |
| 77 | (ptr = nilfs_direct_get_ptr(direct, key)) == | 77 | return -ENOENT; |
| 78 | NILFS_BMAP_INVALID_PTR) | 78 | ptr = nilfs_direct_get_ptr(direct, key); |
| 79 | if (ptr == NILFS_BMAP_INVALID_PTR) | ||
| 79 | return -ENOENT; | 80 | return -ENOENT; |
| 80 | 81 | ||
| 81 | if (NILFS_BMAP_USE_VBN(bmap)) { | 82 | if (NILFS_BMAP_USE_VBN(bmap)) { |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index f6af76042d80..d6b2b83de363 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
| @@ -480,7 +480,7 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, | |||
| 480 | unsigned int cmd, void __user *argp) | 480 | unsigned int cmd, void __user *argp) |
| 481 | { | 481 | { |
| 482 | struct nilfs_argv argv[5]; | 482 | struct nilfs_argv argv[5]; |
| 483 | const static size_t argsz[5] = { | 483 | static const size_t argsz[5] = { |
| 484 | sizeof(struct nilfs_vdesc), | 484 | sizeof(struct nilfs_vdesc), |
| 485 | sizeof(struct nilfs_period), | 485 | sizeof(struct nilfs_period), |
| 486 | sizeof(__u64), | 486 | sizeof(__u64), |
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 685495707181..65c872761177 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
| @@ -1277,7 +1277,10 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) | |||
| 1277 | struct reiserfs_bitmap_info *bitmap; | 1277 | struct reiserfs_bitmap_info *bitmap; |
| 1278 | unsigned int bmap_nr = reiserfs_bmap_count(sb); | 1278 | unsigned int bmap_nr = reiserfs_bmap_count(sb); |
| 1279 | 1279 | ||
| 1280 | /* Avoid lock recursion in fault case */ | ||
| 1281 | reiserfs_write_unlock(sb); | ||
| 1280 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); | 1282 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); |
| 1283 | reiserfs_write_lock(sb); | ||
| 1281 | if (bitmap == NULL) | 1284 | if (bitmap == NULL) |
| 1282 | return -ENOMEM; | 1285 | return -ENOMEM; |
| 1283 | 1286 | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 290ae38fca8a..1150ebb2536f 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
| @@ -31,11 +31,12 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 31 | JOURNAL_PER_BALANCE_CNT * 2 + | 31 | JOURNAL_PER_BALANCE_CNT * 2 + |
| 32 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); | 32 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); |
| 33 | struct reiserfs_transaction_handle th; | 33 | struct reiserfs_transaction_handle th; |
| 34 | int depth; | ||
| 34 | int err; | 35 | int err; |
| 35 | 36 | ||
| 36 | truncate_inode_pages(&inode->i_data, 0); | 37 | truncate_inode_pages(&inode->i_data, 0); |
| 37 | 38 | ||
| 38 | reiserfs_write_lock(inode->i_sb); | 39 | depth = reiserfs_write_lock_once(inode->i_sb); |
| 39 | 40 | ||
| 40 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ | 41 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ |
| 41 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ | 42 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ |
| @@ -74,7 +75,7 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 74 | out: | 75 | out: |
| 75 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ | 76 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ |
| 76 | inode->i_blocks = 0; | 77 | inode->i_blocks = 0; |
| 77 | reiserfs_write_unlock(inode->i_sb); | 78 | reiserfs_write_unlock_once(inode->i_sb, depth); |
| 78 | } | 79 | } |
| 79 | 80 | ||
| 80 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, | 81 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 2f8a7e7b8dab..83ac4d3b3cb0 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
| @@ -2009,10 +2009,11 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
| 2009 | destroy_workqueue(commit_wq); | 2009 | destroy_workqueue(commit_wq); |
| 2010 | commit_wq = NULL; | 2010 | commit_wq = NULL; |
| 2011 | } | 2011 | } |
| 2012 | reiserfs_write_lock(sb); | ||
| 2013 | 2012 | ||
| 2014 | free_journal_ram(sb); | 2013 | free_journal_ram(sb); |
| 2015 | 2014 | ||
| 2015 | reiserfs_write_lock(sb); | ||
| 2016 | |||
| 2016 | return 0; | 2017 | return 0; |
| 2017 | } | 2018 | } |
| 2018 | 2019 | ||
| @@ -2758,11 +2759,18 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
| 2758 | struct reiserfs_journal *journal; | 2759 | struct reiserfs_journal *journal; |
| 2759 | struct reiserfs_journal_list *jl; | 2760 | struct reiserfs_journal_list *jl; |
| 2760 | char b[BDEVNAME_SIZE]; | 2761 | char b[BDEVNAME_SIZE]; |
| 2762 | int ret; | ||
| 2761 | 2763 | ||
| 2764 | /* | ||
| 2765 | * Unlock here to avoid various RECLAIM-FS-ON <-> IN-RECLAIM-FS | ||
| 2766 | * dependency inversion warnings. | ||
| 2767 | */ | ||
| 2768 | reiserfs_write_unlock(sb); | ||
| 2762 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); | 2769 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); |
| 2763 | if (!journal) { | 2770 | if (!journal) { |
| 2764 | reiserfs_warning(sb, "journal-1256", | 2771 | reiserfs_warning(sb, "journal-1256", |
| 2765 | "unable to get memory for journal structure"); | 2772 | "unable to get memory for journal structure"); |
| 2773 | reiserfs_write_lock(sb); | ||
| 2766 | return 1; | 2774 | return 1; |
| 2767 | } | 2775 | } |
| 2768 | memset(journal, 0, sizeof(struct reiserfs_journal)); | 2776 | memset(journal, 0, sizeof(struct reiserfs_journal)); |
| @@ -2771,10 +2779,12 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
| 2771 | INIT_LIST_HEAD(&journal->j_working_list); | 2779 | INIT_LIST_HEAD(&journal->j_working_list); |
| 2772 | INIT_LIST_HEAD(&journal->j_journal_list); | 2780 | INIT_LIST_HEAD(&journal->j_journal_list); |
| 2773 | journal->j_persistent_trans = 0; | 2781 | journal->j_persistent_trans = 0; |
| 2774 | if (reiserfs_allocate_list_bitmaps(sb, | 2782 | ret = reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap, |
| 2775 | journal->j_list_bitmap, | 2783 | reiserfs_bmap_count(sb)); |
| 2776 | reiserfs_bmap_count(sb))) | 2784 | reiserfs_write_lock(sb); |
| 2785 | if (ret) | ||
| 2777 | goto free_and_return; | 2786 | goto free_and_return; |
| 2787 | |||
| 2778 | allocate_bitmap_nodes(sb); | 2788 | allocate_bitmap_nodes(sb); |
| 2779 | 2789 | ||
| 2780 | /* reserved for journal area support */ | 2790 | /* reserved for journal area support */ |
diff --git a/fs/reiserfs/lock.c b/fs/reiserfs/lock.c index ee2cfc0fd8a7..b87aa2c1afc1 100644 --- a/fs/reiserfs/lock.c +++ b/fs/reiserfs/lock.c | |||
| @@ -86,3 +86,12 @@ void reiserfs_check_lock_depth(struct super_block *sb, char *caller) | |||
| 86 | reiserfs_panic(sb, "%s called without kernel lock held %d", | 86 | reiserfs_panic(sb, "%s called without kernel lock held %d", |
| 87 | caller); | 87 | caller); |
| 88 | } | 88 | } |
| 89 | |||
| 90 | #ifdef CONFIG_REISERFS_CHECK | ||
| 91 | void reiserfs_lock_check_recursive(struct super_block *sb) | ||
| 92 | { | ||
| 93 | struct reiserfs_sb_info *sb_i = REISERFS_SB(sb); | ||
| 94 | |||
| 95 | WARN_ONCE((sb_i->lock_depth > 0), "Unwanted recursive reiserfs lock!\n"); | ||
| 96 | } | ||
| 97 | #endif | ||
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index e296ff72a6cc..9d4dcf0b07cb 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
| @@ -921,6 +921,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 921 | struct reiserfs_transaction_handle th; | 921 | struct reiserfs_transaction_handle th; |
| 922 | int jbegin_count; | 922 | int jbegin_count; |
| 923 | unsigned long savelink; | 923 | unsigned long savelink; |
| 924 | int depth; | ||
| 924 | 925 | ||
| 925 | inode = dentry->d_inode; | 926 | inode = dentry->d_inode; |
| 926 | 927 | ||
| @@ -932,7 +933,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 932 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + | 933 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + |
| 933 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | 934 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); |
| 934 | 935 | ||
| 935 | reiserfs_write_lock(dir->i_sb); | 936 | depth = reiserfs_write_lock_once(dir->i_sb); |
| 936 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | 937 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
| 937 | if (retval) | 938 | if (retval) |
| 938 | goto out_unlink; | 939 | goto out_unlink; |
| @@ -993,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 993 | 994 | ||
| 994 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 995 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
| 995 | reiserfs_check_path(&path); | 996 | reiserfs_check_path(&path); |
| 996 | reiserfs_write_unlock(dir->i_sb); | 997 | reiserfs_write_unlock_once(dir->i_sb, depth); |
| 997 | return retval; | 998 | return retval; |
| 998 | 999 | ||
| 999 | end_unlink: | 1000 | end_unlink: |
| @@ -1003,7 +1004,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 1003 | if (err) | 1004 | if (err) |
| 1004 | retval = err; | 1005 | retval = err; |
| 1005 | out_unlink: | 1006 | out_unlink: |
| 1006 | reiserfs_write_unlock(dir->i_sb); | 1007 | reiserfs_write_unlock_once(dir->i_sb, depth); |
| 1007 | return retval; | 1008 | return retval; |
| 1008 | } | 1009 | } |
| 1009 | 1010 | ||
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 8c7033a8b67e..c3b004ee627b 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -83,7 +83,8 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry) | |||
| 83 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 83 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
| 84 | vfs_dq_init(dir); | 84 | vfs_dq_init(dir); |
| 85 | 85 | ||
| 86 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 86 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
| 87 | I_MUTEX_CHILD, dir->i_sb); | ||
| 87 | error = dir->i_op->unlink(dir, dentry); | 88 | error = dir->i_op->unlink(dir, dentry); |
| 88 | mutex_unlock(&dentry->d_inode->i_mutex); | 89 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 89 | 90 | ||
| @@ -98,7 +99,8 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 98 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 99 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
| 99 | vfs_dq_init(dir); | 100 | vfs_dq_init(dir); |
| 100 | 101 | ||
| 101 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 102 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
| 103 | I_MUTEX_CHILD, dir->i_sb); | ||
| 102 | dentry_unhash(dentry); | 104 | dentry_unhash(dentry); |
| 103 | error = dir->i_op->rmdir(dir, dentry); | 105 | error = dir->i_op->rmdir(dir, dentry); |
| 104 | if (!error) | 106 | if (!error) |
| @@ -235,16 +237,22 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
| 235 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) | 237 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) |
| 236 | return 0; | 238 | return 0; |
| 237 | 239 | ||
| 240 | reiserfs_write_unlock(inode->i_sb); | ||
| 238 | dir = open_xa_dir(inode, XATTR_REPLACE); | 241 | dir = open_xa_dir(inode, XATTR_REPLACE); |
| 239 | if (IS_ERR(dir)) { | 242 | if (IS_ERR(dir)) { |
| 240 | err = PTR_ERR(dir); | 243 | err = PTR_ERR(dir); |
| 244 | reiserfs_write_lock(inode->i_sb); | ||
| 241 | goto out; | 245 | goto out; |
| 242 | } else if (!dir->d_inode) { | 246 | } else if (!dir->d_inode) { |
| 243 | err = 0; | 247 | err = 0; |
| 248 | reiserfs_write_lock(inode->i_sb); | ||
| 244 | goto out_dir; | 249 | goto out_dir; |
| 245 | } | 250 | } |
| 246 | 251 | ||
| 247 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | 252 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); |
| 253 | |||
| 254 | reiserfs_write_lock(inode->i_sb); | ||
| 255 | |||
| 248 | buf.xadir = dir; | 256 | buf.xadir = dir; |
| 249 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); | 257 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); |
| 250 | while ((err == 0 || err == -ENOSPC) && buf.count) { | 258 | while ((err == 0 || err == -ENOSPC) && buf.count) { |
| @@ -283,8 +291,9 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
| 283 | err = journal_begin(&th, inode->i_sb, blocks); | 291 | err = journal_begin(&th, inode->i_sb, blocks); |
| 284 | if (!err) { | 292 | if (!err) { |
| 285 | int jerror; | 293 | int jerror; |
| 286 | mutex_lock_nested(&dir->d_parent->d_inode->i_mutex, | 294 | reiserfs_mutex_lock_nested_safe( |
| 287 | I_MUTEX_XATTR); | 295 | &dir->d_parent->d_inode->i_mutex, |
| 296 | I_MUTEX_XATTR, inode->i_sb); | ||
| 288 | err = action(dir, data); | 297 | err = action(dir, data); |
| 289 | jerror = journal_end(&th, inode->i_sb, blocks); | 298 | jerror = journal_end(&th, inode->i_sb, blocks); |
| 290 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); | 299 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); |
| @@ -480,11 +489,16 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
| 480 | if (!buffer) | 489 | if (!buffer) |
| 481 | return lookup_and_delete_xattr(inode, name); | 490 | return lookup_and_delete_xattr(inode, name); |
| 482 | 491 | ||
| 492 | reiserfs_write_unlock(inode->i_sb); | ||
| 483 | dentry = xattr_lookup(inode, name, flags); | 493 | dentry = xattr_lookup(inode, name, flags); |
| 484 | if (IS_ERR(dentry)) | 494 | if (IS_ERR(dentry)) { |
| 495 | reiserfs_write_lock(inode->i_sb); | ||
| 485 | return PTR_ERR(dentry); | 496 | return PTR_ERR(dentry); |
| 497 | } | ||
| 486 | 498 | ||
| 487 | down_write(&REISERFS_I(inode)->i_xattr_sem); | 499 | down_read(&REISERFS_I(inode)->i_xattr_sem); |
| 500 | |||
| 501 | reiserfs_write_lock(inode->i_sb); | ||
| 488 | 502 | ||
| 489 | xahash = xattr_hash(buffer, buffer_size); | 503 | xahash = xattr_hash(buffer, buffer_size); |
| 490 | while (buffer_pos < buffer_size || buffer_pos == 0) { | 504 | while (buffer_pos < buffer_size || buffer_pos == 0) { |
