Whamcloud - gitweb
LU-13783 osd-ldiskfs: use alloc_file_pseudo to create fake files 76/43876/20
authorJames Simmons <jsimmons@infradead.org>
Wed, 8 Dec 2021 22:13:40 +0000 (17:13 -0500)
committerOleg Drokin <green@whamcloud.com>
Thu, 23 Dec 2021 07:17:23 +0000 (07:17 +0000)
With kallsyms_lookup_name() no longer exported with 5.8+ kernels
this means the work around to setup the security handling broke.
Currently osd-ldiskfs will crash due to security_alloc() never
being called. The solution is to use alloc_file_pseudo() instead
to create our fake file.

Change-Id: Ib417ebdda7d9829a231c568022618154c273f3e6
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/43876
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Neil Brown <neilb@suse.de>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/autoconf/lustre-core.m4
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_internal.h
lustre/osd-ldiskfs/osd_io.c
lustre/osd-ldiskfs/osd_scrub.c

index a36ff43..659beb9 100644 (file)
@@ -2213,6 +2213,26 @@ VM_FAULT_RETRY, [
 ]) # LC_VM_FAULT_RETRY
 
 #
+# LC_ALLOC_FILE_PSEUDO
+#
+# kernel 4.18-rc1 commit d93aa9d82aea80b80f225dbf9c7986df444d8106
+# new wrapper: alloc_file_pseudo()
+#
+AC_DEFUN([LC_ALLOC_FILE_PSEUDO], [
+LB_CHECK_COMPILE([if 'alloc_file_pseudo' is defined],
+alloc_file_pseudo, [
+       #include <linux/file.h>
+],[
+       struct file *file;
+       file = alloc_file_pseudo(NULL, NULL, "[test]",
+                                00000002, NULL);
+],[
+       AC_DEFINE(HAVE_ALLOC_FILE_PSEUDO, 1,
+               ['alloc_file_pseudo' exist])
+])
+]) # LC_ALLOC_FILE_PSEUDO
+
+#
 # LC_INODE_TIMESPEC64
 #
 # kernel 4.17-rc7 commit 8efd6894ff089adeeac7cb9f32125b85d963d1bc
@@ -2619,6 +2639,7 @@ AC_DEFUN([LC_PROG_LINUX], [
        LC_I_PAGES
 
        # 4.18
+       LC_ALLOC_FILE_PSEUDO
        LC_INODE_TIMESPEC64
 
        # 4.20
index c95ceb3..0e3ba8c 100644 (file)
@@ -39,7 +39,6 @@
 #define DEBUG_SUBSYSTEM S_OSD
 
 #include <linux/fs_struct.h>
-#include <linux/kallsyms.h>
 #include <linux/module.h>
 #include <linux/user_namespace.h>
 #include <linux/uidgid.h>
@@ -1028,7 +1027,6 @@ static int osd_check_lmv(struct osd_thread_info *oti, struct osd_device *dev,
                         struct inode *inode)
 {
        struct lu_buf *buf = &oti->oti_big_buf;
-       struct dentry *dentry = &oti->oti_obj_dentry;
        struct file *filp;
        struct lmv_mds_md_v1 *lmv1;
        struct osd_check_lmv_buf oclb = {
@@ -1040,12 +1038,24 @@ static int osd_check_lmv(struct osd_thread_info *oti, struct osd_device *dev,
        int rc = 0;
 
        ENTRY;
+       /* We should use the VFS layer to create a real dentry. */
+       oti->oti_obj_dentry.d_inode = inode;
+       oti->oti_obj_dentry.d_sb = inode->i_sb;
+
+       filp = alloc_file_pseudo(inode, dev->od_mnt, "/", O_NOATIME,
+                                inode->i_fop);
+       if (IS_ERR(filp))
+               RETURN(-ENOMEM);
 
+       filp->f_mode |= FMODE_64BITHASH;
+       filp->f_pos = 0;
+       ihold(inode);
 again:
-       rc = __osd_xattr_get(inode, dentry, XATTR_NAME_LMV, buf->lb_buf,
-                            buf->lb_len);
+       rc = __osd_xattr_get(inode, filp->f_path.dentry, XATTR_NAME_LMV,
+                            buf->lb_buf, buf->lb_len);
        if (rc == -ERANGE) {
-               rc = __osd_xattr_get(inode, dentry, XATTR_NAME_LMV, NULL, 0);
+               rc = __osd_xattr_get(inode, filp->f_path.dentry,
+                                    XATTR_NAME_LMV, NULL, 0);
                if (rc > 0) {
                        lu_buf_realloc(buf, rc);
                        if (buf->lb_buf == NULL)
@@ -1073,19 +1083,13 @@ again:
        if (le32_to_cpu(lmv1->lmv_magic) != LMV_MAGIC_V1)
                GOTO(out, rc = 0);
 
-       filp = osd_quasi_file(oti->oti_env, inode);
-       rc = osd_security_file_alloc(filp);
-       if (rc)
-               goto out;
-
        do {
                oclb.oclb_items = 0;
                rc = iterate_dir(filp, &oclb.ctx);
        } while (rc >= 0 && oclb.oclb_items > 0 && !oclb.oclb_found &&
                 filp->f_pos != LDISKFS_HTREE_EOF_64BIT);
-       inode->i_fop->release(inode, filp);
-
 out:
+       fput(filp);
        if (rc < 0)
                CDEBUG(D_LFSCK,
                       "%s: cannot check LMV, ino = %lu/%u: rc = %d\n",
@@ -2090,7 +2094,15 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt,
                if (!rc)
                        rc = rc2;
 
-               osd_process_truncates(env, &truncates);
+               /* We preserve the origin behavior of ignoring any
+                * failures with the underlying punch / truncate
+                * operation. We do record for debugging if an error
+                * does occur in the lctl dk logs.
+                */
+               rc2 = osd_process_truncates(env, &truncates);
+               if (rc2 != 0)
+                       CERROR("%s: failed truncate process: rc = %d\n",
+                              osd_name(osd), rc2);
        } else {
                osd_trans_stop_cb(oh, th->th_result);
                OBD_FREE_PTR(oh);
@@ -2492,15 +2504,6 @@ static int osd_commit_async(const struct lu_env *env,
        RETURN(rc);
 }
 
-static int (*priv_security_file_alloc)(struct file *file);
-
-int osd_security_file_alloc(struct file *file)
-{
-       if (priv_security_file_alloc)
-               return priv_security_file_alloc(file);
-       return 0;
-}
-
 /*
  * Concurrency: shouldn't matter.
  */
@@ -4976,13 +4979,21 @@ static int osd_object_sync(const struct lu_env *env, struct dt_object *dt,
                           __u64 start, __u64 end)
 {
        struct osd_object *obj = osd_dt_obj(dt);
+       struct osd_device *dev = osd_obj2dev(obj);
        struct inode *inode = obj->oo_inode;
-       struct file *file = osd_quasi_file(env, inode);
+       struct file *file;
        int rc;
 
        ENTRY;
+       file = alloc_file_pseudo(inode, dev->od_mnt, "/", O_NOATIME,
+                                inode->i_fop);
+       if (IS_ERR(file))
+               RETURN(PTR_ERR(file));
 
+       file->f_mode |= FMODE_64BITHASH;
        rc = vfs_fsync_range(file, start, end, 0);
+       ihold(inode);
+       fput(file);
 
        RETURN(rc);
 }
@@ -6684,23 +6695,29 @@ static const struct dt_index_operations osd_index_iam_ops = {
 };
 
 struct osd_it_ea *osd_it_dir_init(const struct lu_env *env,
-                                 struct inode *inode, __u32 attr)
+                                 struct osd_device *dev,
+                                 struct inode *inode, u32 attr)
 {
        struct osd_thread_info *info = osd_oti_get(env);
        struct osd_it_ea *oie;
        struct file *file;
-       struct dentry *obj_dentry;
 
        ENTRY;
+       file = alloc_file_pseudo(inode, dev->od_mnt, "/", O_NOATIME,
+                                inode->i_fop);
+       if (IS_ERR(file))
+               RETURN(ERR_CAST(file));
 
-       OBD_SLAB_ALLOC_PTR_GFP(oie, osd_itea_cachep, GFP_NOFS);
-       if (oie == NULL)
-               RETURN(ERR_PTR(-ENOMEM));
-       obj_dentry = &oie->oie_dentry;
+       /* Only FMODE_64BITHASH or FMODE_32BITHASH should be set, NOT both. */
+       if (attr & LUDA_64BITHASH)
+               file->f_mode |= FMODE_64BITHASH;
+       else
+               file->f_mode |= FMODE_32BITHASH;
+       ihold(inode);
 
-       obj_dentry->d_inode = inode;
-       obj_dentry->d_sb = inode->i_sb;
-       obj_dentry->d_name.hash = 0;
+       OBD_SLAB_ALLOC_PTR(oie, osd_itea_cachep);
+       if (!oie)
+               goto out_fput;
 
        oie->oie_rd_dirent       = 0;
        oie->oie_it_dirent       = 0;
@@ -6710,24 +6727,20 @@ struct osd_it_ea *osd_it_dir_init(const struct lu_env *env,
                info->oti_it_ea_buf_used = 1;
        } else {
                OBD_ALLOC(oie->oie_buf, OSD_IT_EA_BUFSIZE);
-               if (oie->oie_buf == NULL)
-                       RETURN(ERR_PTR(-ENOMEM));
+               if (!oie->oie_buf)
+                       goto out_free;
        }
        oie->oie_obj = NULL;
+       oie->oie_file = file;
 
-       file = &oie->oie_file;
+       RETURN(oie);
 
-       /* Only FMODE_64BITHASH or FMODE_32BITHASH should be set, NOT both. */
-       if (attr & LUDA_64BITHASH)
-               file->f_mode    = FMODE_64BITHASH;
-       else
-               file->f_mode    = FMODE_32BITHASH;
-       file->f_path.dentry     = obj_dentry;
-       file->f_mapping         = inode->i_mapping;
-       file->f_op              = inode->i_fop;
-       file->f_inode = inode;
+out_free:
+       OBD_SLAB_FREE_PTR(oie, osd_itea_cachep);
+out_fput:
+       fput(file);
 
-       RETURN(oie);
+       return ERR_PTR(-ENOMEM);
 }
 
 /**
@@ -6741,6 +6754,7 @@ static struct dt_it *osd_it_ea_init(const struct lu_env *env,
                                    __u32 attr)
 {
        struct osd_object *obj = osd_dt_obj(dt);
+       struct osd_device *dev = osd_obj2dev(obj);
        struct lu_object *lo = &dt->do_lu;
        struct osd_it_ea *oie;
 
@@ -6749,9 +6763,9 @@ static struct dt_it *osd_it_ea_init(const struct lu_env *env,
        if (!dt_object_exists(dt) || obj->oo_destroyed)
                RETURN(ERR_PTR(-ENOENT));
 
-       oie = osd_it_dir_init(env, obj->oo_inode, attr);
+       oie = osd_it_dir_init(env, dev, obj->oo_inode, attr);
        if (IS_ERR(oie))
-               RETURN((struct dt_it *)oie);
+               RETURN(ERR_CAST(oie));
 
        oie->oie_obj = obj;
        lu_object_get(lo);
@@ -6764,7 +6778,7 @@ void osd_it_dir_fini(const struct lu_env *env, struct osd_it_ea *oie,
        struct osd_thread_info *info = osd_oti_get(env);
 
        ENTRY;
-       oie->oie_file.f_op->release(inode, &oie->oie_file);
+       fput(oie->oie_file);
        if (unlikely(oie->oie_buf != info->oti_it_ea_buf))
                OBD_FREE(oie->oie_buf, OSD_IT_EA_BUFSIZE);
        else
@@ -6807,7 +6821,7 @@ static int osd_it_ea_get(const struct lu_env *env,
 
        ENTRY;
        LASSERT(((const char *)key)[0] == '\0');
-       it->oie_file.f_pos = 0;
+       it->oie_file->f_pos = 0;
        it->oie_rd_dirent = 0;
        it->oie_it_dirent = 0;
        it->oie_dirent = NULL;
@@ -6928,7 +6942,7 @@ int osd_ldiskfs_it_fill(const struct lu_env *env, const struct dt_it *di)
        struct osd_it_ea *it = (struct osd_it_ea *)di;
        struct osd_object *obj = it->oie_obj;
        struct htree_lock *hlock = NULL;
-       struct file *filp = &it->oie_file;
+       struct file *filp = it->oie_file;
        int rc = 0;
        struct osd_filldir_cbs buf = {
                .ctx.actor = osd_ldiskfs_filldir,
@@ -6950,13 +6964,6 @@ int osd_ldiskfs_it_fill(const struct lu_env *env, const struct dt_it *di)
                }
        }
 
-       filp->f_cred = current_cred();
-       rc = osd_security_file_alloc(filp);
-       if (rc)
-               GOTO(unlock, rc);
-
-       filp->f_flags |= O_NOATIME;
-       filp->f_mode |= FMODE_NONOTIFY;
        rc = iterate_dir(filp, &buf.ctx);
        if (rc)
                GOTO(unlock, rc);
@@ -6966,7 +6973,7 @@ int osd_ldiskfs_it_fill(const struct lu_env *env, const struct dt_it *di)
                 * If it does not get any dirent, it means it has been reached
                 * to the end of the dir
                 */
-               it->oie_file.f_pos = ldiskfs_get_htree_eof(&it->oie_file);
+               it->oie_file->f_pos = ldiskfs_get_htree_eof(it->oie_file);
                if (rc == 0)
                        rc = 1;
        } else {
@@ -7010,7 +7017,7 @@ static int osd_it_ea_next(const struct lu_env *env, struct dt_it *di)
                it->oie_it_dirent++;
                rc = 0;
        } else {
-               if (it->oie_file.f_pos == ldiskfs_get_htree_eof(&it->oie_file))
+               if (it->oie_file->f_pos == ldiskfs_get_htree_eof(it->oie_file))
                        rc = 1;
                else
                        rc = osd_ldiskfs_it_fill(env, di);
@@ -7613,7 +7620,7 @@ static int osd_it_ea_load(const struct lu_env *env,
        int rc;
 
        ENTRY;
-       it->oie_file.f_pos = hash;
+       it->oie_file->f_pos = hash;
 
        rc =  osd_ldiskfs_it_fill(env, di);
        if (rc > 0)
@@ -8564,11 +8571,6 @@ static int __init osd_init(void)
        if (rc)
                return rc;
 
-#ifdef CONFIG_KALLSYMS
-       priv_security_file_alloc =
-               (void *)cfs_kallsyms_lookup_name("security_file_alloc");
-#endif
-
        rc = class_register_type(&osd_obd_device_ops, NULL, true,
                                 LUSTRE_OSD_LDISKFS_NAME, &osd_device_type);
        if (rc) {
@@ -8586,6 +8588,7 @@ static int __init osd_init(void)
                        rc = 0;
                }
        }
+
        return rc;
 }
 
index 0c67dc4..9cc3528 100644 (file)
@@ -519,7 +519,7 @@ struct osd_it_ea_dirent {
 struct osd_it_ea {
        struct osd_object       *oie_obj;
        /** used in ldiskfs iterator, to stored file pointer */
-       struct file             oie_file;
+       struct file             *oie_file;
        /** how many entries have been read-cached from storage */
        int                     oie_rd_dirent;
        /** current entry is being iterated by caller */
@@ -528,7 +528,6 @@ struct osd_it_ea {
        struct osd_it_ea_dirent *oie_dirent;
        /** buffer to hold entries, size == OSD_IT_EA_BUFSIZE */
        void                    *oie_buf;
-       struct dentry           oie_dentry;
 };
 
 /**
@@ -585,10 +584,37 @@ struct osd_iobuf {
        unsigned int       dr_init_at;  /* the line iobuf was initialized */
 };
 
-int osd_security_file_alloc(struct file *file);
-
 #define osd_dirty_inode(inode, flag)  (inode)->i_sb->s_op->dirty_inode((inode), flag)
 
+#ifndef HAVE_ALLOC_FILE_PSEUDO
+
+#define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \
+                                           (flag & __FMODE_NONOTIFY)))
+static inline
+struct file *alloc_file_pseudo(struct inode *inode, struct vfsmount *mnt,
+                              const char *name, int flags,
+                              const struct file_operations *fops)
+{
+       struct qstr this = QSTR_INIT(name, strlen(name));
+       struct path path;
+       struct file *file;
+
+       path.dentry = d_alloc_pseudo(mnt->mnt_sb, &this);
+       if (!path.dentry)
+               return ERR_PTR(-ENOMEM);
+       path.mnt = mntget(mnt);
+       d_instantiate(path.dentry, inode);
+       file = alloc_file(&path, OPEN_FMODE(flags), fops);
+       if (IS_ERR(file)) {
+               ihold(inode);
+               path_put(&path);
+       } else {
+               file->f_flags = flags;
+       }
+       return file;
+}
+#endif /* !HAVE_ALLOC_FILE_PSEUDO */
+
 #ifdef HAVE_INODE_TIMESPEC64
 # define osd_timespec                  timespec64
 #else
@@ -616,12 +642,8 @@ struct osd_thread_info {
        /** dentry for Iterator context. */
        struct dentry           oti_it_dentry;
 
-       union {
-               /* fake struct file for osd_object_sync */
-               struct file             oti_file;
-               /* osd_statfs() */
-               struct kstatfs          oti_ksfs;
-       };
+       /* osd_statfs() */
+       struct kstatfs          oti_ksfs;
 
        struct htree_lock     *oti_hlock;
 
@@ -789,8 +811,9 @@ void osd_add_oi_cache(struct osd_thread_info *info, struct osd_device *osd,
                      struct osd_inode_id *id, const struct lu_fid *fid);
 int osd_get_idif(struct osd_thread_info *info, struct inode *inode,
                 struct dentry *dentry, struct lu_fid *fid);
-struct osd_it_ea *osd_it_dir_init(const struct lu_env *env, struct inode *inode,
-                                 __u32 attr);
+struct osd_it_ea *osd_it_dir_init(const struct lu_env *env,
+                                 struct osd_device *dev, struct inode *inode,
+                                 u32 attr);
 void osd_it_dir_fini(const struct lu_env *env, struct osd_it_ea *oie,
                     struct inode *inode);
 int osd_ldiskfs_it_fill(const struct lu_env *env, const struct dt_it *di);
@@ -1206,43 +1229,6 @@ struct dentry *osd_child_dentry_by_inode(const struct lu_env *env,
         return child_dentry;
 }
 
-/* build quasi file structure when it is needed to call an inode i_fop */
-static inline struct file *osd_quasi_file_init(const struct lu_env *env,
-                                              struct dentry *dentry,
-                                              struct inode *inode)
-{
-       struct osd_thread_info *info = osd_oti_get(env);
-
-       info->oti_file.f_path.dentry = dentry;
-       info->oti_file.f_mapping = inode->i_mapping;
-       info->oti_file.f_op = inode->i_fop;
-       info->oti_file.f_inode = inode;
-       info->oti_file.f_pos = 0;
-       info->oti_file.private_data = NULL;
-       info->oti_file.f_cred = current_cred();
-       info->oti_file.f_flags = O_NOATIME;
-       info->oti_file.f_mode = FMODE_64BITHASH | FMODE_NONOTIFY;
-
-       return &info->oti_file;
-}
-
-static inline struct file *osd_quasi_file(const struct lu_env *env,
-                                         struct inode *inode)
-{
-       struct osd_thread_info *info = osd_oti_get(env);
-
-       info->oti_obj_dentry.d_inode = inode;
-       info->oti_obj_dentry.d_sb = inode->i_sb;
-
-       return osd_quasi_file_init(env, &info->oti_obj_dentry, inode);
-}
-
-static inline struct file *osd_quasi_file_by_dentry(const struct lu_env *env,
-                                                   struct dentry *dentry)
-{
-       return osd_quasi_file_init(env, dentry, dentry->d_inode);
-}
-
 extern int osd_trans_declare_op2rb[];
 extern int ldiskfs_track_declares_assert;
 void osd_trans_dump_creds(const struct lu_env *env, struct thandle *th);
@@ -1575,7 +1561,7 @@ osd_index_backup(const struct lu_env *env, struct osd_device *osd, bool backup)
 int osd_trunc_lock(struct osd_object *obj, struct osd_thandle *oh,
                   bool shared);
 void osd_trunc_unlock_all(const struct lu_env *env, struct list_head *list);
-void osd_process_truncates(const struct lu_env *env, struct list_head *list);
+int osd_process_truncates(const struct lu_env *env, struct list_head *list);
 void osd_execute_truncate(struct osd_object *obj);
 
 #ifdef HAVE_BIO_ENDIO_USES_ONE_ARG
index 5a3bd8c..1db5db3 100644 (file)
@@ -2654,20 +2654,26 @@ static loff_t osd_lseek(const struct lu_env *env, struct dt_object *dt,
                        loff_t offset, int whence)
 {
        struct osd_object *obj = osd_dt_obj(dt);
+       struct osd_device *dev = osd_obj2dev(obj);
        struct inode *inode = obj->oo_inode;
        struct file *file;
        loff_t result;
 
        ENTRY;
-
        LASSERT(dt_object_exists(dt));
        LASSERT(osd_invariant(obj));
        LASSERT(inode);
        LASSERT(offset >= 0);
 
-       file = osd_quasi_file(env, inode);
-       result = file->f_op->llseek(file, offset, whence);
+       file = alloc_file_pseudo(inode, dev->od_mnt, "/", O_NOATIME,
+                                inode->i_fop);
+       if (IS_ERR(file))
+               RETURN(PTR_ERR(file));
 
+       file->f_mode |= FMODE_64BITHASH;
+       result = file->f_op->llseek(file, offset, whence);
+       ihold(inode);
+       fput(file);
        /*
         * If 'offset' is beyond end of object file then treat it as not error
         * but valid case for SEEK_HOLE and return 'offset' as result.
@@ -2847,22 +2853,34 @@ void osd_execute_truncate(struct osd_object *obj)
        osd_partial_page_flush(d, inode, size);
 }
 
-void osd_execute_punch(const struct lu_env *env, struct osd_object *obj,
-                      loff_t start, loff_t end, int mode)
+static int osd_execute_punch(const struct lu_env *env, struct osd_object *obj,
+                            loff_t start, loff_t end, int mode)
 {
        struct osd_device *d = osd_obj2dev(obj);
        struct inode *inode = obj->oo_inode;
-       struct file *file = osd_quasi_file(env, inode);
+       struct file *file;
+       int rc;
+
+       file = alloc_file_pseudo(inode, d->od_mnt, "/", O_NOATIME,
+                                inode->i_fop);
+       if (IS_ERR(file))
+               RETURN(PTR_ERR(file));
 
-       file->f_op->fallocate(file, mode, start, end - start);
-       osd_partial_page_flush_punch(d, inode, start, end - 1);
+       file->f_mode |= FMODE_64BITHASH;
+       rc = file->f_op->fallocate(file, mode, start, end - start);
+       ihold(inode);
+       fput(file);
+       if (rc == 0)
+               osd_partial_page_flush_punch(d, inode, start, end - 1);
+       return rc;
 }
 
-void osd_process_truncates(const struct lu_env *env, struct list_head *list)
+int osd_process_truncates(const struct lu_env *env, struct list_head *list)
 {
        struct osd_access_lock *al;
+       int rc = 0;
 
-       LASSERT(journal_current_handle() == NULL);
+       LASSERT(!journal_current_handle());
 
        list_for_each_entry(al, list, tl_list) {
                if (al->tl_shared)
@@ -2870,7 +2888,9 @@ void osd_process_truncates(const struct lu_env *env, struct list_head *list)
                if (al->tl_truncate)
                        osd_execute_truncate(al->tl_obj);
                else if (al->tl_punch)
-                       osd_execute_punch(env, al->tl_obj, al->tl_start,
-                                         al->tl_end, al->tl_mode);
+                       rc = osd_execute_punch(env, al->tl_obj, al->tl_start,
+                                              al->tl_end, al->tl_mode);
        }
+
+       return rc;
 }
index cdd2b6d..031acd2 100644 (file)
@@ -2142,24 +2142,29 @@ osd_ios_general_scan(struct osd_thread_info *info, struct osd_device *dev,
                .oifb_dentry = dentry
        };
        struct file *filp;
-       struct inode *inode = dentry->d_inode;
+       struct path path;
        int rc;
 
        ENTRY;
+       LASSERT(filldir);
+       path.dentry = dget(dentry);
+       path.mnt = mntget(dev->od_mnt);
 
-       LASSERT(filldir != NULL);
+       filp = dentry_open(&path, O_RDONLY, current_cred());
+       path_put(&path);
+       if (IS_ERR(filp))
+               RETURN(PTR_ERR(filp));
 
-       filp = osd_quasi_file_by_dentry(info->oti_env, dentry);
-       rc = osd_security_file_alloc(filp);
-       if (rc)
-               RETURN(rc);
+       filp->f_mode |= FMODE_64BITHASH | FMODE_NONOTIFY;
+       filp->f_flags |= O_NOATIME;
+       filp->f_pos = 0;
 
        do {
                buf.oifb_items = 0;
                rc = iterate_dir(filp, &buf.ctx);
        } while (rc >= 0 && buf.oifb_items > 0 &&
                 filp->f_pos != LDISKFS_HTREE_EOF_64BIT);
-       inode->i_fop->release(inode, filp);
+       fput(filp);
 
        RETURN(rc);
 }
@@ -3017,11 +3022,11 @@ static int osd_scan_dir(const struct lu_env *env, struct osd_device *dev,
 
        ENTRY;
 
-       oie = osd_it_dir_init(env, inode, LUDA_TYPE);
+       oie = osd_it_dir_init(env, dev, inode, LUDA_TYPE);
        if (IS_ERR(oie))
                RETURN(PTR_ERR(oie));
 
-       oie->oie_file.f_pos = 0;
+       oie->oie_file->f_pos = 0;
        rc = osd_ldiskfs_it_fill(env, (struct dt_it *)oie);
        if (rc > 0)
                rc = -ENODATA;
@@ -3041,8 +3046,8 @@ static int osd_scan_dir(const struct lu_env *env, struct osd_device *dev,
                if (oie->oie_it_dirent <= oie->oie_rd_dirent)
                        continue;
 
-               if (oie->oie_file.f_pos ==
-                   ldiskfs_get_htree_eof(&oie->oie_file))
+               if (oie->oie_file->f_pos ==
+                   ldiskfs_get_htree_eof(oie->oie_file))
                        break;
 
                rc = osd_ldiskfs_it_fill(env, (struct dt_it *)oie);
@@ -3064,7 +3069,7 @@ static int osd_remove_ml_file(struct osd_thread_info *info,
 {
        handle_t *th;
        struct lustre_scrub *scrub = &dev->od_scrub.os_scrub;
-       struct dentry *dentry;
+       struct dentry dentry;
        int rc;
 
        ENTRY;
@@ -3078,10 +3083,10 @@ static int osd_remove_ml_file(struct osd_thread_info *info,
        if (IS_ERR(th))
                RETURN(PTR_ERR(th));
 
-       dentry = &oie->oie_dentry;
-       dentry->d_inode = dir;
-       dentry->d_sb = dir->i_sb;
-       rc = osd_obj_del_entry(info, dev, dentry, oie->oie_dirent->oied_name,
+       /* Should be created by the VFS layer */
+       dentry.d_inode = dir;
+       dentry.d_sb = dir->i_sb;
+       rc = osd_obj_del_entry(info, dev, &dentry, oie->oie_dirent->oied_name,
                               oie->oie_dirent->oied_namelen, th);
        drop_nlink(inode);
        mark_inode_dirty(inode);