backfs_sources := $(filter-out %.mod.c,$(wildcard @EXT4_SRC_DIR@/*.c))
-ext3_new_sources := extents.c mballoc.c group.h fiemap.h
-ext3_new_headers := ext3_extents.h
-
-ext4_new_sources := fiemap.h mmp.c
-ext4_new_sources += htree_lock.c
-ext4_new_headers :=
-
-new_sources := $(ext4_new_sources)
-new_headers := $(ext4_new_headers)
+new_sources := mmp.c htree_lock.c
+new_headers :=
ldiskfs_patched_sources := $(notdir $(backfs_sources) $(backfs_headers)) $(new_sources) $(new_headers)
ldiskfs_sources := $(ldiskfs_patched_sources)
+++ /dev/null
-This patch adds direct EXT4_IOC_FIEMAP support to ldiskfs, for Lustre to call
-without having to go through do_vfs_ioctl() (which isn't exported, and has a
-number of other ioctls which are not suitable for Lustre). The actual FIEMAP
-support is already in the kernel/ext4 for normal usage.
-
-Index: linux-stage/fs/ext4/ext4.h
-===================================================================
---- linux-stage.orig/fs/ext4/ext4.h
-+++ linux-stage/fs/ext4/ext4.h
-@@ -405,7 +405,7 @@ struct ext4_new_group_data {
- #define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input)
- #define EXT4_IOC_MIGRATE _IO('f', 9)
- /* note ioctl 10 reserved for an early version of the FIEMAP ioctl */
-- /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
-+#define EXT4_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
- #define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12)
- #define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent)
-
-Index: linux-stage/fs/ext4/ioctl.c
-===================================================================
---- linux-stage.orig/fs/ext4/ioctl.c
-+++ linux-stage/fs/ext4/ioctl.c
-@@ -18,6 +18,71 @@
- #include "ext4_jbd2.h"
- #include "ext4.h"
-
-+/* So that the fiemap access checks can't overflow on 32 bit machines. */
-+#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
-+
-+static int fiemap_check_ranges(struct super_block *sb,
-+ u64 start, u64 len, u64 *new_len)
-+{
-+ *new_len = len;
-+
-+ if (len == 0)
-+ return -EINVAL;
-+
-+ if (start > sb->s_maxbytes)
-+ return -EFBIG;
-+
-+ /*
-+ * Shrink request scope to what the fs can actually handle.
-+ */
-+ if ((len > sb->s_maxbytes) ||
-+ (sb->s_maxbytes - len) < start)
-+ *new_len = sb->s_maxbytes - start;
-+
-+ return 0;
-+}
-+
-+int ioctl_fiemap(struct inode *inode, struct file *filp, unsigned long arg)
-+{
-+ struct fiemap fiemap;
-+ u64 len;
-+ struct fiemap_extent_info fieinfo = {0, };
-+ struct super_block *sb = inode->i_sb;
-+ int error = 0;
-+
-+ if (copy_from_user(&fiemap, (struct fiemap __user *) arg,
-+ sizeof(struct fiemap)))
-+ return -EFAULT;
-+
-+ if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
-+ return -EINVAL;
-+
-+ error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
-+ &len);
-+ if (error)
-+ return error;
-+
-+ fieinfo.fi_flags = fiemap.fm_flags;
-+ fieinfo.fi_extents_max = fiemap.fm_extent_count;
-+ fieinfo.fi_extents_start = (struct fiemap_extent *)(arg + sizeof(fiemap));
-+
-+ if (fiemap.fm_extent_count != 0 &&
-+ !access_ok(VERIFY_WRITE, (void *)arg,
-+ offsetof(typeof(fiemap), fm_extents[fiemap.fm_extent_count])))
-+ return -EFAULT;
-+
-+ if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
-+ filemap_write_and_wait(inode->i_mapping);
-+
-+ error = ext4_fiemap(inode, &fieinfo, fiemap.fm_start, len);
-+ fiemap.fm_flags = fieinfo.fi_flags;
-+ fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
-+ if (copy_to_user((char *)arg, &fiemap, sizeof(fiemap)))
-+ error = -EFAULT;
-+
-+ return error;
-+}
-+
- long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- {
- struct inode *inode = filp->f_dentry->d_inode;
-@@ -330,6 +395,9 @@ mext_out:
- mnt_drop_write(filp->f_path.mnt);
- return err;
- }
-+ case EXT4_IOC_FIEMAP: {
-+ return ioctl_fiemap(inode, filp, arg);
-+ }
-
- default:
- return -ENOTTY;
-Index: linux-stage/fs/ext4/fiemap.h
-===================================================================
---- /dev/null
-+++ linux-stage/fs/ext4/fiemap.h
-@@ -0,0 +1,2 @@
-+
-+#include_next <fiemap.h>
rhel6.3/ext4-hash-indexed-dir-dotdot-update.patch
rhel6.3/ext4-kill-dx_root.patch
rhel6.3/ext4-extents-mount-option.patch
-rhel6.3/ext4-fiemap-2.6.patch
rhel6.4/ext4-mballoc-pa_free-mismatch.patch
rhel6.3/ext4-data-in-dirent.patch
rhel6.4/ext4-back-dquot-to.patch
rhel6.3/ext4-hash-indexed-dir-dotdot-update.patch
rhel6.3/ext4-kill-dx_root.patch
rhel6.3/ext4-extents-mount-option.patch
-rhel6.3/ext4-fiemap-2.6.patch
rhel6.4/ext4-mballoc-pa_free-mismatch.patch
rhel6.3/ext4-data-in-dirent.patch
rhel6.4/ext4-back-dquot-to.patch
rhel6.3/ext4-hash-indexed-dir-dotdot-update.patch
rhel6.3/ext4-kill-dx_root.patch
rhel6.3/ext4-extents-mount-option.patch
-rhel6.3/ext4-fiemap-2.6.patch
rhel6.4/ext4-mballoc-pa_free-mismatch.patch
rhel6.3/ext4-data-in-dirent.patch
rhel6.4/ext4-back-dquot-to.patch
rhel6.3/ext4-hash-indexed-dir-dotdot-update.patch
rhel6.3/ext4-kill-dx_root.patch
rhel6.3/ext4-extents-mount-option.patch
-rhel6.3/ext4-fiemap-2.6.patch
rhel6.3/ext4-mballoc-pa_free-mismatch.patch
rhel6.3/ext4-data-in-dirent.patch
rhel6.4/ext4-back-dquot-to.patch
rhel6.3/ext4-hash-indexed-dir-dotdot-update.patch
rhel6.3/ext4-kill-dx_root.patch
rhel6.3/ext4-extents-mount-option.patch
-rhel6.3/ext4-fiemap-2.6.patch
rhel6.3/ext4-mballoc-pa_free-mismatch.patch
rhel6.3/ext4-data-in-dirent.patch
rhel6.4/ext4-back-dquot-to.patch
rhel6.3/ext4-hash-indexed-dir-dotdot-update.patch
sles11sp2/ext4-kill-dx_root.patch
sles11sp2/ext4-extents-mount-option.patch
-rhel6.3/ext4-fiemap-2.6.patch
sles11sp2/ext4-mballoc-pa_free-mismatch.patch
sles11sp2/ext4-data-in-dirent.patch
sles11sp2/ext4-large-eas.patch
rhel6.3/ext4-hash-indexed-dir-dotdot-update.patch
sles11sp2/ext4-kill-dx_root.patch
sles11sp2/ext4-extents-mount-option.patch
-rhel6.3/ext4-fiemap-2.6.patch
sles11sp2/ext4-mballoc-pa_free-mismatch.patch
sles11sp2/ext4-data-in-dirent.patch
sles11sp2/ext4-large-eas.patch
RETURN(rc == 0 ? rc2 : rc);
}
+static int fiemap_check_ranges(struct inode *inode,
+ u64 start, u64 len, u64 *new_len)
+{
+ loff_t maxbytes;
+
+ *new_len = len;
+
+ if (len == 0)
+ return -EINVAL;
+
+ if (ldiskfs_test_inode_flag(inode, LDISKFS_INODE_EXTENTS))
+ maxbytes = inode->i_sb->s_maxbytes;
+ else
+ maxbytes = LDISKFS_SB(inode->i_sb)->s_bitmap_maxbytes;
+
+ if (start > maxbytes)
+ return -EFBIG;
+
+ /*
+ * Shrink request scope to what the fs can actually handle.
+ */
+ if (len > maxbytes || (maxbytes - len) < start)
+ *new_len = maxbytes - start;
+
+ return 0;
+}
+
+/* So that the fiemap access checks can't overflow on 32 bit machines. */
+#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
+
static int osd_fiemap_get(const struct lu_env *env, struct dt_object *dt,
struct ll_user_fiemap *fm)
{
- struct inode *inode = osd_dt_obj(dt)->oo_inode;
- struct osd_thread_info *info = osd_oti_get(env);
- struct dentry *dentry = &info->oti_obj_dentry;
- struct file *file = &info->oti_file;
- mm_segment_t saved_fs;
- int rc;
+ struct fiemap_extent_info fieinfo = {0, };
+ struct inode *inode = osd_dt_obj(dt)->oo_inode;
+ u64 len;
+ int rc;
- LASSERT(inode);
- dentry->d_inode = inode;
- dentry->d_sb = inode->i_sb;
- file->f_dentry = dentry;
- file->f_mapping = inode->i_mapping;
- file->f_op = inode->i_fop;
- set_file_inode(file, inode);
-
- saved_fs = get_fs();
- set_fs(get_ds());
- /* ldiskfs_ioctl does not have a inode argument */
- if (inode->i_fop->unlocked_ioctl)
- rc = inode->i_fop->unlocked_ioctl(file, FSFILT_IOC_FIEMAP,
- (long)fm);
- else
- rc = -ENOTTY;
- set_fs(saved_fs);
- return rc;
+
+ LASSERT(inode);
+ if (inode->i_op->fiemap == NULL)
+ return -EOPNOTSUPP;
+
+ if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS)
+ return -EINVAL;
+
+ rc = fiemap_check_ranges(inode, fm->fm_start, fm->fm_length, &len);
+ if (rc)
+ return rc;
+
+ fieinfo.fi_flags = fm->fm_flags;
+ fieinfo.fi_extents_max = fm->fm_extent_count;
+ fieinfo.fi_extents_start = fm->fm_extents;
+
+ if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
+ filemap_write_and_wait(inode->i_mapping);
+
+ rc = inode->i_op->fiemap(inode, &fieinfo, fm->fm_start, len);
+ fm->fm_flags = fieinfo.fi_flags;
+ fm->fm_mapped_extents = fieinfo.fi_extents_mapped;
+
+ return rc;
}
/*