summaryrefslogtreecommitdiff
path: root/open-vm-tools
diff options
context:
space:
mode:
authorVMware, Inc <>2013-09-17 20:32:57 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-09-22 22:19:59 -0700
commit339f41660410a6928c6c657f35b20d8623989fdd (patch)
tree163ceb7944ed28b596a431e9279b9f369c1c35e0 /open-vm-tools
parentedffc5fad3c601e1ee3e391532fbc623f8b19519 (diff)
HGFS: Fix Linux client inode 512B block count
The Linux HGFS client miscalculated the number of 512 byte blocks to set in the inode for the file size. It was incorrectly using the HGFS hardcoded block size instead of 512, which was 1024. This causes the block count to be half the correct number and so du on a file reports the incorrect size. fstat also retrieves this block count in the stat structure so it is likely more applications will break. Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
Diffstat (limited to 'open-vm-tools')
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/fsutil.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/open-vm-tools/modules/linux/vmhgfs/fsutil.c b/open-vm-tools/modules/linux/vmhgfs/fsutil.c
index 65a3647d..4ce77ab7 100644
--- a/open-vm-tools/modules/linux/vmhgfs/fsutil.c
+++ b/open-vm-tools/modules/linux/vmhgfs/fsutil.c
@@ -550,6 +550,43 @@ HgfsUnpackCommonAttr(HgfsReq *req, // IN: Reply packet
*
* HgfsChangeFileAttributes --
*
+ * Calculate the number of 512 byte blocks used.
+ *
+ * Round the size to the next whole block and divide by the block size
+ * to get the number of 512 byte blocks.
+ * Note, this is taken from the nfs client and is simply performing:
+ * (size + 512-1)/ 512)
+ *
+ * Results:
+ * The number of 512 byte blocks for the size.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
+static inline blkcnt_t
+HgfsCalcBlockSize(uint64 tsize)
+{
+ blkcnt_t used = (tsize + 511) >> 9;
+ return (used > ULONG_MAX) ? ULONG_MAX : used;
+}
+#else
+static inline unsigned long
+HgfsCalcBlockSize(uint64 tsize)
+{
+ loff_t used = (tsize + 511) >> 9;
+ return (used > ULONG_MAX) ? ULONG_MAX : used;
+}
+#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsChangeFileAttributes --
+ *
* Update an inode's attributes to match those of the HgfsAttr. May
* cause dirty pages to be flushed, and may invalidate cached pages,
* if there was a change in the file size or modification time in
@@ -663,7 +700,7 @@ HgfsChangeFileAttributes(struct inode *inode, // IN/OUT: Inode
*/
if (attr->mask & HGFS_ATTR_VALID_SIZE) {
loff_t oldSize = compat_i_size_read(inode);
- inode->i_blocks = (attr->size + HGFS_BLOCKSIZE - 1) / HGFS_BLOCKSIZE;
+ inode->i_blocks = HgfsCalcBlockSize(attr->size);
if (oldSize != attr->size) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsChangeFileAttributes: new file "
"size: %"FMT64"u, old file size: %Lu\n", attr->size, oldSize));