From efd647f744f3cf504ed83580274bd4b6918139fe Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Tue, 30 Mar 2010 13:21:31 +0800 Subject: ocfs2_dlmfs: User DLM_* when decoding file open flags. In commit 0016eedc4185a3cd7e578b027a6e69001b85d6c4, we have changed dlmfs to use stackglue. So when use DLM* when we decode dlm flags from open level. Signed-off-by: Tao Ma Signed-off-by: Joel Becker --- fs/ocfs2/dlmfs/dlmfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index 1b0de157a08..a99d1eafa8e 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c @@ -112,20 +112,20 @@ MODULE_PARM_DESC(capabilities, DLMFS_CAPABILITIES); * O_RDONLY -> PRMODE level * O_WRONLY -> EXMODE level * - * O_NONBLOCK -> LKM_NOQUEUE + * O_NONBLOCK -> NOQUEUE */ static int dlmfs_decode_open_flags(int open_flags, int *level, int *flags) { if (open_flags & (O_WRONLY|O_RDWR)) - *level = LKM_EXMODE; + *level = DLM_LOCK_EX; else - *level = LKM_PRMODE; + *level = DLM_LOCK_PR; *flags = 0; if (open_flags & O_NONBLOCK) - *flags |= LKM_NOQUEUE; + *flags |= DLM_LKF_NOQUEUE; return 0; } @@ -166,7 +166,7 @@ static int dlmfs_file_open(struct inode *inode, * to be able userspace to be able to distinguish a * valid lock request from one that simply couldn't be * granted. */ - if (flags & LKM_NOQUEUE && status == -EAGAIN) + if (flags & DLM_LKF_NOQUEUE && status == -EAGAIN) status = -ETXTBSY; kfree(fp); goto bail; @@ -193,7 +193,7 @@ static int dlmfs_file_release(struct inode *inode, status = 0; if (fp) { level = fp->fp_lock_level; - if (level != LKM_IVMODE) + if (level != DLM_LOCK_IV) user_dlm_cluster_unlock(&ip->ip_lockres, level); kfree(fp); -- cgit v1.2.3 From a03ab788d070c256eff1ac24cf0e3bc2ca148096 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Fri, 26 Mar 2010 05:15:12 +0800 Subject: ocfs2: one more warning fix in ocfs2_file_aio_write(), v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes another compiling warning in ocfs2_file_aio_write() like this, fs/ocfs2/file.c: In function ‘ocfs2_file_aio_write’: fs/ocfs2/file.c:2026: warning: suggest parentheses around ‘&&’ within ‘||’ As Joel suggested, '!ret' is unary, this version removes the wrap from '!ret'. Signed-off-by: Coly Li Signed-off-by: Joel Becker --- fs/ocfs2/file.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 17947dc8341..2b4235c5831 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2021,9 +2021,9 @@ out_dio: if (ret < 0) written = ret; - if (!ret && (old_size != i_size_read(inode) || - old_clusters != OCFS2_I(inode)->ip_clusters || - has_refcount)) { + if (!ret && ((old_size != i_size_read(inode)) || + (old_clusters != OCFS2_I(inode)->ip_clusters) || + has_refcount)) { ret = jbd2_journal_force_commit(osb->journal->j_journal); if (ret < 0) written = ret; -- cgit v1.2.3 From 428257f8870f0e72e85ce782d091fa1f366de7df Mon Sep 17 00:00:00 2001 From: Wengang Wang Date: Wed, 24 Mar 2010 22:40:44 +0800 Subject: ocfs2: Check the owner of a lockres inside the spinlock The checking of lockres owner in dlm_update_lvb() is not inside spinlock protection. I don't see problem in current call path of dlm_update_lvb(). But just for code robustness. Signed-off-by: Wengang Wang Signed-off-by: Joel Becker --- fs/ocfs2/dlm/dlmast.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c index dccc439fa08..b7a25ef18e2 100644 --- a/fs/ocfs2/dlm/dlmast.c +++ b/fs/ocfs2/dlm/dlmast.c @@ -185,9 +185,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, BUG_ON(!lksb); /* only updates if this node masters the lockres */ + spin_lock(&res->spinlock); if (res->owner == dlm->node_num) { - - spin_lock(&res->spinlock); /* check the lksb flags for the direction */ if (lksb->flags & DLM_LKSB_GET_LVB) { mlog(0, "getting lvb from lockres for %s node\n", @@ -202,8 +201,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, * here. In the future we might want to clear it at the time * the put is actually done. */ - spin_unlock(&res->spinlock); } + spin_unlock(&res->spinlock); /* reset any lvb flags on the lksb */ lksb->flags &= ~(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB); -- cgit v1.2.3 From a42ab8e1a37257da37e0f018e707bf365ac24531 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Wed, 31 Mar 2010 18:25:44 -0700 Subject: ocfs2: Compute metaecc for superblocks during online resize. Online resize writes out the new superblock and its backups directly. The metaecc data wasn't being recomputed. Let's do that directly. Signed-off-by: Joel Becker Acked-by: Mark Fasheh [ Cc: stable@kernel.org --- fs/ocfs2/buffer_head_io.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c index 21c808f752d..b18c6d677f9 100644 --- a/fs/ocfs2/buffer_head_io.c +++ b/fs/ocfs2/buffer_head_io.c @@ -407,6 +407,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, struct buffer_head *bh) { int ret = 0; + struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; mlog_entry_void(); @@ -426,6 +427,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, get_bh(bh); /* for end_buffer_write_sync() */ bh->b_end_io = end_buffer_write_sync; + ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &di->i_check); submit_bh(WRITE, bh); wait_on_buffer(bh); -- cgit v1.2.3 From 79681842e160c3211eeeb47ea31b061038d1e41e Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Fri, 16 Apr 2010 13:59:25 +0800 Subject: ocfs2: Reset status if we want to restart file extension. In __ocfs2_extend_allocation, we will restart our file extension if ((!status) && restart_func). But there is a bug that the status is still left as -EGAIN. This is really an old bug, but it is masked by the return value of ocfs2_journal_dirty. So it show up when we make ocfs2_journal_dirty void. Signed-off-by: Tao Ma Signed-off-by: Joel Becker --- fs/ocfs2/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 2b4235c5831..20e0ee58dd3 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -684,6 +684,7 @@ restarted_transaction: if (why == RESTART_META) { mlog(0, "restarting function.\n"); restart_func = 1; + status = 0; } else { BUG_ON(why != RESTART_TRANS); -- cgit v1.2.3 From d4cd1871cff68e188dadcf6d1280762522b643eb Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Thu, 22 Apr 2010 16:11:19 +0800 Subject: ocfs2: add OCFS2_INODE_SKIP_ORPHAN_DIR flag and honor it in the inode wipe code Currently in the error path of ocfs2_symlink and ocfs2_mknod, we just call iput with the inode we failed with, but the inode wipe code will complain because we don't add the inode to orphan dir. One solution would be to lock the orphan dir during the entire transaction, but that's too heavy for a rare error path. Instead, we add a flag, OCFS2_INODE_SKIP_ORPHAN_DIR which tells the inode wipe code that it won't find this inode in the orphan dir. [ Merge fixes and comment style cleanups -Mark ] Signed-off-by: Li Dongyang Signed-off-by: Mark Fasheh --- fs/ocfs2/inode.c | 65 +++++++++++++++++++++++++++++++------------------------- fs/ocfs2/inode.h | 2 ++ fs/ocfs2/namei.c | 1 + 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 07cc8bb68b6..26399202be7 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -639,11 +639,13 @@ static int ocfs2_remove_inode(struct inode *inode, goto bail_unlock; } - status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, - orphan_dir_bh); - if (status < 0) { - mlog_errno(status); - goto bail_commit; + if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { + status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, + orphan_dir_bh); + if (status < 0) { + mlog_errno(status); + goto bail_commit; + } } /* set the inodes dtime */ @@ -726,34 +728,35 @@ static int ocfs2_wipe_inode(struct inode *inode, struct inode *orphan_dir_inode = NULL; struct buffer_head *orphan_dir_bh = NULL; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - struct ocfs2_dinode *di; + struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; - di = (struct ocfs2_dinode *) di_bh->b_data; - orphaned_slot = le16_to_cpu(di->i_orphaned_slot); + if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { + orphaned_slot = le16_to_cpu(di->i_orphaned_slot); - status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); - if (status) - return status; + status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); + if (status) + return status; - orphan_dir_inode = ocfs2_get_system_file_inode(osb, - ORPHAN_DIR_SYSTEM_INODE, - orphaned_slot); - if (!orphan_dir_inode) { - status = -EEXIST; - mlog_errno(status); - goto bail; - } + orphan_dir_inode = ocfs2_get_system_file_inode(osb, + ORPHAN_DIR_SYSTEM_INODE, + orphaned_slot); + if (!orphan_dir_inode) { + status = -EEXIST; + mlog_errno(status); + goto bail; + } - /* Lock the orphan dir. The lock will be held for the entire - * delete_inode operation. We do this now to avoid races with - * recovery completion on other nodes. */ - mutex_lock(&orphan_dir_inode->i_mutex); - status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); - if (status < 0) { - mutex_unlock(&orphan_dir_inode->i_mutex); + /* Lock the orphan dir. The lock will be held for the entire + * delete_inode operation. We do this now to avoid races with + * recovery completion on other nodes. */ + mutex_lock(&orphan_dir_inode->i_mutex); + status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); + if (status < 0) { + mutex_unlock(&orphan_dir_inode->i_mutex); - mlog_errno(status); - goto bail; + mlog_errno(status); + goto bail; + } } /* we do this while holding the orphan dir lock because we @@ -794,6 +797,9 @@ static int ocfs2_wipe_inode(struct inode *inode, mlog_errno(status); bail_unlock_dir: + if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR) + return status; + ocfs2_inode_unlock(orphan_dir_inode, 1); mutex_unlock(&orphan_dir_inode->i_mutex); brelse(orphan_dir_bh); @@ -889,7 +895,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode, /* Do some basic inode verification... */ di = (struct ocfs2_dinode *) di_bh->b_data; - if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) { + if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) && + !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { /* * Inodes in the orphan dir must have ORPHANED_FL. The only * inodes that come back out of the orphan dir are reflink diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index ba4fe07b293..0b28e1921a3 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h @@ -100,6 +100,8 @@ struct ocfs2_inode_info #define OCFS2_INODE_MAYBE_ORPHANED 0x00000020 /* Does someone have the file open O_DIRECT */ #define OCFS2_INODE_OPEN_DIRECT 0x00000040 +/* Tell the inode wipe code it's not in orphan dir */ +#define OCFS2_INODE_SKIP_ORPHAN_DIR 0x00000080 static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) { diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index b1eb50ae409..ae315c9c768 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1976,6 +1976,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, } le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL); + OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR; /* Record which orphan dir our inode now resides * in. delete_inode will use this to determine which orphan -- cgit v1.2.3 From ab41fdc8fdd9f0942430941c1e2b516fd481371d Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Thu, 22 Apr 2010 16:11:25 +0800 Subject: ocfs2: use OCFS2_INODE_SKIP_ORPHAN_DIR in ocfs2_symlink error path Mark the inode with flag OCFS2_INODE_SKIP_ORPHAN_DIR when we get an error after allocating one, so that we can kill the inode. Signed-off-by: Li Dongyang Signed-off-by: Mark Fasheh --- fs/ocfs2/namei.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index ae315c9c768..b66e4885582 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1811,6 +1811,7 @@ bail: if (xattr_ac) ocfs2_free_alloc_context(xattr_ac); if ((status < 0) && inode) { + OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; clear_nlink(inode); iput(inode); } -- cgit v1.2.3 From 062d340384dcf77dfd8de0a082b5da571de3925a Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Thu, 22 Apr 2010 16:11:29 +0800 Subject: ocfs2: use OCFS2_INODE_SKIP_ORPHAN_DIR in ocfs2_mknod error path Mark the inode with flag OCFS2_INODE_SKIP_ORPHAN_DIR in ocfs2_mknod, so we can kill the inode in case of error. [ Fixed up comment style -Mark ] Signed-off-by: Li Dongyang Signed-off-by: Mark Fasheh --- fs/ocfs2/namei.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index b66e4885582..8ff035eabfd 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -445,11 +445,6 @@ leave: ocfs2_free_dir_lookup_result(&lookup); - if ((status < 0) && inode) { - clear_nlink(inode); - iput(inode); - } - if (inode_ac) ocfs2_free_alloc_context(inode_ac); @@ -459,6 +454,17 @@ leave: if (meta_ac) ocfs2_free_alloc_context(meta_ac); + /* + * We should call iput after the i_mutex of the bitmap been + * unlocked in ocfs2_free_alloc_context, or the + * ocfs2_delete_inode will mutex_lock again. + */ + if ((status < 0) && inode) { + OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; + clear_nlink(inode); + iput(inode); + } + mlog_exit(status); return status; -- cgit v1.2.3 From a9743fcdc0eb43d028b71267438076e1b0112ba0 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Fri, 23 Apr 2010 11:42:22 -0700 Subject: ocfs2: Add directory entry later in ocfs2_symlink() and ocfs2_mknod() If we get a failure during creation of an inode we'll allow the orphan code to remove the inode, which is correct. However, we need to ensure that we don't get any errors after the call to ocfs2_add_entry(), otherwise we could leave a dangling directory reference. The solution is simple - in both cases, all I had to do was move ocfs2_dentry_attach_lock() above the ocfs2_add_entry() call. Signed-off-by: Mark Fasheh --- fs/ocfs2/namei.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 8ff035eabfd..4cbb18f26c5 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -408,23 +408,28 @@ static int ocfs2_mknod(struct inode *dir, } } - status = ocfs2_add_entry(handle, dentry, inode, - OCFS2_I(inode)->ip_blkno, parent_fe_bh, - &lookup); - if (status < 0) { + /* + * Do this before adding the entry to the directory. We add + * also set d_op after success so that ->d_iput() will cleanup + * the dentry lock even if ocfs2_add_entry() fails below. + */ + status = ocfs2_dentry_attach_lock(dentry, inode, + OCFS2_I(dir)->ip_blkno); + if (status) { mlog_errno(status); goto leave; } + dentry->d_op = &ocfs2_dentry_ops; - status = ocfs2_dentry_attach_lock(dentry, inode, - OCFS2_I(dir)->ip_blkno); - if (status) { + status = ocfs2_add_entry(handle, dentry, inode, + OCFS2_I(inode)->ip_blkno, parent_fe_bh, + &lookup); + if (status < 0) { mlog_errno(status); goto leave; } insert_inode_hash(inode); - dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); status = 0; leave: @@ -1777,22 +1782,27 @@ static int ocfs2_symlink(struct inode *dir, } } - status = ocfs2_add_entry(handle, dentry, inode, - le64_to_cpu(fe->i_blkno), parent_fe_bh, - &lookup); - if (status < 0) { + /* + * Do this before adding the entry to the directory. We add + * also set d_op after success so that ->d_iput() will cleanup + * the dentry lock even if ocfs2_add_entry() fails below. + */ + status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); + if (status) { mlog_errno(status); goto bail; } + dentry->d_op = &ocfs2_dentry_ops; - status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); - if (status) { + status = ocfs2_add_entry(handle, dentry, inode, + le64_to_cpu(fe->i_blkno), parent_fe_bh, + &lookup); + if (status < 0) { mlog_errno(status); goto bail; } insert_inode_hash(inode); - dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); bail: if (status < 0 && did_quota) -- cgit v1.2.3 From 0350cb078f5035716ebdad4ad4709d02fe466a8a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 22 Apr 2010 11:39:29 +0200 Subject: ocfs2: potential ERR_PTR dereference on error paths If "handle" is non null at the end of the function then we assume it's a valid pointer and pass it to ocfs2_commit_trans(); Signed-off-by: Dan Carpenter Cc: Signed-off-by: Joel Becker --- fs/ocfs2/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index ab207901d32..23c254e2601 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -559,6 +559,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); if (IS_ERR(handle)) { status = PTR_ERR(handle); + handle = NULL; mlog_errno(status); goto out; } -- cgit v1.2.3 From c21a534e2f24968cf74976a4e721ac194db30ded Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Wed, 21 Apr 2010 14:05:55 +0800 Subject: ocfs2: Update VFS inode's id info after reflink. In reflink we update the id info on the disk but forgot to update the corresponding information in the VFS inode. Update them accordingly when we want to preserve the attributes. Reported-by: Jeff Liu Signed-off-by: Tao Ma Cc: Signed-off-by: Joel Becker --- fs/ocfs2/refcounttree.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 29405f2ff61..32a8ac589c8 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -4084,6 +4084,9 @@ static int ocfs2_complete_reflink(struct inode *s_inode, di->i_attr = s_di->i_attr; if (preserve) { + t_inode->i_uid = s_inode->i_uid; + t_inode->i_gid = s_inode->i_gid; + t_inode->i_mode = s_inode->i_mode; di->i_uid = s_di->i_uid; di->i_gid = s_di->i_gid; di->i_mode = s_di->i_mode; -- cgit v1.2.3 From a36d515c7a2dfacebcf41729f6812dbc424ebcf0 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Fri, 23 Apr 2010 15:24:59 -0700 Subject: ocfs2_dlmfs: Fix math error when reading LVB. When asked for a partial read of the LVB in a dlmfs file, we can accidentally calculate a negative count. Reported-by: Dan Carpenter Cc: Signed-off-by: Joel Becker --- fs/ocfs2/dlmfs/dlmfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index a99d1eafa8e..b83d6107a1f 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c @@ -262,7 +262,7 @@ static ssize_t dlmfs_file_read(struct file *filp, if ((count + *ppos) > i_size_read(inode)) readlen = i_size_read(inode) - *ppos; else - readlen = count - *ppos; + readlen = count; lvb_buf = kmalloc(readlen, GFP_NOFS); if (!lvb_buf) -- cgit v1.2.3 From 6b933c8e6f1a2f3118082c455eef25f9b1ac7b45 Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Sat, 17 Apr 2010 17:49:10 +0800 Subject: ocfs2: Avoid direct write if we fall back to buffered I/O when we fall back to buffered write from direct write, we call __generic_file_aio_write() but that will end up doing direct write even we are only prepared to do buffered write because the file has the O_DIRECT flag set. This is a fix for https://bugzilla.novell.com/show_bug.cgi?id=591039 revised with Joel's comments. Signed-off-by: Li Dongyang Acked-by: Mark Fasheh Signed-off-by: Joel Becker --- fs/ocfs2/file.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 20e0ee58dd3..a5fbd9cea96 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1982,18 +1982,18 @@ relock: /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb, rw_level); - if (direct_io) { - ret = generic_segment_checks(iov, &nr_segs, &ocount, - VERIFY_READ); - if (ret) - goto out_dio; + ret = generic_segment_checks(iov, &nr_segs, &ocount, + VERIFY_READ); + if (ret) + goto out_dio; - count = ocount; - ret = generic_write_checks(file, ppos, &count, - S_ISBLK(inode->i_mode)); - if (ret) - goto out_dio; + count = ocount; + ret = generic_write_checks(file, ppos, &count, + S_ISBLK(inode->i_mode)); + if (ret) + goto out_dio; + if (direct_io) { written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, ppos, count, ocount); if (written < 0) { @@ -2008,7 +2008,10 @@ relock: goto out_dio; } } else { - written = __generic_file_aio_write(iocb, iov, nr_segs, ppos); + current->backing_dev_info = file->f_mapping->backing_dev_info; + written = generic_file_buffered_write(iocb, iov, nr_segs, *ppos, + ppos, count, 0); + current->backing_dev_info = NULL; } out_dio: -- cgit v1.2.3 From d577632e65ea01fb3b124b652d7bd2381251da3c Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Mon, 3 May 2010 19:15:49 -0700 Subject: ocfs2: Avoid a gcc warning in ocfs2_wipe_inode(). gcc warns that a variable is uninitialized. It's actually handled, but an early return fools gcc. Let's just initialize the variable to a garbage value that will crash if the usage is ever broken. Signed-off-by: Joel Becker --- fs/ocfs2/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 83fe1d38f5c..af189887201 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -725,7 +725,7 @@ static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb, static int ocfs2_wipe_inode(struct inode *inode, struct buffer_head *di_bh) { - int status, orphaned_slot; + int status, orphaned_slot = -1; struct inode *orphan_dir_inode = NULL; struct buffer_head *orphan_dir_bh = NULL; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); -- cgit v1.2.3