From patchwork Wed Oct 20 11:19:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: cwillu X-Patchwork-Id: 268361 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9KBJn3s021768 for ; Wed, 20 Oct 2010 11:19:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751794Ab0JTLTo (ORCPT ); Wed, 20 Oct 2010 07:19:44 -0400 Received: from mail-qy0-f174.google.com ([209.85.216.174]:43928 "EHLO mail-qy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751781Ab0JTLTn (ORCPT ); Wed, 20 Oct 2010 07:19:43 -0400 Received: by qyk12 with SMTP id 12so1411614qyk.19 for ; Wed, 20 Oct 2010 04:19:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:sender:received:date :x-google-sender-auth:message-id:subject:from:to:content-type; bh=NmnZ3c7wZ/4b0SccmJ8xyvdO2HH5N4EUYyGpTIjSRBQ=; b=XC79MzG05MKKXqGcHt1blBuEa0wJwqNyvY+CJeidg8asTbZ50tAsyLfuDpD5BVQ3AJ Nh6VfLC9XIcYMx4gtUjW/Eta//SbjmFN6+DU8snRK3XS2TH/FC8++yG6PtGts/BHe9Cu wVGQG7Pyaaw0dZy8V6M6Q1uHlN7dGkSwN6RVA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; b=uzHiwZPhAaA+ytaU1Mjyk4ZHLy1oAlTm9PBPr1JVZY+Qjc1VtmHFWAkVfclEpQCtf9 BT9rVeYWApQgTdO92ubmFRyutbDUGWGbbn8kXHscetkpcqt/9HDQ/sVC/gBBJ+fcklWR AvT0Huuqrb5SzEoxlWeoBA2D+lh+DQtOrITEc= MIME-Version: 1.0 Received: by 10.229.96.67 with SMTP id g3mr6317467qcn.283.1287573582784; Wed, 20 Oct 2010 04:19:42 -0700 (PDT) Received: by 10.229.106.224 with HTTP; Wed, 20 Oct 2010 04:19:42 -0700 (PDT) Date: Wed, 20 Oct 2010 05:19:42 -0600 X-Google-Sender-Auth: f6W_h81PzSz_z4ide6hnz1YRUNI Message-ID: Subject: [PATCH] Make df report effective sizes, not physical sizes From: cwillu To: linux-btrfs@vger.kernel.org Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 20 Oct 2010 11:19:49 +0000 (UTC) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index ea06877..81d5285 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -728,26 +728,51 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) struct btrfs_super_block *disk_super = &root->fs_info->super_copy; struct list_head *head = &root->fs_info->space_info; struct btrfs_space_info *found; - u64 total_used = 0; - u64 total_used_data = 0; + int factor = 1; + u64 metadata_fuzz; + u64 pool_free = 0; + u64 data_avail = 0; + u64 data_used = 0; int bits = dentry->d_sb->s_blocksize_bits; __be32 *fsid = (__be32 *)root->fs_info->fsid; rcu_read_lock(); list_for_each_entry_rcu(found, head, list) { if (found->flags & (BTRFS_BLOCK_GROUP_METADATA | - BTRFS_BLOCK_GROUP_SYSTEM)) - total_used_data += found->disk_total; - else - total_used_data += found->disk_used; - total_used += found->disk_used; + BTRFS_BLOCK_GROUP_SYSTEM)) { + /* This is space that could be used for data in a pinch, + report it as such. */ + data_avail += found->total_bytes - found->bytes_used; + } else { + data_avail += found->total_bytes; + data_used += found->bytes_used; + + if (found->flags & (BTRFS_BLOCK_GROUP_DUP | + BTRFS_BLOCK_GROUP_RAID1 | + BTRFS_BLOCK_GROUP_RAID10)) + factor = 2; + } + + pool_free += found->disk_total; } rcu_read_unlock(); + pool_free = btrfs_super_total_bytes(disk_super) - pool_free; + do_div(pool_free, factor); + + /* Estimate ~3% of the free pool will go to metadata */ + metadata_fuzz = pool_free; + do_div(metadata_fuzz, 32); + + /* Reported sizes in terms of how much data can fit in files. Metadata + size is reflected by the difference between the reported size and + the actual size of the partition. We're interested directly useful + numbers, even if they don't reflect the particulars: that's what + the df ioctl is for. */ buf->f_namelen = BTRFS_NAME_LEN; - buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; - buf->f_bfree = buf->f_blocks - (total_used >> bits); - buf->f_bavail = buf->f_blocks - (total_used_data >> bits); + buf->f_blocks = (pool_free + data_avail - metadata_fuzz) >> bits; + buf->f_bfree = buf->f_blocks - (data_used >> bits); + buf->f_bavail = buf->f_bfree; buf->f_bsize = dentry->d_sb->s_blocksize; buf->f_type = BTRFS_SUPER_MAGIC;