Whamcloud - gitweb
LU-9679 lustre: use LIST_HEAD() for local lists.
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_handler.c
index eb36066..13e710c 100644 (file)
@@ -42,9 +42,7 @@
 #include <linux/kallsyms.h>
 #include <linux/module.h>
 #include <linux/user_namespace.h>
-#ifdef HAVE_UIDGID_HEADER
-# include <linux/uidgid.h>
-#endif
+#include <linux/uidgid.h>
 
 /* prerequisite for linux/xattr.h */
 #include <linux/types.h>
@@ -423,7 +421,7 @@ struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev,
         */
         /* LASSERT(current->journal_info == NULL); */
 
-       inode = ldiskfs_iget(osd_sb(dev), id->oii_ino);
+       inode = osd_ldiskfs_iget(osd_sb(dev), id->oii_ino);
        if (IS_ERR(inode)) {
                CDEBUG(D_INODE, "no inode: ino = %u, rc = %ld\n",
                       id->oii_ino, PTR_ERR(inode));
@@ -495,13 +493,13 @@ int osd_ldiskfs_add_entry(struct osd_thread_info *info, struct osd_device *osd,
                }
 
                if (fid != NULL)
-                       CWARN("%s: directory (inode: %lu, FID: "DFID") %s "
-                             "maximum entry limit\n",
+                       /* below message is checked in sanity.sh test_129 */
+                       CWARN("%s: directory (inode: %lu, FID: "DFID") %s maximum entry limit\n",
                              osd_name(osd), parent->i_ino, PFID(fid),
                              rc == -ENOSPC ? "has reached" : "is approaching");
                else
-                       CWARN("%s: directory (inode: %lu, FID: unknown) %s "
-                             "maximum entry limit\n",
+                       /* below message is checked in sanity.sh test_129 */
+                       CWARN("%s: directory (inode: %lu, FID: unknown) %s maximum entry limit\n",
                              osd_name(osd), parent->i_ino,
                              rc == -ENOSPC ? "has reached" : "is approaching");
 
@@ -559,7 +557,7 @@ static struct inode *osd_iget_check(struct osd_thread_info *info,
         */
 
 again:
-       inode = ldiskfs_iget(osd_sb(dev), id->oii_ino);
+       inode = osd_ldiskfs_iget(osd_sb(dev), id->oii_ino);
        if (IS_ERR(inode)) {
                rc = PTR_ERR(inode);
                if (!trusted && (rc == -ENOENT || rc == -ESTALE))
@@ -855,10 +853,8 @@ static int osd_check_lma(const struct lu_env *env, struct osd_object *obj)
 }
 
 struct osd_check_lmv_buf {
-#ifdef HAVE_DIR_CONTEXT
        /* please keep it as first member */
        struct dir_context ctx;
-#endif
        struct osd_thread_info *oclb_info;
        struct osd_device *oclb_dev;
        struct osd_idmap_cache *oclb_oic;
@@ -867,7 +863,7 @@ struct osd_check_lmv_buf {
 };
 
 /**
- * It is called internally by ->readdir() to filter out the
+ * It is called internally by ->iterate*() to filter out the
  * local slave object's FID of the striped directory.
  *
  * \retval     1 found the local slave's FID
@@ -964,9 +960,7 @@ static int osd_check_lmv(struct osd_thread_info *oti, struct osd_device *dev,
        const struct file_operations *fops;
        struct lmv_mds_md_v1 *lmv1;
        struct osd_check_lmv_buf oclb = {
-#ifdef HAVE_DIR_CONTEXT
                .ctx.actor = osd_stripe_dir_filldir,
-#endif
                .oclb_info = oti,
                .oclb_dev = dev,
                .oclb_oic = oic,
@@ -1013,25 +1007,20 @@ again:
        dentry->d_sb = inode->i_sb;
        filp->f_pos = 0;
        filp->f_path.dentry = dentry;
-       filp->f_mode = FMODE_64BITHASH;
+       filp->f_flags |= O_NOATIME;
+       filp->f_mode = FMODE_64BITHASH | FMODE_NONOTIFY;
        filp->f_mapping = inode->i_mapping;
        filp->f_op = fops;
        filp->private_data = NULL;
+       filp->f_cred = current_cred();
        set_file_inode(filp, inode);
+       rc = osd_security_file_alloc(filp);
+       if (rc)
+               goto out;
 
        do {
                oclb.oclb_items = 0;
-#ifdef HAVE_DIR_CONTEXT
-               oclb.ctx.pos = filp->f_pos;
-#ifdef HAVE_ITERATE_SHARED
-               rc = fops->iterate_shared(filp, &oclb.ctx);
-#else
-               rc = fops->iterate(filp, &oclb.ctx);
-#endif
-               filp->f_pos = oclb.ctx.pos;
-#else
-               rc = fops->readdir(filp, &oclb, osd_stripe_dir_filldir);
-#endif
+               rc = iterate_dir(filp, &oclb.ctx);
        } while (rc >= 0 && oclb.oclb_items > 0 && !oclb.oclb_found &&
                 filp->f_pos != LDISKFS_HTREE_EOF_64BIT);
        fops->release(inode, filp);
@@ -1128,6 +1117,12 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj,
                goto trigger;
        }
 
+       /* -ESTALE is returned if inode of OST object doesn't exist */
+       if (result == -ESTALE &&
+           fid_is_on_ost(info, dev, fid, OI_CHECK_FLD)) {
+               GOTO(out, result = 0);
+       }
+
        if (result)
                GOTO(out, result);
 
@@ -1290,6 +1285,19 @@ check_lma:
 
        LASSERT(!updated);
 
+       /*
+        * if two OST objects map to the same inode, and inode mode is
+        * (S_IFREG | S_ISUID | S_ISGID | S_ISVTX | 0666), which means it's
+        * reserved by precreate, and not written yet, in this case, don't
+        * set inode for the object whose FID mismatch, so that it can create
+        * inode and not block precreate.
+        */
+       if (fid_is_on_ost(info, dev, fid, OI_CHECK_FLD) &&
+           inode->i_mode == (S_IFREG | S_ISUID | S_ISGID | S_ISVTX | 0666)) {
+               obj->oo_inode = NULL;
+               GOTO(out, result = 0);
+       }
+
        result = osd_oi_lookup(info, dev, fid, id, OI_CHECK_FLD);
        /*
         * "result == -ENOENT" means the cached OI mapping has been removed
@@ -1707,8 +1715,7 @@ static void osd_trans_commit_cb(struct super_block *sb,
        if (error)
                CERROR("transaction @0x%p commit error: %d\n", th, error);
 
-       dt_txn_hook_commit(th);
-
+       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) {
@@ -1865,7 +1872,7 @@ static int osd_trans_start(const struct lu_env *env, struct dt_device *d,
                 */
                if (last_credits != oh->ot_credits &&
                    time_after(jiffies, last_printed +
-                              msecs_to_jiffies(60 * MSEC_PER_SEC)) &&
+                              cfs_time_seconds(60)) &&
                    osd_transaction_size(dev) > 512) {
                        CWARN("%s: credits %u > trans_max %u\n", osd_name(dev),
                              oh->ot_credits, osd_transaction_size(dev));
@@ -1971,7 +1978,7 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt,
        struct osd_device *osd = osd_dt_dev(th->th_dev);
        struct qsd_instance *qsd = osd_def_qsd(osd);
        struct lquota_trans *qtrans;
-       struct list_head truncates = LIST_HEAD_INIT(truncates);
+       LIST_HEAD(truncates);
        int rc = 0, remove_agents = 0;
 
        ENTRY;
@@ -2084,7 +2091,11 @@ static int osd_trans_cb_add(struct thandle *th, struct dt_txn_commit_cb *dcb)
 static void osd_object_delete(const struct lu_env *env, struct lu_object *l)
 {
        struct osd_object *obj = osd_obj(l);
+       struct qsd_instance *qsd = osd_def_qsd(osd_obj2dev(obj));
        struct inode *inode = obj->oo_inode;
+       __u64 projid;
+       qid_t uid;
+       qid_t gid;
 
        LINVRNT(osd_invariant(obj));
 
@@ -2093,27 +2104,36 @@ static void osd_object_delete(const struct lu_env *env, struct lu_object *l)
         */
 
        osd_index_fini(obj);
-       if (inode != NULL) {
-               struct qsd_instance *qsd = osd_def_qsd(osd_obj2dev(obj));
-               qid_t                uid = i_uid_read(inode);
-               qid_t                gid = i_gid_read(inode);
 
-               obj->oo_inode = NULL;
-               iput(inode);
-               if (!obj->oo_header && qsd) {
-                       struct osd_thread_info *info = osd_oti_get(env);
-                       struct lquota_id_info *qi = &info->oti_qi;
+       if (!inode)
+               return;
 
-                       /* Release granted quota to master if necessary */
-                       qi->lqi_id.qid_uid = uid;
-                       qsd_op_adjust(env, qsd, &qi->lqi_id, USRQUOTA);
+       uid = i_uid_read(inode);
+       gid = i_gid_read(inode);
+       projid = i_projid_read(inode);
 
-                       qi->lqi_id.qid_uid = gid;
-                       qsd_op_adjust(env, qsd, &qi->lqi_id, GRPQUOTA);
+       obj->oo_inode = NULL;
+       iput(inode);
 
-                       qi->lqi_id.qid_uid = i_projid_read(inode);
-                       qsd_op_adjust(env, qsd, &qi->lqi_id, PRJQUOTA);
-               }
+       /* do not rebalance quota if the caller needs to release memory
+        * otherwise qsd_refresh_usage() may went into a new ldiskfs
+        * transaction and risk to deadlock - LU-12178 */
+       if (current->flags & (PF_MEMALLOC | PF_KSWAPD))
+               return;
+
+       if (!obj->oo_header && qsd) {
+               struct osd_thread_info *info = osd_oti_get(env);
+               struct lquota_id_info *qi = &info->oti_qi;
+
+               /* Release granted quota to master if necessary */
+               qi->lqi_id.qid_uid = uid;
+               qsd_op_adjust(env, qsd, &qi->lqi_id, USRQUOTA);
+
+               qi->lqi_id.qid_uid = gid;
+               qsd_op_adjust(env, qsd, &qi->lqi_id, GRPQUOTA);
+
+               qi->lqi_id.qid_uid = projid;
+               qsd_op_adjust(env, qsd, &qi->lqi_id, PRJQUOTA);
        }
 }
 
@@ -2159,7 +2179,7 @@ static int osd_object_print(const struct lu_env *env, void *cookie,
  * Concurrency: shouldn't matter.
  */
 int osd_statfs(const struct lu_env *env, struct dt_device *d,
-               struct obd_statfs *sfs)
+               struct obd_statfs *sfs, struct obd_statfs_info *info)
 {
        struct osd_device *osd = osd_dt_dev(d);
        struct super_block *sb = osd_sb(osd);
@@ -2184,8 +2204,11 @@ int osd_statfs(const struct lu_env *env, struct dt_device *d,
                goto out;
 
        statfs_pack(sfs, ksfs);
-       if (unlikely(sb->s_flags & MS_RDONLY))
+       if (unlikely(sb->s_flags & SB_RDONLY))
                sfs->os_state |= OS_STATE_READONLY;
+
+       sfs->os_state |= osd->od_nonrotational ? OS_STATE_NONROT : 0;
+
        if (ldiskfs_has_feature_extents(sb))
                sfs->os_maxbytes = sb->s_maxbytes;
        else
@@ -2199,7 +2222,7 @@ int osd_statfs(const struct lu_env *env, struct dt_device *d,
         *
         * Reserve 0.78% of total space, at least 8MB for small filesystems.
         */
-       CLASSERT(OSD_STATFS_RESERVED > LDISKFS_MAX_BLOCK_SIZE);
+       BUILD_BUG_ON(OSD_STATFS_RESERVED <= LDISKFS_MAX_BLOCK_SIZE);
        reserved = OSD_STATFS_RESERVED >> sb->s_blocksize_bits;
        if (likely(sfs->os_blocks >= reserved << OSD_STATFS_RESERVED_SHIFT))
                reserved = sfs->os_blocks >> OSD_STATFS_RESERVED_SHIFT;
@@ -2255,12 +2278,12 @@ static void osd_conf_get(const struct lu_env *env,
         */
        param->ddp_inodespace     = PER_OBJ_USAGE;
        /*
-        * EXT_INIT_MAX_LEN is the theoretical maximum extent size  (32k blocks
-        * = 128MB) which is unlikely to be hit in real life. Report a smaller
-        * maximum length to not under count the actual number of extents
-        * needed for writing a file.
+        * EXT_INIT_MAX_LEN is the theoretical maximum extent size (32k blocks
+        * is 128MB) which is unlikely to be hit in real life. Report a smaller
+        * maximum length to not under-count the actual number of extents
+        * needed for writing a file if there are sub-optimal block allocations.
         */
-       param->ddp_max_extent_blks = EXT_INIT_MAX_LEN >> 2;
+       param->ddp_max_extent_blks = EXT_INIT_MAX_LEN >> 1;
        /* worst-case extent insertion metadata overhead */
        param->ddp_extent_tax = 6 * LDISKFS_BLOCK_SIZE(sb);
        param->ddp_mntopts = 0;
@@ -2285,8 +2308,8 @@ static void osd_conf_get(const struct lu_env *env,
 #endif
                param->ddp_max_ea_size = sb->s_blocksize - ea_overhead;
 
-       if (param->ddp_max_ea_size > OSD_MAX_EA_SIZE)
-               param->ddp_max_ea_size = OSD_MAX_EA_SIZE;
+       if (param->ddp_max_ea_size > OBD_MAX_EA_SIZE)
+               param->ddp_max_ea_size = OBD_MAX_EA_SIZE;
 
        /*
         * Preferred RPC size for efficient disk IO.  4MB shows good
@@ -2348,6 +2371,11 @@ static void osd_conf_get(const struct lu_env *env,
        }
 }
 
+static struct super_block *osd_mnt_sb_get(const struct dt_device *d)
+{
+       return osd_sb(osd_dt_dev(d));
+}
+
 /*
  * Concurrency: shouldn't matter.
  */
@@ -2399,6 +2427,14 @@ static int osd_commit_async(const struct lu_env *env,
 static int (*priv_dev_set_rdonly)(struct block_device *bdev);
 static int (*priv_dev_check_rdonly)(struct block_device *bdev);
 /* static int (*priv_dev_clear_rdonly)(struct block_device *bdev); */
+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.
@@ -2510,6 +2546,7 @@ static const struct dt_device_operations osd_dt_ops = {
        .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,
@@ -2581,18 +2618,6 @@ static int osd_write_locked(const struct lu_env *env, struct dt_object *dt)
        return obj->oo_owner == env;
 }
 
-static struct timespec *osd_inode_time(const struct lu_env *env,
-                                      struct inode *inode, __u64 seconds)
-{
-       struct osd_thread_info *oti = osd_oti_get(env);
-       struct timespec *t = &oti->oti_time;
-
-       t->tv_sec = seconds;
-       t->tv_nsec = 0;
-       *t = timespec_trunc(*t, inode->i_sb->s_time_gran);
-       return t;
-}
-
 static void osd_inode_getattr(const struct lu_env *env,
                              struct inode *inode, struct lu_attr *attr)
 {
@@ -2770,9 +2795,10 @@ static int osd_declare_attr_set(const struct lu_env *env,
                        RETURN(rc);
 
                gid = i_gid_read(obj->oo_inode);
+               CDEBUG(D_QUOTA, "declare uid %d -> %d gid %d -> %d\n", uid,
+                      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,
-                                         i_gid_read(obj->oo_inode),
+               rc = osd_declare_attr_qid(env, obj, oh, bspace, gid,
                                          attr->la_gid, enforce, GRPQUOTA,
                                          ignore_edquot);
                if (rc)
@@ -2808,11 +2834,11 @@ static int osd_inode_setattr(const struct lu_env *env,
                return 0;
 
        if (bits & LA_ATIME)
-               inode->i_atime  = *osd_inode_time(env, inode, attr->la_atime);
+               inode->i_atime = osd_inode_time(inode, attr->la_atime);
        if (bits & LA_CTIME)
-               inode->i_ctime  = *osd_inode_time(env, inode, attr->la_ctime);
+               inode->i_ctime = osd_inode_time(inode, attr->la_ctime);
        if (bits & LA_MTIME)
-               inode->i_mtime  = *osd_inode_time(env, inode, attr->la_mtime);
+               inode->i_mtime = osd_inode_time(inode, attr->la_mtime);
        if (bits & LA_SIZE) {
                spin_lock(&inode->i_lock);
                LDISKFS_I(inode)->i_disksize = attr->la_size;
@@ -2915,7 +2941,12 @@ static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr)
            (attr->la_valid & LA_GID && attr->la_gid != i_gid_read(inode))) {
                struct iattr iattr;
 
-               ll_vfs_dq_init(inode);
+               CDEBUG(D_QUOTA,
+                      "executing dquot_transfer inode %ld uid %d -> %d gid %d -> %d\n",
+                      inode->i_ino, i_uid_read(inode), attr->la_uid,
+                      i_gid_read(inode), attr->la_gid);
+
+               dquot_initialize(inode);
                iattr.ia_valid = 0;
                if (attr->la_valid & LA_UID)
                        iattr.ia_valid |= ATTR_UID;
@@ -2924,7 +2955,7 @@ 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);
 
-               rc = ll_vfs_dq_transfer(inode, &iattr);
+               rc = dquot_transfer(inode, &iattr);
                if (rc) {
                        CERROR("%s: quota transfer failed: rc = %d. Is quota "
                               "enforcement enabled on the ldiskfs "
@@ -3010,6 +3041,8 @@ static int osd_attr_set(const struct lu_env *env,
 
        ll_dirty_inode(inode, I_DIRTY_DATASYNC);
 
+       osd_trans_exec_check(env, handle, OSD_OT_ATTR_SET);
+
        if (!(attr->la_valid & LA_FLAGS))
                GOTO(out, rc);
 
@@ -3028,6 +3061,9 @@ static int osd_attr_set(const struct lu_env *env,
                lma->lma_incompat |=
                        lustre_to_lma_flags(attr->la_flags);
                lustre_lma_swab(lma);
+
+               osd_trans_exec_op(env, handle, OSD_OT_XATTR_SET);
+
                rc = __osd_xattr_set(info, inode, XATTR_NAME_LMA,
                                     lma, sizeof(*lma), XATTR_REPLACE);
                if (rc != 0) {
@@ -3043,7 +3079,6 @@ static int osd_attr_set(const struct lu_env *env,
                osd_trans_exec_check(env, handle, OSD_OT_XATTR_SET);
        }
 out:
-       osd_trans_exec_check(env, handle, OSD_OT_ATTR_SET);
 
        return rc;
 }
@@ -3057,13 +3092,19 @@ static struct dentry *osd_child_dentry_get(const struct lu_env *env,
 
 static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
                      umode_t mode, struct dt_allocation_hint *hint,
-                     struct thandle *th)
+                     struct thandle *th, struct lu_attr *attr)
 {
        int result;
        struct osd_device *osd = osd_obj2dev(obj);
        struct osd_thandle *oth;
        struct dt_object *parent = NULL;
        struct inode *inode;
+       uid_t owner[2] = {0, 0};
+
+       if (attr->la_valid & LA_UID)
+               owner[0] = attr->la_uid;
+       if (attr->la_valid & LA_GID)
+               owner[1] = attr->la_gid;
 
        LINVRNT(osd_invariant(obj));
        LASSERT(obj->oo_inode == NULL);
@@ -3086,7 +3127,7 @@ static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
        inode = ldiskfs_create_inode(oth->ot_handle,
                                     parent ? osd_dt_obj(parent)->oo_inode :
                                              osd_sb(osd)->s_root->d_inode,
-                                    mode);
+                                    mode, owner);
        if (!IS_ERR(inode)) {
                /* Do not update file c/mtime in ldiskfs. */
                inode->i_flags |= S_NOCMTIME;
@@ -3128,7 +3169,7 @@ static int osd_mkdir(struct osd_thread_info *info, struct osd_object *obj,
 
        oth = container_of(th, struct osd_thandle, ot_super);
        LASSERT(oth->ot_handle->h_transaction != NULL);
-       result = osd_mkfile(info, obj, mode, hint, th);
+       result = osd_mkfile(info, obj, mode, hint, th, attr);
 
        return result;
 }
@@ -3150,7 +3191,7 @@ static int osd_mk_index(struct osd_thread_info *info, struct osd_object *obj,
        oth = container_of(th, struct osd_thandle, ot_super);
        LASSERT(oth->ot_handle->h_transaction != NULL);
 
-       result = osd_mkfile(info, obj, mode, hint, th);
+       result = osd_mkfile(info, obj, mode, hint, th, attr);
        if (result == 0) {
                LASSERT(obj->oo_inode != NULL);
                if (feat->dif_flags & DT_IND_VARKEY)
@@ -3177,7 +3218,8 @@ static int osd_mkreg(struct osd_thread_info *info, struct osd_object *obj,
 {
        LASSERT(S_ISREG(attr->la_mode));
        return osd_mkfile(info, obj, (attr->la_mode &
-                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th);
+                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th,
+                         attr);
 }
 
 static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
@@ -3188,7 +3230,8 @@ static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
 {
        LASSERT(S_ISLNK(attr->la_mode));
        return osd_mkfile(info, obj, (attr->la_mode &
-                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th);
+                        (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th,
+                         attr);
 }
 
 static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
@@ -3205,7 +3248,7 @@ static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
        LASSERT(S_ISCHR(mode) || S_ISBLK(mode) ||
                S_ISFIFO(mode) || S_ISSOCK(mode));
 
-       result = osd_mkfile(info, obj, mode, hint, th);
+       result = osd_mkfile(info, obj, mode, hint, th, attr);
        if (result == 0) {
                LASSERT(obj->oo_inode != NULL);
                /*
@@ -3375,6 +3418,19 @@ static int __osd_oi_insert(const struct lu_env *env, struct osd_object *obj,
        osd_id_gen(id, obj->oo_inode->i_ino, obj->oo_inode->i_generation);
        rc = osd_oi_insert(info, osd, fid, id, oh->ot_handle,
                           OI_CHECK_FLD, NULL);
+       if (CFS_FAIL_CHECK(OBD_FAIL_OSD_DUPLICATE_MAP) && osd->od_is_ost) {
+               struct lu_fid next_fid = *fid;
+
+               /* insert next object in advance, and map to the same inode */
+               next_fid.f_oid++;
+               if (next_fid.f_oid != 0) {
+                       osd_trans_exec_op(env, th, OSD_OT_INSERT);
+                       osd_oi_insert(info, osd, &next_fid, id, oh->ot_handle,
+                                     OI_CHECK_FLD, NULL);
+                       osd_trans_exec_check(env, th, OSD_OT_INSERT);
+               }
+       }
+
        osd_trans_exec_check(env, th, OSD_OT_INSERT);
 
        return rc;
@@ -3439,6 +3495,9 @@ static int osd_declare_create(const struct lu_env *env, struct dt_object *dt,
         */
        osd_trans_declare_op(env, oh, OSD_OT_INSERT,
                             osd_dto_credits_noquota[DTO_INDEX_INSERT] + 1);
+       if (CFS_FAIL_CHECK(OBD_FAIL_OSD_DUPLICATE_MAP))
+               osd_trans_declare_op(env, oh, OSD_OT_INSERT,
+                            osd_dto_credits_noquota[DTO_INDEX_INSERT] + 1);
 
        /* will help to find FID->ino mapping at dt_insert() */
        rc = osd_idc_find_and_init(env, osd_obj2dev(osd_dt_obj(dt)),
@@ -3756,7 +3815,8 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env,
        oh = container_of(th, struct osd_thandle, ot_super);
        LASSERT(oh->ot_handle->h_transaction != NULL);
 
-       local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type);
+       local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type,
+                                    NULL);
        if (IS_ERR(local)) {
                CERROR("%s: create local error %d\n", osd_name(osd),
                       (int)PTR_ERR(local));
@@ -3775,7 +3835,7 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env,
         * debugging if we need to determine where this symlink came from.
         */
        if (S_ISLNK(type)) {
-               CLASSERT(LDISKFS_N_BLOCKS * 4 >= FID_LEN + 1);
+               BUILD_BUG_ON(LDISKFS_N_BLOCKS * 4 < FID_LEN + 1);
                rc = snprintf((char *)LDISKFS_I(local)->i_data,
                              LDISKFS_N_BLOCKS * 4, DFID, PFID(fid));
 
@@ -3859,20 +3919,16 @@ static int osd_process_scheduled_agent_removals(const struct lu_env *env,
        struct osd_thread_info *info = osd_oti_get(env);
        struct osd_obj_orphan *oor, *tmp;
        struct osd_inode_id id;
-       struct list_head list;
+       LIST_HEAD(list);
        struct inode *inode;
        struct lu_fid fid;
        handle_t *jh;
        __u32 ino;
 
-       INIT_LIST_HEAD(&list);
-
        spin_lock(&osd->od_osfs_lock);
        list_for_each_entry_safe(oor, tmp, &osd->od_orphan_list, oor_list) {
-               if (oor->oor_env == env) {
-                       list_del(&oor->oor_list);
-                       list_add(&oor->oor_list, &list);
-               }
+               if (oor->oor_env == env)
+                       list_move(&oor->oor_list, &list);
        }
        spin_unlock(&osd->od_osfs_lock);
 
@@ -4384,7 +4440,7 @@ static int osd_xattr_set_pfid(const struct lu_env *env, struct osd_object *obj,
                        RETURN(fl);
 
                /* Remove old PFID EA entry firstly. */
-               ll_vfs_dq_init(inode);
+               dquot_initialize(inode);
                rc = osd_removexattr(dentry, inode, XATTR_NAME_FID);
                if (rc == -ENODATA) {
                        if ((fl & LU_XATTR_REPLACE) && !(fl & LU_XATTR_CREATE))
@@ -4688,7 +4744,7 @@ static int osd_xattr_del(const struct lu_env *env, struct dt_object *dt,
                                obj->oo_pfid_in_lma = 0;
                }
        } else {
-               ll_vfs_dq_init(inode);
+               dquot_initialize(inode);
                dentry->d_inode = inode;
                dentry->d_sb = inode->i_sb;
                rc = osd_removexattr(dentry, inode, name);
@@ -4723,7 +4779,7 @@ static int osd_object_sync(const struct lu_env *env, struct dt_object *dt,
        file->f_op = inode->i_fop;
        set_file_inode(file, inode);
 
-       rc = ll_vfs_fsync_range(file, start, end, 0);
+       rc = vfs_fsync_range(file, start, end, 0);
 
        RETURN(rc);
 }
@@ -5139,7 +5195,7 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
        LASSERT(oh->ot_handle != NULL);
        LASSERT(oh->ot_handle->h_transaction != NULL);
 
-       ll_vfs_dq_init(dir);
+       dquot_initialize(dir);
        dentry = osd_child_dentry_get(env, obj,
                                      (char *)key, strlen((char *)key));
 
@@ -5374,7 +5430,7 @@ static int __osd_ea_add_rec(struct osd_thread_info *info,
                osd_get_ldiskfs_dirent_param(ldp, fid);
        child = osd_child_dentry_get(info->oti_env, pobj, name, strlen(name));
        child->d_fsdata = (void *)ldp;
-       ll_vfs_dq_init(pobj->oo_inode);
+       dquot_initialize(pobj->oo_inode);
        rc = osd_ldiskfs_add_entry(info, osd_obj2dev(pobj), oth->ot_handle,
                                   child, cinode, hlock);
        if (rc == 0 && OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_TYPE)) {
@@ -6466,13 +6522,11 @@ static void osd_it_ea_put(const struct lu_env *env, struct dt_it *di)
 }
 
 struct osd_filldir_cbs {
-#ifdef HAVE_DIR_CONTEXT
        struct dir_context ctx;
-#endif
        struct osd_it_ea  *it;
 };
 /**
- * It is called internally by ->readdir(). It fills the
+ * It is called internally by ->iterate*(). It fills the
  * iterator's in-memory data structure with required
  * information i.e. name, namelen, rec_size etc.
  *
@@ -6539,7 +6593,7 @@ static int osd_ldiskfs_filldir(void *buf,
 }
 
 /**
- * Calls ->readdir() to load a directory entry at a time
+ * Calls ->iterate*() to load a directory entry at a time
  * and stored it in iterator's in-memory data structure.
  *
  * \param di iterator's in memory structure
@@ -6558,9 +6612,7 @@ static int osd_ldiskfs_it_fill(const struct lu_env *env,
        struct file *filp = &it->oie_file;
        int rc = 0;
        struct osd_filldir_cbs buf = {
-#ifdef HAVE_DIR_CONTEXT
                .ctx.actor = osd_ldiskfs_filldir,
-#endif
                .it = it
        };
 
@@ -6576,17 +6628,16 @@ static int osd_ldiskfs_it_fill(const struct lu_env *env,
                down_read(&obj->oo_ext_idx_sem);
        }
 
-#ifdef HAVE_DIR_CONTEXT
-       buf.ctx.pos = filp->f_pos;
-#ifdef HAVE_ITERATE_SHARED
-       rc = inode->i_fop->iterate_shared(filp, &buf.ctx);
-#else
-       rc = inode->i_fop->iterate(filp, &buf.ctx);
-#endif
-       filp->f_pos = buf.ctx.pos;
-#else
-       rc = inode->i_fop->readdir(filp, &buf, osd_ldiskfs_filldir);
-#endif
+       filp->f_cred = current_cred();
+       rc = osd_security_file_alloc(filp);
+       if (rc)
+               RETURN(rc);
+
+       filp->f_flags |= O_NOATIME;
+       filp->f_mode |= FMODE_NONOTIFY;
+       rc = iterate_dir(filp, &buf.ctx);
+       if (rc)
+               RETURN(rc);
 
        if (hlock != NULL)
                ldiskfs_htree_unlock(hlock);
@@ -6610,7 +6661,7 @@ static int osd_ldiskfs_it_fill(const struct lu_env *env,
 }
 
 /**
- * It calls osd_ldiskfs_it_fill() which will use ->readdir()
+ * It calls osd_ldiskfs_it_fill() which will use ->iterate*()
  * to load a directory entry at a time and stored it in
  * iterator's in-memory data structure.
  *
@@ -6741,7 +6792,7 @@ osd_dirent_reinsert(const struct lu_env *env, struct osd_device *dev,
        ldp = (struct ldiskfs_dentry_param *)osd_oti_get(env)->oti_ldp;
        osd_get_ldiskfs_dirent_param(ldp, fid);
        dentry->d_fsdata = (void *)ldp;
-       ll_vfs_dq_init(dir);
+       dquot_initialize(dir);
        rc = osd_ldiskfs_add_entry(info, dev, jh, dentry, inode, hlock);
        /*
         * It is too bad, we cannot reinsert the name entry back.
@@ -7223,7 +7274,7 @@ static __u64 osd_it_ea_store(const struct lu_env *env, const struct dt_it *di)
 }
 
 /**
- * It calls osd_ldiskfs_it_fill() which will use ->readdir()
+ * It calls osd_ldiskfs_it_fill() which will use ->iterate*()
  * to load a directory entry at a time and stored it i inn,
  * in iterator's in-memory data structure.
  *
@@ -7565,7 +7616,7 @@ static int osd_mount(const struct lu_env *env,
                        "force_over_512tb",
                        NULL
                };
-               strcat(options, opts);
+               strncat(options, opts, PAGE_SIZE);
                for (rc = 0, str = options; sout[rc]; ) {
                        char *op = strstr(str, sout[rc]);
 
@@ -7585,13 +7636,13 @@ static int osd_mount(const struct lu_env *env,
                                ;
                }
        } else {
-               strncat(options, "user_xattr,acl", 14);
+               strncat(options, "user_xattr,acl", PAGE_SIZE);
        }
 
        /* Glom up mount options */
        if (*options != '\0')
-               strcat(options, ",");
-       strlcat(options, "no_mbcache,nodelalloc", PAGE_SIZE);
+               strncat(options, ",", PAGE_SIZE);
+       strncat(options, "no_mbcache,nodelalloc", PAGE_SIZE);
 
        type = get_fs_type("ldiskfs");
        if (!type) {
@@ -7730,6 +7781,8 @@ static int osd_device_init0(const struct lu_env *env,
        o->od_read_cache = 1;
        o->od_writethrough_cache = 1;
        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;
 
        cplen = strlcpy(o->od_svname, lustre_cfg_string(cfg, 4),
@@ -7751,6 +7804,10 @@ static int osd_device_init0(const struct lu_env *env,
        if (rc != 0)
                GOTO(out, rc);
 
+       /* Can only check block device after mount */
+       o->od_nonrotational =
+               blk_queue_nonrot(bdev_get_queue(osd_sb(o)->s_bdev));
+
        rc = osd_obj_map_init(env, o);
        if (rc != 0)
                GOTO(out_mnt, rc);
@@ -8089,13 +8146,13 @@ static int osd_health_check(const struct lu_env *env, struct obd_device *obd)
        struct osd_device *osd = osd_dev(obd->obd_lu_dev);
        struct super_block *sb = osd_sb(osd);
 
-       return (osd->od_mnt == NULL || sb->s_flags & MS_RDONLY);
+       return (osd->od_mnt == NULL || sb->s_flags & SB_RDONLY);
 }
 
 /*
  * lprocfs legacy support.
  */
-static struct obd_ops osd_obd_device_ops = {
+static const struct obd_ops osd_obd_device_ops = {
        .o_owner = THIS_MODULE,
        .o_connect      = osd_obd_connect,
        .o_disconnect   = osd_obd_disconnect,
@@ -8132,10 +8189,11 @@ static int __init osd_init(void)
        struct kobject *kobj;
        int rc;
 
-       CLASSERT(BH_DXLock < sizeof(((struct buffer_head *)0)->b_state) * 8);
+       BUILD_BUG_ON(BH_DXLock >=
+                    sizeof(((struct buffer_head *)0)->b_state) * 8);
 #if !defined(CONFIG_DEBUG_MUTEXES) && !defined(CONFIG_DEBUG_SPINLOCK)
        /* please, try to keep osd_thread_info smaller than a page */
-       CLASSERT(sizeof(struct osd_thread_info) <= PAGE_SIZE);
+       BUILD_BUG_ON(sizeof(struct osd_thread_info) > PAGE_SIZE);
 #endif
 
        osd_oi_mod_init();
@@ -8145,6 +8203,8 @@ static int __init osd_init(void)
                return rc;
 
 #ifdef CONFIG_KALLSYMS
+       priv_security_file_alloc =
+               (void *)kallsyms_lookup_name("security_file_alloc");
        priv_dev_set_rdonly = (void *)kallsyms_lookup_name("dev_set_rdonly");
        priv_dev_check_rdonly =
                (void *)kallsyms_lookup_name("dev_check_rdonly");