diff options
author | VMware, Inc <> | 2013-09-17 20:32:57 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-09-22 22:19:59 -0700 |
commit | 339f41660410a6928c6c657f35b20d8623989fdd (patch) | |
tree | 163ceb7944ed28b596a431e9279b9f369c1c35e0 /open-vm-tools | |
parent | edffc5fad3c601e1ee3e391532fbc623f8b19519 (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.c | 39 |
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)); |