From 06dd22944b73aa05e12ffb2b8544ca1195ad470b Mon Sep 17 00:00:00 2001
From: bobijam <bobijam>
Date: Thu, 16 Aug 2007 03:45:30 +0000
Subject: [PATCH] Branch HEAD b=12743 i=adilger, shadow

Description: df doesn't work properly if diskfs blocksize != 4K
Details    : Choose biggest blocksize of OST's as the LOV's blocksize.
---
 lustre/ChangeLog         |  5 +++++
 lustre/llite/llite_lib.c |  1 +
 lustre/lov/lov_request.c | 29 +++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 43f7c8a66a..a35f12d667 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 10687e3cfa..205ebf9c79 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 fbdefef140..88a8b5736b 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
-- 
GitLab