From 6d5fe29066af5f8e40055fd89b285853c363e947 Mon Sep 17 00:00:00 2001 From: Mikhail Pershin Date: Mon, 17 Aug 2020 14:06:30 +0300 Subject: [PATCH] LU-10810 ptlrpc: introduce OST_SEEK RPC For the purposes of SEEK_HOLE/SEEK_DATA support introduce new OST_SEEK RPC. Patch add RPC layout, unified handler and connect flag for compatibility needs. Signed-off-by: Mikhail Pershin Change-Id: I1580902b6b773d9a6d6f9beaa1ee1da60fbc20f8 Reviewed-on: https://review.whamcloud.com/39707 Reviewed-by: Sebastien Buisson Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/dt_object.h | 1 + lustre/include/lu_target.h | 4 +- lustre/include/lustre_req_layout.h | 1 + lustre/include/obd_support.h | 1 + lustre/include/uapi/linux/lustre/lustre_idl.h | 7 +- lustre/mdt/mdt_handler.c | 4 + lustre/mdt/mdt_io.c | 4 +- lustre/obdclass/lprocfs_status.c | 1 + lustre/ofd/ofd_dev.c | 14 ++-- lustre/ofd/ofd_obd.c | 3 + lustre/osd-ldiskfs/osd_handler.c | 2 + lustre/osd-ldiskfs/osd_io.c | 13 +-- lustre/osd-zfs/osd_handler.c | 6 ++ lustre/osd-zfs/osd_internal.h | 7 ++ lustre/osd-zfs/osd_io.c | 36 ++++---- lustre/ptlrpc/layout.c | 5 ++ lustre/ptlrpc/lproc_ptlrpc.c | 3 +- lustre/ptlrpc/wiretest.c | 14 ++-- lustre/target/tgt_handler.c | 114 ++++++++++++++++++++------ lustre/utils/wirecheck.c | 5 +- lustre/utils/wirehdr.c | 2 +- lustre/utils/wiretest.c | 28 +++++-- 22 files changed, 196 insertions(+), 79 deletions(-) diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index 601b918..5146cc1 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -88,6 +88,7 @@ struct dt_device_param { unsigned int ddp_brw_size; /* optimal RPC size */ /* T10PI checksum type, zero if not supported */ enum cksum_types ddp_t10_cksum_type; + bool ddp_has_lseek_data_hole; }; /** diff --git a/lustre/include/lu_target.h b/lustre/include/lu_target.h index e16e5bc..97ba236 100644 --- a/lustre/include/lu_target.h +++ b/lustre/include/lu_target.h @@ -439,13 +439,13 @@ void tgt_io_thread_done(struct ptlrpc_thread *thread); int tgt_mdt_data_lock(struct ldlm_namespace *ns, struct ldlm_res_id *res_id, struct lustre_handle *lh, int mode, __u64 *flags); -void tgt_mdt_data_unlock(struct lustre_handle *lh, enum ldlm_mode mode); int tgt_extent_lock(const struct lu_env *env, struct ldlm_namespace *ns, struct ldlm_res_id *res_id, __u64 start, __u64 end, struct lustre_handle *lh, int mode, __u64 *flags); -void tgt_extent_unlock(struct lustre_handle *lh, enum ldlm_mode mode); +void tgt_data_unlock(struct lustre_handle *lh, enum ldlm_mode mode); int tgt_brw_read(struct tgt_session_info *tsi); int tgt_brw_write(struct tgt_session_info *tsi); +int tgt_lseek(struct tgt_session_info *tsi); int tgt_hpreq_handler(struct ptlrpc_request *req); void tgt_register_lfsck_in_notify_local(int (*notify)(const struct lu_env *, struct dt_device *, diff --git a/lustre/include/lustre_req_layout.h b/lustre/include/lustre_req_layout.h index bbdc90b..31d9719 100644 --- a/lustre/include/lustre_req_layout.h +++ b/lustre/include/lustre_req_layout.h @@ -210,6 +210,7 @@ extern struct req_format RQF_OST_GET_INFO_LAST_FID; extern struct req_format RQF_OST_SET_INFO_LAST_FID; extern struct req_format RQF_OST_GET_INFO_FIEMAP; extern struct req_format RQF_OST_LADVISE; +extern struct req_format RQF_OST_SEEK; /* LDLM req_format */ extern struct req_format RQF_LDLM_ENQUEUE; diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 62d6266..3edec56 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -339,6 +339,7 @@ extern char obd_jobid_var[]; #define OBD_FAIL_OST_PREPARE_DELAY 0x247 #define OBD_FAIL_OST_2BIG_NIOBUF 0x248 #define OBD_FAIL_OST_FALLOCATE_NET 0x249 +#define OBD_FAIL_OST_SEEK_NET 0x24a #define OBD_FAIL_OST_WR_ATTR_DELAY 0x250 #define OBD_FAIL_LDLM 0x300 diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 375bd88..9390aac 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -849,6 +849,7 @@ struct ptlrpc_body_v2 { #define OBD_CONNECT2_ENCRYPT 0x8000ULL /* client-to-disk encrypt */ #define OBD_CONNECT2_FIDMAP 0x10000ULL /* FID map */ #define OBD_CONNECT2_GETATTR_PFID 0x20000ULL /* pack parent FID in getattr */ +#define OBD_CONNECT2_LSEEK 0x40000ULL /* SEEK_HOLE/DATA RPC */ /* XXX README XXX: * Please DO NOT add flag values here before first ensuring that this same * flag value is not in use on some other branch. Please clear any such @@ -907,7 +908,8 @@ struct ptlrpc_body_v2 { OBD_CONNECT2_PCC | \ OBD_CONNECT2_CRUSH | \ OBD_CONNECT2_ENCRYPT | \ - OBD_CONNECT2_GETATTR_PFID) + OBD_CONNECT2_GETATTR_PFID |\ + OBD_CONNECT2_LSEEK) #define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \ OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \ @@ -929,7 +931,7 @@ struct ptlrpc_body_v2 { OBD_CONNECT_SHORTIO | OBD_CONNECT_FLAGS2) #define OST_CONNECT_SUPPORTED2 (OBD_CONNECT2_LOCKAHEAD | OBD_CONNECT2_INC_XID |\ - OBD_CONNECT2_ENCRYPT) + OBD_CONNECT2_ENCRYPT | OBD_CONNECT2_LSEEK) #define ECHO_CONNECT_SUPPORTED (OBD_CONNECT_FID) #define ECHO_CONNECT_SUPPORTED2 0 @@ -1058,6 +1060,7 @@ enum ost_cmd { OST_QUOTA_ADJUST_QUNIT = 20, /* not used since 2.4 */ OST_LADVISE = 21, OST_FALLOCATE = 22, + OST_SEEK = 23, OST_LAST_OPC /* must be < 33 to avoid MDS_GETATTR */ }; #define OST_FIRST_OPC OST_REPLY diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 2a0c36f..55baf47 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -5436,6 +5436,7 @@ TGT_OST_HDL_HP(HAS_BODY | HAS_REPLY | IS_MUTABLE, OST_PUNCH, mdt_punch_hdl, mdt_hp_punch), TGT_OST_HDL(HAS_BODY | HAS_REPLY, OST_SYNC, mdt_data_sync), +TGT_OST_HDL(HAS_BODY | HAS_REPLY, OST_SEEK, tgt_lseek), }; static struct tgt_handler mdt_sec_ctx_ops[] = { @@ -6329,6 +6330,9 @@ static int mdt_connect_internal(const struct lu_env *env, mdt_enable_slc(mdt); } + if (!mdt->mdt_lut.lut_dt_conf.ddp_has_lseek_data_hole) + data->ocd_connect_flags2 &= ~OBD_CONNECT2_LSEEK; + return 0; } diff --git a/lustre/mdt/mdt_io.c b/lustre/mdt/mdt_io.c index 2115c0a..3714ab7 100644 --- a/lustre/mdt/mdt_io.c +++ b/lustre/mdt/mdt_io.c @@ -949,7 +949,7 @@ out_put: lu_object_put(tsi->tsi_env, &mo->mot_obj); out_unlock: if (srvlock) - tgt_extent_unlock(&lh, LCK_PW); + tgt_data_unlock(&lh, LCK_PW); out: mdt_thread_info_fini(info); return rc; @@ -1388,7 +1388,7 @@ int mdt_data_version_get(struct tgt_session_info *tsi) rc = 0; out: if (srvlock) - tgt_mdt_data_unlock(&lh, lock_mode); + tgt_data_unlock(&lh, lock_mode); repbody->mbo_valid |= OBD_MD_FLFLAGS; repbody->mbo_flags = OBD_FL_FLUSH; diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 85ed714..22842e9 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -635,6 +635,7 @@ static const char *obd_connect_names[] = { "client_encryption", /* 0x8000 */ "fidmap", /* 0x10000 */ "getattr_pfid", /* 0x20000 */ + "lseek", /* 0x40000 */ NULL }; diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index 8b2a720..738d836 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -986,7 +986,7 @@ static int ofd_lock_unlock_region(const struct lu_env *env, return rc; CDEBUG(D_OTHER, "ost lock [%llu,%llu], lh=%p\n", begin, end, &lh); - tgt_extent_unlock(&lh, LCK_PR); + tgt_data_unlock(&lh, LCK_PR); return 0; } @@ -1274,7 +1274,7 @@ static int ofd_getattr_hdl(struct tgt_session_info *tsi) ofd_object_put(tsi->tsi_env, fo); out: if (srvlock) - tgt_extent_unlock(&lh, lock_mode); + tgt_data_unlock(&lh, lock_mode); ofd_counter_incr(tsi->tsi_exp, LPROC_OFD_STATS_GETATTR, tsi->tsi_jobid, ktime_us_delta(ktime_get(), kstart)); @@ -2019,7 +2019,7 @@ out_put: ofd_object_put(tsi->tsi_env, fo); out: if (srvlock) - tgt_extent_unlock(&lh, LCK_PW); + tgt_data_unlock(&lh, LCK_PW); if (rc == 0) { res = ldlm_resource_get(ns, NULL, &tsi->tsi_resid, LDLM_EXTENT, 0); @@ -2042,7 +2042,6 @@ out: RETURN(rc); } - /** * OFD request handler for OST_PUNCH RPC. * @@ -2135,7 +2134,7 @@ out_put: ofd_object_put(tsi->tsi_env, fo); out: if (srvlock) - tgt_extent_unlock(&lh, LCK_PW); + tgt_data_unlock(&lh, LCK_PW); if (rc == 0) { /* we do not call this before to avoid lu_object_find() in * ->lvbo_update() holding another reference on the object. @@ -2324,7 +2323,7 @@ static int ofd_ladvise_hdl(struct tgt_session_info *tsi) req->rq_status = ofd_ladvise_prefetch(env, fo, tbc->local, start, end, dbt); - tgt_extent_unlock(&lockh, LCK_PR); + tgt_data_unlock(&lockh, LCK_PR); break; case LU_LADVISE_DONTNEED: rc = dt_ladvise(env, dob, ladvise->lla_start, @@ -2828,7 +2827,8 @@ TGT_OST_HDL_HP(HAS_BODY | HAS_REPLY | IS_MUTABLE, TGT_OST_HDL(HAS_BODY | HAS_REPLY, OST_SYNC, ofd_sync_hdl), TGT_OST_HDL(HAS_REPLY, OST_QUOTACTL, ofd_quotactl), TGT_OST_HDL(HAS_BODY | HAS_REPLY, OST_LADVISE, ofd_ladvise_hdl), -TGT_OST_HDL(HAS_BODY | HAS_REPLY | IS_MUTABLE, OST_FALLOCATE, ofd_fallocate_hdl) +TGT_OST_HDL(HAS_BODY | HAS_REPLY | IS_MUTABLE, OST_FALLOCATE, ofd_fallocate_hdl), +TGT_OST_HDL(HAS_BODY | HAS_REPLY, OST_SEEK, tgt_lseek), }; static struct tgt_opc_slice ofd_common_slice[] = { diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index e92d0f0..05e8293 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -360,6 +360,9 @@ static int ofd_parse_connect_data(const struct lu_env *env, } } + if (!ofd->ofd_lut.lut_dt_conf.ddp_has_lseek_data_hole) + data->ocd_connect_flags2 &= ~OBD_CONNECT2_LSEEK; + RETURN(0); } diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index c561425..ec9febb 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2354,6 +2354,8 @@ static void osd_conf_get(const struct lu_env *env, d->od_svname, name); } } + + param->ddp_has_lseek_data_hole = true; } static struct super_block *osd_mnt_sb_get(const struct dt_device *d) diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index e1fea27..8ce4b08 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -2335,15 +2335,18 @@ static loff_t osd_lseek(const struct lu_env *env, struct dt_object *dt, 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); - /* when result is out of file range then it must be virtual hole - * at the end of file, but this is not real file end, so return - * just -ENXIO and LOV will merge all results + + /* + * 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. + * LOV will decide if it is beyond real end of file or not. */ - if (result == i_size_read(inode)) - result = -ENXIO; + if (whence == SEEK_HOLE && result == -ENXIO) + result = offset; CDEBUG(D_INFO, "seek %s from %lld: %lld\n", whence == SEEK_HOLE ? "hole" : "data", offset, result); diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c index cb08b0c..bca22d1 100644 --- a/lustre/osd-zfs/osd_handler.c +++ b/lustre/osd-zfs/osd_handler.c @@ -642,6 +642,12 @@ static void osd_conf_get(const struct lu_env *env, param->ddp_brw_size = osd->od_max_blksz; else param->ddp_brw_size = ONE_MB_BRW_SIZE; + +#ifdef HAVE_DMU_OFFSET_NEXT + param->ddp_has_lseek_data_hole = true; +#else + param->ddp_has_lseek_data_hole = false; +#endif } /* diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h index 499108e..4e818c2 100644 --- a/lustre/osd-zfs/osd_internal.h +++ b/lustre/osd-zfs/osd_internal.h @@ -1141,4 +1141,11 @@ osd_index_backup(const struct lu_env *env, struct osd_device *osd, bool backup) #define inode_timespec_t timestruc_t #endif +#ifdef HAVE_DMU_OFFSET_NEXT +#define osd_dmu_offset_next(os, obj, hole, res) \ + dmu_offset_next((os), (obj), (hole), (res)) +#else +#define osd_dmu_offset_next(os, obj, hole, res) (EBUSY) +#endif + #endif /* _OSD_INTERNAL_H */ diff --git a/lustre/osd-zfs/osd_io.c b/lustre/osd-zfs/osd_io.c index e528ae5..ab1fc5f 100644 --- a/lustre/osd-zfs/osd_io.c +++ b/lustre/osd-zfs/osd_io.c @@ -1192,33 +1192,31 @@ static loff_t osd_lseek(const struct lu_env *env, struct dt_object *dt, LASSERT(dt_object_exists(dt)); LASSERT(osd_invariant(obj)); + LASSERT(offset >= 0); - if (offset < 0 || offset >= size) - RETURN(-ENXIO); + /* for SEEK_HOLE treat 'offset' beyond the end of file as in real + * hole. LOV to decide after all if that real hole or not. + */ + if (offset >= size) + RETURN(hole ? offset : -ENXIO); -#ifdef HAVE_DMU_OFFSET_NEXT - rc = dmu_offset_next(osd_obj2dev(obj)->od_os, obj->oo_dn->dn_object, - hole, &result); + rc = osd_dmu_offset_next(osd_obj2dev(obj)->od_os, + obj->oo_dn->dn_object, hole, &result); if (rc == ESRCH) RETURN(-ENXIO); -#else - /* - * In absence of dmu_offset_next() just do nothing but - * return EBUSY as does dmu_offset_next() and that means - * generic approach should be used. + + /* file was dirty, so fall back to using generic logic: + * For HOLE return file size, for DATA the result is set + * already to the 'offset' parameter value. */ - rc = EBUSY; -#endif - /* file was dirty, so fall back to using generic logic */ if (rc == EBUSY && hole) - RETURN(-ENXIO); /* see comment below */ + result = size; - /* when result is out of file range then it must be virtual hole - * at the end of file, but this is not real file end, so return - * just -ENXIO and LOV will translate it properly. + /* dmu_offset_next() only works on whole blocks so may return SEEK_HOLE + * result as end of the last block instead of logical EOF which we need */ - if (result >= size) - RETURN(-ENXIO); + if (result > size) + result = size; RETURN(result); } diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index e0929ab..5c99dc1 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -837,6 +837,7 @@ static struct req_format *req_formats[] = { &RQF_OST_SET_INFO_LAST_FID, &RQF_OST_GET_INFO_FIEMAP, &RQF_OST_LADVISE, + &RQF_OST_SEEK, &RQF_LDLM_ENQUEUE, &RQF_LDLM_ENQUEUE_LVB, &RQF_LDLM_CONVERT, @@ -1740,6 +1741,10 @@ struct req_format RQF_OST_FALLOCATE = DEFINE_REQ_FMT0("OST_FALLOCATE", ost_body_capa, ost_body_only); EXPORT_SYMBOL(RQF_OST_FALLOCATE); +struct req_format RQF_OST_SEEK = + DEFINE_REQ_FMT0("OST_SEEK", ost_body_only, ost_body_only); +EXPORT_SYMBOL(RQF_OST_SEEK); + struct req_format RQF_OST_SYNC = DEFINE_REQ_FMT0("OST_SYNC", ost_body_capa, ost_body_only); EXPORT_SYMBOL(RQF_OST_SYNC); diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index 9bb515b..af7b5fd 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -66,7 +66,8 @@ static struct ll_rpc_opcode { { OST_QUOTACTL, "ost_quotactl" }, { OST_QUOTA_ADJUST_QUNIT, "ost_quota_adjust_qunit" }, { OST_LADVISE, "ost_ladvise" }, - { OST_FALLOCATE, "ost_fallocate"}, + { OST_FALLOCATE, "ost_fallocate" }, + { OST_SEEK, "ost_seek" }, { MDS_GETATTR, "mds_getattr" }, { MDS_GETATTR_NAME, "mds_getattr_lock" }, { MDS_CLOSE, "mds_close" }, diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 4c1557f..a9167f2 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -106,7 +106,9 @@ void lustre_assert_wire_constants(void) (long long)OST_LADVISE); LASSERTF(OST_FALLOCATE == 22, "found %lld\n", (long long)OST_FALLOCATE); - LASSERTF(OST_LAST_OPC == 23, "found %lld\n", + LASSERTF(OST_SEEK == 23, "found %lld\n", + (long long)OST_SEEK); + LASSERTF(OST_LAST_OPC == 24, "found %lld\n", (long long)OST_LAST_OPC); LASSERTF(OBD_OBJECT_EOF == 0xffffffffffffffffULL, "found 0x%.16llxULL\n", OBD_OBJECT_EOF); @@ -452,7 +454,7 @@ void lustre_assert_wire_constants(void) LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n", (unsigned)LMAI_ORPHAN); LASSERTF(LMAI_ENCRYPT == 0x00000020UL, "found 0x%.8xUL\n", - (unsigned)LMAI_ENCRYPT); + (unsigned)LMAI_ENCRYPT); /* Checks for struct lustre_ost_attrs */ LASSERTF((int)sizeof(struct lustre_ost_attrs) == 64, "found %lld\n", @@ -1373,10 +1375,12 @@ void lustre_assert_wire_constants(void) OBD_CONNECT2_ASYNC_DISCARD); LASSERTF(OBD_CONNECT2_ENCRYPT == 0x8000ULL, "found 0x%.16llxULL\n", OBD_CONNECT2_ENCRYPT); - LASSERTF(OBD_CONNECT2_FIDMAP== 0x10000ULL, "found 0x%.16llxULL\n", + LASSERTF(OBD_CONNECT2_FIDMAP == 0x10000ULL, "found 0x%.16llxULL\n", OBD_CONNECT2_FIDMAP); - LASSERTF(OBD_CONNECT2_GETATTR_PFID== 0x20000ULL, "found 0x%.16llxULL\n", + LASSERTF(OBD_CONNECT2_GETATTR_PFID == 0x20000ULL, "found 0x%.16llxULL\n", OBD_CONNECT2_GETATTR_PFID); + LASSERTF(OBD_CONNECT2_LSEEK == 0x40000ULL, "found 0x%.16llxULL\n", + OBD_CONNECT2_LSEEK); LASSERTF(OBD_CKSUM_CRC32 == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)OBD_CKSUM_CRC32); LASSERTF(OBD_CKSUM_ADLER == 0x00000002UL, "found 0x%.8xUL\n", @@ -2582,7 +2586,7 @@ void lustre_assert_wire_constants(void) LASSERTF(LUSTRE_SET_SYNC_FL == 0x00040000UL, "found 0x%.8xUL\n", (unsigned)LUSTRE_SET_SYNC_FL); LASSERTF(LUSTRE_ENCRYPT_FL == 0x00800000UL, "found 0x%.8xUL\n", - (unsigned)LUSTRE_ENCRYPT_FL); + (unsigned)LUSTRE_ENCRYPT_FL); LASSERTF(MDS_INODELOCK_LOOKUP == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)MDS_INODELOCK_LOOKUP); LASSERTF(MDS_INODELOCK_UPDATE == 0x00000002UL, "found 0x%.8xUL\n", diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index 09cfe32..45e3b30 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -1678,13 +1678,6 @@ int tgt_mdt_data_lock(struct ldlm_namespace *ns, struct ldlm_res_id *res_id, } EXPORT_SYMBOL(tgt_mdt_data_lock); -void tgt_mdt_data_unlock(struct lustre_handle *lh, enum ldlm_mode mode) -{ - LASSERT(lustre_handle_is_used(lh)); - ldlm_lock_decref(lh, mode); -} -EXPORT_SYMBOL(tgt_mdt_data_unlock); - /** * Helper function for getting server side [start, start+count] DLM lock * if asked by client. @@ -1722,30 +1715,41 @@ int tgt_extent_lock(const struct lu_env *env, struct ldlm_namespace *ns, } EXPORT_SYMBOL(tgt_extent_lock); -void tgt_extent_unlock(struct lustre_handle *lh, enum ldlm_mode mode) +static int tgt_data_lock(const struct lu_env *env, struct obd_export *exp, + struct ldlm_res_id *res_id, __u64 start, __u64 end, + struct lustre_handle *lh, enum ldlm_mode mode) +{ + struct ldlm_namespace *ns = exp->exp_obd->obd_namespace; + __u64 flags = 0; + + /* MDT IO for data-on-mdt */ + if (exp->exp_connect_data.ocd_connect_flags & OBD_CONNECT_IBITS) + return tgt_mdt_data_lock(ns, res_id, lh, mode, &flags); + + return tgt_extent_lock(env, ns, res_id, start, end, lh, mode, &flags); +} + +void tgt_data_unlock(struct lustre_handle *lh, enum ldlm_mode mode) { LASSERT(lustre_handle_is_used(lh)); ldlm_lock_decref(lh, mode); } -EXPORT_SYMBOL(tgt_extent_unlock); +EXPORT_SYMBOL(tgt_data_unlock); static int tgt_brw_lock(const struct lu_env *env, struct obd_export *exp, struct ldlm_res_id *res_id, struct obd_ioobj *obj, struct niobuf_remote *nb, struct lustre_handle *lh, enum ldlm_mode mode) { - struct ldlm_namespace *ns = exp->exp_obd->obd_namespace; - __u64 flags = 0; - int nrbufs = obj->ioo_bufcnt; - int i; - int rc; + int nrbufs = obj->ioo_bufcnt; + int i; ENTRY; LASSERT(mode == LCK_PR || mode == LCK_PW); LASSERT(!lustre_handle_is_used(lh)); - if (ns->ns_obd->obd_recovering) + if (exp->exp_obd->obd_recovering) RETURN(0); if (nrbufs == 0 || !(nb[0].rnb_flags & OBD_BRW_SRVLOCK)) @@ -1755,15 +1759,9 @@ static int tgt_brw_lock(const struct lu_env *env, struct obd_export *exp, if (!(nb[i].rnb_flags & OBD_BRW_SRVLOCK)) RETURN(-EFAULT); - /* MDT IO for data-on-mdt */ - if (exp->exp_connect_data.ocd_connect_flags & OBD_CONNECT_IBITS) - rc = tgt_mdt_data_lock(ns, res_id, lh, mode, &flags); - else - rc = tgt_extent_lock(env, ns, res_id, nb[0].rnb_offset, - nb[nrbufs - 1].rnb_offset + - nb[nrbufs - 1].rnb_len - 1, - lh, mode, &flags); - RETURN(rc); + return tgt_data_lock(env, exp, res_id, nb[0].rnb_offset, + nb[nrbufs - 1].rnb_offset + + nb[nrbufs - 1].rnb_len - 1, lh, mode); } static void tgt_brw_unlock(struct obd_export *exp, struct obd_ioobj *obj, @@ -1778,7 +1776,7 @@ static void tgt_brw_unlock(struct obd_export *exp, struct obd_ioobj *obj, lustre_handle_is_used(lh)); if (lustre_handle_is_used(lh)) - tgt_extent_unlock(lh, mode); + tgt_data_unlock(lh, mode); EXIT; } @@ -2770,6 +2768,72 @@ out: } EXPORT_SYMBOL(tgt_brw_write); +/** + * Common request handler for OST_SEEK RPC. + * + * Unified request handling for OST_SEEK RPC. + * It takes object by its FID, does needed lseek and packs result + * into reply. Only SEEK_HOLE and SEEK_DATA are supported. + * + * \param[in] tsi target session environment for this request + * + * \retval 0 if successful + * \retval negative value on error + */ +int tgt_lseek(struct tgt_session_info *tsi) +{ + struct lustre_handle lh = { 0 }; + struct dt_object *dob; + struct ost_body *repbody; + loff_t offset = tsi->tsi_ost_body->oa.o_size; + int whence = tsi->tsi_ost_body->oa.o_mode; + bool srvlock; + int rc = 0; + + ENTRY; + + if (whence != SEEK_HOLE && whence != SEEK_DATA) + RETURN(-EPROTO); + + /* Negative offset is prohibited on wire and must be handled on client + * prior sending RPC. + */ + if (offset < 0) + RETURN(-EPROTO); + + repbody = req_capsule_server_get(tsi->tsi_pill, &RMF_OST_BODY); + if (repbody == NULL) + RETURN(-ENOMEM); + repbody->oa = tsi->tsi_ost_body->oa; + + srvlock = tsi->tsi_ost_body->oa.o_valid & OBD_MD_FLFLAGS && + tsi->tsi_ost_body->oa.o_flags & OBD_FL_SRVLOCK; + if (srvlock) { + rc = tgt_data_lock(tsi->tsi_env, tsi->tsi_exp, &tsi->tsi_resid, + offset, OBD_OBJECT_EOF, &lh, LCK_PR); + if (rc) + RETURN(rc); + } + + dob = dt_locate(tsi->tsi_env, tsi->tsi_tgt->lut_bottom, &tsi->tsi_fid); + if (IS_ERR(dob)) + GOTO(out, rc = PTR_ERR(dob)); + + if (!dt_object_exists(dob)) + GOTO(obj_put, rc = -ENOENT); + + repbody->oa.o_size = dt_lseek(tsi->tsi_env, dob, offset, whence); + rc = 0; +obj_put: + dt_object_put(tsi->tsi_env, dob); +out: + if (srvlock) + tgt_data_unlock(&lh, LCK_PR); + + RETURN(rc); +} +EXPORT_SYMBOL(tgt_lseek); + /* Check if request can be reconstructed from saved reply data * A copy of the reply data is returned in @trd if the pointer is not NULL */ diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 1ec105c..3508daf 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -626,6 +626,7 @@ check_obd_connect_data(void) CHECK_DEFINE_64X(OBD_CONNECT2_ENCRYPT); CHECK_DEFINE_64X(OBD_CONNECT2_FIDMAP); CHECK_DEFINE_64X(OBD_CONNECT2_GETATTR_PFID); + CHECK_DEFINE_64X(OBD_CONNECT2_LSEEK); CHECK_VALUE_X(OBD_CKSUM_CRC32); CHECK_VALUE_X(OBD_CKSUM_ADLER); @@ -882,6 +883,7 @@ check_lmv_mds_md_v1(void) CHECK_CDEFINE(LMV_HASH_TYPE_MASK); CHECK_CDEFINE(LMV_HASH_FLAG_MERGE); CHECK_CDEFINE(LMV_HASH_FLAG_SPLIT); + CHECK_CDEFINE(LMV_HASH_FLAG_LOST_LMV); CHECK_CDEFINE(LMV_HASH_FLAG_BAD_TYPE); CHECK_CDEFINE(LMV_HASH_FLAG_MIGRATION); CHECK_CDEFINE(LMV_CRUSH_PG_COUNT); @@ -1140,7 +1142,7 @@ check_mdt_body(void) CHECK_MEMBER(mdt_body, mbo_projid); CHECK_MEMBER(mdt_body, mbo_dom_size); CHECK_MEMBER(mdt_body, mbo_dom_blocks); - CHECK_MEMBER(mdt_body, mbo_padding_8); + CHECK_MEMBER(mdt_body, mbo_btime); CHECK_MEMBER(mdt_body, mbo_padding_9); CHECK_MEMBER(mdt_body, mbo_padding_10); @@ -2757,6 +2759,7 @@ main(int argc, char **argv) CHECK_VALUE(OST_QUOTA_ADJUST_QUNIT); CHECK_VALUE(OST_LADVISE); CHECK_VALUE(OST_FALLOCATE); + CHECK_VALUE(OST_SEEK); CHECK_VALUE(OST_LAST_OPC); CHECK_DEFINE_64X(OBD_OBJECT_EOF); diff --git a/lustre/utils/wirehdr.c b/lustre/utils/wirehdr.c index 49c732b..ed3e662 100644 --- a/lustre/utils/wirehdr.c +++ b/lustre/utils/wirehdr.c @@ -53,7 +53,7 @@ #define LASSERT(cond) if (!(cond)) { printf("failed " #cond "\n"); ret = 1; } #define LASSERTF(cond, fmt, ...) if (!(cond)) { printf("failed '" #cond "'" fmt, ## __VA_ARGS__); ret = 1; } /* - * BUILD_BUG_ON() is Compile-time LASSERT, which verifies correctness at + * BUILD_BUG_ON() is Compile-time check which verifies correctness at * compile-time rather than runtime. If "cond" is true, then there are two * identical cases ("0" and "0"), which is an error that causes the compiler to * complain. If "cond" is false, then there are two different cases diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 5084d96..399084e 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -41,8 +41,8 @@ #include #include #ifdef CONFIG_FS_POSIX_ACL -#ifdef HAVE_STRUCT_POSIX_ACL_XATTR #include +#ifdef HAVE_STRUCT_POSIX_ACL_XATTR # define posix_acl_xattr_header struct posix_acl_xattr_header # define posix_acl_xattr_entry struct posix_acl_xattr_entry #endif /* HAVE_STRUCT_POSIX_ACL_XATTR */ @@ -51,12 +51,18 @@ #include #define LASSERT(cond) if (!(cond)) { printf("failed " #cond "\n"); ret = 1; } -#define LASSERTF(cond, fmt, ...) if (!(cond)) { printf("failed '" #cond "'" fmt, ## __VA_ARGS__);ret = 1;} +#define LASSERTF(cond, fmt, ...) if (!(cond)) { printf("failed '" #cond "'" fmt, ## __VA_ARGS__); ret = 1; } /* * BUILD_BUG_ON() is Compile-time check which verifies correctness at - * compile-time rather than runtime. + * compile-time rather than runtime. If "cond" is true, then there are two + * identical cases ("0" and "0"), which is an error that causes the compiler to + * complain. If "cond" is false, then there are two different cases + * ("(non-zero)" and "0"). + * */ -#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) +#ifndef BUILD_BUG_ON +#define BUILD_BUG_ON(cond) do {switch (0) {case (cond): case 1: break; } } while (0) +#endif int ret; @@ -132,7 +138,9 @@ void lustre_assert_wire_constants(void) (long long)OST_LADVISE); LASSERTF(OST_FALLOCATE == 22, "found %lld\n", (long long)OST_FALLOCATE); - LASSERTF(OST_LAST_OPC == 23, "found %lld\n", + LASSERTF(OST_SEEK == 23, "found %lld\n", + (long long)OST_SEEK); + LASSERTF(OST_LAST_OPC == 24, "found %lld\n", (long long)OST_LAST_OPC); LASSERTF(OBD_OBJECT_EOF == 0xffffffffffffffffULL, "found 0x%.16llxULL\n", OBD_OBJECT_EOF); @@ -478,7 +486,7 @@ void lustre_assert_wire_constants(void) LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n", (unsigned)LMAI_ORPHAN); LASSERTF(LMAI_ENCRYPT == 0x00000020UL, "found 0x%.8xUL\n", - (unsigned)LMAI_ENCRYPT); + (unsigned)LMAI_ENCRYPT); /* Checks for struct lustre_ost_attrs */ LASSERTF((int)sizeof(struct lustre_ost_attrs) == 64, "found %lld\n", @@ -1399,10 +1407,12 @@ void lustre_assert_wire_constants(void) OBD_CONNECT2_ASYNC_DISCARD); LASSERTF(OBD_CONNECT2_ENCRYPT == 0x8000ULL, "found 0x%.16llxULL\n", OBD_CONNECT2_ENCRYPT); - LASSERTF(OBD_CONNECT2_FIDMAP== 0x10000ULL, "found 0x%.16llxULL\n", + LASSERTF(OBD_CONNECT2_FIDMAP == 0x10000ULL, "found 0x%.16llxULL\n", OBD_CONNECT2_FIDMAP); - LASSERTF(OBD_CONNECT2_GETATTR_PFID== 0x20000ULL, "found 0x%.16llxULL\n", + LASSERTF(OBD_CONNECT2_GETATTR_PFID == 0x20000ULL, "found 0x%.16llxULL\n", OBD_CONNECT2_GETATTR_PFID); + LASSERTF(OBD_CONNECT2_LSEEK == 0x40000ULL, "found 0x%.16llxULL\n", + OBD_CONNECT2_LSEEK); LASSERTF(OBD_CKSUM_CRC32 == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)OBD_CKSUM_CRC32); LASSERTF(OBD_CKSUM_ADLER == 0x00000002UL, "found 0x%.8xUL\n", @@ -2608,7 +2618,7 @@ void lustre_assert_wire_constants(void) LASSERTF(LUSTRE_SET_SYNC_FL == 0x00040000UL, "found 0x%.8xUL\n", (unsigned)LUSTRE_SET_SYNC_FL); LASSERTF(LUSTRE_ENCRYPT_FL == 0x00800000UL, "found 0x%.8xUL\n", - (unsigned)LUSTRE_ENCRYPT_FL); + (unsigned)LUSTRE_ENCRYPT_FL); LASSERTF(MDS_INODELOCK_LOOKUP == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)MDS_INODELOCK_LOOKUP); LASSERTF(MDS_INODELOCK_UPDATE == 0x00000002UL, "found 0x%.8xUL\n", -- 1.8.3.1