[PATCH 10/14] PMFS: Fix two bugs in pmfs_update_time_and_size()

Matthew Wilcox matthew.r.wilcox at intel.com
Mon Oct 7 09:37:37 EDT 2013

From: Matthew Wilcox <willy at linux.intel.com>

cmpxchg_double_local() wants compatible types, so read i_size into a
local little-endian temporary.  This fixes a bug on big-endian systems,
since it would write a non-byteswapped value to pi->i_size.  It also
fixes a consistency bug on 32-bit systems as reading i_size without
using i_size_read() is dangerous.

Signed-off-by: Matthew Wilcox <matthew.r.wilcox at intel.com>
 fs/pmfs/pmfs.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/pmfs/pmfs.h b/fs/pmfs/pmfs.h
index 8c7fdd9..e183564 100644
--- a/fs/pmfs/pmfs.h
+++ b/fs/pmfs/pmfs.h
@@ -400,7 +400,9 @@ static inline void pmfs_memcpy_atomic (void *dst, const void *src, u8 size)
 static inline void pmfs_update_time_and_size(struct inode *inode,
 	struct pmfs_inode *pi)
-	uint32_t words[2];
+	__le32 words[2];
+	__le64 new_pi_size = cpu_to_le64(i_size_read(inode));
 	/* pi->i_size, pi->i_ctime, and pi->i_mtime need to be atomically updated.
  	* So use cmpxchg16b here. */
 	words[0] = cpu_to_le32(inode->i_ctime.tv_sec);
@@ -408,7 +410,7 @@ static inline void pmfs_update_time_and_size(struct inode *inode,
 	/* TODO: the following function assumes cmpxchg16b instruction writes
  	* 16 bytes atomically. Confirm if it is really true. */
 	cmpxchg_double_local(&pi->i_size, (u64 *)&pi->i_ctime, pi->i_size,
-		*(u64 *)&pi->i_ctime, inode->i_size, *(u64 *)words);
+		*(u64 *)&pi->i_ctime, new_pi_size, *(u64 *)words);
 /* assumes the length to be 4-byte aligned */

More information about the Linux-pmfs mailing list