From: Vladimir Saveliev Date: Fri, 5 Nov 2010 15:21:44 +0000 (+0300) Subject: b=15599 hsm infrastructure X-Git-Tag: 2.0.56.0~39 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=2e0ad6d40070d38076c77038b7d48ac90af7b130;p=fs%2Flustre-release.git b=15599 hsm infrastructure https://bugzilla.lustre.org/attachment.cgi?id=31961 and wiretest update (https://bugzilla.lustre.org/attachment.cgi?id=31991) a=jc.lafoucriere i=andreas.dilger i=nathan.rutman i=vladimir.saveliev --- diff --git a/libcfs/include/libcfs/darwin/kp30.h b/libcfs/include/libcfs/darwin/kp30.h index 7dc581e..bf5e7dc 100644 --- a/libcfs/include/libcfs/darwin/kp30.h +++ b/libcfs/include/libcfs/darwin/kp30.h @@ -116,6 +116,7 @@ typedef struct { #define IOCTL_LIBCFS_TYPE struct libcfs_ioctl_data +#define LPO64 "%#llo" #define LPU64 "%llu" #define LPD64 "%lld" #define LPX64 "%#llx" diff --git a/libcfs/include/libcfs/libcfs.h b/libcfs/include/libcfs/libcfs.h index 06a4a37..74208ac 100644 --- a/libcfs/include/libcfs/libcfs.h +++ b/libcfs/include/libcfs/libcfs.h @@ -260,10 +260,15 @@ void cfs_stack_trace_fill(struct cfs_stack_trace *trace); */ void *cfs_stack_trace_frame(struct cfs_stack_trace *trace, int frame_no); +#ifndef O_NOACCESS +#define O_NOACCESS O_NONBLOCK +#endif + /* * Universal open flags. */ -#define CFS_O_ACCMODE 0003 +#define CFS_O_NOACCESS 0003 +#define CFS_O_ACCMODE CFS_O_NOACCESS #define CFS_O_CREAT 0100 #define CFS_O_EXCL 0200 #define CFS_O_NOCTTY 0400 diff --git a/libcfs/include/libcfs/libcfs_kernelcomm.h b/libcfs/include/libcfs/libcfs_kernelcomm.h index b2e5406..9f24d59 100644 --- a/libcfs/include/libcfs/libcfs_kernelcomm.h +++ b/libcfs/include/libcfs/libcfs_kernelcomm.h @@ -77,6 +77,9 @@ enum kuc_generic_message_type { KUC_MSG_SHUTDOWN = 1, }; +/* prototype for callback function on kuc groups */ +typedef int (*libcfs_kkuc_cb_t)(__u32 data, void *cb_arg); + /* KUC Broadcast Groups. This determines which userspace process hears which * messages. Mutliple transports may be used within a group, or multiple * groups may use the same transport. Broadcast @@ -89,8 +92,11 @@ enum kuc_generic_message_type { /* Kernel methods */ extern int libcfs_kkuc_msg_put(cfs_file_t *fp, void *payload); extern int libcfs_kkuc_group_put(int group, void *payload); -extern int libcfs_kkuc_group_add(cfs_file_t *fp, int uid, int group); +extern int libcfs_kkuc_group_add(cfs_file_t *fp, int uid, int group, + __u32 data); extern int libcfs_kkuc_group_rem(int uid, int group); +extern int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func, + void *cb_arg); #define LK_FLG_STOP 0x01 diff --git a/libcfs/include/libcfs/linux/kp30.h b/libcfs/include/libcfs/linux/kp30.h index 71d88c3..122a506 100644 --- a/libcfs/include/libcfs/linux/kp30.h +++ b/libcfs/include/libcfs/linux/kp30.h @@ -305,12 +305,14 @@ extern int lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size, # define LPD64 "%Ld" # define LPX64 "%#Lx" # define LPX64i "%Lx" +# define LPO64 "%#Lo" # define LPF64 "L" #else # define LPU64 "%lu" # define LPD64 "%ld" # define LPX64 "%#lx" # define LPX64i "%lx" +# define LPO64 "%#lo" # define LPF64 "l" #endif diff --git a/libcfs/include/libcfs/posix/posix-wordsize.h b/libcfs/include/libcfs/posix/posix-wordsize.h index ede6dce..e6730cd 100644 --- a/libcfs/include/libcfs/posix/posix-wordsize.h +++ b/libcfs/include/libcfs/posix/posix-wordsize.h @@ -119,18 +119,21 @@ typedef struct { # define LPD64 "%Ld" # define LPX64 "%#Lx" # define LPX64i "%Lx" +# define LPO64 "%#Lo" # define LPF64 "L" #elif (BITS_PER_LONG == 32) # define LPU64 "%Lu" # define LPD64 "%Ld" # define LPX64 "%#Lx" # define LPX64i "%Lx" +# define LPO64 "%#Lo" # define LPF64 "L" #elif (BITS_PER_LONG == 64) # define LPU64 "%lu" # define LPD64 "%ld" -# define LPX64 "%#lx" # define LPX64i "%lx" +# define LPX64 "%#lx" +# define LPO64 "%#lo" # define LPF64 "l" #endif diff --git a/libcfs/include/libcfs/winnt/kp30.h b/libcfs/include/libcfs/winnt/kp30.h index 38c1197..5f1ba6d 100644 --- a/libcfs/include/libcfs/winnt/kp30.h +++ b/libcfs/include/libcfs/winnt/kp30.h @@ -150,6 +150,7 @@ typedef struct { #define LPU64 "%I64u" #define LPD64 "%I64d" #define LPX64 "%#I64x" +#define LPO64 "%#I64o" /* * long_ptr_t & ulong_ptr_t, same to "long" for linux diff --git a/libcfs/libcfs/darwin/darwin-fs.c b/libcfs/libcfs/darwin/darwin-fs.c index b592d88..2234082 100644 --- a/libcfs/libcfs/darwin/darwin-fs.c +++ b/libcfs/libcfs/darwin/darwin-fs.c @@ -448,7 +448,7 @@ int cfs_oflags2univ(int flags) { int f; - f = flags & O_ACCMODE; + f = flags & O_NOACCESS; f |= (flags & O_CREAT) ? CFS_O_CREAT: 0; f |= (flags & O_TRUNC) ? CFS_O_TRUNC: 0; f |= (flags & O_EXCL) ? CFS_O_EXCL: 0; diff --git a/libcfs/libcfs/kernel_user_comm.c b/libcfs/libcfs/kernel_user_comm.c index 357bcf1..a25e803 100644 --- a/libcfs/libcfs/kernel_user_comm.c +++ b/libcfs/libcfs/kernel_user_comm.c @@ -40,7 +40,7 @@ */ #define DEBUG_SUBSYSTEM S_CLASS -#define D_KUC 0 +#define D_KUC D_OTHER #include @@ -105,7 +105,7 @@ int libcfs_ukuc_msg_get(lustre_kernelcomm *link, char *buf, int maxsize, } kuch = (struct kuc_hdr *)buf; - CDEBUG(D_KUC, " Received message mg=%x t=%d m=%d l=%d\n", + CDEBUG(D_KUC, "Received message mg=%x t=%d m=%d l=%d\n", kuch->kuc_magic, kuch->kuc_transport, kuch->kuc_msgtype, kuch->kuc_msglen); @@ -190,6 +190,7 @@ struct kkuc_reg { cfs_list_t kr_chain; int kr_uid; cfs_file_t *kr_fp; + __u32 kr_data; }; static cfs_list_t kkuc_groups[KUC_GRP_MAX+1] = {}; /* Protect message sending against remove and adds */ @@ -200,7 +201,7 @@ static CFS_DECLARE_RWSEM(kg_sem); * @param uid identidier for this receiver * @param group group number */ -int libcfs_kkuc_group_add(cfs_file_t *filp, int uid, int group) +int libcfs_kkuc_group_add(cfs_file_t *filp, int uid, int group, __u32 data) { struct kkuc_reg *reg; @@ -220,6 +221,7 @@ int libcfs_kkuc_group_add(cfs_file_t *filp, int uid, int group) reg->kr_fp = filp; reg->kr_uid = uid; + reg->kr_data = data; cfs_down_write(&kg_sem); if (kkuc_groups[group].next == NULL) @@ -258,7 +260,8 @@ int libcfs_kkuc_group_rem(int uid, int group) cfs_list_del(®->kr_chain); CDEBUG(D_KUC, "Removed uid=%d fp=%p from group %d\n", reg->kr_uid, reg->kr_fp, group); - cfs_put_file(reg->kr_fp); + if (reg->kr_fp != NULL) + cfs_put_file(reg->kr_fp); cfs_free(reg); } } @@ -276,7 +279,13 @@ int libcfs_kkuc_group_put(int group, void *payload) cfs_down_read(&kg_sem); cfs_list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { + if (reg->kr_fp != NULL) { rc = libcfs_kkuc_msg_put(reg->kr_fp, payload); + if (rc == -EPIPE) { + cfs_put_file(reg->kr_fp); + reg->kr_fp = NULL; + } + } } cfs_up_read(&kg_sem); @@ -284,5 +293,39 @@ int libcfs_kkuc_group_put(int group, void *payload) } CFS_EXPORT_SYMBOL(libcfs_kkuc_group_put); +/** + * Calls a callback function for each link of the given kuc group. + * @param group the group to call the function on. + * @param cb_func the function to be called. + * @param cb_arg iextra argument to be passed to the callback function. + */ +int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func, + void *cb_arg) +{ + struct kkuc_reg *reg; + int rc = 0; + ENTRY; + + if (group > KUC_GRP_MAX) { + CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); + RETURN(-EINVAL); + } + + /* no link for this group */ + if (kkuc_groups[group].next == NULL) + RETURN(0); + + cfs_down_read(&kg_sem); + cfs_list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { + if (reg->kr_fp != NULL) { + rc = cb_func(reg->kr_data, cb_arg); + } + } + cfs_up_read(&kg_sem); + + RETURN(rc); +} +CFS_EXPORT_SYMBOL(libcfs_kkuc_group_foreach); + #endif /* LUSTRE_UTILS */ diff --git a/libcfs/libcfs/linux/linux-fs.c b/libcfs/libcfs/linux/linux-fs.c index 82ecbf2..2bf8593 100644 --- a/libcfs/libcfs/linux/linux-fs.c +++ b/libcfs/libcfs/linux/linux-fs.c @@ -89,6 +89,7 @@ cfs_user_write (cfs_file_t *filp, const char *buf, size_t count, loff_t *offset) } #if !(CFS_O_CREAT == O_CREAT && CFS_O_EXCL == O_EXCL && \ + CFS_O_NOACCESS == O_NOACCESS &&\ CFS_O_TRUNC == O_TRUNC && CFS_O_APPEND == O_APPEND &&\ CFS_O_NONBLOCK == O_NONBLOCK && CFS_O_NDELAY == O_NDELAY &&\ CFS_O_SYNC == O_SYNC && CFS_O_ASYNC == FASYNC &&\ @@ -97,9 +98,9 @@ cfs_user_write (cfs_file_t *filp, const char *buf, size_t count, loff_t *offset) int cfs_oflags2univ(int flags) { - int f; - - f = flags & O_ACCMODE; + int f; + + f = flags & O_NOACCESS; f |= (flags & O_CREAT) ? CFS_O_CREAT: 0; f |= (flags & O_EXCL) ? CFS_O_EXCL: 0; f |= (flags & O_NOCTTY) ? CFS_O_NOCTTY: 0; diff --git a/lustre/cmm/cmm_object.c b/lustre/cmm/cmm_object.c index 86741be..9c115de 100644 --- a/lustre/cmm/cmm_object.c +++ b/lustre/cmm/cmm_object.c @@ -284,6 +284,15 @@ static int cml_readlink(const struct lu_env *env, struct md_object *mo, RETURN(rc); } +static int cml_changelog(const struct lu_env *env, enum changelog_rec_type type, + int flags, struct md_object *mo) +{ + int rc; + ENTRY; + rc = mo_changelog(env, type, flags, md_object_next(mo)); + RETURN(rc); +} + static int cml_xattr_list(const struct lu_env *env, struct md_object *mo, struct lu_buf *buf) { @@ -410,6 +419,7 @@ static const struct md_object_operations cml_mo_ops = { .moo_close = cml_close, .moo_readpage = cml_readpage, .moo_readlink = cml_readlink, + .moo_changelog = cml_changelog, .moo_capa_get = cml_capa_get, .moo_object_sync = cml_object_sync, .moo_version_get = cml_version_get, @@ -866,7 +876,7 @@ static const struct md_dir_operations cml_dir_ops = { .mdo_name_insert = cml_name_insert, .mdo_rename = cml_rename, .mdo_rename_tgt = cml_rename_tgt, - .mdo_create_data = cml_create_data + .mdo_create_data = cml_create_data, }; /** @} */ /** @} */ @@ -1024,6 +1034,12 @@ static int cmr_readlink(const struct lu_env *env, struct md_object *mo, return -EFAULT; } +static int cmr_changelog(const struct lu_env *env, enum changelog_rec_type type, + int flags, struct md_object *mo) +{ + return -EFAULT; +} + static int cmr_xattr_list(const struct lu_env *env, struct md_object *mo, struct lu_buf *buf) { @@ -1128,6 +1144,7 @@ static const struct md_object_operations cmr_mo_ops = { .moo_close = cmr_close, .moo_readpage = cmr_readpage, .moo_readlink = cmr_readlink, + .moo_changelog = cmr_changelog, .moo_capa_get = cmr_capa_get, .moo_object_sync = cmr_object_sync, .moo_version_get = cmr_version_get, diff --git a/lustre/include/darwin/lustre_dlm.h b/lustre/include/darwin/lustre_dlm.h index ab5fea5..5287821 100644 --- a/lustre/include/darwin/lustre_dlm.h +++ b/lustre/include/darwin/lustre_dlm.h @@ -40,17 +40,4 @@ #ifndef _LUSTRE_DLM_H__ #error Do not #include this file directly. #include instead #endif - -#define IT_OPEN 0x0001 -#define IT_CREAT 0x0002 -#define IT_READDIR 0x0004 -#define IT_GETATTR 0x0008 -#define IT_LOOKUP 0x0010 -#define IT_UNLINK 0x0020 -#define IT_GETXATTR 0x0040 -#define IT_EXEC 0x0080 -#define IT_PIN 0x0100 -#define IT_CHDIR 0x0200 - - #endif diff --git a/lustre/include/darwin/lustre_lib.h b/lustre/include/darwin/lustre_lib.h index b4d7e45..60cda4b 100644 --- a/lustre/include/darwin/lustre_lib.h +++ b/lustre/include/darwin/lustre_lib.h @@ -58,6 +58,7 @@ #define LPU64 "%llu" #define LPD64 "%lld" #define LPX64 "%llx" +#define LPO64 "%llo" #endif struct obd_ioctl_data; diff --git a/lustre/include/darwin/lustre_lite.h b/lustre/include/darwin/lustre_lite.h index 98bba91..3395832 100644 --- a/lustre/include/darwin/lustre_lite.h +++ b/lustre/include/darwin/lustre_lite.h @@ -61,23 +61,6 @@ struct iattr { unsigned int ia_attr_flags; }; -/* - * intent data-structured. For Linux they are defined in - * linux/include/linux/dcache.h - */ -#define IT_OPEN 0x0001 -#define IT_CREAT 0x0002 -#define IT_READDIR 0x0004 -#define IT_GETATTR 0x0008 -#define IT_LOOKUP 0x0010 -#define IT_UNLINK 0x0020 -#define IT_GETXATTR 0x0040 -#define IT_EXEC 0x0080 -#define IT_PIN 0x0100 - -#define IT_FL_LOCKED 0x0001 -#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */ - #define INTENT_MAGIC 0x19620323 /* Happy birthday! */ struct lustre_intent_data { diff --git a/lustre/include/darwin/lustre_user.h b/lustre/include/darwin/lustre_user.h index 3821a83..506a9e2 100644 --- a/lustre/include/darwin/lustre_user.h +++ b/lustre/include/darwin/lustre_user.h @@ -63,10 +63,12 @@ typedef struct stat lstat_t; # define LPU64 "%llu" # define LPD64 "%lld" # define LPX64 "%#llx" +# define LPO64 "%#llo" #elif (BITS_PER_LONG == 64 || __WORDSIZE == 64) # define LPU64 "%lu" # define LPD64 "%ld" # define LPX64 "%#lx" +# define LPO64 "%#lo" #endif #endif /* !LPU64 */ diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index b008dcb..f5eb5cd 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -208,19 +208,7 @@ struct iattr { #define ll_iattr iattr -#define IT_OPEN 0x0001 -#define IT_CREAT 0x0002 -#define IT_READDIR 0x0004 -#define IT_GETATTR 0x0008 -#define IT_LOOKUP 0x0010 -#define IT_UNLINK 0x0020 -#define IT_GETXATTR 0x0040 -#define IT_EXEC 0x0080 -#define IT_PIN 0x0100 - -#define IT_FL_LOCKED 0x0001 -#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */ - +/* defined in kernel header include/linux/namei.h */ #define INTENT_MAGIC 0x19620323 struct lustre_intent_data { diff --git a/lustre/include/linux/lustre_intent.h b/lustre/include/linux/lustre_intent.h index 8c0a862..9bf28d4 100644 --- a/lustre/include/linux/lustre_intent.h +++ b/lustre/include/linux/lustre_intent.h @@ -41,15 +41,7 @@ #ifndef HAVE_VFS_INTENT_PATCHES -#define IT_OPEN (1 << 0) -#define IT_CREAT (1 << 1) -#define IT_READDIR (1 << 2) -#define IT_GETATTR (1 << 3) -#define IT_LOOKUP (1 << 4) -#define IT_UNLINK (1 << 5) -#define IT_TRUNC (1 << 6) -#define IT_GETXATTR (1 << 7) - +/* intent IT_XXX are defined in lustre/include/obd.h */ struct lustre_intent_data { int it_disposition; int it_status; diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index a60e444..eefff59 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1097,7 +1097,7 @@ extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb); OBD_CONNECT_MDS_MDS | OBD_CONNECT_FID | \ LRU_RESIZE_CONNECT_FLAG | OBD_CONNECT_VBR | \ OBD_CONNECT_LOV_V3 | OBD_CONNECT_SOM | \ - OBD_CONNECT_FULL20) + OBD_CONNECT_FULL20 | OBD_CONNECT_LAYOUTLOCK) #define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \ OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \ OBD_CONNECT_TRUNCLOCK | OBD_CONNECT_INDEX | \ @@ -1839,6 +1839,9 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa); #define MDS_OPEN_LOCK 04000000000 /* This open requires open lock */ #define MDS_OPEN_HAS_EA 010000000000 /* specify object create pattern */ #define MDS_OPEN_HAS_OBJS 020000000000 /* Just set the EA the obj exist */ +#define MDS_OPEN_NORESTORE 0100000000000ULL /* Do not restore file at open */ +#define MDS_OPEN_NEWSTRIPE 0200000000000ULL /* New stripe needed (restripe or + * hsm restore) */ /* permission for create non-directory file */ #define MAY_CREATE (1 << 7) @@ -1888,12 +1891,26 @@ struct mdt_rec_create { __u64 cr_padding_1; /* rr_blocks */ __u32 cr_mode; __u32 cr_bias; - __u32 cr_flags; /* for use with open */ - __u32 cr_padding_2; /* rr_padding_2 */ + /* use of helpers set/get_mrc_cr_flags() is needed to access + * 64 bits cr_flags [cr_flags_l, cr_flags_h], this is done to + * extend cr_flags size without breaking 1.8 compat */ + __u32 cr_flags_l; /* for use with open, low 32 bits */ + __u32 cr_flags_h; /* for use with open, high 32 bits */ __u32 cr_padding_3; /* rr_padding_3 */ __u32 cr_padding_4; /* rr_padding_4 */ }; +static inline void set_mrc_cr_flags(struct mdt_rec_create *mrc, __u64 flags) +{ + mrc->cr_flags_l = (__u32)(flags & 0xFFFFFFFFUll); + mrc->cr_flags_h = (__u32)(flags >> 32); +} + +static inline __u64 get_mrc_cr_flags(struct mdt_rec_create *mrc) +{ + return ((__u64)(mrc->cr_flags_l) | ((__u64)mrc->cr_flags_h << 32)); +} + /* instance of mdt_reint_rec */ struct mdt_rec_link { __u32 lk_opcode; diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index cb7d19d..4ea95a9 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -322,7 +322,8 @@ typedef struct lu_fid lustre_fid; /* printf display format e.g. printf("file FID is "DFID"\n", PFID(fid)); */ -#define DFID "["LPX64":0x%x:0x%x]" +#define DFID_NOBRACE LPX64":0x%x:0x%x" +#define DFID "["DFID_NOBRACE"]" #define PFID(fid) \ (fid)->f_seq, \ (fid)->f_oid, \ @@ -498,6 +499,83 @@ static inline const char *changelog_type2str(int type) { #define CLF_VERSION 0x1000 #define CLF_FLAGMASK 0x0FFF /* Anything under the flagmask may be per-type (if desired) */ +/* Flags for unlink */ +#define CLF_UNLINK_LAST 0x0001 /* Unlink of last hardlink */ +#define CLF_UNLINK_HSM_EXISTS 0x0002 /* File has something in HSM */ + /* HSM cleaning needed */ +/* Flags for HSM */ +/* 12b used (from high weight to low weight): + * 2b for flags + * 3b for event + * 7b for error code + */ +#define CLF_HSM_ERR_L 0 /* HSM return code, 7 bits */ +#define CLF_HSM_ERR_H 6 +#define CLF_HSM_EVENT_L 7 /* HSM event, 3 bits, see enum hsm_event */ +#define CLF_HSM_EVENT_H 9 +#define CLF_HSM_FLAG_L 10 /* HSM flags, 2 bits, 1 used, 1 spare */ +#define CLF_HSM_FLAG_H 11 +#define CLF_HSM_SPARE_L 12 /* 4 spare bits */ +#define CLF_HSM_SPARE_H 15 +#define CLF_HSM_LAST 15 + +#define CLF_GET_BITS(_b, _h, _l) \ + _b &= (0xFFFF << (CLF_HSM_LAST - _h)); \ + _b = _b >> (_l + CLF_HSM_LAST - _h) + +#define CLF_HSM_SUCCESS 0x00 +#define CLF_HSM_MAXERROR 0x7E +#define CLF_HSM_ERROVERFLOW 0x7F + +#define CLF_HSM_DIRTY 1 /* file is dirty after HSM request end */ + +/* 3 bits field => 8 values allowed */ +enum hsm_event { + HE_ARCHIVE = 0, + HE_RESTORE = 1, + HE_CANCEL = 2, + HE_RELEASE = 3, + HE_REMOVE = 4, + HE_STATE = 5, + HE_SPARE1 = 6, + HE_SPARE2 = 7, +}; + +static inline enum hsm_event hsm_get_cl_event(__u16 flags) +{ + enum hsm_event he; + + CLF_GET_BITS(flags, CLF_HSM_EVENT_H, CLF_HSM_EVENT_L); + he = flags; + return he; +} + +static inline void hsm_set_cl_event(int *flags, enum hsm_event he) +{ + *flags |= (he << CLF_HSM_EVENT_L); +} + +static inline __u16 hsm_get_cl_flags(int flags) +{ + CLF_GET_BITS(flags, CLF_HSM_FLAG_H, CLF_HSM_FLAG_L); + return flags; +} + +static inline void hsm_set_cl_flags(int *flags, int bits) +{ + *flags |= (bits << CLF_HSM_FLAG_L); +} + +static inline int hsm_get_cl_error(int flags) +{ + CLF_GET_BITS(flags, CLF_HSM_ERR_H, CLF_HSM_ERR_L); + return flags; +} + +static inline void hsm_set_cl_error(int *flags, int error) +{ + *flags |= (error << CLF_HSM_ERR_L); +} #define CR_MAXSIZE (PATH_MAX + sizeof(struct changelog_rec)) struct changelog_rec { @@ -538,49 +616,211 @@ enum changelog_message_type { /********* HSM **********/ +/** HSM per-file state + * See HSM_FLAGS below. + */ +enum hsm_states { + HS_EXISTS = 0x00000001, + HS_DIRTY = 0x00000002, + HS_RELEASED = 0x00000004, + HS_ARCHIVED = 0x00000008, + HS_NORELEASE = 0x00000010, + HS_NOARCHIVE = 0x00000020, + HS_LOST = 0x00000040, +}; -#define HSM_FLAGS_MASK 0 +/* HSM user-setable flags. */ +#define HSM_USER_MASK (HS_NORELEASE | HS_NOARCHIVE | HS_DIRTY) +/* Other HSM flags. */ +#define HSM_STATUS_MASK (HS_EXISTS | HS_LOST | HS_RELEASED | HS_ARCHIVED) -enum hsm_message_type { - HMT_ACTION_LIST = 100, /* message is a hsm_action_list */ +/* + * All HSM-related possible flags that could be applied to a file. + * This should be kept in sync with hsm_states. + */ +#define HSM_FLAGS_MASK (HSM_USER_MASK | HSM_STATUS_MASK) + +/** + * HSM request progress state + */ +enum hsm_progress_states { + HPS_WAITING = 1, + HPS_RUNNING = 2, + HPS_DONE = 3, +}; +#define HPS_NONE 0 + +static inline char *hsm_progress_state2name(enum hsm_progress_states s) +{ + switch (s) { + case HPS_WAITING: return "waiting"; + case HPS_RUNNING: return "running"; + case HPS_DONE: return "done"; + default: return "unknown"; + } +} + +struct hsm_extent { + __u64 offset; + __u64 length; +} __attribute__((packed)); + +/** + * Current HSM states of a Lustre file. + * + * This structure purpose is to be sent to user-space mainly. It describes the + * current HSM flags and in-progress action. + */ +struct hsm_user_state { + /** Current HSM states, from enum hsm_states. */ + __u32 hus_states; + __u32 hus_archive_num; + /** The current undergoing action, if there is one */ + __u32 hus_in_progress_state; + __u32 hus_in_progress_action; + struct hsm_extent hus_in_progress_location; + char hus_extended_info[]; +}; + +struct hsm_state_set_ioc { + struct lu_fid hssi_fid; + __u64 hssi_setmask; + __u64 hssi_clearmask; +}; + +/***** HSM user requests ******/ +/* User-generated (lfs/ioctl) request types */ +enum hsm_user_action { + HUA_NONE = 1, /* no action (noop) */ + HUA_ARCHIVE = 10, /* copy to hsm */ + HUA_RESTORE = 11, /* prestage */ + HUA_RELEASE = 12, /* drop ost objects */ + HUA_REMOVE = 13, /* remove from archive */ + HUA_CANCEL = 14 /* cancel a request */ }; -/* User-generated (ioctl) request types */ -enum hsm_request { - HSMR_ARCHIVE = 10, /* copy to hsm */ - HSMR_RESTORE = 11, /* prestage */ - HSMR_RELEASE = 12, /* drop ost objects */ - HSMR_REMOVE = 13, /* remove from archive */ - HSMR_CANCEL = 14 +static inline char *hsm_user_action2name(enum hsm_user_action a) +{ + switch (a) { + case HUA_NONE: return "NOOP"; + case HUA_ARCHIVE: return "ARCHIVE"; + case HUA_RESTORE: return "RESTORE"; + case HUA_RELEASE: return "RELEASE"; + case HUA_REMOVE: return "REMOVE"; + case HUA_CANCEL: return "CANCEL"; + default: return "UNKNOWN"; + } +} + +struct hsm_user_item { + lustre_fid hui_fid; + struct hsm_extent hui_extent; +} __attribute__((packed)); + +struct hsm_user_request { + __u32 hur_action; /* enum hsm_user_action */ + __u32 hur_archive_num; /* archive number, used only with HUA_ARCHIVE */ + __u32 hur_itemcount; + __u32 hur_data_len; + struct hsm_user_item hur_user_item[0]; + /* extra data blob at end of struct (after all + * hur_user_items), only use helpers to access it + */ +} __attribute__((packed)); + +/** Return pointer to data field in a hsm user request */ +static inline void *hur_data(struct hsm_user_request *hur) +{ + return &(hur->hur_user_item[hur->hur_itemcount]); +} + +/** Compute the current length of the provided hsm_user_request. */ +static inline int hur_len(struct hsm_user_request *hur) +{ + int data_offset; + + data_offset = hur_data(hur) - (void *)hur; + return (data_offset + hur->hur_data_len); +} + +/****** HSM RPCs to copytool *****/ +/* Message types the copytool may receive */ +enum hsm_message_type { + HMT_ACTION_LIST = 100, /* message is a hsm_action_list */ }; -/* Copytool commands */ -enum hsm_action { +/* Actions the copytool may be instructed to take for a given action_item */ +enum hsm_copytool_action { + HSMA_NONE = 10, /* no action */ HSMA_ARCHIVE = 20, /* arbitrary offset */ HSMA_RESTORE = 21, HSMA_REMOVE = 22, HSMA_CANCEL = 23 }; +static inline char *hsm_copytool_action2name(enum hsm_copytool_action a) +{ + switch (a) { + case HSMA_NONE: return "NOOP"; + case HSMA_ARCHIVE: return "ARCHIVE"; + case HSMA_RESTORE: return "RESTORE"; + case HSMA_REMOVE: return "REMOVE"; + case HSMA_CANCEL: return "CANCEL"; + default: return "UNKNOWN"; + } +} + /* Copytool item action description */ struct hsm_action_item { __u32 hai_len; /* valid size of this struct */ - __u32 hai_action; /* enum actually, but use known size */ + __u32 hai_action; /* hsm_copytool_action, but use known size */ lustre_fid hai_fid; /* Lustre FID to operated on */ + struct hsm_extent hai_extent; /* byte range to operate on */ __u64 hai_cookie; /* action cookie from coordinator */ - __u64 hai_extent_start; /* byte range to operate on */ - __u64 hai_extent_end; __u64 hai_gid; /* grouplock id */ char hai_data[0]; /* variable length */ } __attribute__((packed)); +/* + * helper function which print in hexa the first bytes of + * hai opaque field + * \param hai [IN] record to print + * \param buffer [OUT] output buffer + * \param len [IN] max buffer len + * \retval buffer + */ +static inline char *hai_dump_data_field(struct hsm_action_item *hai, + char *buffer, int len) +{ + int i, sz, data_len; + char *ptr; + + LASSERT(len > 0); + + ptr = buffer; + sz = len; + data_len = hai->hai_len - sizeof(*hai); + for (i = 0 ; (i < data_len) && (sz > 0) ; i++) + { + int cnt; + + cnt = snprintf(ptr, sz, "%.2X", + (unsigned char)hai->hai_data[i]); + ptr += cnt; + sz -= cnt; + } + *ptr = '\0'; + return buffer; +} + /* Copytool action list */ #define HAL_VERSION 1 #define HAL_MAXSIZE 4096 /* bytes, used in userspace only */ struct hsm_action_list { __u32 hal_version; __u32 hal_count; /* number of hai's to follow */ + __u64 hal_compound_id; /* returned by coordinator */ __u32 hal_archive_num; /* which archive backend */ __u32 padding1; char hal_fsname[0]; /* null-terminated */ @@ -602,6 +842,34 @@ static __inline__ struct hsm_action_item * hai_next(struct hsm_action_item *hai) cfs_size_round(hai->hai_len)); } +/* Return size of an hsm_action_list */ +static __inline__ int hal_size(struct hsm_action_list *hal) +{ + int i, sz; + struct hsm_action_item *hai; + + LASSERT(hal->hal_version == HAL_VERSION); + sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname)); + hai = hai_zero(hal); + for (i = 0 ; i < hal->hal_count ; i++) { + sz += cfs_size_round(hai->hai_len); + hai = hai_next(hai); + } + return(sz); +} + +/* Copytool progress reporting */ +#define HP_FLAG_COMPLETED 0x01 +#define HP_FLAG_RETRY 0x02 + +struct hsm_progress { + lustre_fid hp_fid; + __u64 hp_cookie; + struct hsm_extent hp_extent; + __u16 hp_flags; + __u16 hp_errval; /* positive val */ +} __attribute__((packed)); + /** @} lustreuser */ #endif /* _LUSTRE_USER_H */ diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index afe8d35..6336580 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -149,9 +149,8 @@ typedef enum { struct md_hsm { __u32 mh_flags; + __u32 mh_archive_number; }; -#define ma_hsm_flags ma_hsm.mh_flags -#define HSM_FLAGS_MASK 0 #define IOEPOCH_INVAL 0 @@ -199,7 +198,7 @@ struct md_op_spec { int no_create; /** Create flag from client: such as MDS_OPEN_CREAT, and others. */ - __u32 sp_cr_flags; + __u64 sp_cr_flags; /** Should mdd do lookup sanity check or not. */ int sp_cr_lookup; @@ -246,7 +245,9 @@ struct md_object_operations { int (*moo_readlink)(const struct lu_env *env, struct md_object *obj, struct lu_buf *buf); - + int (*moo_changelog)(const struct lu_env *env, + enum changelog_rec_type type, int flags, + struct md_object *obj); /** part of cross-ref operation */ int (*moo_object_create)(const struct lu_env *env, struct md_object *obj, @@ -619,6 +620,14 @@ static inline int mo_readlink(const struct lu_env *env, return m->mo_ops->moo_readlink(env, m, buf); } +static inline int mo_changelog(const struct lu_env *env, + enum changelog_rec_type type, + int flags, struct md_object *m) +{ + LASSERT(m->mo_ops->moo_changelog); + return m->mo_ops->moo_changelog(env, type, flags, m); +} + static inline int mo_attr_set(const struct lu_env *env, struct md_object *m, const struct md_attr *at) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index f55aa5b..5b0c59a 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1164,6 +1164,18 @@ enum obd_cleanup_stage { struct lu_context; +/* /!\ must be coherent with include/linux/namei.h on patched kernel */ +#define IT_OPEN (1 << 0) +#define IT_CREAT (1 << 1) +#define IT_READDIR (1 << 2) +#define IT_GETATTR (1 << 3) +#define IT_LOOKUP (1 << 4) +#define IT_UNLINK (1 << 5) +#define IT_TRUNC (1 << 6) +#define IT_GETXATTR (1 << 7) +#define IT_EXEC (1 << 8) +#define IT_PIN (1 << 9) + static inline int it_to_lock_mode(struct lookup_intent *it) { /* CREAT needs to be tested before open (both could be set) */ diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index c9585b0..5adae76 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -103,6 +103,12 @@ void obd_zombie_impexp_stop(void); void obd_zombie_impexp_cull(void); void obd_zombie_barrier(void); void obd_exports_barrier(struct obd_device *obd); +int kuc_len(int payload_len); +struct kuc_hdr * kuc_ptr(void *p); +int kuc_ispayload(void *p); +void *kuc_alloc(int payload_len, int transport, int type); +void kuc_free(void *p, int payload_len); + /* obd_config.c */ int class_process_config(struct lustre_cfg *lcfg); int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 1e4bc75..8e8b707 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -150,7 +150,7 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, rec->cr_time = op_data->op_mod_time; rec->cr_suppgid1 = op_data->op_suppgids[0]; rec->cr_suppgid2 = op_data->op_suppgids[1]; - rec->cr_flags = op_data->op_flags & MF_SOM_LOCAL_FLAGS; + set_mrc_cr_flags(rec, op_data->op_flags & MF_SOM_LOCAL_FLAGS); rec->cr_bias = op_data->op_bias; mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1); @@ -164,9 +164,9 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, } } -static __u32 mds_pack_open_flags(__u32 flags, __u32 mode) +static __u64 mds_pack_open_flags(__u32 flags, __u32 mode) { - __u32 cr_flags = (flags & (FMODE_READ | FMODE_WRITE | + __u64 cr_flags = (flags & (FMODE_READ | FMODE_WRITE | MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS | MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK)); if (flags & O_CREAT) @@ -188,6 +188,9 @@ static __u32 mds_pack_open_flags(__u32 flags, __u32 mode) if (flags & O_LOV_DELAY_CREATE) cr_flags |= MDS_OPEN_DELAY_CREATE; + if ((flags & O_NOACCESS) || (flags & O_NONBLOCK)) + cr_flags |= MDS_OPEN_NORESTORE; + return cr_flags; } @@ -198,6 +201,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, { struct mdt_rec_create *rec; char *tmp; + __u64 cr_flags; CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_create)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); @@ -212,7 +216,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, rec->cr_fid2 = op_data->op_fid2; } rec->cr_mode = mode; - rec->cr_flags = mds_pack_open_flags(flags, mode); + cr_flags = mds_pack_open_flags(flags, mode); rec->cr_rdev = rdev; rec->cr_time = op_data->op_mod_time; rec->cr_suppgid1 = op_data->op_suppgids[0]; @@ -229,7 +233,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, } if (lmm) { - rec->cr_flags |= MDS_OPEN_HAS_EA; + cr_flags |= MDS_OPEN_HAS_EA; #ifndef __KERNEL__ /*XXX a hack for liblustre to set EA (LL_IOC_LOV_SETSTRIPE) */ rec->cr_fid2 = op_data->op_fid2; @@ -237,6 +241,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, tmp = req_capsule_client_get(&req->rq_pill, &RMF_EADATA); memcpy (tmp, lmm, lmmlen); } + set_mrc_cr_flags(rec, cr_flags); } static inline __u64 attr_pack(unsigned int ia_valid) { diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 7c1db00..dff860bc 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -1417,7 +1417,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, GOTO(out, rc = 0); } case LL_IOC_GET_CONNECT_FLAGS: { - if (cfs_copy_to_user(uarg, &exp->exp_connect_flags, sizeof(__u64))) + if (cfs_copy_to_user(uarg, &exp->exp_connect_flags, + sizeof(__u64))) GOTO(out, rc = -EFAULT); else GOTO(out, rc = 0); @@ -1487,8 +1488,8 @@ static void lustre_swab_hai(struct hsm_action_item *h) __swab32s(&h->hai_action); lustre_swab_lu_fid(&h->hai_fid); __swab64s(&h->hai_cookie); - __swab64s(&h->hai_extent_start); - __swab64s(&h->hai_extent_end); + __swab64s(&h->hai_extent.offset); + __swab64s(&h->hai_extent.length); __swab64s(&h->hai_gid); } @@ -1532,7 +1533,8 @@ static int mdc_ioc_hsm_ct_start(struct obd_export *exp, rc = libcfs_kkuc_group_rem(lk->lk_uid,lk->lk_group); else { cfs_file_t *fp = cfs_get_fd(lk->lk_wfd); - rc = libcfs_kkuc_group_add(fp, lk->lk_uid,lk->lk_group); + rc = libcfs_kkuc_group_add(fp, lk->lk_uid,lk->lk_group, + lk->lk_data); if (rc && fp) cfs_put_file(fp); } diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index aefd6cb..ba0ab43 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -619,6 +619,7 @@ static int __mdd_index_delete(const struct lu_env *env, struct mdd_object *pobj, static int mdd_changelog_ns_store(const struct lu_env *env, struct mdd_device *mdd, enum changelog_rec_type type, + int flags, struct mdd_object *target, struct mdd_object *parent, const struct lu_fid *tf, @@ -650,7 +651,7 @@ static int mdd_changelog_ns_store(const struct lu_env *env, RETURN(-ENOMEM); rec = (struct llog_changelog_rec *)buf->lb_buf; - rec->cr.cr_flags = CLF_VERSION; + rec->cr.cr_flags = CLF_VERSION | (CLF_FLAGMASK & flags); rec->cr.cr_type = (__u32)type; tfid = tf ? tf : mdo2fid(target); rec->cr.cr_tfid = *tfid; @@ -752,7 +753,7 @@ out_unlock: mdd_pdo_write_unlock(env, mdd_tobj, dlh); out_trans: if (rc == 0) - rc = mdd_changelog_ns_store(env, mdd, CL_HARDLINK, mdd_sobj, + rc = mdd_changelog_ns_store(env, mdd, CL_HARDLINK, 0, mdd_sobj, mdd_tobj, NULL, lname, handle); mdd_trans_stop(env, mdd, rc, handle); out_pending: @@ -780,7 +781,9 @@ int mdd_finish_unlink(const struct lu_env *env, LASSERT(mdd_write_locked(env, obj) != 0); - rc = mdd_iattr_get(env, obj, ma); + /* read HSM flags, needed to set changelogs flags */ + ma->ma_need = MA_HSM | MA_INODE; + rc = mdd_attr_get_internal(env, obj, ma); if (rc == 0 && ma->ma_attr.la_nlink == 0) { obj->mod_flags |= DEAD_OBJ; /* add new orphan and the object @@ -923,11 +926,18 @@ cleanup: mdd_write_unlock(env, mdd_cobj); mdd_pdo_write_unlock(env, mdd_pobj, dlh); out_trans: - if (rc == 0) + if (rc == 0) { + int cl_flags; + + cl_flags = (ma->ma_attr.la_nlink == 0) ? CLF_UNLINK_LAST : 0; + if ((ma->ma_valid & MA_HSM) && + (ma->ma_hsm.mh_flags & HS_EXISTS)) + cl_flags |= CLF_UNLINK_HSM_EXISTS; + rc = mdd_changelog_ns_store(env, mdd, - is_dir ? CL_RMDIR : CL_UNLINK, - mdd_cobj, mdd_pobj, NULL, lname, - handle); + is_dir ? CL_RMDIR : CL_UNLINK, cl_flags, + mdd_cobj, mdd_pobj, NULL, lname, handle); + } mdd_trans_stop(env, mdd, rc, handle); #ifdef HAVE_QUOTA_SUPPORT @@ -1301,7 +1311,7 @@ out_trans: if (rc == 0) /* Bare EXT record with no RENAME in front of it signifies a partial slave op */ - rc = mdd_changelog_ns_store(env, mdd, CL_EXT, mdd_tobj, + rc = mdd_changelog_ns_store(env, mdd, CL_EXT, 0, mdd_tobj, mdd_tpobj, NULL, lname, handle); mdd_trans_stop(env, mdd, rc, handle); @@ -1852,10 +1862,10 @@ out_trans: S_ISDIR(attr->la_mode) ? CL_MKDIR : S_ISREG(attr->la_mode) ? CL_CREATE : S_ISLNK(attr->la_mode) ? CL_SOFTLINK : CL_MKNOD, - son, mdd_pobj, NULL, lname, handle); + 0, son, mdd_pobj, NULL, lname, handle); mdd_trans_stop(env, mdd, rc, handle); out_free: - /* finis lov_create stuff, free all temporary data */ + /* finish lov_create stuff, free all temporary data */ mdd_lov_create_finish(env, mdd, lmm, lmm_size, spec); out_pending: #ifdef HAVE_QUOTA_SUPPORT @@ -2226,10 +2236,10 @@ cleanup: mdd_pdo_write_unlock(env, mdd_spobj, sdlh); cleanup_unlocked: if (rc == 0) - rc = mdd_changelog_ns_store(env, mdd, CL_RENAME, mdd_tobj, + rc = mdd_changelog_ns_store(env, mdd, CL_RENAME, 0, mdd_tobj, mdd_spobj, lf, lsname, handle); if (rc == 0) - rc = mdd_changelog_ns_store(env, mdd, CL_EXT, mdd_tobj, + rc = mdd_changelog_ns_store(env, mdd, CL_EXT, 0, mdd_tobj, mdd_tpobj, lf, ltname, handle); mdd_trans_stop(env, mdd, rc, handle); @@ -2536,5 +2546,5 @@ const struct md_dir_operations mdd_dir_ops = { .mdo_name_insert = mdd_name_insert, .mdo_name_remove = mdd_name_remove, .mdo_rename_tgt = mdd_rename_tgt, - .mdo_create_data = mdd_create_data + .mdo_create_data = mdd_create_data, }; diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 8e23458..ba090f1 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -251,6 +251,8 @@ int mdd_object_kill(const struct lu_env *env, struct mdd_object *obj, struct md_attr *ma); int mdd_iattr_get(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma); +int mdd_attr_get_internal(const struct lu_env *env, struct mdd_object *mdd_obj, + struct md_attr *ma); int mdd_attr_get_internal_locked(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma); @@ -380,7 +382,8 @@ struct mdd_object *mdd_object_find(const struct lu_env *env, int mdd_get_default_md(struct mdd_object *mdd_obj, struct lov_mds_md *lmm); int mdd_readpage(const struct lu_env *env, struct md_object *obj, const struct lu_rdpg *rdpg); - +int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, + int flags, struct md_object *obj); /* mdd_quota.c*/ #ifdef HAVE_QUOTA_SUPPORT int mdd_quota_notify(const struct lu_env *env, struct md_device *m); diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 4470ff7..4882609 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -714,9 +714,9 @@ static int __mdd_lma_get(const struct lu_env *env, struct mdd_object *mdd_obj, /* Swab and copy LMA */ if (ma->ma_need & MA_HSM) { if (lma->lma_compat & LMAC_HSM) - ma->ma_hsm_flags = lma->lma_flags & HSM_FLAGS_MASK; + ma->ma_hsm.mh_flags = lma->lma_flags & HSM_FLAGS_MASK; else - ma->ma_hsm_flags = 0; + ma->ma_hsm.mh_flags = 0; ma->ma_valid |= MA_HSM; } @@ -733,8 +733,7 @@ static int __mdd_lma_get(const struct lu_env *env, struct mdd_object *mdd_obj, RETURN(0); } -static int mdd_attr_get_internal(const struct lu_env *env, - struct mdd_object *mdd_obj, +int mdd_attr_get_internal(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma) { int rc = 0; @@ -762,8 +761,8 @@ static int mdd_attr_get_internal(const struct lu_env *env, rc = mdd_def_acl_get(env, mdd_obj, ma); } #endif - CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64"\n", - rc, ma->ma_valid); + CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64" ma_lmm=%p\n", + rc, ma->ma_valid, ma->ma_lmm); RETURN(rc); } @@ -1281,6 +1280,28 @@ static int mdd_changelog_data_store(const struct lu_env *env, return 0; } +int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, + int flags, struct md_object *obj) +{ + struct thandle *handle; + struct mdd_object *mdd_obj = md2mdd_obj(obj); + struct mdd_device *mdd = mdo2mdd(obj); + int rc; + ENTRY; + + handle = mdd_trans_start(env, mdd); + + if (IS_ERR(handle)) + return(PTR_ERR(handle)); + + rc = mdd_changelog_data_store(env, mdd, type, flags, mdd_obj, + handle); + + mdd_trans_stop(env, mdd, rc, handle); + + RETURN(rc); +} + /** * Should be called with write lock held. * @@ -1311,7 +1332,7 @@ static int __mdd_lma_set(const struct lu_env *env, struct mdd_object *mdd_obj, /* Copy HSM data */ if (ma->ma_valid & MA_HSM) { - lma->lma_flags |= ma->ma_hsm_flags & HSM_FLAGS_MASK; + lma->lma_flags |= ma->ma_hsm.mh_flags & HSM_FLAGS_MASK; lma->lma_compat |= LMAC_HSM; } @@ -2408,6 +2429,7 @@ const struct md_object_operations mdd_obj_ops = { .moo_close = mdd_close, .moo_readpage = mdd_readpage, .moo_readlink = mdd_readlink, + .moo_changelog = mdd_changelog, .moo_capa_get = mdd_capa_get, .moo_object_sync = mdd_object_sync, .moo_version_get = mdd_version_get, diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 07ce5ab..2a3b4a0 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -903,7 +903,7 @@ static int mdt_create_unpack(struct mdt_thread_info *info) attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_ATIME; memset(&sp->u, 0, sizeof(sp->u)); - sp->sp_cr_flags = rec->cr_flags; + sp->sp_cr_flags = get_mrc_cr_flags(rec); sp->sp_ck_split = !!(rec->cr_bias & MDS_CHECK_SPLIT); info->mti_cross_ref = !!(rec->cr_bias & MDS_CROSS_REF); @@ -914,7 +914,8 @@ static int mdt_create_unpack(struct mdt_thread_info *info) if (!info->mti_cross_ref) { rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); - rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, RCL_CLIENT) - 1; + rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, + RCL_CLIENT) - 1; LASSERT(rr->rr_name && rr->rr_namelen > 0); } else { rr->rr_name = NULL; @@ -1172,7 +1173,7 @@ static int mdt_open_unpack(struct mdt_thread_info *info) attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_ATIME; memset(&info->mti_spec.u, 0, sizeof(info->mti_spec.u)); - info->mti_spec.sp_cr_flags = rec->cr_flags; + info->mti_spec.sp_cr_flags = get_mrc_cr_flags(rec); /* Do not trigger ASSERTION if client miss to set such flags. */ if (unlikely(info->mti_spec.sp_cr_flags == 0)) RETURN(-EPROTO); diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 81d6069..e0d4072 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -586,7 +586,7 @@ void mdt_mfd_set_mode(struct mdt_file_data *mfd, int mode) } static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p, - struct mdt_object *o, int flags, int created) + struct mdt_object *o, __u64 flags, int created) { struct ptlrpc_request *req = mdt_info_req(info); struct mdt_export_data *med = &req->rq_export->exp_mdt_data; @@ -677,8 +677,7 @@ static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p, old_mfd = mdt_handle2mfd(info, info->mti_rr.rr_handle); if (old_mfd) { CDEBUG(D_HA, "del orph mfd %p fid=("DFID") " - "cookie=" LPX64"\n", - mfd, + "cookie=" LPX64"\n", mfd, PFID(mdt_object_fid(mfd->mfd_object)), info->mti_rr.rr_handle->cookie); cfs_spin_lock(&med->med_open_lock); @@ -716,7 +715,7 @@ static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p, static int mdt_finish_open(struct mdt_thread_info *info, struct mdt_object *p, struct mdt_object *o, - int flags, int created, struct ldlm_reply *rep) + __u64 flags, int created, struct ldlm_reply *rep) { struct ptlrpc_request *req = mdt_info_req(info); struct obd_export *exp = req->rq_export; @@ -1152,7 +1151,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) struct mdt_body *repbody; struct lu_fid *child_fid = &info->mti_tmp_fid1; struct md_attr *ma = &info->mti_attr; - __u32 create_flags = info->mti_spec.sp_cr_flags; + __u64 create_flags = info->mti_spec.sp_cr_flags; struct mdt_reint_record *rr = &info->mti_rr; struct lu_name *lname; int result, rc; @@ -1189,7 +1188,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) GOTO(out, result = err_serious(-EINVAL)); CDEBUG(D_INODE, "I am going to open "DFID"/(%s->"DFID") " - "cr_flag=0%o mode=0%06o msg_flag=0x%x\n", + "cr_flag="LPO64" mode=0%06o msg_flag=0x%x\n", PFID(rr->rr_fid1), rr->rr_name, PFID(rr->rr_fid2), create_flags, ma->ma_attr.la_mode, msg_flags); @@ -1210,7 +1209,8 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) * via a regular replay. */ if (!(create_flags & MDS_OPEN_CREAT)) { - DEBUG_REQ(D_ERROR, req,"OPEN & CREAT not in open replay."); + DEBUG_REQ(D_ERROR, req, + "OPEN & CREAT not in open replay."); GOTO(out, result = -EFAULT); } CDEBUG(D_INFO, "Open replay did find object, continue as " diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index e7632ca..7dd25ad 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -1710,3 +1710,70 @@ void obd_zombie_impexp_stop(void) #endif } +/***** Kernel-userspace comm helpers *******/ + +/* Get length of entire message, including header */ +int kuc_len(int payload_len) +{ + return sizeof(struct kuc_hdr) + payload_len; +} +EXPORT_SYMBOL(kuc_len); + +/* Get a pointer to kuc header, given a ptr to the payload + * @param p Pointer to payload area + * @returns Pointer to kuc header + */ +struct kuc_hdr * kuc_ptr(void *p) +{ + struct kuc_hdr *lh = ((struct kuc_hdr *)p) - 1; + LASSERT(lh->kuc_magic == KUC_MAGIC); + return lh; +} +EXPORT_SYMBOL(kuc_ptr); + +/* Test if payload is part of kuc message + * @param p Pointer to payload area + * @returns boolean + */ +int kuc_ispayload(void *p) +{ + struct kuc_hdr *kh = ((struct kuc_hdr *)p) - 1; + + if (kh->kuc_magic == KUC_MAGIC) + return 1; + else + return 0; +} +EXPORT_SYMBOL(kuc_ispayload); + +/* Alloc space for a message, and fill in header + * @return Pointer to payload area + */ +void *kuc_alloc(int payload_len, int transport, int type) +{ + struct kuc_hdr *lh; + int len = kuc_len(payload_len); + + OBD_ALLOC(lh, len); + if (lh == NULL) + return ERR_PTR(-ENOMEM); + + lh->kuc_magic = KUC_MAGIC; + lh->kuc_transport = transport; + lh->kuc_msgtype = type; + lh->kuc_msglen = len; + + return (void *)(lh + 1); +} +EXPORT_SYMBOL(kuc_alloc); + +/* Takes pointer to payload area */ +inline void kuc_free(void *p, int payload_len) +{ + struct kuc_hdr *lh = kuc_ptr(p); + OBD_FREE(lh, kuc_len(payload_len)); +} +EXPORT_SYMBOL(kuc_free); + + + diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 4412167..56558e5 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -2297,3 +2297,40 @@ void lustre_swab_lustre_capa_key(struct lustre_capa_key *k) CLASSERT(offsetof(typeof(*k), lk_padding) != 0); } +void lustre_swab_hsm_state(struct hsm_state_set_ioc *hssi) +{ + lustre_swab_lu_fid(&hssi->hssi_fid); + __swab64s(&hssi->hssi_setmask); + __swab64s(&hssi->hssi_clearmask); +} +EXPORT_SYMBOL(lustre_swab_hsm_state); + +void lustre_swab_hsm_user_request(struct hsm_user_request *hur) +{ + int i; + + __swab32s(&hur->hur_action); + __swab32s(&hur->hur_itemcount); + __swab32s(&hur->hur_data_len); + for (i = 0; i < hur->hur_itemcount; i++) { + struct hsm_user_item *hui = &hur->hur_user_item[i]; + lustre_swab_lu_fid(&hui->hui_fid); + __swab64s(&hui->hui_extent.offset); + __swab64s(&hui->hui_extent.length); + } + /* Note: data blob is not swabbed here */ +} +EXPORT_SYMBOL(lustre_swab_hsm_user_request); + +void lustre_swab_hsm_progress(struct hsm_progress *hp) +{ + lustre_swab_lu_fid(&hp->hp_fid); + __swab64s(&hp->hp_cookie); + __swab64s(&hp->hp_extent.offset); + __swab64s(&hp->hp_extent.length); + __swab16s(&hp->hp_flags); + __swab16s(&hp->hp_errval); +} +EXPORT_SYMBOL(lustre_swab_hsm_progress); + + diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index e819c88..dc414a4 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -1361,14 +1361,14 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mdt_rec_create, cr_bias)); LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_bias) == 4, " found %lld\n", (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_bias)); - LASSERTF((int)offsetof(struct mdt_rec_create, cr_flags) == 120, " found %lld\n", - (long long)(int)offsetof(struct mdt_rec_create, cr_flags)); - LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_flags) == 4, " found %lld\n", - (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_flags)); - LASSERTF((int)offsetof(struct mdt_rec_create, cr_padding_2) == 124, " found %lld\n", - (long long)(int)offsetof(struct mdt_rec_create, cr_padding_2)); - LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_padding_2) == 4, " found %lld\n", - (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_padding_2)); + LASSERTF((int)offsetof(struct mdt_rec_create, cr_flags_l) == 120, " found %lld\n", + (long long)(int)offsetof(struct mdt_rec_create, cr_flags_l)); + LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_flags_l) == 4, " found %lld\n", + (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_flags_l)); + LASSERTF((int)offsetof(struct mdt_rec_create, cr_flags_h) == 124, " found %lld\n", + (long long)(int)offsetof(struct mdt_rec_create, cr_flags_h)); + LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_flags_h) == 4, " found %lld\n", + (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_flags_h)); LASSERTF((int)offsetof(struct mdt_rec_create, cr_padding_3) == 128, " found %lld\n", (long long)(int)offsetof(struct mdt_rec_create, cr_padding_3)); LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_padding_3) == 4, " found %lld\n", diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index d574047..97c86c0 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -601,8 +601,8 @@ check_mdt_rec_create(void) CHECK_MEMBER(mdt_rec_create, cr_padding_1); CHECK_MEMBER(mdt_rec_create, cr_mode); CHECK_MEMBER(mdt_rec_create, cr_bias); - CHECK_MEMBER(mdt_rec_create, cr_flags); - CHECK_MEMBER(mdt_rec_create, cr_padding_2); + CHECK_MEMBER(mdt_rec_create, cr_flags_l); + CHECK_MEMBER(mdt_rec_create, cr_flags_h); CHECK_MEMBER(mdt_rec_create, cr_padding_3); CHECK_MEMBER(mdt_rec_create, cr_padding_4); } @@ -1229,6 +1229,37 @@ check_link_ea_entry(void) CHECK_MEMBER(link_ea_entry, lee_name); } +static void +check_hsm_user_item(void) +{ + BLANK_LINE(); + CHECK_STRUCT(hsm_user_item); + CHECK_MEMBER(hsm_user_item, hui_fid); + CHECK_MEMBER(hsm_user_item, hui_extent); +} + +static void +check_hsm_user_request(void) +{ + BLANK_LINE(); + CHECK_STRUCT(hsm_user_request); + CHECK_MEMBER(hsm_user_request, hur_action); + CHECK_MEMBER(hsm_user_request, hur_archive_num); + CHECK_MEMBER(hsm_user_request, hur_itemcount); + CHECK_MEMBER(hsm_user_request, hur_data_len); +} + +static void +check_hsm_user_state(void) +{ + BLANK_LINE(); + CHECK_STRUCT(hsm_user_state); + CHECK_MEMBER(hsm_user_state, hus_states); + CHECK_MEMBER(hsm_user_state, hus_archive_num); + CHECK_MEMBER(hsm_user_state, hus_in_progress_state); + CHECK_MEMBER(hsm_user_state, hus_in_progress_action); + CHECK_MEMBER(hsm_user_state, hus_in_progress_location); +} static void system_string (char *cmdline, char *str, int len) @@ -1495,6 +1526,9 @@ main(int argc, char **argv) printf("#endif\n"); check_link_ea_header(); check_link_ea_entry(); + check_hsm_user_item(); + check_hsm_user_request(); + check_hsm_user_state(); printf("}\n\n"); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 7da51fd..b330ab0 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -1358,14 +1358,14 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mdt_rec_create, cr_bias)); LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_bias) == 4, " found %lld\n", (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_bias)); - LASSERTF((int)offsetof(struct mdt_rec_create, cr_flags) == 120, " found %lld\n", - (long long)(int)offsetof(struct mdt_rec_create, cr_flags)); - LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_flags) == 4, " found %lld\n", - (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_flags)); - LASSERTF((int)offsetof(struct mdt_rec_create, cr_padding_2) == 124, " found %lld\n", - (long long)(int)offsetof(struct mdt_rec_create, cr_padding_2)); - LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_padding_2) == 4, " found %lld\n", - (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_padding_2)); + LASSERTF((int)offsetof(struct mdt_rec_create, cr_flags_l) == 120, " found %lld\n", + (long long)(int)offsetof(struct mdt_rec_create, cr_flags_l)); + LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_flags_l) == 4, " found %lld\n", + (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_flags_l)); + LASSERTF((int)offsetof(struct mdt_rec_create, cr_flags_h) == 124, " found %lld\n", + (long long)(int)offsetof(struct mdt_rec_create, cr_flags_h)); + LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_flags_h) == 4, " found %lld\n", + (long long)(int)sizeof(((struct mdt_rec_create *)0)->cr_flags_h)); LASSERTF((int)offsetof(struct mdt_rec_create, cr_padding_3) == 128, " found %lld\n", (long long)(int)offsetof(struct mdt_rec_create, cr_padding_3)); LASSERTF((int)sizeof(((struct mdt_rec_create *)0)->cr_padding_3) == 4, " found %lld\n",