Whamcloud - gitweb
LU-11130 osd-ldiskfs: create non-empty local agent symlinks
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_handler.c
index a268b88..12b1d32 100644 (file)
@@ -1894,6 +1894,9 @@ static int osd_trans_start(const struct lu_env *env, struct dt_device *d,
                        oh->ot_credits = osd_transaction_size(dev);
        }
 
+       if (OBD_FAIL_CHECK(OBD_FAIL_OSD_TXN_START))
+               GOTO(out, rc = -EIO);
+
        /*
         * XXX temporary stuff. Some abstraction layer should
         * be used.
@@ -2311,22 +2314,32 @@ static void osd_conf_get(const struct lu_env *env,
                            sizeof("T10-DIF-TYPE") - 1) == 0) {
                        /* also skip "1/3-" at end */
                        const int type_off = sizeof("T10-DIF-TYPE.");
+                       char type_number = name[type_off - 2];
 
-                       if (interval != 512 && interval != 4096)
+                       if (interval != 512 && interval != 4096) {
                                CERROR("%s: unsupported T10PI sector size %u\n",
                                       d->od_svname, interval);
-                       else if (strcmp(name + type_off, "CRC") == 0)
+                       } else if (type_number != '1' && type_number != '3') {
+                               CERROR("%s: unsupported T10PI type %s\n",
+                                      d->od_svname, name);
+                       } else if (strcmp(name + type_off, "CRC") == 0) {
+                               d->od_t10_type = type_number == '1' ?
+                                       OSD_T10_TYPE1_CRC : OSD_T10_TYPE3_CRC;
                                param->ddp_t10_cksum_type = interval == 512 ?
                                        OBD_CKSUM_T10CRC512 :
                                        OBD_CKSUM_T10CRC4K;
-                       else if (strcmp(name + type_off, "IP") == 0)
+                       } else if (strcmp(name + type_off, "IP") == 0) {
+                               d->od_t10_type = type_number == '1' ?
+                                       OSD_T10_TYPE1_IP : OSD_T10_TYPE3_IP;
                                param->ddp_t10_cksum_type = interval == 512 ?
                                        OBD_CKSUM_T10IP512 :
                                        OBD_CKSUM_T10IP4K;
-                       else
+                       } else {
                                CERROR("%s: unsupported checksum type of "
                                       "T10PI type '%s'",
                                       d->od_svname, name);
+                       }
+
                } else {
                        CERROR("%s: unsupported T10PI type '%s'",
                               d->od_svname, name);
@@ -2340,10 +2353,12 @@ static void osd_conf_get(const struct lu_env *env,
 static int osd_sync(const struct lu_env *env, struct dt_device *d)
 {
        int rc;
+       struct super_block *s = osd_sb(osd_dt_dev(d));
+       ENTRY;
 
-       CDEBUG(D_CACHE, "%s: syncing OSD\n", osd_dt_dev(d)->od_svname);
-
-       rc = ldiskfs_force_commit(osd_sb(osd_dt_dev(d)));
+       down_read(&s->s_umount);
+       rc = s->s_op->sync_fs(s, 1);
+       up_read(&s->s_umount);
 
        CDEBUG(D_CACHE, "%s: synced OSD: rc = %d\n", osd_dt_dev(d)->od_svname,
               rc);
@@ -2367,11 +2382,16 @@ static int osd_commit_async(const struct lu_env *env,
                            struct dt_device *d)
 {
        struct super_block *s = osd_sb(osd_dt_dev(d));
+       int rc;
 
        ENTRY;
 
        CDEBUG(D_HA, "%s: async commit OSD\n", osd_dt_dev(d)->od_svname);
-       RETURN(s->s_op->sync_fs(s, 0));
+       down_read(&s->s_umount);
+       rc = s->s_op->sync_fs(s, 0);
+       up_read(&s->s_umount);
+
+       RETURN(rc);
 }
 
 /* Our own copy of the set readonly functions if present, or NU if not. */
@@ -3418,6 +3438,12 @@ 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);
 
+       /* will help to find FID->ino mapping at dt_insert() */
+       rc = osd_idc_find_and_init(env, osd_obj2dev(osd_dt_obj(dt)),
+                                  osd_dt_obj(dt));
+       if (rc != 0)
+               RETURN(rc);
+
        if (!attr)
                RETURN(0);
 
@@ -3427,10 +3453,6 @@ static int osd_declare_create(const struct lu_env *env, struct dt_object *dt,
        if (rc != 0)
                RETURN(rc);
 
-       /* will help to find FID->ino mapping at dt_insert() */
-       rc = osd_idc_find_and_init(env, osd_obj2dev(osd_dt_obj(dt)),
-                                  osd_dt_obj(dt));
-
        RETURN(rc);
 }
 
@@ -3745,6 +3767,19 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env,
         */
        local->i_gid = current_fsgid();
        ldiskfs_set_inode_state(local, LDISKFS_STATE_LUSTRE_NOSCRUB);
+
+       /* e2fsck doesn't like empty symlinks.  Store remote FID as symlink.
+        * That gives e2fsck something to look at and be happy, and allows
+        * debugging if we need to determine where this symlink came from.
+        */
+       if (S_ISLNK(type)) {
+               CLASSERT(LDISKFS_N_BLOCKS * 4 >= FID_LEN + 1);
+               rc = snprintf((char *)LDISKFS_I(local)->i_data,
+                             LDISKFS_N_BLOCKS * 4, DFID, PFID(fid));
+
+               i_size_write(local, rc);
+               LDISKFS_I(local)->i_disksize = rc;
+       }
        unlock_new_inode(local);
 
        /* Agent inode should not have project ID */
@@ -5252,8 +5287,7 @@ static int osd_index_declare_iam_insert(const struct lu_env *env,
  */
 static int osd_index_iam_insert(const struct lu_env *env, struct dt_object *dt,
                                const struct dt_rec *rec,
-                               const struct dt_key *key, struct thandle *th,
-                               int ignore_quota)
+                               const struct dt_key *key, struct thandle *th)
 {
        struct osd_object *obj = osd_dt_obj(dt);
        struct iam_path_descr *ipd;
@@ -5943,8 +5977,7 @@ static int osd_index_declare_ea_insert(const struct lu_env *env,
  */
 static int osd_index_ea_insert(const struct lu_env *env, struct dt_object *dt,
                               const struct dt_rec *rec,
-                              const struct dt_key *key, struct thandle *th,
-                              int ignore_quota)
+                              const struct dt_key *key, struct thandle *th)
 {
        struct osd_object *obj = osd_dt_obj(dt);
        struct osd_device *osd = osd_dev(dt->do_lu.lo_dev);
@@ -5971,19 +6004,24 @@ static int osd_index_ea_insert(const struct lu_env *env, struct dt_object *dt,
 
        idc = osd_idc_find(env, osd, fid);
        if (unlikely(idc == NULL)) {
-               /*
-                * this dt_insert() wasn't declared properly, so
-                * FID is missing in OI cache. we better do not
-                * lookup FID in FLDB/OI and don't risk to deadlock,
-                * but in some special cases (lfsck testing, etc)
-                * it's much simpler than fixing a caller
-                */
-               CERROR("%s: "DFID" wasn't declared for insert\n",
-                      osd_name(osd), PFID(fid));
-               dump_stack();
                idc = osd_idc_find_or_init(env, osd, fid);
-               if (IS_ERR(idc))
+               if (IS_ERR(idc)) {
+                       /*
+                        * this dt_insert() wasn't declared properly, so
+                        * FID is missing in OI cache. we better do not
+                        * lookup FID in FLDB/OI and don't risk to deadlock,
+                        * but in some special cases (lfsck testing, etc)
+                        * it's much simpler than fixing a caller.
+                        *
+                        * normally this error should be placed after the first
+                        * find, but migrate may attach source stripes to
+                        * target, which doesn't create stripes.
+                        */
+                       CERROR("%s: "DFID" wasn't declared for insert\n",
+                              osd_name(osd), PFID(fid));
+                       dump_stack();
                        RETURN(PTR_ERR(idc));
+               }
        }
 
        if (idc->oic_remote) {
@@ -7296,6 +7334,16 @@ static void osd_key_fini(const struct lu_context *ctx,
        struct ldiskfs_inode_info *lli = LDISKFS_I(info->oti_inode);
        struct osd_idmap_cache *idc = info->oti_ins_cache;
 
+       if (info->oti_dio_pages) {
+               int i;
+               for (i = 0; i < PTLRPC_MAX_BRW_PAGES; i++) {
+                       if (info->oti_dio_pages[i])
+                               __free_page(info->oti_dio_pages[i]);
+               }
+               OBD_FREE(info->oti_dio_pages,
+                        sizeof(struct page *) * PTLRPC_MAX_BRW_PAGES);
+       }
+
        if (info->oti_inode != NULL)
                OBD_FREE_PTR(lli);
        if (info->oti_hlock != NULL)
@@ -7303,6 +7351,7 @@ static void osd_key_fini(const struct lu_context *ctx,
        OBD_FREE(info->oti_it_ea_buf, OSD_IT_EA_BUFSIZE);
        lu_buf_free(&info->oti_iobuf.dr_pg_buf);
        lu_buf_free(&info->oti_iobuf.dr_bl_buf);
+       lu_buf_free(&info->oti_iobuf.dr_lnb_buf);
        lu_buf_free(&info->oti_big_buf);
        if (idc != NULL) {
                LASSERT(info->oti_ins_cache_size > 0);
@@ -7606,6 +7655,12 @@ static int osd_mount(const struct lu_env *env,
        if (lmd_flags & LMD_FLG_NOSCRUB)
                o->od_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 */
+               o->od_writethrough_cache = 0;
+               o->od_read_cache = 0;
+       }
+
        GOTO(out, rc = 0);
 
 out_mnt:
@@ -7661,6 +7716,7 @@ static int osd_device_init0(const struct lu_env *env,
        INIT_LIST_HEAD(&o->od_index_restore_list);
        spin_lock_init(&o->od_lock);
        o->od_index_backup_policy = LIBP_NONE;
+       o->od_t10_type = 0;
 
        o->od_read_cache = 1;
        o->od_writethrough_cache = 1;