diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-09 18:11:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-09 18:11:58 -0500 |
commit | e36aeee65d4db050bd8713537416a0a0632db079 (patch) | |
tree | 4d6ec6397598bb93e877ef84cdd6537a62736484 /fs | |
parent | b2f051ae390432789f2b02fe451aa23ae2698e3d (diff) | |
parent | e325a88f17196f18888f6e1426eb9fe3b4346d28 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
ocfs2: fix rename vs unlink race
[PATCH] Fix possibly too long write in o2hb_setup_one_bio()
ocfs2: fix write() performance regression
ocfs2: Commit journal on sync writes
ocfs2: Re-order iput in ocfs2_drop_dentry_lock
ocfs2: Create locks at initially requested level
[PATCH] Fix priority mistakes in fs/ocfs2/{alloc.c, dlmglue.c}
[2.6 patch] make ocfs2_find_entry_el() static
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/alloc.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/aops.c | 22 | ||||
-rw-r--r-- | fs/ocfs2/cluster/heartbeat.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/dcache.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/dir.c | 6 | ||||
-rw-r--r-- | fs/ocfs2/dlmglue.c | 25 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 26 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 13 |
8 files changed, 73 insertions, 25 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 4ba7f0bdc248..ce62c152823d 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -3946,7 +3946,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
3946 | struct ocfs2_merge_ctxt ctxt; | 3946 | struct ocfs2_merge_ctxt ctxt; |
3947 | struct ocfs2_extent_list *rightmost_el; | 3947 | struct ocfs2_extent_list *rightmost_el; |
3948 | 3948 | ||
3949 | if (!rec->e_flags & OCFS2_EXT_UNWRITTEN) { | 3949 | if (!(rec->e_flags & OCFS2_EXT_UNWRITTEN)) { |
3950 | ret = -EIO; | 3950 | ret = -EIO; |
3951 | mlog_errno(ret); | 3951 | mlog_errno(ret); |
3952 | goto out; | 3952 | goto out; |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index c69c1b300155..556e34ccb005 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -729,6 +729,27 @@ static void ocfs2_clear_page_regions(struct page *page, | |||
729 | } | 729 | } |
730 | 730 | ||
731 | /* | 731 | /* |
732 | * Nonsparse file systems fully allocate before we get to the write | ||
733 | * code. This prevents ocfs2_write() from tagging the write as an | ||
734 | * allocating one, which means ocfs2_map_page_blocks() might try to | ||
735 | * read-in the blocks at the tail of our file. Avoid reading them by | ||
736 | * testing i_size against each block offset. | ||
737 | */ | ||
738 | static int ocfs2_should_read_blk(struct inode *inode, struct page *page, | ||
739 | unsigned int block_start) | ||
740 | { | ||
741 | u64 offset = page_offset(page) + block_start; | ||
742 | |||
743 | if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | ||
744 | return 1; | ||
745 | |||
746 | if (i_size_read(inode) > offset) | ||
747 | return 1; | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | /* | ||
732 | * Some of this taken from block_prepare_write(). We already have our | 753 | * Some of this taken from block_prepare_write(). We already have our |
733 | * mapping by now though, and the entire write will be allocating or | 754 | * mapping by now though, and the entire write will be allocating or |
734 | * it won't, so not much need to use BH_New. | 755 | * it won't, so not much need to use BH_New. |
@@ -781,6 +802,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno, | |||
781 | set_buffer_uptodate(bh); | 802 | set_buffer_uptodate(bh); |
782 | } else if (!buffer_uptodate(bh) && !buffer_delay(bh) && | 803 | } else if (!buffer_uptodate(bh) && !buffer_delay(bh) && |
783 | !buffer_new(bh) && | 804 | !buffer_new(bh) && |
805 | ocfs2_should_read_blk(inode, page, block_start) && | ||
784 | (block_start < from || block_end > to)) { | 806 | (block_start < from || block_end > to)) { |
785 | ll_rw_block(READ, 1, &bh); | 807 | ll_rw_block(READ, 1, &bh); |
786 | *wait_bh++=bh; | 808 | *wait_bh++=bh; |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 9cc7c0418b70..f02ccb34604d 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -267,7 +267,7 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg, | |||
267 | current_page = cs / spp; | 267 | current_page = cs / spp; |
268 | page = reg->hr_slot_data[current_page]; | 268 | page = reg->hr_slot_data[current_page]; |
269 | 269 | ||
270 | vec_len = min(PAGE_CACHE_SIZE, | 270 | vec_len = min(PAGE_CACHE_SIZE - vec_start, |
271 | (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); | 271 | (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); |
272 | 272 | ||
273 | mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n", | 273 | mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n", |
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index 3094ddb7a254..1957a5ed219e 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c | |||
@@ -318,9 +318,9 @@ out_attach: | |||
318 | static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, | 318 | static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, |
319 | struct ocfs2_dentry_lock *dl) | 319 | struct ocfs2_dentry_lock *dl) |
320 | { | 320 | { |
321 | iput(dl->dl_inode); | ||
321 | ocfs2_simple_drop_lockres(osb, &dl->dl_lockres); | 322 | ocfs2_simple_drop_lockres(osb, &dl->dl_lockres); |
322 | ocfs2_lock_res_free(&dl->dl_lockres); | 323 | ocfs2_lock_res_free(&dl->dl_lockres); |
323 | iput(dl->dl_inode); | ||
324 | kfree(dl); | 324 | kfree(dl); |
325 | } | 325 | } |
326 | 326 | ||
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 6a2f143e269c..63b28fdceb4a 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -208,9 +208,9 @@ out: | |||
208 | return NULL; | 208 | return NULL; |
209 | } | 209 | } |
210 | 210 | ||
211 | struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen, | 211 | static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen, |
212 | struct inode *dir, | 212 | struct inode *dir, |
213 | struct ocfs2_dir_entry **res_dir) | 213 | struct ocfs2_dir_entry **res_dir) |
214 | { | 214 | { |
215 | struct super_block *sb; | 215 | struct super_block *sb; |
216 | struct buffer_head *bh_use[NAMEI_RA_SIZE]; | 216 | struct buffer_head *bh_use[NAMEI_RA_SIZE]; |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 41c76ff2fcfb..4e97dcceaf8f 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -670,7 +670,7 @@ static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *loc | |||
670 | { | 670 | { |
671 | mlog_entry_void(); | 671 | mlog_entry_void(); |
672 | 672 | ||
673 | BUG_ON((!lockres->l_flags & OCFS2_LOCK_BUSY)); | 673 | BUG_ON((!(lockres->l_flags & OCFS2_LOCK_BUSY))); |
674 | BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED); | 674 | BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED); |
675 | 675 | ||
676 | if (lockres->l_requested > LKM_NLMODE && | 676 | if (lockres->l_requested > LKM_NLMODE && |
@@ -980,18 +980,6 @@ again: | |||
980 | goto unlock; | 980 | goto unlock; |
981 | } | 981 | } |
982 | 982 | ||
983 | if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) { | ||
984 | /* lock has not been created yet. */ | ||
985 | spin_unlock_irqrestore(&lockres->l_lock, flags); | ||
986 | |||
987 | ret = ocfs2_lock_create(osb, lockres, LKM_NLMODE, 0); | ||
988 | if (ret < 0) { | ||
989 | mlog_errno(ret); | ||
990 | goto out; | ||
991 | } | ||
992 | goto again; | ||
993 | } | ||
994 | |||
995 | if (lockres->l_flags & OCFS2_LOCK_BLOCKED && | 983 | if (lockres->l_flags & OCFS2_LOCK_BLOCKED && |
996 | !ocfs2_may_continue_on_blocked_lock(lockres, level)) { | 984 | !ocfs2_may_continue_on_blocked_lock(lockres, level)) { |
997 | /* is the lock is currently blocked on behalf of | 985 | /* is the lock is currently blocked on behalf of |
@@ -1006,7 +994,14 @@ again: | |||
1006 | mlog(ML_ERROR, "lockres %s has action %u pending\n", | 994 | mlog(ML_ERROR, "lockres %s has action %u pending\n", |
1007 | lockres->l_name, lockres->l_action); | 995 | lockres->l_name, lockres->l_action); |
1008 | 996 | ||
1009 | lockres->l_action = OCFS2_AST_CONVERT; | 997 | if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) { |
998 | lockres->l_action = OCFS2_AST_ATTACH; | ||
999 | lkm_flags &= ~LKM_CONVERT; | ||
1000 | } else { | ||
1001 | lockres->l_action = OCFS2_AST_CONVERT; | ||
1002 | lkm_flags |= LKM_CONVERT; | ||
1003 | } | ||
1004 | |||
1010 | lockres->l_requested = level; | 1005 | lockres->l_requested = level; |
1011 | lockres_or_flags(lockres, OCFS2_LOCK_BUSY); | 1006 | lockres_or_flags(lockres, OCFS2_LOCK_BUSY); |
1012 | spin_unlock_irqrestore(&lockres->l_lock, flags); | 1007 | spin_unlock_irqrestore(&lockres->l_lock, flags); |
@@ -1021,7 +1016,7 @@ again: | |||
1021 | status = dlmlock(osb->dlm, | 1016 | status = dlmlock(osb->dlm, |
1022 | level, | 1017 | level, |
1023 | &lockres->l_lksb, | 1018 | &lockres->l_lksb, |
1024 | lkm_flags|LKM_CONVERT, | 1019 | lkm_flags, |
1025 | lockres->l_name, | 1020 | lockres->l_name, |
1026 | OCFS2_LOCK_ID_MAX_LEN - 1, | 1021 | OCFS2_LOCK_ID_MAX_LEN - 1, |
1027 | ocfs2_locking_ast, | 1022 | ocfs2_locking_ast, |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index f92fe91ff260..bbac7cd33e0b 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1891,9 +1891,11 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1891 | ssize_t written = 0; | 1891 | ssize_t written = 0; |
1892 | size_t ocount; /* original count */ | 1892 | size_t ocount; /* original count */ |
1893 | size_t count; /* after file limit checks */ | 1893 | size_t count; /* after file limit checks */ |
1894 | loff_t *ppos = &iocb->ki_pos; | 1894 | loff_t old_size, *ppos = &iocb->ki_pos; |
1895 | u32 old_clusters; | ||
1895 | struct file *file = iocb->ki_filp; | 1896 | struct file *file = iocb->ki_filp; |
1896 | struct inode *inode = file->f_path.dentry->d_inode; | 1897 | struct inode *inode = file->f_path.dentry->d_inode; |
1898 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1897 | 1899 | ||
1898 | mlog_entry("(0x%p, %u, '%.*s')\n", file, | 1900 | mlog_entry("(0x%p, %u, '%.*s')\n", file, |
1899 | (unsigned int)nr_segs, | 1901 | (unsigned int)nr_segs, |
@@ -1949,6 +1951,13 @@ relock: | |||
1949 | goto relock; | 1951 | goto relock; |
1950 | } | 1952 | } |
1951 | 1953 | ||
1954 | /* | ||
1955 | * To later detect whether a journal commit for sync writes is | ||
1956 | * necessary, we sample i_size, and cluster count here. | ||
1957 | */ | ||
1958 | old_size = i_size_read(inode); | ||
1959 | old_clusters = OCFS2_I(inode)->ip_clusters; | ||
1960 | |||
1952 | /* communicate with ocfs2_dio_end_io */ | 1961 | /* communicate with ocfs2_dio_end_io */ |
1953 | ocfs2_iocb_set_rw_locked(iocb, rw_level); | 1962 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
1954 | 1963 | ||
@@ -1978,6 +1987,21 @@ out_dio: | |||
1978 | /* buffered aio wouldn't have proper lock coverage today */ | 1987 | /* buffered aio wouldn't have proper lock coverage today */ |
1979 | BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); | 1988 | BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); |
1980 | 1989 | ||
1990 | if ((file->f_flags & O_SYNC && !direct_io) || IS_SYNC(inode)) { | ||
1991 | /* | ||
1992 | * The generic write paths have handled getting data | ||
1993 | * to disk, but since we don't make use of the dirty | ||
1994 | * inode list, a manual journal commit is necessary | ||
1995 | * here. | ||
1996 | */ | ||
1997 | if (old_size != i_size_read(inode) || | ||
1998 | old_clusters != OCFS2_I(inode)->ip_clusters) { | ||
1999 | ret = journal_force_commit(osb->journal->j_journal); | ||
2000 | if (ret < 0) | ||
2001 | written = ret; | ||
2002 | } | ||
2003 | } | ||
2004 | |||
1981 | /* | 2005 | /* |
1982 | * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io | 2006 | * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io |
1983 | * function pointer which is called when o_direct io completes so that | 2007 | * function pointer which is called when o_direct io completes so that |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 729259016c18..989ac2718587 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -1105,9 +1105,16 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1105 | goto bail; | 1105 | goto bail; |
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | if (!new_de && new_inode) | 1108 | if (!new_de && new_inode) { |
1109 | mlog(ML_ERROR, "inode %lu does not exist in it's parent " | 1109 | /* |
1110 | "directory!", new_inode->i_ino); | 1110 | * Target was unlinked by another node while we were |
1111 | * waiting to get to ocfs2_rename(). There isn't | ||
1112 | * anything we can do here to help the situation, so | ||
1113 | * bubble up the appropriate error. | ||
1114 | */ | ||
1115 | status = -ENOENT; | ||
1116 | goto bail; | ||
1117 | } | ||
1111 | 1118 | ||
1112 | /* In case we need to overwrite an existing file, we blow it | 1119 | /* In case we need to overwrite an existing file, we blow it |
1113 | * away first */ | 1120 | * away first */ |