+ struct lod_device *lod = dt2lod_dev(dev);
+ struct lod_ost_desc *ost;
+ struct lod_mdt_desc *mdt;
+ struct obd_statfs ost_sfs;
+ u64 ost_files = 0;
+ u64 ost_ffree = 0;
+ int i, rc, bs;
+
+ rc = dt_statfs(env, dt2lod_dev(dev)->lod_child, sfs);
+ if (rc)
+ GOTO(out, rc);
+
+ bs = sfs->os_bsize;
+
+ sfs->os_bavail = 0;
+ sfs->os_blocks = 0;
+ sfs->os_bfree = 0;
+ sfs->os_granted = 0;
+
+ lod_getref(&lod->lod_mdt_descs);
+ lod_foreach_mdt(lod, i) {
+ mdt = MDT_TGT(lod, i);
+ LASSERT(mdt && mdt->ltd_mdt);
+ rc = dt_statfs(env, mdt->ltd_mdt, &ost_sfs);
+ /* ignore errors */
+ if (rc)
+ continue;
+ sfs->os_files += ost_sfs.os_files;
+ sfs->os_ffree += ost_sfs.os_ffree;
+ lod_statfs_sum(sfs, &ost_sfs, &bs);
+ }
+ lod_putref(lod, &lod->lod_mdt_descs);
+
+ /*
+ * at some point we can check whether DoM is enabled and
+ * decide how to account MDT space. for simplicity let's
+ * just fallback to pre-DoM policy if any OST is alive
+ */
+ lod_getref(&lod->lod_ost_descs);
+ lod_foreach_ost(lod, i) {
+ ost = OST_TGT(lod, i);
+ LASSERT(ost && ost->ltd_ost);
+ rc = dt_statfs(env, ost->ltd_ost, &ost_sfs);
+ /* ignore errors */
+ if (rc || ost_sfs.os_bsize == 0)
+ continue;
+ if (!ost_files) {
+ /*
+ * if only MDTs with DoM then report only MDT blocks,
+ * otherwise show only OST blocks, and DoM is "free"
+ */
+ sfs->os_bavail = 0;
+ sfs->os_blocks = 0;
+ sfs->os_bfree = 0;
+ sfs->os_granted = 0;
+ }
+ ost_files += ost_sfs.os_files;
+ ost_ffree += ost_sfs.os_ffree;
+ ost_sfs.os_bavail += ost_sfs.os_granted;
+ lod_statfs_sum(sfs, &ost_sfs, &bs);
+ LASSERTF(bs == ost_sfs.os_bsize, "%d != %d\n",
+ (int)sfs->os_bsize, (int)ost_sfs.os_bsize);
+ }
+ lod_putref(lod, &lod->lod_ost_descs);
+ sfs->os_state |= OS_STATE_SUM;
+
+ /* If we have _some_ OSTs, but don't have as many free objects on the
+ * OSTs as inodes on the MDTs, reduce the reported number of inodes
+ * to compensate, so that the "inodes in use" number is correct.
+ * This should be kept in sync with ll_statfs_internal().
+ */
+ if (ost_files && ost_ffree < sfs->os_ffree) {
+ sfs->os_files = (sfs->os_files - sfs->os_ffree) + ost_ffree;
+ sfs->os_ffree = ost_ffree;
+ }
+
+ /* a single successful statfs should be enough */
+ rc = 0;
+
+out:
+ RETURN(rc);