diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 43f7c8a66abe4f8b844007e8e765eca2036faf91..a35f12d6672dea189793187f31e16ecafbacd8c4 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -96,6 +96,11 @@ Description: sanity.sh failed test 103
 Details    : RHEL mis-interpret setfacl "-X" param, so we won't test setfacl
              with param "-X".
 
+Severity   : normal
+Bugzilla   : 12743
+Description: df doesn't work properly if diskfs blocksize != 4K
+Details    : Choose biggest blocksize of OST's as the LOV's blocksize.
+
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c
index 10687e3cfa935b677962c5a68c9dfdee2f52ac57..205ebf9c79788ed82ec5e0e7dd0d2d3fbcf21fe8 100644
--- a/lustre/llite/llite_lib.c
+++ b/lustre/llite/llite_lib.c
@@ -1428,6 +1428,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
                obd_osfs.os_bavail, obd_osfs.os_blocks, obd_osfs.os_ffree,
                obd_osfs.os_files);
 
+        osfs->os_bsize = obd_osfs.os_bsize;
         osfs->os_blocks = obd_osfs.os_blocks;
         osfs->os_bfree = obd_osfs.os_bfree;
         osfs->os_bavail = obd_osfs.os_bavail;
diff --git a/lustre/lov/lov_request.c b/lustre/lov/lov_request.c
index fbdefef140941eda53bb16e1d6f1d9c7de8c4898..88a8b5736b91bb0a42d7b9b4a0832b4133152335 100644
--- a/lustre/lov/lov_request.c
+++ b/lustre/lov/lov_request.c
@@ -1497,6 +1497,8 @@ int lov_fini_statfs_set(struct lov_request_set *set)
 void lov_update_statfs(struct obd_device *obd, struct obd_statfs *osfs,
                        struct obd_statfs *lov_sfs, int success)
 {
+        int shift = 0, quit = 0;
+        __u64 tmp;
         spin_lock(&obd->obd_osfs_lock);
         memcpy(&obd->obd_osfs, lov_sfs, sizeof(*lov_sfs));
         obd->obd_osfs_age = get_jiffies_64();
@@ -1505,6 +1507,33 @@ void lov_update_statfs(struct obd_device *obd, struct obd_statfs *osfs,
         if (success == 0) {
                 memcpy(osfs, lov_sfs, sizeof(*lov_sfs));
         } else {
+                if (osfs->os_bsize != lov_sfs->os_bsize) {
+                        /* assume all block sizes are always powers of 2 */
+                        /* get the bits difference */
+                        tmp = osfs->os_bsize | lov_sfs->os_bsize;
+                        for (shift = 0; shift <= 64; ++shift) {
+                                if (tmp & 1) {
+                                        if (quit)
+                                                break;
+                                        else
+                                                quit = 1;
+                                        shift = 0;
+                                }
+                                tmp >>= 1;
+                        }
+                }
+
+                if (osfs->os_bsize < lov_sfs->os_bsize) {
+                        osfs->os_bsize = lov_sfs->os_bsize;
+
+                        osfs->os_bfree  >>= shift;
+                        osfs->os_bavail >>= shift;
+                        osfs->os_blocks >>= shift;
+                } else if (shift != 0) {
+                        lov_sfs->os_bfree  >>= shift;
+                        lov_sfs->os_bavail >>= shift;
+                        lov_sfs->os_blocks >>= shift;
+                }
 #ifdef MIN_DF
                 /* Sandia requested that df (and so, statfs) only
                    returned minimal available space on