All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ulrich Hecht <uli@suse.de>
To: linux-btrfs@vger.kernel.org
Cc: uli@suse.de
Subject: [PATCH v3] Btrfs: compressed file size ioctl
Date: Fri,  6 Aug 2010 14:21:44 +0200	[thread overview]
Message-ID: <1281097304-27628-1-git-send-email-uli@suse.de> (raw)

Returns a file's size on disk. Based on a patch by Chris Ball, improved
following suggestions by Chris Mason and Miao Xie.

Minimal example:

 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdio.h>
 #define BTRFS_IOCTL_MAGIC 0x94
 #define BTRFS_IOC_COMPR_SIZE   _IOR(BTRFS_IOCTL_MAGIC, 21, uint64_t)
int main(int argc, char **argv)
{
  uint64_t size = -1;
  int d = open(argv[1], O_RDONLY);
  ioctl(d, BTRFS_IOC_COMPR_SIZE, &size);
  printf("%zd\n", size);
  return 0;
}

Signed-off-by: Ulrich Hecht <uli@suse.de>
---
 fs/btrfs/ioctl.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/ioctl.h |    1 +
 2 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 9254b3d..603da9e 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1750,6 +1750,46 @@ out_drop_write:
 	return ret;
 }
 
+static long btrfs_ioctl_compsize(struct file *file, void __user *argp)
+{
+	/* This ioctl returns the compressed size of an inode on disk
+	 * by counting the on-disk space used by all of its extents.
+	 */
+	struct inode *inode = fdentry(file)->d_inode;
+	struct extent_map *em;
+	u64 len = inode->i_size;
+	u64 compressed_size = 0;
+	u64 offset = 0;
+
+	if (S_ISDIR(inode->i_mode))
+		return -EISDIR;
+	
+	lock_extent(&BTRFS_I(inode)->io_tree, 0, len, GFP_NOFS);
+	mutex_lock(&inode->i_mutex);
+
+	/* do any pending delalloc/csum calc on inode, one way or
+	   another, and lock file content */
+	btrfs_wait_ordered_range(inode, 0, (u64)-1);
+
+	while (offset < len) {
+		em = btrfs_get_extent(inode, NULL, 0, offset, 1, 0);
+		BUG_ON(IS_ERR(em) || !em);
+		if (em->block_len != (u64)-1)
+			compressed_size += em->block_len;
+		offset += em->len;
+		free_extent_map(em);
+	}
+
+	mutex_unlock(&inode->i_mutex);
+	unlock_extent(&BTRFS_I(inode)->io_tree, 0, len, GFP_NOFS);
+
+	/* We've succeeded in going through all extents; set the final size. */
+	if (copy_to_user(argp, &compressed_size, sizeof(compressed_size)))
+		return -EFAULT;
+
+	return 0;
+}
+
 static long btrfs_ioctl_clone_range(struct file *file, void __user *argp)
 {
 	struct btrfs_ioctl_clone_range_args args;
@@ -2034,6 +2074,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 	case BTRFS_IOC_SYNC:
 		btrfs_sync_fs(file->f_dentry->d_sb, 1);
 		return 0;
+	case BTRFS_IOC_COMPR_SIZE:
+		return btrfs_ioctl_compsize(file, argp);
 	}
 
 	return -ENOTTY;
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 424694a..a01ef1e 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -178,4 +178,5 @@ struct btrfs_ioctl_space_args {
 #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
 #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
 				    struct btrfs_ioctl_space_args)
+#define BTRFS_IOC_COMPR_SIZE _IOR(BTRFS_IOCTL_MAGIC, 21, u64)
 #endif
-- 
1.7.1


             reply	other threads:[~2010-08-06 12:21 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-06 12:21 Ulrich Hecht [this message]
2010-08-06 18:22 ` [PATCH v3] Btrfs: compressed file size ioctl Diego Calleja

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1281097304-27628-1-git-send-email-uli@suse.de \
    --to=uli@suse.de \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.