Patchwork [RFC,5/12] ext4: Add the EXT4_IOC_FIBMAP ioctl

login
register
mail settings
Submitter Akira Fujita
Date Sept. 27, 2008, 7:26 a.m.
Message ID <48DDE03B.5000505@rs.jp.nec.com>
Download mbox | patch
Permalink /patch/1761/
State Changes Requested
Headers show

Comments

Akira Fujita - Sept. 27, 2008, 7:26 a.m.
ext4: online defrag -- Add the EXT4_IOC_FIBMAP ioctl.

From: Akira Fujita <a-fujita@rs.jp.nec.com>

The EXT4_IOC_FIBMAP ioctl gets the physical block offset of target inode
with ext4_bmap().  This ioctl is used only in the relevant defrag (-r).

In the relevant defrag, in order to move the files under
the specified directory close together with the block containing the directory data,
defragger sets this physical block offset to the goal of block allocation.

We will use the FS_IOC_FIEMAP ioctl instead of it in the next version,
so this will go away.

Signed-off-by: Akira Fujita <a-fujita@rs.jp.nec.com>
Signed-off-by: Takashi Sato <t-sato@yk.jp.nec.com>
---
 fs/ext4/defrag.c |   17 +++++++++++++++--
 fs/ext4/ext4.h   |    2 ++
 fs/ext4/inode.c  |    2 +-
 fs/ext4/ioctl.c  |    1 +
 4 files changed, 19 insertions(+), 3 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/fs/ext4/defrag.c b/fs/ext4/defrag.c
index 4dd4318..49b8d49 100644
--- a/fs/ext4/defrag.c
+++ b/fs/ext4/defrag.c
@@ -95,13 +95,26 @@  int ext4_defrag_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 {
 	int err = 0;

-	if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) {
+	if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL ||
+					cmd == EXT4_IOC_FIBMAP)) {
 		printk(KERN_ERR "ext4 defrag: ino[%lu] is not extents "
 					"based file\n", inode->i_ino);
 		return -EOPNOTSUPP;
 	}

-	if (cmd == EXT4_IOC_DEFRAG) {
+	if (cmd == EXT4_IOC_FIBMAP) {
+		ext4_fsblk_t __user *p = (ext4_fsblk_t __user *)arg;
+		ext4_fsblk_t block = 0;
+		struct address_space *mapping = filp->f_mapping;
+
+		if (copy_from_user(&block, (ext4_fsblk_t __user *)arg,
+					sizeof(block)))
+			return -EFAULT;
+
+		block = ext4_bmap(mapping, block);
+
+		return put_user(block, p);
+	} else if (cmd == EXT4_IOC_DEFRAG) {
 		struct ext4_ext_defrag_data defrag;
 		struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 556ff5e..db4891c 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -303,6 +303,7 @@  struct ext4_new_group_data {
 #define EXT4_IOC_MIGRATE		_IO('f', 9)
  /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
 #define EXT4_IOC_DEFRAG			_IOW('f', 15, struct ext4_ext_defrag_data)
+#define EXT4_IOC_FIBMAP			_IOW('f', 16, ext4_fsblk_t)

 /*
  * ioctl commands in 32 bit emulation
@@ -1017,6 +1018,7 @@  extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
 				    __u32 minor_hash,
 				    struct ext4_dir_entry_2 *dirent);
 extern void ext4_htree_free_dir_info(struct dir_private_info *p);
+extern sector_t ext4_bmap(struct address_space *mapping, sector_t block);

 /* fsync.c */
 extern int ext4_sync_file(struct file *, struct dentry *, int);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 9b0117c..24d37cb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2706,7 +2706,7 @@  out:
  * So, if we see any bmap calls here on a modified, data-journaled file,
  * take extra steps to flush any blocks which might be in the cache.
  */
-static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
+sector_t ext4_bmap(struct address_space *mapping, sector_t block)
 {
 	struct inode *inode = mapping->host;
 	journal_t *journal;
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 1c25e8e..5982f3e 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -256,6 +256,7 @@  setversion_out:

 		return err;
 	}
+	case EXT4_IOC_FIBMAP:
 	case EXT4_IOC_DEFRAG: {
 		return ext4_defrag_ioctl(inode, filp, cmd, arg);
 	}