diff --git a/fs/ext4/defrag.c b/fs/ext4/defrag.c
index 891e599..67030bc 100644
--- a/fs/ext4/defrag.c
+++ b/fs/ext4/defrag.c
@@ -20,6 +20,8 @@
 #include "ext4_extents.h"
 #include "group.h"

+#define FIEMAP_MAX_EXTENTS	(UINT_MAX / sizeof(struct fiemap_extent))
+
 /**
  * ext4_defrag_next_extent - Search for the next extent and set it to "extent"
  *
@@ -91,6 +93,117 @@ err:
 }

 /**
+ * ext4_defrag_fiemap_ino - Get extents information by inode number
+ *
+ * @filp:			pointer to file
+ * @arg:			pointer to fiemap_ino
+ *  @fiemap_ino->ino:		an inode number which is used to get
+ *				extent information
+ *  @fiemap_ino->fiemap:	request for fiemap ioctl
+ *
+ * This function returns 0 if succeed, otherwise returns error value.
+ */
+int
+ext4_defrag_fiemap_ino(struct file *filp, unsigned long arg)
+{
+	struct fiemap_ino fiemap_ino;
+	struct fiemap_extent_info fieinfo = { 0, };
+	struct inode *inode;
+	struct super_block *sb = filp->f_dentry->d_inode->i_sb;
+	u64 len = 0;
+	int err = 0;
+
+	if (copy_from_user(&fiemap_ino, (struct fiemap_ino __user *)arg,
+			   sizeof(struct fiemap_ino)))
+		return -EFAULT;
+
+	/* Special inodes shouldn't be choiced */
+	if (fiemap_ino.ino < EXT4_GOOD_OLD_FIRST_INO)
+		return -ENOENT;
+
+	inode = ext4_iget(sb, fiemap_ino.ino);
+	if (IS_ERR(inode))
+		return PTR_ERR(inode);
+
+	/*
+	 * If we do not have the permission to access the inode,
+	 * just skip it.
+	 */
+	if (!capable(CAP_DAC_OVERRIDE)) {
+		if ((inode->i_mode & S_IRUSR) != S_IRUSR)
+			return -EACCES;
+		if (current->fsuid != inode->i_uid)
+			return -EACCES;
+	}
+
+	/* Return -ENOENT if a file does not exist */
+	if (!inode->i_nlink || !S_ISREG(inode->i_mode)) {
+		err = -ENOENT;
+		goto out;
+	}
+
+	if (!inode->i_op->fiemap) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (fiemap_ino.fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (fiemap_ino.fiemap.fm_length == 0) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (fiemap_ino.fiemap.fm_start > sb->s_maxbytes) {
+		err = -EFBIG;
+		goto out;
+	}
+
+	/*
+	 * Check offset and length
+	 * If the specified range exceeds the max file size,
+	 * adjust the length.
+	 */
+	if ((fiemap_ino.fiemap.fm_length > sb->s_maxbytes) ||
+	    (sb->s_maxbytes - fiemap_ino.fiemap.fm_length)
+	     < fiemap_ino.fiemap.fm_start)
+		len = sb->s_maxbytes - fiemap_ino.fiemap.fm_start;
+	else
+		len = fiemap_ino.fiemap.fm_length;
+
+	fieinfo.fi_flags = fiemap_ino.fiemap.fm_flags;
+	fieinfo.fi_extents_max = fiemap_ino.fiemap.fm_extent_count;
+	fieinfo.fi_extents_start =
+		(struct fiemap_extent *)(arg + sizeof(fiemap_ino));
+
+	if (fiemap_ino.fiemap.fm_extent_count != 0 &&
+	    !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
+		       fieinfo.fi_extents_max * sizeof(struct fiemap_extent))) {
+		err = -EFAULT;
+		goto out;
+	}
+
+	if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
+		filemap_write_and_wait(inode->i_mapping);
+
+	err = inode->i_op->fiemap(inode, &fieinfo,
+				fiemap_ino.fiemap.fm_start, len);
+	if (!err) {
+		fiemap_ino.fiemap.fm_flags = fieinfo.fi_flags;
+		fiemap_ino.fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
+		if (copy_to_user((char *)arg, &fiemap_ino, sizeof(fiemap_ino)))
+			err = -EFAULT;
+	}
+
+out:
+	iput(inode);
+	return err;
+}
+
+/**
  * ext4_defrag_merge_across_blocks - Merge extents across leaf block
  *
  * @handle:		journal handle
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index f7b092d..c72703f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -305,6 +305,7 @@ struct ext4_new_group_data {
 #define EXT4_IOC_DEFRAG			_IOW('f', 15, struct ext4_ext_defrag_data)
 #define EXT4_IOC_SUPER_INFO		_IOR('f', 16, struct ext4_super_block)
 #define EXT4_IOC_FREE_BLOCKS_INFO	_IOWR('f', 17, struct ext4_extents_info)
+#define EXT4_IOC_FIEMAP_INO		_IOWR('f', 18, struct fiemap_ino)

 /*
  * ioctl commands in 32 bit emulation
@@ -352,6 +353,11 @@ struct ext4_extents_info {
 	struct ext4_extent_data ext[DEFRAG_MAX_ENT];
 };

+struct fiemap_ino {
+	__u64 ino;
+	struct fiemap fiemap;
+};
+
 #define EXT4_TRANS_META_BLOCKS 4 /* bitmap + group desc + sb + inode */

 /*
@@ -1185,6 +1191,7 @@ extern int ext4_ext_journal_restart(handle_t *handle, int needed);
 /* defrag.c */
 extern int ext4_defrag(struct file *filp, ext4_lblk_t block_start,
 			ext4_lblk_t defrag_size, ext4_fsblk_t goal);
+extern int ext4_defrag_fiemap_ino(struct file *filp, unsigned long arg);

 static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
 {
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 5709574..b69b54a 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -256,6 +256,13 @@ setversion_out:
 			return 0;
 	}

+	case EXT4_IOC_FIEMAP_INO: {
+		int err;
+
+		err = ext4_defrag_fiemap_ino(filp, arg);
+		return err;
+	}
+
 	case EXT4_IOC_FREE_BLOCKS_INFO: {
 		struct ext4_extents_info ext_info;
 		int err;
