Whamcloud - gitweb
LU-15880 quota: fix issues in reserving quota
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_handler.c
index f2fedaa..ab7facf 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>
@@ -75,6 +74,9 @@
 
 #include <lustre_linkea.h>
 
+/* encoding routines */
+#include <lustre_crypto.h>
+
 /* Maximum EA size is limited by LNET_MTU for remote objects */
 #define OSD_MAX_EA_SIZE 1048364
 
@@ -209,13 +211,13 @@ osd_idc_add(const struct lu_env *env, struct osd_device *osd,
                i = oti->oti_ins_cache_size * 2;
                if (i == 0)
                        i = OSD_INS_CACHE_SIZE;
-               OBD_ALLOC_PTR_ARRAY(idc, i);
+               OBD_ALLOC_PTR_ARRAY_LARGE(idc, i);
                if (idc == NULL)
                        return ERR_PTR(-ENOMEM);
                if (oti->oti_ins_cache != NULL) {
                        memcpy(idc, oti->oti_ins_cache,
                               oti->oti_ins_cache_used * sizeof(*idc));
-                       OBD_FREE_PTR_ARRAY(oti->oti_ins_cache,
+                       OBD_FREE_PTR_ARRAY_LARGE(oti->oti_ins_cache,
                                           oti->oti_ins_cache_used);
                }
                oti->oti_ins_cache = idc;
@@ -515,11 +517,18 @@ struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev,
                iput(inode);
                inode = ERR_PTR(-ESTALE);
        } else if (is_bad_inode(inode)) {
-               rc = -ENOENT;
                CWARN("%s: bad inode: ino = %u: rc = %d\n",
-                     osd_dev2name(dev), id->oii_ino, rc);
+                     osd_dev2name(dev), id->oii_ino, -ENOENT);
                iput(inode);
-               inode = ERR_PTR(rc);
+               inode = ERR_PTR(-ENOENT);
+       } else  if (osd_is_ea_inode(inode)) {
+               /*
+                * EA inode is internal ldiskfs object, should don't visible
+                * on osd
+                */
+               CDEBUG(D_INODE, "EA inode: ino = %u\n", id->oii_ino);
+               iput(inode);
+               inode = ERR_PTR(-ENOENT);
        } else if ((rc = osd_attach_jinode(inode))) {
                iput(inode);
                inode = ERR_PTR(rc);
@@ -632,7 +641,7 @@ static struct inode *osd_iget_check(struct osd_thread_info *info,
         */
 
 again:
-       inode = osd_ldiskfs_iget(osd_sb(dev), id->oii_ino);
+       inode = osd_iget(info, dev, id);
        if (IS_ERR(inode)) {
                rc = PTR_ERR(inode);
                if (!trusted && (rc == -ENOENT || rc == -ESTALE))
@@ -643,40 +652,6 @@ again:
                GOTO(put, rc);
        }
 
-       if (is_bad_inode(inode)) {
-               rc = -ENOENT;
-               if (!trusted)
-                       goto check_oi;
-
-               CDEBUG(D_INODE, "bad inode for FID: "DFID", ino = %u\n",
-                      PFID(fid), id->oii_ino);
-               GOTO(put, rc);
-       }
-
-       if (id->oii_gen != OSD_OII_NOGEN &&
-           inode->i_generation != id->oii_gen) {
-               rc = -ESTALE;
-               if (!trusted)
-                       goto check_oi;
-
-               CDEBUG(D_INODE, "unmatched inode for FID: "DFID", ino = %u, "
-                      "oii_gen = %u, i_generation = %u\n", PFID(fid),
-                      id->oii_ino, id->oii_gen, inode->i_generation);
-               GOTO(put, rc);
-       }
-
-       if (inode->i_nlink == 0) {
-               rc = -ENOENT;
-               if (!trusted)
-                       goto check_oi;
-
-               CDEBUG(D_INODE, "stale inode for FID: "DFID", ino = %u\n",
-                      PFID(fid), id->oii_ino);
-               GOTO(put, rc);
-       }
-
-       ldiskfs_clear_inode_state(inode, LDISKFS_STATE_LUSTRE_DESTROY);
-
 check_oi:
        if (rc != 0) {
                __u32 saved_ino = id->oii_ino;
@@ -750,19 +725,6 @@ check_oi:
                        rc = -ENOENT;
                else
                        rc = -EREMCHG;
-       } else {
-               if (id->oii_gen == OSD_OII_NOGEN)
-                       osd_id_gen(id, inode->i_ino, inode->i_generation);
-
-               /*
-                * Do not update file c/mtime in ldiskfs.
-                * NB: we don't have any lock to protect this because we don't
-                * have reference on osd_object now, but contention with
-                * another lookup + attr_set can't happen in the tiny window
-                * between if (...) and set S_NOCMTIME.
-                */
-               if (!(inode->i_flags & S_NOCMTIME))
-                       inode->i_flags |= S_NOCMTIME;
        }
 
        GOTO(put, rc);
@@ -1025,7 +987,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 = {
@@ -1037,12 +998,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)
@@ -1070,19 +1043,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",
@@ -1155,6 +1122,7 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj,
        }
 
        id = &info->oti_id;
+       memset(id, 0, sizeof(struct osd_inode_id));
        if (!list_empty(&scrub->os_inconsistent_items)) {
                /* Search order: 2. OI scrub pending list. */
                result = osd_oii_lookup(dev, fid, id);
@@ -1171,7 +1139,7 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj,
        /* Search order: 3. OI files. */
        result = osd_oi_lookup(info, dev, fid, id, OI_CHECK_FLD);
        if (result == -ENOENT) {
-               if (!(fid_is_norm(fid) || fid_is_igif(fid)) ||
+               if (!fid_is_norm(fid) ||
                    fid_is_on_ost(info, dev, fid, OI_CHECK_FLD) ||
                    !ldiskfs_test_bit(osd_oi_fid2idx(dev, fid),
                                      sf->sf_oi_bitmap))
@@ -1257,7 +1225,7 @@ trigger:
                goto found;
        }
 
-       if (dev->od_auto_scrub_interval == AS_NEVER) {
+       if (dev->od_scrub.os_scrub.os_auto_scrub_interval == AS_NEVER) {
                if (!remote)
                        GOTO(out, result = -EREMCHG);
 
@@ -1778,7 +1746,6 @@ static void osd_trans_commit_cb(struct super_block *sb,
        if (error)
                CERROR("transaction @0x%p commit error: %d\n", th, error);
 
-       OBD_FAIL_TIMEOUT(OBD_FAIL_OST_DELAY_TRANS, 40);
        /* call per-transaction callbacks if any */
        list_for_each_entry_safe(dcb, tmp, &oh->ot_commit_dcb_list,
                                 dcb_linkage) {
@@ -2086,7 +2053,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);
@@ -2488,15 +2463,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.
  */
@@ -2572,18 +2538,39 @@ const int osd_dto_credits_noquota[DTO_NR] = {
        [DTO_ATTR_SET_CHOWN] = 0
 };
 
+/* reserve or free quota for some operation */
+static int osd_reserve_or_free_quota(const struct lu_env *env,
+                                    struct dt_device *dev,
+                                    struct lquota_id_info *qi)
+{
+       struct osd_device       *osd = osd_dt_dev(dev);
+       struct qsd_instance     *qsd = NULL;
+       int rc;
+
+       ENTRY;
+
+       if (qi->lqi_is_blk)
+               qsd = osd->od_quota_slave_dt;
+       else
+               qsd = osd->od_quota_slave_md;
+
+       rc = qsd_reserve_or_free_quota(env, qsd, qi);
+       RETURN(rc);
+}
+
 static const struct dt_device_operations osd_dt_ops = {
-       .dt_root_get       = osd_root_get,
-       .dt_statfs         = osd_statfs,
-       .dt_trans_create   = osd_trans_create,
-       .dt_trans_start    = osd_trans_start,
-       .dt_trans_stop     = osd_trans_stop,
-       .dt_trans_cb_add   = osd_trans_cb_add,
-       .dt_conf_get       = osd_conf_get,
-       .dt_mnt_sb_get     = osd_mnt_sb_get,
-       .dt_sync           = osd_sync,
-       .dt_ro             = osd_ro,
-       .dt_commit_async   = osd_commit_async,
+       .dt_root_get              = osd_root_get,
+       .dt_statfs                = osd_statfs,
+       .dt_trans_create          = osd_trans_create,
+       .dt_trans_start           = osd_trans_start,
+       .dt_trans_stop            = osd_trans_stop,
+       .dt_trans_cb_add          = osd_trans_cb_add,
+       .dt_conf_get              = osd_conf_get,
+       .dt_mnt_sb_get            = osd_mnt_sb_get,
+       .dt_sync                  = osd_sync,
+       .dt_ro                    = osd_ro,
+       .dt_commit_async          = osd_commit_async,
+       .dt_reserve_or_free_quota = osd_reserve_or_free_quota,
 };
 
 static void osd_read_lock(const struct lu_env *env, struct dt_object *dt,
@@ -2781,7 +2768,7 @@ static int osd_declare_attr_qid(const struct lu_env *env,
                                struct osd_object *obj,
                                struct osd_thandle *oh, long long bspace,
                                qid_t old_id, qid_t new_id, bool enforce,
-                               unsigned int type, bool ignore_edquot)
+                               unsigned int type)
 {
        int rc;
        struct osd_thread_info *info = osd_oti_get(env);
@@ -2796,7 +2783,7 @@ static int osd_declare_attr_qid(const struct lu_env *env,
        qi->lqi_space      = 1;
        /* Reserve credits for the new id */
        rc = osd_declare_qid(env, oh, qi, NULL, enforce, NULL);
-       if (ignore_edquot && (rc == -EDQUOT || rc == -EINPROGRESS))
+       if (rc == -EDQUOT || rc == -EINPROGRESS)
                rc = 0;
        if (rc)
                RETURN(rc);
@@ -2805,7 +2792,7 @@ static int osd_declare_attr_qid(const struct lu_env *env,
        qi->lqi_id.qid_uid = old_id;
        qi->lqi_space = -1;
        rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL);
-       if (ignore_edquot && (rc == -EDQUOT || rc == -EINPROGRESS))
+       if (rc == -EDQUOT || rc == -EINPROGRESS)
                rc = 0;
        if (rc)
                RETURN(rc);
@@ -2821,7 +2808,7 @@ static int osd_declare_attr_qid(const struct lu_env *env,
         * to save credit reservation.
         */
        rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL);
-       if (ignore_edquot && (rc == -EDQUOT || rc == -EINPROGRESS))
+       if (rc == -EDQUOT || rc == -EINPROGRESS)
                rc = 0;
        if (rc)
                RETURN(rc);
@@ -2830,7 +2817,7 @@ static int osd_declare_attr_qid(const struct lu_env *env,
        qi->lqi_id.qid_uid = old_id;
        qi->lqi_space      = -bspace;
        rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL);
-       if (ignore_edquot && (rc == -EDQUOT || rc == -EINPROGRESS))
+       if (rc == -EDQUOT || rc == -EINPROGRESS)
                rc = 0;
 
        RETURN(rc);
@@ -2881,20 +2868,11 @@ static int osd_declare_attr_set(const struct lu_env *env,
         * space adjustment once the operation is completed.
         */
        if (attr->la_valid & LA_UID || attr->la_valid & LA_GID) {
-               bool ignore_edquot = !(attr->la_flags & LUSTRE_SET_SYNC_FL);
-
-               if (!ignore_edquot)
-                       CDEBUG(D_QUOTA,
-                              "%s: enforce quota on UID %u, GID %u (quota space is %lld)\n",
-                              osd_ino2name(obj->oo_inode), attr->la_uid,
-                              attr->la_gid, bspace);
-
                /* USERQUOTA */
                uid = i_uid_read(obj->oo_inode);
                enforce = (attr->la_valid & LA_UID) && (attr->la_uid != uid);
                rc = osd_declare_attr_qid(env, obj, oh, bspace, uid,
-                                         attr->la_uid, enforce, USRQUOTA,
-                                         true);
+                                         attr->la_uid, enforce, USRQUOTA);
                if (rc)
                        RETURN(rc);
 
@@ -2903,8 +2881,7 @@ static int osd_declare_attr_set(const struct lu_env *env,
                       attr->la_uid, gid, attr->la_gid);
                enforce = (attr->la_valid & LA_GID) && (attr->la_gid != gid);
                rc = osd_declare_attr_qid(env, obj, oh, bspace, gid,
-                                         attr->la_gid, enforce, GRPQUOTA,
-                                         ignore_edquot);
+                                         attr->la_gid, enforce, GRPQUOTA);
                if (rc)
                        RETURN(rc);
 
@@ -2917,7 +2894,7 @@ static int osd_declare_attr_set(const struct lu_env *env,
                                        (attr->la_projid != projid);
                rc = osd_declare_attr_qid(env, obj, oh, bspace,
                                          (qid_t)projid, (qid_t)attr->la_projid,
-                                         enforce, PRJQUOTA, true);
+                                         enforce, PRJQUOTA);
                if (rc)
                        RETURN(rc);
        }
@@ -3044,7 +3021,9 @@ static int osd_transfer_project(struct inode *inode, __u32 projid,
        dquot_initialize(inode);
        transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
        if (transfer_to[PRJQUOTA]) {
+               lock_dquot_transfer(inode);
                err = __dquot_transfer(inode, transfer_to);
+               unlock_dquot_transfer(inode);
                dqput(transfer_to[PRJQUOTA]);
                if (err)
                        return err;
@@ -3077,7 +3056,9 @@ static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr,
                iattr.ia_uid = make_kuid(&init_user_ns, attr->la_uid);
                iattr.ia_gid = make_kgid(&init_user_ns, attr->la_gid);
 
+               lock_dquot_transfer(inode);
                rc = dquot_transfer(inode, &iattr);
+               unlock_dquot_transfer(inode);
                if (rc) {
                        CERROR("%s: quota transfer failed. Is quota enforcement enabled on the ldiskfs filesystem? rc = %d\n",
                               osd_ino2name(inode), rc);
@@ -3444,7 +3425,6 @@ static void osd_ah_init(const struct lu_env *env, struct dt_allocation_hint *ah,
        LASSERT(ah);
 
        ah->dah_parent = parent;
-       ah->dah_mode = child_mode;
 
        if (parent != NULL && !dt_object_remote(parent)) {
                /* will help to find FID->ino at dt_insert("..") */
@@ -4285,7 +4265,7 @@ static int osd_ref_add(const struct lu_env *env, struct dt_object *dt,
                /* inc_nlink from 0 may cause WARN_ON */
                set_nlink(inode, 1);
        else {
-               ldiskfs_inc_count(oh->ot_handle, inode);
+               osd_ldiskfs_inc_count(oh->ot_handle, inode);
                if (!S_ISDIR(inode->i_mode))
                        LASSERT(inode->i_nlink <= LDISKFS_LINK_MAX);
        }
@@ -4364,7 +4344,7 @@ static int osd_ref_del(const struct lu_env *env, struct dt_object *dt,
        CDEBUG(D_INODE, DFID" decrease nlink %d\n",
               PFID(lu_object_fid(&dt->do_lu)), inode->i_nlink);
 
-       ldiskfs_dec_count(oh->ot_handle, inode);
+       osd_ldiskfs_dec_count(oh->ot_handle, inode);
        spin_unlock(&obj->oo_guard);
 
        osd_dirty_inode(inode, I_DIRTY_DATASYNC);
@@ -4467,8 +4447,18 @@ static int osd_xattr_get(const struct lu_env *env, struct dt_object *dt,
                        ol->ol_comp_id = 0;
                }
        } else {
-               rc = __osd_xattr_get(inode, dentry, name,
-                                    buf->lb_buf, buf->lb_len);
+               /* Get enc context xattr directly from ldiskfs instead of going
+                * through the VFS, as there is no xattr handler for
+                * "encryption.".
+                */
+               if (strcmp(name, LL_XATTR_NAME_ENCRYPTION_CONTEXT) == 0)
+                       rc = ldiskfs_xattr_get(inode,
+                                         LDISKFS_XATTR_INDEX_ENCRYPTION,
+                                         LDISKFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+                                         buf->lb_buf, buf->lb_len);
+               else
+                       rc = __osd_xattr_get(inode, dentry, name,
+                                            buf->lb_buf, buf->lb_len);
        }
 
        if (cache_xattr) {
@@ -4836,7 +4826,27 @@ static int osd_xattr_set(const struct lu_env *env, struct dt_object *dt,
        if (fl & LU_XATTR_CREATE)
                fs_flags |= XATTR_CREATE;
 
-       rc = __osd_xattr_set(info, inode, name, buf->lb_buf, len, fs_flags);
+       if (strcmp(name, LL_XATTR_NAME_ENCRYPTION_CONTEXT) == 0) {
+               /* Set enc context xattr directly in ldiskfs instead of going
+                * through the VFS, as there is no xattr handler for
+                * "encryption.".
+                */
+               struct osd_thandle *oth = container_of(handle,
+                                                      struct osd_thandle,
+                                                      ot_super);
+
+               if (!oth->ot_handle)
+                       /* this should be already part of a transaction */
+                       RETURN(-EPROTO);
+
+               rc = ldiskfs_xattr_set_handle(oth->ot_handle, inode,
+                                         LDISKFS_XATTR_INDEX_ENCRYPTION,
+                                         LDISKFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+                                         buf->lb_buf, len, fs_flags);
+       } else {
+               rc = __osd_xattr_set(info, inode, name,
+                                    buf->lb_buf, len, fs_flags);
+       }
        osd_trans_exec_check(env, handle, OSD_OT_XATTR_SET);
 
        if (rc == 0 &&
@@ -4854,9 +4864,11 @@ static int osd_xattr_list(const struct lu_env *env, struct dt_object *dt,
                          const struct lu_buf *buf)
 {
        struct osd_object *obj = osd_dt_obj(dt);
+       struct osd_device *dev = osd_obj2dev(obj);
        struct inode *inode = obj->oo_inode;
        struct osd_thread_info *info = osd_oti_get(env);
        struct dentry *dentry = &info->oti_obj_dentry;
+       int rc;
 
        if (!dt_object_exists(dt))
                return -ENOENT;
@@ -4867,7 +4879,31 @@ static int osd_xattr_list(const struct lu_env *env, struct dt_object *dt,
 
        dentry->d_inode = inode;
        dentry->d_sb = inode->i_sb;
-       return inode->i_op->listxattr(dentry, buf->lb_buf, buf->lb_len);
+       rc = inode->i_op->listxattr(dentry, buf->lb_buf, buf->lb_len);
+
+       if (rc < 0 || buf->lb_buf == NULL)
+               return rc;
+
+       /* Hide virtual project ID xattr from list if disabled */
+       if (!dev->od_enable_projid_xattr) {
+               char *end = (char *)buf->lb_buf + rc;
+               char *p = buf->lb_buf;
+
+               while (p < end) {
+                       char *next = p + strlen(p) + 1;
+
+                       if (strcmp(p, XATTR_NAME_PROJID) == 0) {
+                               if (end - next > 0)
+                                       memmove(p, next, end - next);
+                               rc -= next - p;
+                               break;
+                       }
+
+                       p = next;
+               }
+       }
+
+       return rc;
 }
 
 static int osd_declare_xattr_del(const struct lu_env *env,
@@ -4954,13 +4990,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);
 }
@@ -5344,6 +5388,42 @@ static void osd_take_care_of_agent(const struct lu_env *env,
 }
 
 /**
+ * Utility function to get real name from object name
+ *
+ * \param[in] obj      pointer to the object to be handled
+ * \param[in] name     object name
+ * \param[in] len      object name len
+ * \param[out]ln       pointer to the struct lu_name to hold the real name
+ *
+ * If file is not encrypted, real name is just the object name.
+ * If file is encrypted, object name needs to be decoded. In
+ * this case a new buffer is allocated, and ln->ln_name needs to be freed by
+ * the caller.
+ *
+ * \retval   0, on success
+ * \retval -ve, on error
+ */
+static int obj_name2lu_name(struct osd_object *obj, const char *name,
+                           int len, struct lu_name *ln)
+{
+       if (!(obj->oo_lma_flags & LUSTRE_ENCRYPT_FL)) {
+               ln->ln_name = name;
+               ln->ln_namelen = len;
+       } else {
+               char *buf = kmalloc(len, GFP_NOFS);
+
+               if (!buf)
+                       return -ENOMEM;
+
+               len = critical_decode(name, len, buf);
+               ln->ln_name = buf;
+               ln->ln_namelen = len;
+       }
+
+       return 0;
+}
+
+/**
  * Index delete function for interoperability mode (b11826).
  * It will remove the directory entry added by osd_index_ea_insert().
  * This entry is needed to maintain name->fid mapping.
@@ -5364,6 +5444,7 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
        struct buffer_head *bh;
        struct htree_lock *hlock = NULL;
        struct osd_device *osd = osd_dev(dt->do_lu.lo_dev);
+       struct lu_name ln;
        int rc;
 
        ENTRY;
@@ -5375,6 +5456,10 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
        LASSERT(!dt_object_remote(dt));
        LASSERT(handle != NULL);
 
+       rc = obj_name2lu_name(obj, (char *)key, strlen((char *)key), &ln);
+       if (rc)
+               RETURN(rc);
+
        osd_trans_exec_op(env, handle, OSD_OT_DELETE);
 
        oh = container_of(handle, struct osd_thandle, ot_super);
@@ -5382,8 +5467,7 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
        LASSERT(oh->ot_handle->h_transaction != NULL);
 
        dquot_initialize(dir);
-       dentry = osd_child_dentry_get(env, obj,
-                                     (char *)key, strlen((char *)key));
+       dentry = osd_child_dentry_get(env, obj, ln.ln_name, ln.ln_namelen);
 
        if (obj->oo_hl_head != NULL) {
                hlock = osd_oti_get(env)->oti_hlock;
@@ -5437,6 +5521,8 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
 out:
        LASSERT(osd_invariant(obj));
        osd_trans_exec_check(env, handle, OSD_OT_DELETE);
+       if (ln.ln_name != (char *)key)
+               kfree(ln.ln_name);
        RETURN(rc);
 }
 
@@ -5611,6 +5697,7 @@ static int __osd_ea_add_rec(struct osd_thread_info *info,
        struct ldiskfs_dentry_param *ldp;
        struct dentry *child;
        struct osd_thandle *oth;
+       struct lu_name ln;
        int rc;
 
        oth = container_of(th, struct osd_thandle, ot_super);
@@ -5618,12 +5705,17 @@ static int __osd_ea_add_rec(struct osd_thread_info *info,
        LASSERT(oth->ot_handle->h_transaction != NULL);
        LASSERT(pobj->oo_inode);
 
+       rc = obj_name2lu_name(pobj, name, strlen(name), &ln);
+       if (rc)
+               RETURN(rc);
+
        ldp = (struct ldiskfs_dentry_param *)info->oti_ldp;
        if (unlikely(osd_object_is_root(pobj)))
                ldp->edp_magic = 0;
        else
                osd_get_ldiskfs_dirent_param(ldp, fid);
-       child = osd_child_dentry_get(info->oti_env, pobj, name, strlen(name));
+       child = osd_child_dentry_get(info->oti_env, pobj,
+                                    ln.ln_name, ln.ln_namelen);
        child->d_fsdata = (void *)ldp;
        dquot_initialize(pobj->oo_inode);
        rc = osd_ldiskfs_add_entry(info, osd_obj2dev(pobj), oth->ot_handle,
@@ -5652,6 +5744,8 @@ static int __osd_ea_add_rec(struct osd_thread_info *info,
                }
        }
 
+       if (ln.ln_name != name)
+               kfree(ln.ln_name);
        RETURN(rc);
 }
 
@@ -5779,8 +5873,10 @@ static int osd_ea_add_rec(const struct lu_env *env, struct osd_object *pobj,
 }
 
 static int
-osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev,
-                     const struct lu_fid *fid, struct osd_inode_id *id)
+osd_ldiskfs_consistency_check(struct osd_thread_info *oti,
+                             struct osd_device *dev,
+                             const struct lu_fid *fid,
+                             struct osd_inode_id *id)
 {
        struct lustre_scrub *scrub = &dev->od_scrub.os_scrub;
        struct inode *inode = NULL;
@@ -5789,18 +5885,8 @@ osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev,
        int rc;
 
        ENTRY;
-
-       if (!fid_is_norm(fid) && !fid_is_igif(fid))
-               RETURN(0);
-
-       if (scrub->os_running && scrub->os_pos_current > id->oii_ino)
-               RETURN(0);
-
-       if (dev->od_auto_scrub_interval == AS_NEVER ||
-           ktime_get_real_seconds() <
-           scrub->os_file.sf_time_last_complete + dev->od_auto_scrub_interval)
+       if (!scrub_needs_check(scrub, fid, id->oii_ino))
                RETURN(0);
-
 again:
        rc = osd_oi_lookup(oti, dev, fid, &oti->oti_id, 0);
        if (rc == -ENOENT) {
@@ -5863,7 +5949,8 @@ trigger:
                GOTO(out, rc);
        }
 
-       if (dev->od_auto_scrub_interval != AS_NEVER && ++once == 1) {
+       if (dev->od_scrub.os_scrub.os_auto_scrub_interval != AS_NEVER &&
+           ++once == 1) {
                rc = osd_scrub_start(oti->oti_env, dev, SS_AUTO_PARTIAL |
                                     SS_CLEAR_DRYRUN | SS_CLEAR_FAILOUT);
                CDEBUG_LIMIT(D_LFSCK | D_CONSOLE | D_WARNING,
@@ -6054,6 +6141,7 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
        struct buffer_head *bh;
        struct lu_fid *fid = (struct lu_fid *)rec;
        struct htree_lock *hlock = NULL;
+       struct lu_name ln;
        int ino;
        int rc;
 
@@ -6062,8 +6150,11 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
        LASSERT(dir->i_op != NULL);
        LASSERT(dir->i_op->lookup != NULL);
 
-       dentry = osd_child_dentry_get(env, obj,
-                                     (char *)key, strlen((char *)key));
+       rc = obj_name2lu_name(obj, (char *)key, strlen((char *)key), &ln);
+       if (rc)
+               RETURN(rc);
+
+       dentry = osd_child_dentry_get(env, obj, ln.ln_name, ln.ln_namelen);
 
        if (obj->oo_hl_head != NULL) {
                hlock = osd_oti_get(env)->oti_hlock;
@@ -6113,7 +6204,7 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
                if (rc != 0 || osd_remote_fid(env, dev, fid))
                        GOTO(out, rc);
 
-               rc = osd_consistency_check(oti, dev, fid, id);
+               rc = osd_ldiskfs_consistency_check(oti, dev, fid, id);
                if (rc != -ENOENT) {
                        /* Other error should not affect lookup result. */
                        rc = 0;
@@ -6139,7 +6230,9 @@ out:
                ldiskfs_htree_unlock(hlock);
        else
                up_read(&obj->oo_ext_idx_sem);
-       return rc;
+       if (ln.ln_name != (char *)key)
+               kfree(ln.ln_name);
+       RETURN(rc);
 }
 
 static int osd_index_declare_ea_insert(const struct lu_env *env,
@@ -6213,7 +6306,7 @@ static int osd_index_declare_ea_insert(const struct lu_env *env,
                    i_projid_read(inode) != 0)
                        rc = osd_declare_attr_qid(env, osd_dt_obj(dt), oh,
                                                  0, i_projid_read(inode),
-                                                 0, false, PRJQUOTA, true);
+                                                 0, false, PRJQUOTA);
 #endif
        }
 
@@ -6605,23 +6698,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;
@@ -6631,24 +6730,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);
 }
 
 /**
@@ -6662,6 +6757,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;
 
@@ -6670,9 +6766,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);
@@ -6685,7 +6781,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
@@ -6728,7 +6824,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;
@@ -6759,29 +6855,29 @@ struct osd_filldir_cbs {
  * \retval 1 on buffer full
  */
 #ifdef HAVE_FILLDIR_USE_CTX
-static int osd_ldiskfs_filldir(struct dir_context *buf,
+static int osd_ldiskfs_filldir(struct dir_context *ctx,
 #else
-static int osd_ldiskfs_filldir(void *buf,
+static int osd_ldiskfs_filldir(void *ctx,
 #endif
                               const char *name, int namelen,
                               loff_t offset, __u64 ino, unsigned int d_type)
 {
-       struct osd_it_ea *it = ((struct osd_filldir_cbs *)buf)->it;
+       struct osd_it_ea *it = ((struct osd_filldir_cbs *)ctx)->it;
        struct osd_object *obj = it->oie_obj;
        struct osd_it_ea_dirent *ent = it->oie_dirent;
        struct lu_fid *fid = &ent->oied_fid;
+       char *buf = it->oie_buf;
        struct osd_fid_pack *rec;
-
        ENTRY;
 
-/* this should never happen */
+       /* this should never happen */
        if (unlikely(namelen == 0 || namelen > LDISKFS_NAME_LEN)) {
                CERROR("ldiskfs return invalid namelen %d\n", namelen);
                RETURN(-EIO);
        }
 
-       if ((void *)ent - it->oie_buf + sizeof(*ent) + namelen >
-           OSD_IT_EA_BUFSIZE)
+       /* Check for enough space. Note oied_name is not NUL terminated. */
+       if (&ent->oied_name[namelen] > buf + OSD_IT_EA_BUFSIZE)
                RETURN(1);
 
        /* "." is just the object itself. */
@@ -6804,15 +6900,30 @@ static int osd_ldiskfs_filldir(void *buf,
                *fid = obj->oo_dt.do_lu.lo_header->loh_fid;
        }
 
+       if (obj == NULL || !(obj->oo_lma_flags & LUSTRE_ENCRYPT_FL)) {
+               ent->oied_namelen = namelen;
+               memcpy(ent->oied_name, name, namelen);
+       } else {
+               int encoded_namelen = critical_chars(name, namelen);
+
+               /* Check again for enough space. */
+               if (&ent->oied_name[encoded_namelen] > buf + OSD_IT_EA_BUFSIZE)
+                       RETURN(1);
+
+               ent->oied_namelen = encoded_namelen;
+
+               if (encoded_namelen == namelen)
+                       memcpy(ent->oied_name, name, namelen);
+               else
+                       critical_encode(name, namelen, ent->oied_name);
+       }
+
        ent->oied_ino     = ino;
        ent->oied_off     = offset;
-       ent->oied_namelen = namelen;
        ent->oied_type    = d_type;
 
-       memcpy(ent->oied_name, name, namelen);
-
        it->oie_rd_dirent++;
-       it->oie_dirent = (void *)ent + cfs_size_round(sizeof(*ent) + namelen);
+       it->oie_dirent = (void *)ent + cfs_size_round(sizeof(*ent) + ent->oied_namelen);
        RETURN(0);
 }
 
@@ -6831,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,
@@ -6853,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);
@@ -6869,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 {
@@ -6913,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);
@@ -7062,6 +7166,7 @@ osd_dirent_check_repair(const struct lu_env *env, struct osd_object *obj,
        int rc;
        bool dotdot = false;
        bool dirty = false;
+       struct lu_name ln;
 
        ENTRY;
 
@@ -7096,8 +7201,11 @@ osd_dirent_check_repair(const struct lu_env *env, struct osd_object *obj,
                RETURN(rc);
        }
 
-       dentry = osd_child_dentry_by_inode(env, dir, ent->oied_name,
-                                          ent->oied_namelen);
+       rc = obj_name2lu_name(obj, ent->oied_name, ent->oied_namelen, &ln);
+       if (rc)
+               RETURN(rc);
+
+       dentry = osd_child_dentry_by_inode(env, dir, ln.ln_name, ln.ln_namelen);
        rc = osd_get_lma(info, inode, dentry, &info->oti_ost_attrs);
        if (rc == -ENODATA || !fid_is_sane(&lma->lma_self_fid))
                lma = NULL;
@@ -7370,6 +7478,8 @@ out_inode:
        iput(inode);
        if (rc >= 0 && !dirty)
                dev->od_dirent_journal = 0;
+       if (ln.ln_name != ent->oied_name)
+               kfree(ln.ln_name);
 
        return rc;
 }
@@ -7510,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)
@@ -7634,7 +7744,7 @@ static void osd_key_fini(const struct lu_context *ctx,
        lu_buf_free(&info->oti_big_buf);
        if (idc != NULL) {
                LASSERT(info->oti_ins_cache_size > 0);
-               OBD_FREE_PTR_ARRAY(idc, info->oti_ins_cache_size);
+               OBD_FREE_PTR_ARRAY_LARGE(idc, info->oti_ins_cache_size);
                info->oti_ins_cache = NULL;
                info->oti_ins_cache_size = 0;
        }
@@ -7649,6 +7759,8 @@ static void osd_key_exit(const struct lu_context *ctx,
        LASSERT(info->oti_r_locks == 0);
        LASSERT(info->oti_w_locks == 0);
        LASSERT(info->oti_txns    == 0);
+       LASSERTF(info->oti_dio_pages_used == 0, "%d\n",
+                info->oti_dio_pages_used);
 }
 
 /* type constructor/destructor: osd_type_init, osd_type_fini */
@@ -7916,6 +8028,12 @@ static int osd_mount(const struct lu_env *env,
                GOTO(out_mnt, rc = -EINVAL);
        }
 
+       if (ldiskfs_has_feature_fast_commit(o->od_mnt->mnt_sb)) {
+               CERROR("%s: device %s is mounted with fast_commit that breaks recovery\n",
+                      name, dev);
+               GOTO(out_mnt, rc = -EOPNOTSUPP);
+       }
+
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 53, 0)
 #ifdef LDISKFS_MOUNT_DIRDATA
        if (ldiskfs_has_feature_dirdata(o->od_mnt->mnt_sb))
@@ -7931,7 +8049,7 @@ static int osd_mount(const struct lu_env *env,
        if (unlikely(!ldiskfs_has_feature_largedir(o->od_mnt->mnt_sb) &&
                     !strstr(name, "MGS"))) {
                ldiskfs_set_feature_largedir(o->od_mnt->mnt_sb);
-               LCONSOLE_INFO("%s: enable 'large_dir' feature on device '%s'\n",
+               LCONSOLE_INFO("%s: enabled 'large_dir' feature on device %s\n",
                              name, dev);
        }
 #endif
@@ -7944,7 +8062,7 @@ static int osd_mount(const struct lu_env *env,
        }
 
        if (lmd_flags & LMD_FLG_NOSCRUB)
-               o->od_auto_scrub_interval = AS_NEVER;
+               o->od_scrub.os_scrub.os_auto_scrub_interval = AS_NEVER;
 
        if (blk_queue_nonrot(bdev_get_queue(osd_sb(o)->s_bdev))) {
                /* do not use pagecache with flash-backed storage */
@@ -8018,10 +8136,11 @@ static int osd_device_init0(const struct lu_env *env,
 
        o->od_read_cache = 1;
        o->od_writethrough_cache = 1;
+       o->od_enable_projid_xattr = 0;
        o->od_readcache_max_filesize = OSD_MAX_CACHE_SIZE;
        o->od_readcache_max_iosize = OSD_READCACHE_MAX_IO_MB << 20;
        o->od_writethrough_max_iosize = OSD_WRITECACHE_MAX_IO_MB << 20;
-       o->od_auto_scrub_interval = AS_DEFAULT;
+       o->od_scrub.os_scrub.os_auto_scrub_interval = AS_DEFAULT;
        /* default fallocate to unwritten extents: LU-14326/LU-14333 */
        o->od_fallocate_zero_blocks = 0;
 
@@ -8066,12 +8185,17 @@ static int osd_device_init0(const struct lu_env *env,
                restored = true;
 
        INIT_LIST_HEAD(&o->od_ios_list);
+
+       rc = lprocfs_init_brw_stats(&o->od_brw_stats);
+       if (rc)
+               GOTO(out_brw_stats, rc);
+
        /* setup scrub, including OI files initialization */
        o->od_in_init = 1;
        rc = osd_scrub_setup(env, o, restored);
        o->od_in_init = 0;
        if (rc < 0)
-               GOTO(out_site, rc);
+               GOTO(out_brw_stats, rc);
 
        rc = osd_procfs_init(o, o->od_svname);
        if (rc != 0) {
@@ -8087,8 +8211,8 @@ static int osd_device_init0(const struct lu_env *env,
        /* currently it's no need to prepare qsd_instance_md for OST */
        if (!o->od_is_ost) {
                o->od_quota_slave_md = qsd_init(env, o->od_svname,
-                                               &o->od_dt_dev,
-                                               o->od_proc_entry, true);
+                                               &o->od_dt_dev, o->od_proc_entry,
+                                               true, true);
                if (IS_ERR(o->od_quota_slave_md)) {
                        rc = PTR_ERR(o->od_quota_slave_md);
                        o->od_quota_slave_md = NULL;
@@ -8097,7 +8221,7 @@ static int osd_device_init0(const struct lu_env *env,
        }
 
        o->od_quota_slave_dt = qsd_init(env, o->od_svname, &o->od_dt_dev,
-                                       o->od_proc_entry, false);
+                                       o->od_proc_entry, false, true);
 
        if (IS_ERR(o->od_quota_slave_dt)) {
                if (o->od_quota_slave_md != NULL) {
@@ -8122,6 +8246,8 @@ out_procfs:
        osd_procfs_fini(o);
 out_scrub:
        osd_scrub_cleanup(env, o);
+out_brw_stats:
+       lprocfs_fini_brw_stats(&o->od_brw_stats);
 out_site:
        lu_site_fini(&o->od_site);
 out_compat:
@@ -8458,11 +8584,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) {
@@ -8480,6 +8601,7 @@ static int __init osd_init(void)
                        rc = 0;
                }
        }
+
        return rc;
 }