*/
/*
* This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
*
* lustre/include/lustre/lustre_user.h
*
* @{
*/
+#include <linux/fs.h>
+#include <linux/limits.h>
#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/quota.h>
#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/lustre/lustre_fiemap.h>
+#include <linux/lustre/lustre_ver.h>
-#ifdef __KERNEL__
-# include <linux/fs.h>
-# include <linux/quota.h>
-# include <linux/string.h> /* snprintf() */
-# include <linux/version.h>
-# include <uapi/linux/lustre/lustre_fiemap.h>
-#else /* !__KERNEL__ */
-# include <limits.h>
+#ifndef __KERNEL__
+# define __USE_ISOC99 1
# include <stdbool.h>
# include <stdio.h> /* snprintf() */
-# include <stdint.h>
-# include <string.h>
-# define NEED_QUOTA_DEFS
-/* # include <sys/quota.h> - this causes complaints about caddr_t */
# include <sys/stat.h>
-# include <linux/lustre/lustre_fiemap.h>
-#endif /* __KERNEL__ */
-
-/* Handle older distros */
-#ifndef __ALIGN_KERNEL
-# define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
-# define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
-#endif
+# define FILEID_LUSTRE 0x97 /* for name_to_handle_at() (and llapi_fd2fid()) */
+#endif /* !__KERNEL__ */
#if defined(__cplusplus)
extern "C" {
#endif
+#ifdef __STRICT_ANSI__
+#define typeof __typeof__
+#endif
+
/*
* This is a temporary solution of adding quota type.
* Should be removed as soon as system header is updated.
#define fstatat_f fstatat
#endif
-#define HAVE_LOV_USER_MDS_DATA
+#ifndef STATX_BASIC_STATS
+/*
+ * Timestamp structure for the timestamps in struct statx.
+ *
+ * tv_sec holds the number of seconds before (negative) or after (positive)
+ * 00:00:00 1st January 1970 UTC.
+ *
+ * tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time.
+ *
+ * __reserved is held in case we need a yet finer resolution.
+ */
+struct statx_timestamp {
+ __s64 tv_sec;
+ __u32 tv_nsec;
+ __s32 __reserved;
+};
+
+/*
+ * Structures for the extended file attribute retrieval system call
+ * (statx()).
+ *
+ * The caller passes a mask of what they're specifically interested in as a
+ * parameter to statx(). What statx() actually got will be indicated in
+ * st_mask upon return.
+ *
+ * For each bit in the mask argument:
+ *
+ * - if the datum is not supported:
+ *
+ * - the bit will be cleared, and
+ *
+ * - the datum will be set to an appropriate fabricated value if one is
+ * available (eg. CIFS can take a default uid and gid), otherwise
+ *
+ * - the field will be cleared;
+ *
+ * - otherwise, if explicitly requested:
+ *
+ * - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is
+ * set or if the datum is considered out of date, and
+ *
+ * - the field will be filled in and the bit will be set;
+ *
+ * - otherwise, if not requested, but available in approximate form without any
+ * effort, it will be filled in anyway, and the bit will be set upon return
+ * (it might not be up to date, however, and no attempt will be made to
+ * synchronise the internal state first);
+ *
+ * - otherwise the field and the bit will be cleared before returning.
+ *
+ * Items in STATX_BASIC_STATS may be marked unavailable on return, but they
+ * will have values installed for compatibility purposes so that stat() and
+ * co. can be emulated in userspace.
+ */
+struct statx {
+ /* 0x00 */
+ __u32 stx_mask; /* What results were written [uncond] */
+ __u32 stx_blksize; /* Preferred general I/O size [uncond] */
+ __u64 stx_attributes; /* Flags conveying information about the file [uncond] */
+ /* 0x10 */
+ __u32 stx_nlink; /* Number of hard links */
+ __u32 stx_uid; /* User ID of owner */
+ __u32 stx_gid; /* Group ID of owner */
+ __u16 stx_mode; /* File mode */
+ __u16 __spare0[1];
+ /* 0x20 */
+ __u64 stx_ino; /* Inode number */
+ __u64 stx_size; /* File size */
+ __u64 stx_blocks; /* Number of 512-byte blocks allocated */
+ __u64 stx_attributes_mask; /* Mask to show what's supported in stx_attributes */
+ /* 0x40 */
+ struct statx_timestamp stx_atime; /* Last access time */
+ struct statx_timestamp stx_btime; /* File creation time */
+ struct statx_timestamp stx_ctime; /* Last attribute change time */
+ struct statx_timestamp stx_mtime; /* Last data modification time */
+ /* 0x80 */
+ __u32 stx_rdev_major; /* Device ID of special file [if bdev/cdev] */
+ __u32 stx_rdev_minor;
+ __u32 stx_dev_major; /* ID of device containing file [uncond] */
+ __u32 stx_dev_minor;
+ /* 0x90 */
+ __u64 __spare2[14]; /* Spare space for future expansion */
+ /* 0x100 */
+};
+
+/*
+ * Flags to be stx_mask
+ *
+ * Query request/result mask for statx() and struct statx::stx_mask.
+ *
+ * These bits should be set in the mask argument of statx() to request
+ * particular items when calling statx().
+ */
+#define STATX_TYPE 0x00000001U /* Want/got stx_mode & S_IFMT */
+#define STATX_MODE 0x00000002U /* Want/got stx_mode & ~S_IFMT */
+#define STATX_NLINK 0x00000004U /* Want/got stx_nlink */
+#define STATX_UID 0x00000008U /* Want/got stx_uid */
+#define STATX_GID 0x00000010U /* Want/got stx_gid */
+#define STATX_ATIME 0x00000020U /* Want/got stx_atime */
+#define STATX_MTIME 0x00000040U /* Want/got stx_mtime */
+#define STATX_CTIME 0x00000080U /* Want/got stx_ctime */
+#define STATX_INO 0x00000100U /* Want/got stx_ino */
+#define STATX_SIZE 0x00000200U /* Want/got stx_size */
+#define STATX_BLOCKS 0x00000400U /* Want/got stx_blocks */
+#define STATX_BASIC_STATS 0x000007ffU /* The stuff in the normal stat struct */
+#define STATX_BTIME 0x00000800U /* Want/got stx_btime */
+#define STATX_ALL 0x00000fffU /* All currently supported flags */
+#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */
+
+/*
+ * Attributes to be found in stx_attributes and masked in stx_attributes_mask.
+ *
+ * These give information about the features or the state of a file that might
+ * be of use to ordinary userspace programs such as GUIs or ls rather than
+ * specialised tools.
+ *
+ * Note that the flags marked [I] correspond to generic FS_IOC_FLAGS
+ * semantically. Where possible, the numerical value is picked to correspond
+ * also.
+ */
+#define STATX_ATTR_COMPRESSED 0x00000004 /* [I] File is compressed by the fs */
+#define STATX_ATTR_IMMUTABLE 0x00000010 /* [I] File is marked immutable */
+#define STATX_ATTR_APPEND 0x00000020 /* [I] File is append-only */
+#define STATX_ATTR_NODUMP 0x00000040 /* [I] File is not to be dumped */
+#define STATX_ATTR_ENCRYPTED 0x00000800 /* [I] File requires key to decrypt in fs */
+
+#define STATX_ATTR_AUTOMOUNT 0x00001000 /* Dir: Automount trigger */
+
+#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from statx() */
+#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */
+#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd with the server */
+#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the server */
+
+#endif /* STATX_BASIC_STATS */
+
+typedef struct statx lstatx_t;
#define LUSTRE_EOF 0xffffffffffffffffULL
#define LUSTRE_FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_DEVICE_ORDER)
enum obd_statfs_state {
- OS_STATE_DEGRADED = 0x00000001, /**< RAID degraded/rebuilding */
- OS_STATE_READONLY = 0x00000002, /**< filesystem is read-only */
- OS_STATE_NOPRECREATE = 0x00000004, /**< no object precreation */
- OS_STATE_ENOSPC = 0x00000020, /**< not enough free space */
- OS_STATE_ENOINO = 0x00000040, /**< not enough inodes */
- OS_STATE_SUM = 0x00000100, /**< aggregated for all tagrets */
- OS_STATE_NONROT = 0x00000200, /**< non-rotational device */
+ OS_STATFS_DEGRADED = 0x00000001, /**< RAID degraded/rebuilding */
+ OS_STATFS_READONLY = 0x00000002, /**< filesystem is read-only */
+ OS_STATFS_NOPRECREATE = 0x00000004, /**< no object precreation */
+ OS_STATFS_UNUSED1 = 0x00000008, /**< obsolete 1.6, was EROFS=30 */
+ OS_STATFS_UNUSED2 = 0x00000010, /**< obsolete 1.6, was EROFS=30 */
+ OS_STATFS_ENOSPC = 0x00000020, /**< not enough free space */
+ OS_STATFS_ENOINO = 0x00000040, /**< not enough inodes */
+ OS_STATFS_SUM = 0x00000100, /**< aggregated for all tagrets */
+ OS_STATFS_NONROT = 0x00000200, /**< non-rotational device */
};
/** filesystem statistics/attributes for target device */
__u32 os_bsize; /* block size in bytes for os_blocks */
__u32 os_namelen; /* maximum length of filename in bytes*/
__u64 os_maxbytes; /* maximum object size in bytes */
- __u32 os_state; /**< obd_statfs_state OS_STATE_* flag */
+ __u32 os_state; /**< obd_statfs_state OS_STATFS_* */
__u32 os_fprecreated; /* objs available now to the caller */
/* used in QoS code to find preferred
* OSTs */
* used.
**/
__u32 f_ver;
-};
+} __attribute__((packed));
static inline bool fid_is_zero(const struct lu_fid *fid)
{
return fid->f_seq == 0 && fid->f_oid == 0;
}
+/* The data name_to_handle_at() places in a struct file_handle (at f_handle) */
+struct lustre_file_handle {
+ struct lu_fid lfh_child;
+ struct lu_fid lfh_parent;
+};
+
/* 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. */
is on the remote MDT */
LMAI_STRIPED = 0x00000008, /* striped directory inode */
LMAI_ORPHAN = 0x00000010, /* inode is orphan */
+ LMAI_ENCRYPT = 0x00000020, /* inode is encrypted */
LMA_INCOMPAT_SUPP = (LMAI_AGENT | LMAI_REMOTE_PARENT | \
- LMAI_STRIPED | LMAI_ORPHAN)
+ LMAI_STRIPED | LMAI_ORPHAN | LMAI_ENCRYPT)
};
} oi;
struct lu_fid oi_fid;
};
-};
+} __attribute__((packed));
#define DOSTID "%#llx:%llu"
#define POSTID(oi) ((unsigned long long)ostid_seq(oi)), \
* *INFO - set/get lov_user_mds_data
*/
/* lustre_ioctl.h 101-150 */
+/* ioctl codes 128-143 are reserved for fsverity */
#define LL_IOC_GETFLAGS _IOR ('f', 151, long)
#define LL_IOC_SETFLAGS _IOW ('f', 152, long)
#define LL_IOC_CLRFLAGS _IOW ('f', 153, long)
#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_RMFID _IOR('f', 242, struct fid_array)
+#define LL_IOC_UNLOCK_FOREIGN _IO('f', 242)
#define LL_IOC_SET_LEASE _IOWR('f', 243, struct ll_ioc_lease)
#define LL_IOC_SET_LEASE_OLD _IOWR('f', 243, long)
#define LL_IOC_GET_LEASE _IO('f', 244)
#define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
#define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
#endif
-#define LL_IOC_FSGETXATTR FS_IOC_FSGETXATTR
-#define LL_IOC_FSSETXATTR FS_IOC_FSSETXATTR
#ifndef FS_XFLAG_PROJINHERIT
#define FS_XFLAG_PROJINHERIT 0x00000200
#endif
#define LL_STATFS_LOV 2
#define LL_STATFS_NODELAY 4
-#define IOC_MDC_TYPE 'i'
-#define IOC_MDC_LOOKUP _IOWR(IOC_MDC_TYPE, 20, struct obd_device *)
-#define IOC_MDC_GETFILESTRIPE _IOWR(IOC_MDC_TYPE, 21, struct lov_user_md *)
-#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 *)
+#define IOC_MDC_TYPE 'i'
+#define IOC_MDC_LOOKUP _IOWR(IOC_MDC_TYPE, 20, struct obd_device *)
+#define IOC_MDC_GETFILESTRIPE _IOWR(IOC_MDC_TYPE, 21, struct lov_user_md *)
+#define IOC_MDC_GETFILEINFO_V1 _IOWR(IOC_MDC_TYPE, 22, struct lov_user_mds_data_v1 *)
+#define IOC_MDC_GETFILEINFO_V2 _IOWR(IOC_MDC_TYPE, 22, struct lov_user_mds_data)
+#define LL_IOC_MDC_GETINFO_V1 _IOWR(IOC_MDC_TYPE, 23, struct lov_user_mds_data_v1 *)
+#define LL_IOC_MDC_GETINFO_V2 _IOWR(IOC_MDC_TYPE, 23, struct lov_user_mds_data)
+#define IOC_MDC_GETFILEINFO IOC_MDC_GETFILEINFO_V1
+#define LL_IOC_MDC_GETINFO LL_IOC_MDC_GETINFO_V1
#define MAX_OBD_NAME 128 /* If this changes, a NEW ioctl must be added */
#define LL_FILE_GROUP_LOCKED 0x00000002
#define LL_FILE_READAHEA 0x00000004
#define LL_FILE_LOCKED_DIRECTIO 0x00000008 /* client-side locks with dio */
-#define LL_FILE_LOCKLESS_IO 0x00000010 /* server-side locks with cio */
#define LL_FILE_FLOCK_WARNING 0x00000020 /* warned about disabled flock */
#define LOV_USER_MAGIC_V1 0x0BD10BD0
#define LOV_USER_MAGIC_SPECIFIC 0x0BD50BD0 /* for specific OSTs */
#define LOV_USER_MAGIC_COMP_V1 0x0BD60BD0
#define LOV_USER_MAGIC_FOREIGN 0x0BD70BD0
+#define LOV_USER_MAGIC_SEL 0x0BD80BD0
#define LMV_USER_MAGIC 0x0CD30CD0 /* default lmv magic */
#define LMV_USER_MAGIC_V0 0x0CD20CD0 /* old default lmv magic*/
#define LOV_PATTERN_RAID1 0x002
#define LOV_PATTERN_MDT 0x100
#define LOV_PATTERN_OVERSTRIPING 0x200
+#define LOV_PATTERN_FOREIGN 0x400
#define LOV_PATTERN_F_MASK 0xffff0000
#define LOV_PATTERN_F_HOLE 0x40000000 /* there is hole in LOV EA */
#define LOV_PATTERN_DEFAULT 0xffffffff
#define LOV_OFFSET_DEFAULT ((__u16)-1)
+#define LMV_OFFSET_DEFAULT ((__u32)-1)
static inline bool lov_pattern_supported(__u32 pattern)
{
#define XATTR_LUSTRE_PREFIX "lustre."
#define XATTR_LUSTRE_LOV XATTR_LUSTRE_PREFIX"lov"
+/* Please update if XATTR_LUSTRE_LOV".set" groks more flags in the future */
+#define allowed_lustre_lov(att) (strcmp((att), XATTR_LUSTRE_LOV".add") == 0 || \
+ strcmp((att), XATTR_LUSTRE_LOV".set") == 0 || \
+ strcmp((att), XATTR_LUSTRE_LOV".set.flags") == 0 || \
+ strcmp((att), XATTR_LUSTRE_LOV".del") == 0)
+
#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 */
* used when reading */
};
struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
-} __attribute__((packed, __may_alias__));
+} __attribute__((packed, __may_alias__));
struct lov_user_md_v3 { /* LOV EA user data (host-endian) */
__u32 lmm_magic; /* magic number = LOV_USER_MAGIC_V3 */
};
char lmm_pool_name[LOV_MAXPOOLNAME + 1]; /* pool name */
struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
-} __attribute__((packed));
+} __attribute__((packed, __may_alias__));
struct lov_foreign_md {
__u32 lfm_magic; /* magic number = LOV_MAGIC_FOREIGN */
__u32 lfm_type; /* type, see LU_FOREIGN_TYPE_ */
__u32 lfm_flags; /* flags, type specific */
char lfm_value[];
-};
+} __attribute__((packed));
#define foreign_size(lfm) (((struct lov_foreign_md *)lfm)->lfm_length + \
offsetof(struct lov_foreign_md, lfm_value))
struct lu_extent {
__u64 e_start;
__u64 e_end;
-};
+} __attribute__((packed));
#define DEXT "[%#llx, %#llx)"
-#define PEXT(ext) (ext)->e_start, (ext)->e_end
+#define PEXT(ext) (unsigned long long)(ext)->e_start, (unsigned long long)(ext)->e_end
static inline bool lu_extent_is_overlapped(struct lu_extent *e1,
struct lu_extent *e2)
LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
LCME_FL_EXTENSION)
+/* The component flags can be set by users at creation/modification time. */
+#define LCME_USER_COMP_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
+ LCME_FL_EXTENSION)
+
/* The mirror flags can be set by users at creation time. */
#define LCME_USER_MIRROR_FLAGS (LCME_FL_PREF_RW)
/* Compile with -D_LARGEFILE64_SOURCE or -D_GNU_SOURCE (or #define) to
* use this. It is unsafe to #define those values in this header as it
* is possible the application has already #included <sys/stat.h>. */
-#ifdef HAVE_LOV_USER_MDS_DATA
-#define lov_user_mds_data lov_user_mds_data_v1
+#define lov_user_mds_data lov_user_mds_data_v2
struct lov_user_mds_data_v1 {
lstat_t lmd_st; /* MDS stat struct */
struct lov_user_md_v1 lmd_lmm; /* LOV EA V1 user data */
} __attribute__((packed));
-#endif
+
+struct lov_user_mds_data_v2 {
+ struct lu_fid lmd_fid; /* Lustre FID */
+ lstatx_t lmd_stx; /* MDS statx struct */
+ __u64 lmd_flags; /* MDS stat flags */
+ __u32 lmd_lmmsize; /* LOV EA size */
+ __u32 lmd_padding; /* unused */
+ struct lov_user_md_v1 lmd_lmm; /* LOV EA user data */
+} __attribute__((packed));
struct lmv_user_mds_data {
struct lu_fid lum_fid;
__u32 lum_padding;
__u32 lum_mds;
-};
+} __attribute__((packed, __may_alias__));
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,
+ LMV_HASH_TYPE_CRUSH = 3,
LMV_HASH_TYPE_MAX,
};
-#define LMV_HASH_TYPE_DEFAULT LMV_HASH_TYPE_FNV_1A_64
-
-#define LMV_HASH_NAME_ALL_CHARS "all_char"
-#define LMV_HASH_NAME_FNV_1A_64 "fnv_1a_64"
+static __attribute__((unused)) const char *mdt_hash_name[] = {
+ "none",
+ "all_char",
+ "fnv_1a_64",
+ "crush",
+};
-/* not real hash type, but exposed to user as "space" hash type */
-#define LMV_HASH_NAME_SPACE "space"
+#define LMV_HASH_TYPE_DEFAULT LMV_HASH_TYPE_CRUSH
/* Right now only the lower part(0-16bits) of lmv_hash_type is being used,
* and the higher part will be the flag to indicate the status of object,
* might be interpreted differently with different flags. */
#define LMV_HASH_TYPE_MASK 0x0000ffff
-/* once this is set on a plain directory default layout, newly created
- * subdirectories will be distributed on all MDTs by space usage.
- */
-#define LMV_HASH_FLAG_SPACE 0x08000000
+static inline bool lmv_is_known_hash_type(__u32 type)
+{
+ return (type & LMV_HASH_TYPE_MASK) == LMV_HASH_TYPE_FNV_1A_64 ||
+ (type & LMV_HASH_TYPE_MASK) == LMV_HASH_TYPE_ALL_CHARS ||
+ (type & LMV_HASH_TYPE_MASK) == LMV_HASH_TYPE_CRUSH;
+}
+
+#define LMV_HASH_FLAG_MERGE 0x04000000
+#define LMV_HASH_FLAG_SPLIT 0x08000000
/* The striped directory has ever lost its master LMV EA, then LFSCK
* re-generated it. This flag is used to indicate such case. It is an
* on-disk flag. */
-#define LMV_HASH_FLAG_LOST_LMV 0x10000000
+#define LMV_HASH_FLAG_LOST_LMV 0x10000000
+
+#define LMV_HASH_FLAG_BAD_TYPE 0x20000000
+#define LMV_HASH_FLAG_MIGRATION 0x80000000
+
+#define LMV_HASH_FLAG_LAYOUT_CHANGE \
+ (LMV_HASH_FLAG_MIGRATION | LMV_HASH_FLAG_SPLIT | LMV_HASH_FLAG_MERGE)
+
+/* both SPLIT and MIGRATION are set for directory split */
+static inline bool lmv_hash_is_splitting(__u32 hash)
+{
+ return (hash & LMV_HASH_FLAG_LAYOUT_CHANGE) ==
+ (LMV_HASH_FLAG_SPLIT | LMV_HASH_FLAG_MIGRATION);
+}
-#define LMV_HASH_FLAG_BAD_TYPE 0x20000000
-#define LMV_HASH_FLAG_MIGRATION 0x80000000
+/* both MERGE and MIGRATION are set for directory merge */
+static inline bool lmv_hash_is_merging(__u32 hash)
+{
+ return (hash & LMV_HASH_FLAG_LAYOUT_CHANGE) ==
+ (LMV_HASH_FLAG_MERGE | LMV_HASH_FLAG_MIGRATION);
+}
+
+/* only MIGRATION is set for directory migration */
+static inline bool lmv_hash_is_migrating(__u32 hash)
+{
+ return (hash & LMV_HASH_FLAG_LAYOUT_CHANGE) == LMV_HASH_FLAG_MIGRATION;
+}
-extern char *mdt_hash_name[LMV_HASH_TYPE_MAX];
+static inline bool lmv_hash_is_restriping(__u32 hash)
+{
+ return lmv_hash_is_splitting(hash) || lmv_hash_is_merging(hash);
+}
+
+static inline bool lmv_hash_is_layout_changing(__u32 hash)
+{
+ return lmv_hash_is_splitting(hash) || lmv_hash_is_merging(hash) ||
+ lmv_hash_is_migrating(hash);
+}
struct lustre_foreign_type {
- uint32_t lft_type;
- const char *lft_name;
+ __u32 lft_type;
+ const char *lft_name;
};
/**
**/
enum lustre_foreign_types {
LU_FOREIGN_TYPE_NONE = 0,
- LU_FOREIGN_TYPE_DAOS = 0xda05,
+ LU_FOREIGN_TYPE_SYMLINK = 0xda05,
/* must be the max/last one */
LU_FOREIGN_TYPE_UNKNOWN = 0xffffffff,
};
#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_magic; /* must be the first field */
__u32 lum_stripe_count; /* dirstripe count */
__u32 lum_stripe_offset; /* MDT idx for default dirstripe */
__u32 lum_hash_type; /* Dir stripe policy */
- __u32 lum_type; /* LMV type: default */
- __u32 lum_padding1;
+ __u32 lum_type; /* LMV type: default */
+ __u8 lum_max_inherit; /* inherit depth of default LMV */
+ __u8 lum_max_inherit_rr; /* inherit depth of default LMV to round-robin mkdir */
+ __u16 lum_padding1;
__u32 lum_padding2;
__u32 lum_padding3;
char lum_pool_name[LOV_MAXPOOLNAME + 1];
LMV_TYPE_DEFAULT = 0x0000,
};
+/* lum_max_inherit will be decreased by 1 after each inheritance if it's not
+ * LMV_INHERIT_UNLIMITED or > LMV_INHERIT_MAX.
+ */
+enum {
+ /* for historical reason, 0 means unlimited inheritance */
+ LMV_INHERIT_UNLIMITED = 0,
+ /* unlimited lum_max_inherit by default */
+ LMV_INHERIT_DEFAULT = 0,
+ /* not inherit any more */
+ LMV_INHERIT_END = 1,
+ /* max inherit depth */
+ LMV_INHERIT_MAX = 250,
+ /* [251, 254] are reserved */
+ /* not set, or when inherit depth goes beyond end, */
+ LMV_INHERIT_NONE = 255,
+};
+
+enum {
+ /* not set, or when inherit_rr depth goes beyond end, */
+ LMV_INHERIT_RR_NONE = 0,
+ /* disable lum_max_inherit_rr by default */
+ LMV_INHERIT_RR_DEFAULT = 0,
+ /* not inherit any more */
+ LMV_INHERIT_RR_END = 1,
+ /* max inherit depth */
+ LMV_INHERIT_RR_MAX = 250,
+ /* [251, 254] are reserved */
+ /* unlimited inheritance */
+ LMV_INHERIT_RR_UNLIMITED = 255,
+};
+
static inline int lmv_user_md_size(int stripes, int lmm_magic)
{
int size = sizeof(struct lmv_user_md);
}
#define LUSTRE_MAXFSNAME 8
+#define LUSTRE_MAXINSTANCE 16
/* Extract fsname from uuid (or target name) of a target
e.g. (myfs-OST0007_UUID -> myfs)
#define FID_NOBRACE_LEN 40
#define FID_LEN (FID_NOBRACE_LEN + 2)
#define DFID_NOBRACE "%#llx:0x%x:0x%x"
-#define DFID "["DFID_NOBRACE"]"
+#define DFID "[" DFID_NOBRACE "]"
#define PFID(fid) (unsigned long long)(fid)->f_seq, (fid)->f_oid, (fid)->f_ver
/* scanf input parse format for fids in DFID_NOBRACE format
* Need to strip '[' from DFID format first or use "["SFID"]" at caller.
* usage: sscanf(fidstr, SFID, RFID(&fid)); */
#define SFID "0x%llx:0x%x:0x%x"
-#define RFID(fid) &((fid)->f_seq), &((fid)->f_oid), &((fid)->f_ver)
+#define RFID(fid) (unsigned long long *)&((fid)->f_seq), &((fid)->f_oid), &((fid)->f_ver)
/********* Quotas **********/
#define LUSTRE_QUOTABLOCK_BITS 10
#define LUSTRE_QUOTABLOCK_SIZE (1 << LUSTRE_QUOTABLOCK_BITS)
-static inline __u64 lustre_stoqb(size_t space)
+static inline __u64 lustre_stoqb(__kernel_size_t space)
{
return (space + LUSTRE_QUOTABLOCK_SIZE - 1) >> LUSTRE_QUOTABLOCK_BITS;
}
#define LUSTRE_Q_FINVALIDATE 0x80000c /* deprecated as of 2.4 */
#define LUSTRE_Q_GETDEFAULT 0x80000d /* get default quota */
#define LUSTRE_Q_SETDEFAULT 0x80000e /* set default quota */
-
+#define LUSTRE_Q_GETQUOTAPOOL 0x80000f /* get user pool quota */
+#define LUSTRE_Q_SETQUOTAPOOL 0x800010 /* set user pool quota */
+#define LUSTRE_Q_GETINFOPOOL 0x800011 /* get pool quota info */
+#define LUSTRE_Q_SETINFOPOOL 0x800012 /* set pool quota info */
+#define LUSTRE_Q_GETDEFAULT_POOL 0x800013 /* get default pool quota*/
+#define LUSTRE_Q_SETDEFAULT_POOL 0x800014 /* set default pool quota */
/* In the current Lustre implementation, the grace time is either the time
* or the timestamp to be used after some quota ID exceeds the soft limt,
* 48 bits should be enough, its high 16 bits can be used as quota flags.
#define LQUOTA_FLAG(t) (t >> LQUOTA_GRACE_BITS)
#define LQUOTA_GRACE_FLAG(t, f) ((__u64)t | (__u64)f << LQUOTA_GRACE_BITS)
+/* special grace time, only notify the user when its quota is over soft limit
+ * but doesn't block new writes until the hard limit is reached. */
+#define NOTIFY_GRACE "notify"
+#define NOTIFY_GRACE_TIME LQUOTA_GRACE_MASK
+
/* different quota flags */
/* the default quota flag, the corresponding quota ID will use the default
* */
#define LQUOTA_FLAG_DEFAULT 0x0001
+#define LUSTRE_Q_CMD_IS_POOL(cmd) \
+ (cmd == LUSTRE_Q_GETQUOTAPOOL || \
+ cmd == LUSTRE_Q_SETQUOTAPOOL || \
+ cmd == LUSTRE_Q_SETINFOPOOL || \
+ cmd == LUSTRE_Q_GETINFOPOOL || \
+ cmd == LUSTRE_Q_SETDEFAULT_POOL || \
+ cmd == LUSTRE_Q_GETDEFAULT_POOL)
+
#define ALLQUOTA 255 /* set all quota */
-static inline char *qtype_name(int qtype)
+static inline const char *qtype_name(int qtype)
{
switch (qtype) {
case USRQUOTA:
}
#define IDENTITY_DOWNCALL_MAGIC 0x6d6dd629
-#define SEPOL_DOWNCALL_MAGIC 0x8b8bb842
/* permission */
#define N_PERMS_MAX 64
__u32 idd_groups[0];
};
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
+/* old interface struct is deprecated in 2.14 */
+#define SEPOL_DOWNCALL_MAGIC_OLD 0x8b8bb842
+struct sepol_downcall_data_old {
+ __u32 sdd_magic;
+ __s64 sdd_sepol_mtime;
+ __u16 sdd_sepol_len;
+ char sdd_sepol[0];
+};
+#endif
+
+#define SEPOL_DOWNCALL_MAGIC 0x8b8bb843
struct sepol_downcall_data {
- __u32 sdd_magic;
- time_t sdd_sepol_mtime;
- __u16 sdd_sepol_len;
- char sdd_sepol[0];
+ __u32 sdd_magic;
+ __u16 sdd_sepol_len;
+ __u16 sdd_padding1;
+ __s64 sdd_sepol_mtime;
+ char sdd_sepol[0];
};
#ifdef NEED_QUOTA_DEFS
/* XXX: same as if_dqblk struct in kernel, plus one padding */
struct obd_dqblk {
- __u64 dqb_bhardlimit;
- __u64 dqb_bsoftlimit;
- __u64 dqb_curspace;
+ __u64 dqb_bhardlimit; /* kbytes unit */
+ __u64 dqb_bsoftlimit; /* kbytes unit */
+ __u64 dqb_curspace; /* bytes unit */
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
struct obd_dqblk qc_dqblk;
char obd_type[16];
struct obd_uuid obd_uuid;
+ char qc_poolname[0];
};
/* swap layout flags */
LA_LAYOUT_VERSION = 1 << 16, /* 0x10000 */
LA_LSIZE = 1 << 17, /* 0x20000 */
LA_LBLOCKS = 1 << 18, /* 0x40000 */
+ LA_BTIME = 1 << 19, /* 0x80000 */
/**
* Attributes must be transmitted to OST objects
*/
};
static inline const char *changelog_type2str(int type) {
- static const char *changelog_str[] = {
+ static const char *const changelog_str[] = {
"MARK", "CREAT", "MKDIR", "HLINK", "SLINK", "MKNOD", "UNLNK",
"RMDIR", "RENME", "RNMTO", "OPEN", "CLOSE", "LYOUT", "TRUNC",
"SATTR", "XATTR", "HSM", "MTIME", "CTIME", "ATIME", "MIGRT",
static inline void hsm_set_cl_event(enum changelog_rec_flags *clf_flags,
enum hsm_event he)
{
- *clf_flags |= (he << CLF_HSM_EVENT_L);
+ *clf_flags = (enum changelog_rec_flags)
+ (*clf_flags | (he << CLF_HSM_EVENT_L));
}
static inline __u16 hsm_get_cl_flags(enum changelog_rec_flags clf_flags)
static inline void hsm_set_cl_flags(enum changelog_rec_flags *clf_flags,
unsigned int bits)
{
- *clf_flags |= (bits << CLF_HSM_FLAG_L);
+ *clf_flags = (enum changelog_rec_flags)
+ (*clf_flags | (bits << CLF_HSM_FLAG_L));
}
static inline int hsm_get_cl_error(enum changelog_rec_flags clf_flags)
static inline void hsm_set_cl_error(enum changelog_rec_flags *clf_flags,
unsigned int error)
{
- *clf_flags |= (error << CLF_HSM_ERR_L);
+ *clf_flags = (enum changelog_rec_flags)
+ (*clf_flags | (error << CLF_HSM_ERR_L));
}
enum changelog_rec_extra_flags {
__u32 cr_markerflags; /**< CL_MARK flags */
};
struct lu_fid cr_pfid; /**< parent fid */
-};
+} __attribute__ ((packed));
/* Changelog extension for RENAME. */
struct changelog_ext_rename {
static inline struct changelog_ext_extra_flags *changelog_rec_extra_flags(
const struct changelog_rec *rec);
-static inline size_t changelog_rec_offset(enum changelog_rec_flags crf,
+static inline __kernel_size_t changelog_rec_offset(enum changelog_rec_flags crf,
enum changelog_rec_extra_flags cref)
{
- size_t size = sizeof(struct changelog_rec);
+ __kernel_size_t size = sizeof(struct changelog_rec);
if (crf & CLF_RENAME)
size += sizeof(struct changelog_ext_rename);
return size;
}
-static inline size_t changelog_rec_size(const struct changelog_rec *rec)
+static inline __kernel_size_t changelog_rec_size(const struct changelog_rec *rec)
{
enum changelog_rec_extra_flags cref = CLFE_INVALID;
if (rec->cr_flags & CLF_EXTRA_FLAGS)
- cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
+ cref = (enum changelog_rec_extra_flags)
+ changelog_rec_extra_flags(rec)->cr_extra_flags;
- return changelog_rec_offset(rec->cr_flags, cref);
+ return changelog_rec_offset(
+ (enum changelog_rec_flags)rec->cr_flags, cref);
}
-static inline size_t changelog_rec_varsize(const struct changelog_rec *rec)
+static inline __kernel_size_t changelog_rec_varsize(const struct changelog_rec *rec)
{
return changelog_rec_size(rec) - sizeof(*rec) + rec->cr_namelen;
}
static inline
struct changelog_ext_rename *changelog_rec_rename(const struct changelog_rec *rec)
{
- enum changelog_rec_flags crf = rec->cr_flags & CLF_VERSION;
+ enum changelog_rec_flags crf = (enum changelog_rec_flags)
+ (rec->cr_flags & CLF_VERSION);
return (struct changelog_ext_rename *)((char *)rec +
changelog_rec_offset(crf,
static inline
struct changelog_ext_jobid *changelog_rec_jobid(const struct changelog_rec *rec)
{
- enum changelog_rec_flags crf = rec->cr_flags &
- (CLF_VERSION | CLF_RENAME);
+ enum changelog_rec_flags crf = (enum changelog_rec_flags)
+ (rec->cr_flags & (CLF_VERSION | CLF_RENAME));
return (struct changelog_ext_jobid *)((char *)rec +
changelog_rec_offset(crf,
struct changelog_ext_extra_flags *changelog_rec_extra_flags(
const struct changelog_rec *rec)
{
- enum changelog_rec_flags crf = rec->cr_flags &
- (CLF_VERSION | CLF_RENAME | CLF_JOBID);
+ enum changelog_rec_flags crf = (enum changelog_rec_flags)
+ (rec->cr_flags & (CLF_VERSION | CLF_RENAME | CLF_JOBID));
return (struct changelog_ext_extra_flags *)((char *)rec +
changelog_rec_offset(crf,
struct changelog_ext_uidgid *changelog_rec_uidgid(
const struct changelog_rec *rec)
{
- enum changelog_rec_flags crf = rec->cr_flags &
- (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+ enum changelog_rec_flags crf = (enum changelog_rec_flags)
+ (rec->cr_flags &
+ (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS));
return (struct changelog_ext_uidgid *)((char *)rec +
changelog_rec_offset(crf,
static inline
struct changelog_ext_nid *changelog_rec_nid(const struct changelog_rec *rec)
{
- enum changelog_rec_flags crf = rec->cr_flags &
- (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+ enum changelog_rec_flags crf = (enum changelog_rec_flags)
+ (rec->cr_flags &
+ (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS));
enum changelog_rec_extra_flags cref = CLFE_INVALID;
if (rec->cr_flags & CLF_EXTRA_FLAGS)
- cref = changelog_rec_extra_flags(rec)->cr_extra_flags &
- CLFE_UIDGID;
+ cref = (enum changelog_rec_extra_flags)
+ (changelog_rec_extra_flags(rec)->cr_extra_flags &
+ CLFE_UIDGID);
return (struct changelog_ext_nid *)((char *)rec +
changelog_rec_offset(crf, cref));
struct changelog_ext_openmode *changelog_rec_openmode(
const struct changelog_rec *rec)
{
- enum changelog_rec_flags crf = rec->cr_flags &
- (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+ enum changelog_rec_flags crf = (enum changelog_rec_flags)
+ (rec->cr_flags &
+ (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS));
enum changelog_rec_extra_flags cref = CLFE_INVALID;
- if (rec->cr_flags & CLF_EXTRA_FLAGS)
- cref = changelog_rec_extra_flags(rec)->cr_extra_flags &
- (CLFE_UIDGID | CLFE_NID);
+ if (rec->cr_flags & CLF_EXTRA_FLAGS) {
+ cref = (enum changelog_rec_extra_flags)
+ (changelog_rec_extra_flags(rec)->cr_extra_flags &
+ (CLFE_UIDGID | CLFE_NID));
+ }
return (struct changelog_ext_openmode *)((char *)rec +
changelog_rec_offset(crf, cref));
struct changelog_ext_xattr *changelog_rec_xattr(
const struct changelog_rec *rec)
{
- enum changelog_rec_flags crf = rec->cr_flags &
- (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+ enum changelog_rec_flags crf = (enum changelog_rec_flags)
+ (rec->cr_flags &
+ (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS));
enum changelog_rec_extra_flags cref = CLFE_INVALID;
if (rec->cr_flags & CLF_EXTRA_FLAGS)
- cref = changelog_rec_extra_flags(rec)->cr_extra_flags &
- (CLFE_UIDGID | CLFE_NID | CLFE_OPEN);
+ cref = (enum changelog_rec_extra_flags)
+ (changelog_rec_extra_flags(rec)->cr_extra_flags &
+ (CLFE_UIDGID | CLFE_NID | CLFE_OPEN));
return (struct changelog_ext_xattr *)((char *)rec +
changelog_rec_offset(crf, cref));
enum changelog_rec_extra_flags cref = CLFE_INVALID;
if (rec->cr_flags & CLF_EXTRA_FLAGS)
- cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
+ cref = (enum changelog_rec_extra_flags)
+ changelog_rec_extra_flags(rec)->cr_extra_flags;
- return (char *)rec + changelog_rec_offset(rec->cr_flags & CLF_SUPPORTED,
- cref & CLFE_SUPPORTED);
+ return (char *)rec + changelog_rec_offset(
+ (enum changelog_rec_flags)(rec->cr_flags & CLF_SUPPORTED),
+ (enum changelog_rec_extra_flags)(cref & CLFE_SUPPORTED));
}
-static inline size_t changelog_rec_snamelen(const struct changelog_rec *rec)
+static inline __kernel_size_t changelog_rec_snamelen(const struct changelog_rec *rec)
{
return rec->cr_namelen - strlen(changelog_rec_name(rec)) - 1;
}
char *rnm_mov;
enum changelog_rec_extra_flags cref = CLFE_INVALID;
- crf_wanted &= CLF_SUPPORTED;
- cref_want &= CLFE_SUPPORTED;
+ crf_wanted = (enum changelog_rec_flags)
+ (crf_wanted & CLF_SUPPORTED);
+ cref_want = (enum changelog_rec_extra_flags)
+ (cref_want & CLFE_SUPPORTED);
if ((rec->cr_flags & CLF_SUPPORTED) == crf_wanted) {
if (!(rec->cr_flags & CLF_EXTRA_FLAGS) ||
/* Locations of extensions in the remapped record */
if (rec->cr_flags & CLF_EXTRA_FLAGS) {
xattr_mov = (char *)rec +
- changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
- cref_want & ~CLFE_XATTR);
+ changelog_rec_offset(
+ (enum changelog_rec_flags)
+ (crf_wanted & CLF_SUPPORTED),
+ (enum changelog_rec_extra_flags)
+ (cref_want & ~CLFE_XATTR));
omd_mov = (char *)rec +
- changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
- cref_want & ~(CLFE_OPEN |
- CLFE_XATTR));
+ changelog_rec_offset(
+ (enum changelog_rec_flags)
+ (crf_wanted & CLF_SUPPORTED),
+ (enum changelog_rec_extra_flags)
+ (cref_want & ~(CLFE_OPEN | CLFE_XATTR)));
nid_mov = (char *)rec +
- changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
- cref_want & ~(CLFE_NID |
- CLFE_OPEN |
- CLFE_XATTR));
+ changelog_rec_offset(
+ (enum changelog_rec_flags)
+ (crf_wanted & CLF_SUPPORTED),
+ (enum changelog_rec_extra_flags)
+ (cref_want &
+ ~(CLFE_NID | CLFE_OPEN | CLFE_XATTR)));
uidgid_mov = (char *)rec +
- changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
- cref_want & ~(CLFE_UIDGID |
+ changelog_rec_offset(
+ (enum changelog_rec_flags)
+ (crf_wanted & CLF_SUPPORTED),
+ (enum changelog_rec_extra_flags)
+ (cref_want & ~(CLFE_UIDGID |
CLFE_NID |
CLFE_OPEN |
- CLFE_XATTR));
- cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
+ CLFE_XATTR)));
+ cref = (enum changelog_rec_extra_flags)
+ changelog_rec_extra_flags(rec)->cr_extra_flags;
}
ef_mov = (char *)rec +
- changelog_rec_offset(crf_wanted & ~CLF_EXTRA_FLAGS,
- CLFE_INVALID);
+ changelog_rec_offset(
+ (enum changelog_rec_flags)
+ (crf_wanted & ~CLF_EXTRA_FLAGS), CLFE_INVALID);
jid_mov = (char *)rec +
- changelog_rec_offset(crf_wanted &
- ~(CLF_EXTRA_FLAGS | CLF_JOBID),
+ changelog_rec_offset((enum changelog_rec_flags)(crf_wanted &
+ ~(CLF_EXTRA_FLAGS | CLF_JOBID)),
CLFE_INVALID);
rnm_mov = (char *)rec +
- changelog_rec_offset(crf_wanted &
+ changelog_rec_offset((enum changelog_rec_flags)(crf_wanted &
~(CLF_EXTRA_FLAGS |
CLF_JOBID |
- CLF_RENAME),
+ CLF_RENAME)),
CLFE_INVALID);
/* Move the extension fields to the desired positions */
/**
* 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 ]
+ * instead of an errno because __kernel_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)
+static inline __kernel_size_t hur_len(struct hsm_user_request *hur)
{
__u64 size;
(__u64)hur->hur_request.hr_itemcount *
sizeof(hur->hur_user_item[0]) + hur->hur_request.hr_data_len;
- if (size != (ssize_t)size)
+ if ((__kernel_ssize_t)size < 0)
return -1;
return size;
* \retval buffer
*/
static inline char *hai_dump_data_field(const struct hsm_action_item *hai,
- char *buffer, size_t len)
+ char *buffer, __kernel_size_t len)
{
int i;
int data_len;
/* Return pointer to first hai in action list */
static inline struct hsm_action_item *hai_first(struct hsm_action_list *hal)
{
- size_t offset = __ALIGN_KERNEL(strlen(hal->hal_fsname) + 1, 8);
+ __kernel_size_t offset = __ALIGN_KERNEL(strlen(hal->hal_fsname) + 1, 8);
return (struct hsm_action_item *)(hal->hal_fsname + offset);
}
/* Return pointer to next hai */
static inline struct hsm_action_item * hai_next(struct hsm_action_item *hai)
{
- size_t offset = __ALIGN_KERNEL(hai->hai_len, 8);
+ __kernel_size_t offset = __ALIGN_KERNEL(hai->hai_len, 8);
return (struct hsm_action_item *)((char *)hai + offset);
}
/* Return size of an hsm_action_list */
-static inline size_t hal_size(struct hsm_action_list *hal)
+static inline __kernel_size_t hal_size(struct hsm_action_list *hal)
{
__u32 i;
- size_t sz;
+ __kernel_size_t sz;
struct hsm_action_item *hai;
sz = sizeof(*hal) + __ALIGN_KERNEL(strlen(hal->hal_fsname) + 1, 8);
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;
-};
-
enum lu_ladvise_type {
LU_LADVISE_INVALID = 0,
LU_LADVISE_WILLREAD = 1,
PCC_STATE_FL_ATTR_VALID = 0x01,
/* The file is being attached into PCC */
PCC_STATE_FL_ATTACHING = 0x02,
- /* Allow to auto attach at open */
- PCC_STATE_FL_OPEN_ATTACH = 0x04,
};
struct lu_pcc_state {
char pccs_path[PATH_MAX];
};
+struct fid_array {
+ __u32 fa_nr;
+ /* make header's size equal lu_fid */
+ __u32 fa_padding0;
+ __u64 fa_padding1;
+ struct lu_fid fa_fids[0];
+};
+#define OBD_MAX_FIDS_IN_ARRAY 4096
+
+/* more types could be defined upon need for more complex
+ * format to be used in foreign symlink LOV/LMV EAs, like
+ * one to describe a delimiter string and occurence number
+ * of delimited sub-string, ...
+ */
+enum ll_foreign_symlink_upcall_item_type {
+ EOB_TYPE = 1,
+ STRING_TYPE = 2,
+ POSLEN_TYPE = 3,
+};
+
+/* may need to be modified to allow for more format items to be defined, and
+ * like for ll_foreign_symlink_upcall_item_type enum
+ */
+struct ll_foreign_symlink_upcall_item {
+ __u32 type;
+ union {
+ struct {
+ __u32 pos;
+ __u32 len;
+ };
+ struct {
+ size_t size;
+ union {
+ /* internal storage of constant string */
+ char *string;
+ /* upcall stores constant string in a raw */
+ char bytestring[0];
+ };
+ };
+ };
+};
+
+#define POSLEN_ITEM_SZ (offsetof(struct ll_foreign_symlink_upcall_item, len) + \
+ sizeof(((struct ll_foreign_symlink_upcall_item *)0)->len))
+#define STRING_ITEM_SZ(sz) ( \
+ offsetof(struct ll_foreign_symlink_upcall_item, bytestring) + \
+ (sz + sizeof(__u32) - 1) / sizeof(__u32) * sizeof(__u32))
+
+/* presently limited to not cause max stack frame size to be reached
+ * because of temporary automatic array of
+ * "struct ll_foreign_symlink_upcall_item" presently used in
+ * foreign_symlink_upcall_info_store()
+ */
+#define MAX_NB_UPCALL_ITEMS 32
+
#if defined(__cplusplus)
}
#endif