*/
#ifndef __KERNEL__
+#include <stdio.h>
#include <libcfs/posix/posix-types.h>
#endif
#include <lustre/ll_fiemap.h>
#error Unsupported operating system.
#endif
+#define LUSTRE_EOF 0xffffffffffffffffULL
+
/* for statfs() */
#define LL_SUPER_MAGIC 0x0BD00BD0
__u32 f_ver;
};
+static inline bool fid_is_zero(const struct lu_fid *fid)
+{
+ return fid->f_seq == 0 && fid->f_oid == 0;
+}
+
+/* Currently, the filter_fid::ff_parent::f_ver is not the real parent
+ * MDT-object's FID::f_ver, instead it is the OST-object index in its
+ * parent MDT-object's layout EA. */
+#define f_stripe_idx f_ver
+
struct filter_fid {
struct lu_fid ff_parent; /* ff_parent.f_ver == file stripe number */
};
*/
struct ost_id {
union {
- struct ostid {
+ struct {
__u64 oi_id;
__u64 oi_seq;
} oi;
* *STRIPE* - set/get lov_user_md
* *INFO - set/get lov_user_mds_data
*/
-/* see <lustre_lib.h> for ioctl numberss 101-150 */
+/* lustre_ioctl.h 101-150 */
#define LL_IOC_GETFLAGS _IOR ('f', 151, long)
#define LL_IOC_SETFLAGS _IOW ('f', 152, long)
#define LL_IOC_CLRFLAGS _IOW ('f', 153, long)
-/* LL_IOC_LOV_SETSTRIPE: See also OBD_IOC_LOV_SETSTRIPE */
#define LL_IOC_LOV_SETSTRIPE _IOW ('f', 154, long)
-/* LL_IOC_LOV_GETSTRIPE: See also OBD_IOC_LOV_GETSTRIPE */
#define LL_IOC_LOV_GETSTRIPE _IOW ('f', 155, long)
-/* LL_IOC_LOV_SETEA: See also OBD_IOC_LOV_SETEA */
#define LL_IOC_LOV_SETEA _IOW ('f', 156, long)
#define LL_IOC_RECREATE_OBJ _IOW ('f', 157, long)
#define LL_IOC_RECREATE_FID _IOW ('f', 157, struct lu_fid)
#define LL_IOC_GROUP_LOCK _IOW ('f', 158, long)
#define LL_IOC_GROUP_UNLOCK _IOW ('f', 159, long)
-/* LL_IOC_QUOTACHECK: See also OBD_IOC_QUOTACHECK */
-#define LL_IOC_QUOTACHECK _IOW ('f', 160, int)
-/* LL_IOC_POLL_QUOTACHECK: See also OBD_IOC_POLL_QUOTACHECK */
-#define LL_IOC_POLL_QUOTACHECK _IOR ('f', 161, struct if_quotacheck *)
-/* LL_IOC_QUOTACTL: See also OBD_IOC_QUOTACTL */
-#define LL_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl)
+/* LL_IOC_QUOTACHECK 160 OBD_IOC_QUOTACHECK */
+/* LL_IOC_POLL_QUOTACHECK 161 OBD_IOC_POLL_QUOTACHECK */
+/* LL_IOC_QUOTACTL 162 OBD_IOC_QUOTACTL */
#define IOC_OBD_STATFS _IOWR('f', 164, struct obd_statfs *)
#define IOC_LOV_GETINFO _IOWR('f', 165, struct lov_user_mds_data *)
#define LL_IOC_FLUSHCTX _IOW ('f', 166, long)
#define LL_IOC_PATH2FID _IOR ('f', 173, long)
#define LL_IOC_GET_CONNECT_FLAGS _IOWR('f', 174, __u64 *)
#define LL_IOC_GET_MDTIDX _IOR ('f', 175, int)
-
-/* see <lustre_lib.h> for ioctl numbers 177-210 */
-
+/* lustre_ioctl.h 177-210 */
#define LL_IOC_HSM_STATE_GET _IOR('f', 211, struct hsm_user_state)
#define LL_IOC_HSM_STATE_SET _IOW('f', 212, struct hsm_state_set)
#define LL_IOC_HSM_CT_START _IOW('f', 213, struct lustre_kernelcomm)
struct lustre_swap_layouts)
#define LL_IOC_HSM_ACTION _IOR('f', 220, \
struct hsm_current_action)
-/* see <lustre_lib.h> for ioctl numbers 221-232 */
-
+/* lustre_ioctl.h 221-232 */
#define LL_IOC_LMV_SETSTRIPE _IOWR('f', 240, struct lmv_user_md)
#define LL_IOC_LMV_GETSTRIPE _IOWR('f', 241, struct lmv_user_md)
#define LL_IOC_REMOVE_ENTRY _IOWR('f', 242, __u64)
-
#define LL_IOC_SET_LEASE _IOWR('f', 243, long)
#define LL_IOC_GET_LEASE _IO('f', 244)
+#define LL_IOC_HSM_IMPORT _IOWR('f', 245, struct hsm_user_import)
+#define LL_IOC_LMV_SET_DEFAULT_STRIPE _IOWR('f', 246, struct lmv_user_md)
+#define LL_IOC_MIGRATE _IOR('f', 247, int)
#define LL_STATFS_LMV 1
#define LL_STATFS_LOV 2
#define IOC_MDC_GETFILEINFO _IOWR(IOC_MDC_TYPE, 22, struct lov_user_mds_data *)
#define LL_IOC_MDC_GETINFO _IOWR(IOC_MDC_TYPE, 23, struct lov_user_mds_data *)
-/* Keep these for backward compartability. */
-#define LL_IOC_OBD_STATFS IOC_OBD_STATFS
-#define IOC_MDC_GETSTRIPE IOC_MDC_GETFILESTRIPE
-
-
#define MAX_OBD_NAME 128 /* If this changes, a NEW ioctl must be added */
-/* Hopefully O_LOV_DELAY_CREATE does not conflict with standard O_xxx flags.
- * Previously it was defined as 0100000000 and conflicts with FMODE_NONOTIFY
- * which was added since kernel 2.6.36, so we redefine it as 020000000.
- * To be compatible with old version's statically linked binary, finally we
- * define it as (020000000 | 0100000000).
- * */
-#define O_LOV_DELAY_CREATE 0120000000
+/* Define O_LOV_DELAY_CREATE to be a mask that is not useful for regular
+ * files, but are unlikely to be used in practice and are not harmful if
+ * used incorrectly. O_NOCTTY and FASYNC are only meaningful for character
+ * devices and are safe for use on new files. See LU-4209. */
+/* To be compatible with old statically linked binary we keep the check for
+ * the older 0100000000 flag. This is already removed upstream. LU-812. */
+#define O_LOV_DELAY_CREATE_1_8 0100000000 /* FMODE_NONOTIFY masked in 2.6.36 */
+#define O_LOV_DELAY_CREATE_MASK (O_NOCTTY | FASYNC)
+#define O_LOV_DELAY_CREATE (O_LOV_DELAY_CREATE_1_8 | \
+ O_LOV_DELAY_CREATE_MASK)
#define LL_FILE_IGNORE_LOCK 0x00000001
#define LL_FILE_GROUP_LOCKED 0x00000002
#define LOV_USER_MAGIC_JOIN_V1 0x0BD20BD0
#define LOV_USER_MAGIC_V3 0x0BD30BD0
-#define LMV_MAGIC_V1 0x0CD10CD0 /*normal stripe lmv magic */
-#define LMV_USER_MAGIC 0x0CD20CD0 /*default lmv magic*/
+#define LMV_USER_MAGIC 0x0CD30CD0 /*default lmv magic*/
-#define LOV_PATTERN_RAID0 0x001
-#define LOV_PATTERN_RAID1 0x002
-#define LOV_PATTERN_FIRST 0x100
+#define LOV_PATTERN_RAID0 0x001
+#define LOV_PATTERN_RAID1 0x002
+#define LOV_PATTERN_FIRST 0x100
+#define LOV_PATTERN_CMOBD 0x200
+
+#define LOV_PATTERN_F_MASK 0xffff0000
+#define LOV_PATTERN_F_HOLE 0x40000000 /* there is hole in LOV EA */
+#define LOV_PATTERN_F_RELEASED 0x80000000 /* HSM released file */
#define LOV_MAXPOOLNAME 16
#define LOV_POOLNAMEF "%.16s"
#define LOV_ALL_STRIPES 0xffff /* only valid for directories */
#define LOV_V1_INSANE_STRIPE_COUNT 65532 /* maximum stripe count bz13933 */
+#define XATTR_LUSTRE_PREFIX "lustre."
+#define XATTR_LUSTRE_LOV XATTR_LUSTRE_PREFIX"lov"
+
#define lov_user_ost_data lov_user_ost_data_v1
struct lov_user_ost_data_v1 { /* per-stripe data structure */
struct ost_id l_ost_oi; /* OST object ID */
} __attribute__((packed));
#endif
-/* keep this to be the same size as lov_user_ost_data_v1 */
struct lmv_user_mds_data {
struct lu_fid lum_fid;
__u32 lum_padding;
__u32 lum_mds;
};
-/* lum_type */
-enum {
- LMV_STRIPE_TYPE = 0,
- LMV_DEFAULT_TYPE = 1,
+enum lmv_hash_type {
+ LMV_HASH_TYPE_UNKNOWN = 0, /* 0 is reserved for testing purpose */
+ LMV_HASH_TYPE_ALL_CHARS = 1,
+ LMV_HASH_TYPE_FNV_1A_64 = 2,
};
+#define LMV_HASH_NAME_ALL_CHARS "all_char"
+#define LMV_HASH_NAME_FNV_1A_64 "fnv_1a_64"
+
+/* Got this according to how get LOV_MAX_STRIPE_COUNT, see above,
+ * (max buffer size - lmv+rpc header) / sizeof(struct lmv_user_mds_data) */
+#define LMV_MAX_STRIPE_COUNT 2000 /* ((12 * 4096 - 256) / 24) */
#define lmv_user_md lmv_user_md_v1
struct lmv_user_md_v1 {
__u32 lum_magic; /* must be the first field */
__u32 lum_padding3;
char lum_pool_name[LOV_MAXPOOLNAME];
struct lmv_user_mds_data lum_objects[0];
-};
+} __attribute__((packed));
static inline int lmv_user_md_size(int stripes, int lmm_magic)
{
char uuid[UUID_MAX];
};
-static inline int obd_uuid_equals(const struct obd_uuid *u1,
- const struct obd_uuid *u2)
+static inline bool obd_uuid_equals(const struct obd_uuid *u1,
+ const struct obd_uuid *u2)
{
- return strcmp((char *)u1->uuid, (char *)u2->uuid) == 0;
+ return strcmp((char *)u1->uuid, (char *)u2->uuid) == 0;
}
static inline int obd_uuid_empty(struct obd_uuid *uuid)
}
/* For printf's only, make sure uuid is terminated */
-static inline char *obd_uuid2str(struct obd_uuid *uuid)
+static inline char *obd_uuid2str(const struct obd_uuid *uuid)
{
+ if (uuid == NULL)
+ return NULL;
+
if (uuid->uuid[sizeof(*uuid) - 1] != '\0') {
/* Obviously not safe, but for printfs, no real harm done...
we're always null-terminated, even in a race. */
strncpy(buf, uuid, buflen - 1);
buf[buflen - 1] = '\0';
p = strrchr(buf, '-');
- if (p)
- *p = '\0';
+ if (p != NULL)
+ *p = '\0';
}
/* printf display format
/********* Quotas **********/
+#define LUSTRE_QUOTABLOCK_BITS 10
+#define LUSTRE_QUOTABLOCK_SIZE (1 << LUSTRE_QUOTABLOCK_BITS)
+
+static inline __u64 lustre_stoqb(size_t space)
+{
+ return (space + LUSTRE_QUOTABLOCK_SIZE - 1) >> LUSTRE_QUOTABLOCK_BITS;
+}
+
+#define Q_QUOTACHECK 0x800100 /* deprecated as of 2.4 */
+#define Q_INITQUOTA 0x800101 /* deprecated as of 2.4 */
+#define Q_GETOINFO 0x800102 /* get obd quota info */
+#define Q_GETOQUOTA 0x800103 /* get obd quotas */
+#define Q_FINVALIDATE 0x800104 /* deprecated as of 2.4 */
+
/* these must be explicitly translated into linux Q_* in ll_dir_ioctl */
#define LUSTRE_Q_QUOTAON 0x800002 /* turn quotas on */
#define LUSTRE_Q_QUOTAOFF 0x800003 /* turn quotas off */
*/
#define LUSTRE_VOLATILE_HDR ".\x0c\x13\x14\x12:VOLATILE"
#define LUSTRE_VOLATILE_HDR_LEN 14
-/* hdr + MDT index */
-#define LUSTRE_VOLATILE_IDX LUSTRE_VOLATILE_HDR":%.4X:"
typedef enum lustre_quota_version {
LUSTRE_QUOTA_V2 = 1
};
/* swap layout flags */
-#define SWAP_LAYOUTS_CHECK_DV1 (1 << 0)
-#define SWAP_LAYOUTS_CHECK_DV2 (1 << 1)
-#define SWAP_LAYOUTS_KEEP_MTIME (1 << 2)
-#define SWAP_LAYOUTS_KEEP_ATIME (1 << 3)
+#define SWAP_LAYOUTS_CHECK_DV1 (1 << 0)
+#define SWAP_LAYOUTS_CHECK_DV2 (1 << 1)
+#define SWAP_LAYOUTS_KEEP_MTIME (1 << 2)
+#define SWAP_LAYOUTS_KEEP_ATIME (1 << 3)
+
+/* Swap XATTR_NAME_HSM as well, only on the MDT so far */
+#define SWAP_LAYOUTS_MDS_HSM (1 << 31)
struct lustre_swap_layouts {
__u64 sl_flags;
__u32 sl_fd;
#define CLF_UNLINK_HSM_EXISTS 0x0002 /* File has something in HSM */
/* HSM cleaning needed */
/* Flags for rename */
-#define CLF_RENAME_LAST 0x0001 /* rename unlink last hardlink of target */
+#define CLF_RENAME_LAST 0x0001 /* rename unlink last hardlink
+ * of target */
+#define CLF_RENAME_LAST_EXISTS 0x0002 /* rename unlink last hardlink of target
+ * has an archive in backend */
/* Flags for HSM */
/* 12b used (from high weight to low weight):
static inline enum hsm_event hsm_get_cl_event(__u16 flags)
{
- return CLF_GET_BITS(flags, CLF_HSM_EVENT_H, CLF_HSM_EVENT_L);
+ return (enum hsm_event)CLF_GET_BITS(flags, CLF_HSM_EVENT_H,
+ CLF_HSM_EVENT_L);
}
static inline void hsm_set_cl_event(int *flags, enum hsm_event he)
*flags |= (error << CLF_HSM_ERR_L);
}
-#define CR_MAXSIZE cfs_size_round(2*NAME_MAX + 1 + sizeof(struct changelog_rec))
+#define CR_MAXSIZE cfs_size_round(2*NAME_MAX + 1 + \
+ sizeof(struct changelog_ext_rec))
struct changelog_rec {
__u16 cr_namelen;
__u64 idv_version;
__u64 idv_flags; /* See LL_DV_xxx */
};
-#define LL_DV_NOFLUSH 0x01 /* Do not take READ EXTENT LOCK before sampling
- version. Dirty caches are left unchanged. */
+#define LL_DV_RD_FLUSH (1 << 0) /* Flush dirty pages from clients */
+#define LL_DV_WR_FLUSH (1 << 1) /* Flush all caching pages from clients */
#ifndef offsetof
-# define offsetof(typ,memb) ((unsigned long)((char *)&(((typ *)0)->memb)))
+#define offsetof(typ, memb) ((unsigned long)((char *)&(((typ *)0)->memb)))
#endif
#define dot_lustre_name ".lustre"
};
#define HPS_NONE 0
-static inline char *hsm_progress_state2name(enum hsm_progress_states s)
+static inline const char *hsm_progress_state2name(enum hsm_progress_states s)
{
switch (s) {
case HPS_WAITING: return "waiting";
HUA_CANCEL = 14 /* cancel a request */
};
-static inline char *hsm_user_action2name(enum hsm_user_action a)
+static inline const char *hsm_user_action2name(enum hsm_user_action a)
{
switch (a) {
case HUA_NONE: return "NOOP";
return &(hur->hur_user_item[hur->hur_request.hr_itemcount]);
}
-/** Compute the current length of the provided hsm_user_request. */
-static inline int hur_len(struct hsm_user_request *hur)
+/**
+ * Compute the current length of the provided hsm_user_request. This returns -1
+ * instead of an errno because ssize_t is defined to be only [ -1, SSIZE_MAX ]
+ *
+ * return -1 on bounds check error.
+ */
+static inline ssize_t hur_len(struct hsm_user_request *hur)
{
- return offsetof(struct hsm_user_request,
- hur_user_item[hur->hur_request.hr_itemcount]) +
- hur->hur_request.hr_data_len;
+ __u64 size;
+
+ /* can't overflow a __u64 since hr_itemcount is only __u32 */
+ size = offsetof(struct hsm_user_request, hur_user_item[0]) +
+ (__u64)hur->hur_request.hr_itemcount *
+ sizeof(hur->hur_user_item[0]) + hur->hur_request.hr_data_len;
+
+ if (size != (ssize_t)size)
+ return -1;
+
+ return size;
}
/****** HSM RPCs to copytool *****/
HSMA_CANCEL = 23
};
-static inline char *hsm_copytool_action2name(enum hsm_copytool_action a)
+static inline const char *hsm_copytool_action2name(enum hsm_copytool_action a)
{
switch (a) {
case HSMA_NONE: return "NOOP";
* \param len [IN] max buffer len
* \retval buffer
*/
-static inline char *hai_dump_data_field(struct hsm_action_item *hai,
+static inline char *hai_dump_data_field(const struct hsm_action_item *hai,
char *buffer, int len)
{
int i, sz, data_len;
#endif
/* Return pointer to first hai in action list */
-static inline struct hsm_action_item * hai_zero(struct hsm_action_list *hal)
+static inline struct hsm_action_item *hai_first(struct hsm_action_list *hal)
{
- return (struct hsm_action_item *)(hal->hal_fsname +
- cfs_size_round(strlen(hal-> \
- hal_fsname)));
+ return (struct hsm_action_item *)(hal->hal_fsname +
+ cfs_size_round(strlen(hal-> \
+ hal_fsname)
+ + 1));
}
/* Return pointer to next hai */
static inline struct hsm_action_item * hai_next(struct hsm_action_item *hai)
}
/* Return size of an hsm_action_list */
-static inline int hal_size(struct hsm_action_list *hal)
+static inline size_t hal_size(struct hsm_action_list *hal)
{
- int i, sz;
+ __u32 i;
+ size_t sz;
struct hsm_action_item *hai;
- sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname));
- hai = hai_zero(hal);
- for (i = 0 ; i < hal->hal_count ; i++, hai = hai_next(hai))
+ sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname) + 1);
+ hai = hai_first(hal);
+ for (i = 0; i < hal->hal_count ; i++, hai = hai_next(hai))
sz += cfs_size_round(hai->hai_len);
return sz;
}
+/* HSM file import
+ * describe the attributes to be set on imported file
+ */
+struct hsm_user_import {
+ __u64 hui_size;
+ __u64 hui_atime;
+ __u64 hui_mtime;
+ __u32 hui_atime_ns;
+ __u32 hui_mtime_ns;
+ __u32 hui_uid;
+ __u32 hui_gid;
+ __u32 hui_mode;
+ __u32 hui_archive_id;
+};
+
/* Copytool progress reporting */
#define HP_FLAG_COMPLETED 0x01
#define HP_FLAG_RETRY 0x02
__u32 padding;
};
-/**
- * Use by copytool during any hsm request they handled.
- * This structure is initialized by llapi_hsm_copy_start()
- * which is an helper over the ioctl() interface
- * Store Lustre, internal use only, data.
- */
struct hsm_copy {
__u64 hc_data_version;
__u16 hc_flags;
struct hsm_action_item hc_hai;
};
+/* JSON objects */
+enum llapi_json_types {
+ LLAPI_JSON_INTEGER = 1,
+ LLAPI_JSON_BIGNUM,
+ LLAPI_JSON_REAL,
+ LLAPI_JSON_STRING
+};
+
+struct llapi_json_item {
+ char *lji_key;
+ __u32 lji_type;
+ union {
+ int lji_integer;
+ __u64 lji_u64;
+ double lji_real;
+ char *lji_string;
+ };
+ struct llapi_json_item *lji_next;
+};
+
+struct llapi_json_item_list {
+ int ljil_item_count;
+ struct llapi_json_item *ljil_items;
+};
+
/** @} lustreuser */
#endif /* _LUSTRE_USER_H */