[PATCH] ceph: cleanup in __ceph_do_pending_vmtruncate() method

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Viacheslav Dubeyko <Slava.Dubeyko@xxxxxxx>

The Coverity Scan service has detected an unchecked return
value in __ceph_do_pending_vmtruncate() method [1].

The CID 114041 contains explanation: " Calling
filemap_write_and_wait_range without checking return value.
If the function returns an error value, the error value
may be mistaken for a normal value. Value returned from
a function is not checked for errors before being used.
(CWE-252)".

The patch adds the checking of returned value of
filemap_write_and_wait_range() and reporting the error
message if something wrong is happened during the call.
It reworks the logic by removing the jump to retry
label because it could be the reason of potential
infinite loop in the case of error condition during
the filemap_write_and_wait_range() call. It was removed
the check to == ci->i_truncate_pagecache_size because
the to variable is set by ci->i_truncate_pagecache_size
in the above code logic. The uneccessary finish variable
has been removed because the to variable always has
ci->i_truncate_pagecache_size value. Now if the condition
ci->i_truncate_pending == 0 is true then logic will jump
to the end of the function and wake_up_all(&ci->i_cap_wq)
will be called.

[1] https://scan5.scan.coverity.com/#/project-view/64304/10063?selectedIssue=114041

Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@xxxxxxx>
cc: Alex Markuze <amarkuze@xxxxxxxxxx>
cc: Ilya Dryomov <idryomov@xxxxxxxxx>
cc: Ceph Development <ceph-devel@xxxxxxxxxxxxxxx>
---
 fs/ceph/inode.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index fc543075b827..53ce776b04b5 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -2203,17 +2203,17 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
 	struct ceph_client *cl = ceph_inode_to_client(inode);
 	struct ceph_inode_info *ci = ceph_inode(inode);
 	u64 to;
-	int wrbuffer_refs, finish = 0;
+	int wrbuffer_refs;
+	int err;
 
 	mutex_lock(&ci->i_truncate_mutex);
-retry:
 	spin_lock(&ci->i_ceph_lock);
+
+	wrbuffer_refs = ci->i_wrbuffer_ref;
 	if (ci->i_truncate_pending == 0) {
 		doutc(cl, "%p %llx.%llx none pending\n", inode,
 		      ceph_vinop(inode));
-		spin_unlock(&ci->i_ceph_lock);
-		mutex_unlock(&ci->i_truncate_mutex);
-		return;
+		goto out_unlock;
 	}
 
 	/*
@@ -2224,9 +2224,14 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
 		spin_unlock(&ci->i_ceph_lock);
 		doutc(cl, "%p %llx.%llx flushing snaps first\n", inode,
 		      ceph_vinop(inode));
-		filemap_write_and_wait_range(&inode->i_data, 0,
-					     inode->i_sb->s_maxbytes);
-		goto retry;
+		err = filemap_write_and_wait_range(&inode->i_data, 0,
+						   inode->i_sb->s_maxbytes);
+		spin_lock(&ci->i_ceph_lock);
+
+		if (unlikely(err)) {
+			pr_err_client(cl, "failed of flushing snaps: err %d\n",
+					err);
+		}
 	}
 
 	/* there should be no reader or writer */
@@ -2242,20 +2247,17 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
 	truncate_pagecache(inode, to);
 
 	spin_lock(&ci->i_ceph_lock);
-	if (to == ci->i_truncate_pagecache_size) {
-		ci->i_truncate_pending = 0;
-		finish = 1;
-	}
-	spin_unlock(&ci->i_ceph_lock);
-	if (!finish)
-		goto retry;
+	ci->i_truncate_pending = 0;
 
+out_unlock:
+	spin_unlock(&ci->i_ceph_lock);
 	mutex_unlock(&ci->i_truncate_mutex);
 
 	if (wrbuffer_refs == 0)
 		ceph_check_caps(ci, 0);
 
 	wake_up_all(&ci->i_cap_wq);
+	return;
 }
 
 static void ceph_inode_work(struct work_struct *work)
-- 
2.50.1





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux