Commit | Line | Data |
---|---|---|
d7e09d03 PT |
1 | /* |
2 | * GPL HEADER START | |
3 | * | |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 only, | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License version 2 for more details (a copy is included | |
14 | * in the LICENSE file that accompanied this code). | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * version 2 along with this program; If not, see | |
6a5b99a4 | 18 | * http://www.gnu.org/licenses/gpl-2.0.html |
d7e09d03 | 19 | * |
d7e09d03 PT |
20 | * GPL HEADER END |
21 | */ | |
22 | /* | |
23 | * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | * | |
1dc563a6 | 26 | * Copyright (c) 2010, 2015, Intel Corporation. |
d7e09d03 PT |
27 | */ |
28 | /* | |
29 | * This file is part of Lustre, http://www.lustre.org/ | |
30 | * Lustre is a trademark of Sun Microsystems, Inc. | |
31 | * | |
32 | * lustre/include/lustre/lustre_user.h | |
33 | * | |
34 | * Lustre public user-space interface definitions. | |
35 | */ | |
36 | ||
37 | #ifndef _LUSTRE_USER_H | |
38 | #define _LUSTRE_USER_H | |
39 | ||
40 | /** \defgroup lustreuser lustreuser | |
41 | * | |
42 | * @{ | |
43 | */ | |
44 | ||
1accaadf GKH |
45 | #include "ll_fiemap.h" |
46 | #include "../linux/lustre_user.h" | |
d7e09d03 | 47 | |
00c0a6ae JH |
48 | #define LUSTRE_EOF 0xffffffffffffffffULL |
49 | ||
d7e09d03 PT |
50 | /* for statfs() */ |
51 | #define LL_SUPER_MAGIC 0x0BD00BD0 | |
52 | ||
53 | #ifndef FSFILT_IOC_GETFLAGS | |
54 | #define FSFILT_IOC_GETFLAGS _IOR('f', 1, long) | |
55 | #define FSFILT_IOC_SETFLAGS _IOW('f', 2, long) | |
56 | #define FSFILT_IOC_GETVERSION _IOR('f', 3, long) | |
57 | #define FSFILT_IOC_SETVERSION _IOW('f', 4, long) | |
58 | #define FSFILT_IOC_GETVERSION_OLD _IOR('v', 1, long) | |
59 | #define FSFILT_IOC_SETVERSION_OLD _IOW('v', 2, long) | |
60 | #define FSFILT_IOC_FIEMAP _IOWR('f', 11, struct ll_user_fiemap) | |
61 | #endif | |
62 | ||
63 | /* FIEMAP flags supported by Lustre */ | |
64 | #define LUSTRE_FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_DEVICE_ORDER) | |
65 | ||
66 | enum obd_statfs_state { | |
67 | OS_STATE_DEGRADED = 0x00000001, /**< RAID degraded/rebuilding */ | |
68 | OS_STATE_READONLY = 0x00000002, /**< filesystem is read-only */ | |
69 | OS_STATE_RDONLY_1 = 0x00000004, /**< obsolete 1.6, was EROFS=30 */ | |
70 | OS_STATE_RDONLY_2 = 0x00000008, /**< obsolete 1.6, was EROFS=30 */ | |
71 | OS_STATE_RDONLY_3 = 0x00000010, /**< obsolete 1.6, was EROFS=30 */ | |
72 | }; | |
73 | ||
74 | struct obd_statfs { | |
75 | __u64 os_type; | |
76 | __u64 os_blocks; | |
77 | __u64 os_bfree; | |
78 | __u64 os_bavail; | |
79 | __u64 os_files; | |
80 | __u64 os_ffree; | |
81 | __u8 os_fsid[40]; | |
82 | __u32 os_bsize; | |
83 | __u32 os_namelen; | |
84 | __u64 os_maxbytes; | |
85 | __u32 os_state; /**< obd_statfs_state OS_STATE_* flag */ | |
c56e256d OD |
86 | __u32 os_fprecreated; /* objs available now to the caller */ |
87 | /* used in QoS code to find preferred OSTs */ | |
d7e09d03 PT |
88 | __u32 os_spare2; |
89 | __u32 os_spare3; | |
90 | __u32 os_spare4; | |
91 | __u32 os_spare5; | |
92 | __u32 os_spare6; | |
93 | __u32 os_spare7; | |
94 | __u32 os_spare8; | |
95 | __u32 os_spare9; | |
96 | }; | |
97 | ||
98 | /** | |
99 | * File IDentifier. | |
100 | * | |
101 | * FID is a cluster-wide unique identifier of a file or an object (stripe). | |
102 | * FIDs are never reused. | |
103 | **/ | |
104 | struct lu_fid { | |
105 | /** | |
106 | * FID sequence. Sequence is a unit of migration: all files (objects) | |
107 | * with FIDs from a given sequence are stored on the same server. | |
108 | * Lustre should support 2^64 objects, so even if each sequence | |
109 | * has only a single object we can still enumerate 2^64 objects. | |
110 | **/ | |
111 | __u64 f_seq; | |
112 | /* FID number within sequence. */ | |
113 | __u32 f_oid; | |
114 | /** | |
115 | * FID version, used to distinguish different versions (in the sense | |
116 | * of snapshots, etc.) of the same file system object. Not currently | |
117 | * used. | |
118 | **/ | |
119 | __u32 f_ver; | |
120 | }; | |
121 | ||
00c0a6ae JH |
122 | static inline bool fid_is_zero(const struct lu_fid *fid) |
123 | { | |
124 | return !fid->f_seq && !fid->f_oid; | |
125 | } | |
126 | ||
d7e09d03 PT |
127 | struct filter_fid { |
128 | struct lu_fid ff_parent; /* ff_parent.f_ver == file stripe number */ | |
129 | }; | |
130 | ||
131 | /* keep this one for compatibility */ | |
132 | struct filter_fid_old { | |
133 | struct lu_fid ff_parent; | |
134 | __u64 ff_objid; | |
135 | __u64 ff_seq; | |
136 | }; | |
137 | ||
138 | /* Userspace should treat lu_fid as opaque, and only use the following methods | |
139 | * to print or parse them. Other functions (e.g. compare, swab) could be moved | |
c56e256d OD |
140 | * here from lustre_idl.h if needed. |
141 | */ | |
d8f6bc9a | 142 | struct lu_fid; |
d7e09d03 PT |
143 | |
144 | /** | |
145 | * Following struct for object attributes, that will be kept inode's EA. | |
146 | * Introduced in 2.0 release (please see b15993, for details) | |
147 | * Added to all objects since Lustre 2.4 as contains self FID | |
148 | */ | |
149 | struct lustre_mdt_attrs { | |
150 | /** | |
151 | * Bitfield for supported data in this structure. From enum lma_compat. | |
152 | * lma_self_fid and lma_flags are always available. | |
153 | */ | |
154 | __u32 lma_compat; | |
155 | /** | |
156 | * Per-file incompat feature list. Lustre version should support all | |
157 | * flags set in this field. The supported feature mask is available in | |
158 | * LMA_INCOMPAT_SUPP. | |
159 | */ | |
160 | __u32 lma_incompat; | |
161 | /** FID of this inode */ | |
162 | struct lu_fid lma_self_fid; | |
163 | }; | |
164 | ||
165 | /** | |
166 | * Prior to 2.4, the LMA structure also included SOM attributes which has since | |
167 | * been moved to a dedicated xattr | |
168 | * lma_flags was also removed because of lma_compat/incompat fields. | |
169 | */ | |
170 | #define LMA_OLD_SIZE (sizeof(struct lustre_mdt_attrs) + 5 * sizeof(__u64)) | |
171 | ||
172 | /** | |
173 | * OST object IDentifier. | |
174 | */ | |
175 | struct ost_id { | |
176 | union { | |
d6099af2 | 177 | struct { |
d7e09d03 PT |
178 | __u64 oi_id; |
179 | __u64 oi_seq; | |
180 | } oi; | |
181 | struct lu_fid oi_fid; | |
182 | }; | |
183 | }; | |
184 | ||
55f5a824 | 185 | #define DOSTID "%#llx:%llu" |
d7e09d03 PT |
186 | #define POSTID(oi) ostid_seq(oi), ostid_id(oi) |
187 | ||
188 | /* | |
189 | * The ioctl naming rules: | |
190 | * LL_* - works on the currently opened filehandle instead of parent dir | |
191 | * *_OBD_* - gets data for both OSC or MDC (LOV, LMV indirectly) | |
192 | * *_MDC_* - gets/sets data related to MDC | |
193 | * *_LOV_* - gets/sets data related to OSC/LOV | |
194 | * *FILE* - called on parent dir and passes in a filename | |
195 | * *STRIPE* - set/get lov_user_md | |
196 | * *INFO - set/get lov_user_mds_data | |
197 | */ | |
8877d3bf | 198 | /* lustre_ioctl.h 101-150 */ |
e9570b49 OD |
199 | #define LL_IOC_GETFLAGS _IOR('f', 151, long) |
200 | #define LL_IOC_SETFLAGS _IOW('f', 152, long) | |
201 | #define LL_IOC_CLRFLAGS _IOW('f', 153, long) | |
e9570b49 | 202 | #define LL_IOC_LOV_SETSTRIPE _IOW('f', 154, long) |
e9570b49 | 203 | #define LL_IOC_LOV_GETSTRIPE _IOW('f', 155, long) |
e9570b49 OD |
204 | #define LL_IOC_LOV_SETEA _IOW('f', 156, long) |
205 | #define LL_IOC_RECREATE_OBJ _IOW('f', 157, long) | |
206 | #define LL_IOC_RECREATE_FID _IOW('f', 157, struct lu_fid) | |
207 | #define LL_IOC_GROUP_LOCK _IOW('f', 158, long) | |
208 | #define LL_IOC_GROUP_UNLOCK _IOW('f', 159, long) | |
8877d3bf JH |
209 | /* #define LL_IOC_QUOTACHECK 160 OBD_IOC_QUOTACHECK */ |
210 | /* #define LL_IOC_POLL_QUOTACHECK 161 OBD_IOC_POLL_QUOTACHECK */ | |
211 | /* #define LL_IOC_QUOTACTL 162 OBD_IOC_QUOTACTL */ | |
d7e09d03 PT |
212 | #define IOC_OBD_STATFS _IOWR('f', 164, struct obd_statfs *) |
213 | #define IOC_LOV_GETINFO _IOWR('f', 165, struct lov_user_mds_data *) | |
e9570b49 | 214 | #define LL_IOC_FLUSHCTX _IOW('f', 166, long) |
341f1f0a | 215 | /* LL_IOC_RMTACL 167 obsolete */ |
e9570b49 | 216 | #define LL_IOC_GETOBDCOUNT _IOR('f', 168, long) |
d7e09d03 PT |
217 | #define LL_IOC_LLOOP_ATTACH _IOWR('f', 169, long) |
218 | #define LL_IOC_LLOOP_DETACH _IOWR('f', 170, long) | |
219 | #define LL_IOC_LLOOP_INFO _IOWR('f', 171, struct lu_fid) | |
220 | #define LL_IOC_LLOOP_DETACH_BYDEV _IOWR('f', 172, long) | |
e9570b49 | 221 | #define LL_IOC_PATH2FID _IOR('f', 173, long) |
d7e09d03 | 222 | #define LL_IOC_GET_CONNECT_FLAGS _IOWR('f', 174, __u64 *) |
e9570b49 | 223 | #define LL_IOC_GET_MDTIDX _IOR('f', 175, int) |
d7e09d03 | 224 | |
8877d3bf | 225 | /* lustre_ioctl.h 177-210 */ |
d7e09d03 PT |
226 | #define LL_IOC_HSM_STATE_GET _IOR('f', 211, struct hsm_user_state) |
227 | #define LL_IOC_HSM_STATE_SET _IOW('f', 212, struct hsm_state_set) | |
228 | #define LL_IOC_HSM_CT_START _IOW('f', 213, struct lustre_kernelcomm) | |
229 | #define LL_IOC_HSM_COPY_START _IOW('f', 214, struct hsm_copy *) | |
230 | #define LL_IOC_HSM_COPY_END _IOW('f', 215, struct hsm_copy *) | |
231 | #define LL_IOC_HSM_PROGRESS _IOW('f', 216, struct hsm_user_request) | |
232 | #define LL_IOC_HSM_REQUEST _IOW('f', 217, struct hsm_user_request) | |
233 | #define LL_IOC_DATA_VERSION _IOR('f', 218, struct ioc_data_version) | |
234 | #define LL_IOC_LOV_SWAP_LAYOUTS _IOW('f', 219, \ | |
235 | struct lustre_swap_layouts) | |
236 | #define LL_IOC_HSM_ACTION _IOR('f', 220, \ | |
237 | struct hsm_current_action) | |
238 | /* see <lustre_lib.h> for ioctl numbers 221-232 */ | |
239 | ||
240 | #define LL_IOC_LMV_SETSTRIPE _IOWR('f', 240, struct lmv_user_md) | |
241 | #define LL_IOC_LMV_GETSTRIPE _IOWR('f', 241, struct lmv_user_md) | |
d3a8a4e2 JX |
242 | #define LL_IOC_SET_LEASE _IOWR('f', 243, long) |
243 | #define LL_IOC_GET_LEASE _IO('f', 244) | |
a720b790 | 244 | #define LL_IOC_HSM_IMPORT _IOWR('f', 245, struct hsm_user_import) |
6e23ea98 | 245 | #define LL_IOC_LMV_SET_DEFAULT_STRIPE _IOWR('f', 246, struct lmv_user_md) |
79496845 | 246 | #define LL_IOC_MIGRATE _IOR('f', 247, int) |
d3a8a4e2 | 247 | |
d7e09d03 PT |
248 | #define LL_STATFS_LMV 1 |
249 | #define LL_STATFS_LOV 2 | |
250 | #define LL_STATFS_NODELAY 4 | |
251 | ||
252 | #define IOC_MDC_TYPE 'i' | |
253 | #define IOC_MDC_LOOKUP _IOWR(IOC_MDC_TYPE, 20, struct obd_device *) | |
254 | #define IOC_MDC_GETFILESTRIPE _IOWR(IOC_MDC_TYPE, 21, struct lov_user_md *) | |
255 | #define IOC_MDC_GETFILEINFO _IOWR(IOC_MDC_TYPE, 22, struct lov_user_mds_data *) | |
256 | #define LL_IOC_MDC_GETINFO _IOWR(IOC_MDC_TYPE, 23, struct lov_user_mds_data *) | |
257 | ||
d7e09d03 PT |
258 | #define MAX_OBD_NAME 128 /* If this changes, a NEW ioctl must be added */ |
259 | ||
38585ccc AD |
260 | /* Define O_LOV_DELAY_CREATE to be a mask that is not useful for regular |
261 | * files, but are unlikely to be used in practice and are not harmful if | |
262 | * used incorrectly. O_NOCTTY and FASYNC are only meaningful for character | |
c56e256d OD |
263 | * devices and are safe for use on new files (See LU-812, LU-4209). |
264 | */ | |
38585ccc | 265 | #define O_LOV_DELAY_CREATE (O_NOCTTY | FASYNC) |
d7e09d03 PT |
266 | |
267 | #define LL_FILE_IGNORE_LOCK 0x00000001 | |
268 | #define LL_FILE_GROUP_LOCKED 0x00000002 | |
269 | #define LL_FILE_READAHEA 0x00000004 | |
270 | #define LL_FILE_LOCKED_DIRECTIO 0x00000008 /* client-side locks with dio */ | |
271 | #define LL_FILE_LOCKLESS_IO 0x00000010 /* server-side locks with cio */ | |
272 | #define LL_FILE_RMTACL 0x00000020 | |
273 | ||
274 | #define LOV_USER_MAGIC_V1 0x0BD10BD0 | |
275 | #define LOV_USER_MAGIC LOV_USER_MAGIC_V1 | |
276 | #define LOV_USER_MAGIC_JOIN_V1 0x0BD20BD0 | |
277 | #define LOV_USER_MAGIC_V3 0x0BD30BD0 | |
278 | ||
8f18c8a4 | 279 | #define LMV_USER_MAGIC 0x0CD30CD0 /*default lmv magic*/ |
d7e09d03 | 280 | |
00c0a6ae JH |
281 | #define LOV_PATTERN_RAID0 0x001 |
282 | #define LOV_PATTERN_RAID1 0x002 | |
283 | #define LOV_PATTERN_FIRST 0x100 | |
284 | #define LOV_PATTERN_CMOBD 0x200 | |
285 | ||
286 | #define LOV_PATTERN_F_MASK 0xffff0000 | |
865b734e | 287 | #define LOV_PATTERN_F_HOLE 0x40000000 /* there is hole in LOV EA */ |
00c0a6ae JH |
288 | #define LOV_PATTERN_F_RELEASED 0x80000000 /* HSM released file */ |
289 | ||
d7e09d03 PT |
290 | #define LOV_MAXPOOLNAME 16 |
291 | #define LOV_POOLNAMEF "%.16s" | |
292 | ||
293 | #define LOV_MIN_STRIPE_BITS 16 /* maximum PAGE_SIZE (ia64), power of 2 */ | |
294 | #define LOV_MIN_STRIPE_SIZE (1 << LOV_MIN_STRIPE_BITS) | |
295 | #define LOV_MAX_STRIPE_COUNT_OLD 160 | |
296 | /* This calculation is crafted so that input of 4096 will result in 160 | |
297 | * which in turn is equal to old maximal stripe count. | |
f16192ed | 298 | * XXX: In fact this is too simplified for now, what it also need is to get |
d7e09d03 PT |
299 | * ea_type argument to clearly know how much space each stripe consumes. |
300 | * | |
301 | * The limit of 12 pages is somewhat arbitrary, but is a reasonably large | |
302 | * allocation that is sufficient for the current generation of systems. | |
303 | * | |
c56e256d OD |
304 | * (max buffer size - lov+rpc header) / sizeof(struct lov_ost_data_v1) |
305 | */ | |
d7e09d03 PT |
306 | #define LOV_MAX_STRIPE_COUNT 2000 /* ((12 * 4096 - 256) / 24) */ |
307 | #define LOV_ALL_STRIPES 0xffff /* only valid for directories */ | |
308 | #define LOV_V1_INSANE_STRIPE_COUNT 65532 /* maximum stripe count bz13933 */ | |
309 | ||
310 | #define lov_user_ost_data lov_user_ost_data_v1 | |
311 | struct lov_user_ost_data_v1 { /* per-stripe data structure */ | |
312 | struct ost_id l_ost_oi; /* OST object ID */ | |
313 | __u32 l_ost_gen; /* generation of this OST index */ | |
314 | __u32 l_ost_idx; /* OST index in LOV */ | |
ae127bf3 | 315 | } __packed; |
d7e09d03 PT |
316 | |
317 | #define lov_user_md lov_user_md_v1 | |
318 | struct lov_user_md_v1 { /* LOV EA user data (host-endian) */ | |
319 | __u32 lmm_magic; /* magic number = LOV_USER_MAGIC_V1 */ | |
320 | __u32 lmm_pattern; /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */ | |
321 | struct ost_id lmm_oi; /* LOV object ID */ | |
322 | __u32 lmm_stripe_size; /* size of stripe in bytes */ | |
323 | __u16 lmm_stripe_count; /* num stripes in use for this object */ | |
324 | union { | |
325 | __u16 lmm_stripe_offset; /* starting stripe offset in | |
c56e256d OD |
326 | * lmm_objects, use when writing |
327 | */ | |
d7e09d03 | 328 | __u16 lmm_layout_gen; /* layout generation number |
c56e256d OD |
329 | * used when reading |
330 | */ | |
d7e09d03 PT |
331 | }; |
332 | struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */ | |
333 | } __attribute__((packed, __may_alias__)); | |
334 | ||
335 | struct lov_user_md_v3 { /* LOV EA user data (host-endian) */ | |
336 | __u32 lmm_magic; /* magic number = LOV_USER_MAGIC_V3 */ | |
337 | __u32 lmm_pattern; /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */ | |
338 | struct ost_id lmm_oi; /* LOV object ID */ | |
339 | __u32 lmm_stripe_size; /* size of stripe in bytes */ | |
340 | __u16 lmm_stripe_count; /* num stripes in use for this object */ | |
341 | union { | |
342 | __u16 lmm_stripe_offset; /* starting stripe offset in | |
c56e256d OD |
343 | * lmm_objects, use when writing |
344 | */ | |
d7e09d03 | 345 | __u16 lmm_layout_gen; /* layout generation number |
c56e256d OD |
346 | * used when reading |
347 | */ | |
d7e09d03 PT |
348 | }; |
349 | char lmm_pool_name[LOV_MAXPOOLNAME]; /* pool name */ | |
350 | struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */ | |
ae127bf3 | 351 | } __packed; |
d7e09d03 | 352 | |
bc06a678 | 353 | static inline __u32 lov_user_md_size(__u16 stripes, __u32 lmm_magic) |
354 | { | |
355 | if (lmm_magic == LOV_USER_MAGIC_V3) | |
356 | return sizeof(struct lov_user_md_v3) + | |
357 | stripes * sizeof(struct lov_user_ost_data_v1); | |
358 | else | |
359 | return sizeof(struct lov_user_md_v1) + | |
360 | stripes * sizeof(struct lov_user_ost_data_v1); | |
361 | } | |
362 | ||
d7e09d03 PT |
363 | /* Compile with -D_LARGEFILE64_SOURCE or -D_GNU_SOURCE (or #define) to |
364 | * use this. It is unsafe to #define those values in this header as it | |
365 | * is possible the application has already #included <sys/stat.h>. */ | |
366 | #ifdef HAVE_LOV_USER_MDS_DATA | |
367 | #define lov_user_mds_data lov_user_mds_data_v1 | |
368 | struct lov_user_mds_data_v1 { | |
369 | lstat_t lmd_st; /* MDS stat struct */ | |
370 | struct lov_user_md_v1 lmd_lmm; /* LOV EA V1 user data */ | |
ae127bf3 | 371 | } __packed; |
d7e09d03 PT |
372 | |
373 | struct lov_user_mds_data_v3 { | |
374 | lstat_t lmd_st; /* MDS stat struct */ | |
375 | struct lov_user_md_v3 lmd_lmm; /* LOV EA V3 user data */ | |
ae127bf3 | 376 | } __packed; |
d7e09d03 PT |
377 | #endif |
378 | ||
d7e09d03 PT |
379 | struct lmv_user_mds_data { |
380 | struct lu_fid lum_fid; | |
381 | __u32 lum_padding; | |
382 | __u32 lum_mds; | |
383 | }; | |
384 | ||
00c0a6ae | 385 | enum lmv_hash_type { |
893ab747 | 386 | LMV_HASH_TYPE_UNKNOWN = 0, /* 0 is reserved for testing purpose */ |
00c0a6ae JH |
387 | LMV_HASH_TYPE_ALL_CHARS = 1, |
388 | LMV_HASH_TYPE_FNV_1A_64 = 2, | |
389 | }; | |
390 | ||
391 | #define LMV_HASH_NAME_ALL_CHARS "all_char" | |
392 | #define LMV_HASH_NAME_FNV_1A_64 "fnv_1a_64" | |
393 | ||
2de35386 | 394 | /* |
395 | * Got this according to how get LOV_MAX_STRIPE_COUNT, see above, | |
396 | * (max buffer size - lmv+rpc header) / sizeof(struct lmv_user_mds_data) | |
397 | */ | |
398 | #define LMV_MAX_STRIPE_COUNT 2000 /* ((12 * 4096 - 256) / 24) */ | |
d7e09d03 PT |
399 | #define lmv_user_md lmv_user_md_v1 |
400 | struct lmv_user_md_v1 { | |
401 | __u32 lum_magic; /* must be the first field */ | |
402 | __u32 lum_stripe_count; /* dirstripe count */ | |
403 | __u32 lum_stripe_offset; /* MDT idx for default dirstripe */ | |
404 | __u32 lum_hash_type; /* Dir stripe policy */ | |
405 | __u32 lum_type; /* LMV type: default or normal */ | |
406 | __u32 lum_padding1; | |
407 | __u32 lum_padding2; | |
408 | __u32 lum_padding3; | |
409 | char lum_pool_name[LOV_MAXPOOLNAME]; | |
410 | struct lmv_user_mds_data lum_objects[0]; | |
2de35386 | 411 | } __packed; |
d7e09d03 PT |
412 | |
413 | static inline int lmv_user_md_size(int stripes, int lmm_magic) | |
414 | { | |
415 | return sizeof(struct lmv_user_md) + | |
416 | stripes * sizeof(struct lmv_user_mds_data); | |
417 | } | |
418 | ||
2de35386 | 419 | void lustre_swab_lmv_user_md(struct lmv_user_md *lum); |
420 | ||
d7e09d03 PT |
421 | struct ll_recreate_obj { |
422 | __u64 lrc_id; | |
423 | __u32 lrc_ost_idx; | |
424 | }; | |
425 | ||
426 | struct ll_fid { | |
427 | __u64 id; /* holds object id */ | |
428 | __u32 generation; /* holds object generation */ | |
429 | __u32 f_type; /* holds object type or stripe idx when passing it to | |
430 | * OST for saving into EA. */ | |
431 | }; | |
432 | ||
433 | #define UUID_MAX 40 | |
434 | struct obd_uuid { | |
435 | char uuid[UUID_MAX]; | |
436 | }; | |
437 | ||
211b3168 JL |
438 | static inline bool obd_uuid_equals(const struct obd_uuid *u1, |
439 | const struct obd_uuid *u2) | |
d7e09d03 PT |
440 | { |
441 | return strcmp((char *)u1->uuid, (char *)u2->uuid) == 0; | |
442 | } | |
443 | ||
444 | static inline int obd_uuid_empty(struct obd_uuid *uuid) | |
445 | { | |
446 | return uuid->uuid[0] == '\0'; | |
447 | } | |
448 | ||
449 | static inline void obd_str2uuid(struct obd_uuid *uuid, const char *tmp) | |
450 | { | |
451 | strncpy((char *)uuid->uuid, tmp, sizeof(*uuid)); | |
452 | uuid->uuid[sizeof(*uuid) - 1] = '\0'; | |
453 | } | |
454 | ||
455 | /* For printf's only, make sure uuid is terminated */ | |
1ecc2061 | 456 | static inline char *obd_uuid2str(const struct obd_uuid *uuid) |
d7e09d03 | 457 | { |
a739735c SB |
458 | if (!uuid) |
459 | return NULL; | |
460 | ||
d7e09d03 PT |
461 | if (uuid->uuid[sizeof(*uuid) - 1] != '\0') { |
462 | /* Obviously not safe, but for printfs, no real harm done... | |
c56e256d OD |
463 | * we're always null-terminated, even in a race. |
464 | */ | |
d7e09d03 | 465 | static char temp[sizeof(*uuid)]; |
50ffcb7e | 466 | |
d7e09d03 PT |
467 | memcpy(temp, uuid->uuid, sizeof(*uuid) - 1); |
468 | temp[sizeof(*uuid) - 1] = '\0'; | |
469 | return temp; | |
470 | } | |
471 | return (char *)(uuid->uuid); | |
472 | } | |
473 | ||
474 | /* Extract fsname from uuid (or target name) of a target | |
c56e256d OD |
475 | * e.g. (myfs-OST0007_UUID -> myfs) |
476 | * see also deuuidify. | |
477 | */ | |
d7e09d03 PT |
478 | static inline void obd_uuid2fsname(char *buf, char *uuid, int buflen) |
479 | { | |
480 | char *p; | |
481 | ||
482 | strncpy(buf, uuid, buflen - 1); | |
483 | buf[buflen - 1] = '\0'; | |
484 | p = strrchr(buf, '-'); | |
485 | if (p) | |
defa220f | 486 | *p = '\0'; |
d7e09d03 PT |
487 | } |
488 | ||
489 | /* printf display format | |
c56e256d OD |
490 | * e.g. printf("file FID is "DFID"\n", PFID(fid)); |
491 | */ | |
001f5487 | 492 | #define FID_NOBRACE_LEN 40 |
493 | #define FID_LEN (FID_NOBRACE_LEN + 2) | |
55f5a824 | 494 | #define DFID_NOBRACE "%#llx:0x%x:0x%x" |
d7e09d03 PT |
495 | #define DFID "["DFID_NOBRACE"]" |
496 | #define PFID(fid) \ | |
497 | (fid)->f_seq, \ | |
498 | (fid)->f_oid, \ | |
499 | (fid)->f_ver | |
500 | ||
501 | /* scanf input parse format -- strip '[' first. | |
c56e256d OD |
502 | * e.g. sscanf(fidstr, SFID, RFID(&fid)); |
503 | */ | |
f7941e4d | 504 | #define SFID "0x%llx:0x%x:0x%x" |
d7e09d03 PT |
505 | #define RFID(fid) \ |
506 | &((fid)->f_seq), \ | |
507 | &((fid)->f_oid), \ | |
508 | &((fid)->f_ver) | |
509 | ||
d7e09d03 PT |
510 | /********* Quotas **********/ |
511 | ||
00c0a6ae JH |
512 | #define Q_QUOTACHECK 0x800100 /* deprecated as of 2.4 */ |
513 | #define Q_INITQUOTA 0x800101 /* deprecated as of 2.4 */ | |
514 | #define Q_GETOINFO 0x800102 /* get obd quota info */ | |
515 | #define Q_GETOQUOTA 0x800103 /* get obd quotas */ | |
516 | #define Q_FINVALIDATE 0x800104 /* deprecated as of 2.4 */ | |
517 | ||
d7e09d03 PT |
518 | /* these must be explicitly translated into linux Q_* in ll_dir_ioctl */ |
519 | #define LUSTRE_Q_QUOTAON 0x800002 /* turn quotas on */ | |
520 | #define LUSTRE_Q_QUOTAOFF 0x800003 /* turn quotas off */ | |
521 | #define LUSTRE_Q_GETINFO 0x800005 /* get information about quota files */ | |
522 | #define LUSTRE_Q_SETINFO 0x800006 /* set information about quota files */ | |
523 | #define LUSTRE_Q_GETQUOTA 0x800007 /* get user quota structure */ | |
524 | #define LUSTRE_Q_SETQUOTA 0x800008 /* set user quota structure */ | |
525 | /* lustre-specific control commands */ | |
526 | #define LUSTRE_Q_INVALIDATE 0x80000b /* invalidate quota data */ | |
527 | #define LUSTRE_Q_FINVALIDATE 0x80000c /* invalidate filter quota data */ | |
528 | ||
529 | #define UGQUOTA 2 /* set both USRQUOTA and GRPQUOTA */ | |
530 | ||
531 | struct if_quotacheck { | |
532 | char obd_type[16]; | |
533 | struct obd_uuid obd_uuid; | |
534 | }; | |
535 | ||
536 | #define IDENTITY_DOWNCALL_MAGIC 0x6d6dd629 | |
537 | ||
538 | /* permission */ | |
539 | #define N_PERMS_MAX 64 | |
540 | ||
541 | struct perm_downcall_data { | |
542 | __u64 pdd_nid; | |
543 | __u32 pdd_perm; | |
544 | __u32 pdd_padding; | |
545 | }; | |
546 | ||
547 | struct identity_downcall_data { | |
548 | __u32 idd_magic; | |
549 | __u32 idd_err; | |
550 | __u32 idd_uid; | |
551 | __u32 idd_gid; | |
552 | __u32 idd_nperms; | |
553 | __u32 idd_ngroups; | |
554 | struct perm_downcall_data idd_perms[N_PERMS_MAX]; | |
555 | __u32 idd_groups[0]; | |
556 | }; | |
557 | ||
d7e09d03 PT |
558 | /* lustre volatile file support |
559 | * file name header: .^L^S^T^R:volatile" | |
560 | */ | |
561 | #define LUSTRE_VOLATILE_HDR ".\x0c\x13\x14\x12:VOLATILE" | |
562 | #define LUSTRE_VOLATILE_HDR_LEN 14 | |
563 | /* hdr + MDT index */ | |
564 | #define LUSTRE_VOLATILE_IDX LUSTRE_VOLATILE_HDR":%.4X:" | |
565 | ||
52c902fc | 566 | enum lustre_quota_version { |
d7e09d03 | 567 | LUSTRE_QUOTA_V2 = 1 |
52c902fc | 568 | }; |
d7e09d03 PT |
569 | |
570 | /* XXX: same as if_dqinfo struct in kernel */ | |
571 | struct obd_dqinfo { | |
572 | __u64 dqi_bgrace; | |
573 | __u64 dqi_igrace; | |
574 | __u32 dqi_flags; | |
575 | __u32 dqi_valid; | |
576 | }; | |
577 | ||
578 | /* XXX: same as if_dqblk struct in kernel, plus one padding */ | |
579 | struct obd_dqblk { | |
580 | __u64 dqb_bhardlimit; | |
581 | __u64 dqb_bsoftlimit; | |
582 | __u64 dqb_curspace; | |
583 | __u64 dqb_ihardlimit; | |
584 | __u64 dqb_isoftlimit; | |
585 | __u64 dqb_curinodes; | |
586 | __u64 dqb_btime; | |
587 | __u64 dqb_itime; | |
588 | __u32 dqb_valid; | |
589 | __u32 dqb_padding; | |
590 | }; | |
591 | ||
592 | enum { | |
593 | QC_GENERAL = 0, | |
594 | QC_MDTIDX = 1, | |
595 | QC_OSTIDX = 2, | |
596 | QC_UUID = 3 | |
597 | }; | |
598 | ||
599 | struct if_quotactl { | |
600 | __u32 qc_cmd; | |
601 | __u32 qc_type; | |
602 | __u32 qc_id; | |
603 | __u32 qc_stat; | |
604 | __u32 qc_valid; | |
605 | __u32 qc_idx; | |
606 | struct obd_dqinfo qc_dqinfo; | |
607 | struct obd_dqblk qc_dqblk; | |
608 | char obd_type[16]; | |
609 | struct obd_uuid obd_uuid; | |
610 | }; | |
611 | ||
612 | /* swap layout flags */ | |
48d23e61 JX |
613 | #define SWAP_LAYOUTS_CHECK_DV1 (1 << 0) |
614 | #define SWAP_LAYOUTS_CHECK_DV2 (1 << 1) | |
615 | #define SWAP_LAYOUTS_KEEP_MTIME (1 << 2) | |
616 | #define SWAP_LAYOUTS_KEEP_ATIME (1 << 3) | |
617 | ||
618 | /* Swap XATTR_NAME_HSM as well, only on the MDT so far */ | |
619 | #define SWAP_LAYOUTS_MDS_HSM (1 << 31) | |
d7e09d03 PT |
620 | struct lustre_swap_layouts { |
621 | __u64 sl_flags; | |
622 | __u32 sl_fd; | |
623 | __u32 sl_gid; | |
624 | __u64 sl_dv1; | |
625 | __u64 sl_dv2; | |
626 | }; | |
627 | ||
d7e09d03 PT |
628 | /********* Changelogs **********/ |
629 | /** Changelog record types */ | |
630 | enum changelog_rec_type { | |
631 | CL_MARK = 0, | |
632 | CL_CREATE = 1, /* namespace */ | |
633 | CL_MKDIR = 2, /* namespace */ | |
634 | CL_HARDLINK = 3, /* namespace */ | |
635 | CL_SOFTLINK = 4, /* namespace */ | |
636 | CL_MKNOD = 5, /* namespace */ | |
637 | CL_UNLINK = 6, /* namespace */ | |
638 | CL_RMDIR = 7, /* namespace */ | |
639 | CL_RENAME = 8, /* namespace */ | |
640 | CL_EXT = 9, /* namespace extended record (2nd half of rename) */ | |
641 | CL_OPEN = 10, /* not currently used */ | |
642 | CL_CLOSE = 11, /* may be written to log only with mtime change */ | |
e11b0b16 | 643 | CL_LAYOUT = 12, /* file layout/striping modified */ |
d7e09d03 PT |
644 | CL_TRUNC = 13, |
645 | CL_SETATTR = 14, | |
646 | CL_XATTR = 15, | |
647 | CL_HSM = 16, /* HSM specific events, see flags */ | |
648 | CL_MTIME = 17, /* Precedence: setattr > mtime > ctime > atime */ | |
649 | CL_CTIME = 18, | |
650 | CL_ATIME = 19, | |
d7e09d03 PT |
651 | CL_LAST |
652 | }; | |
653 | ||
60753e90 MR |
654 | static inline const char *changelog_type2str(int type) |
655 | { | |
d7e09d03 PT |
656 | static const char *changelog_str[] = { |
657 | "MARK", "CREAT", "MKDIR", "HLINK", "SLINK", "MKNOD", "UNLNK", | |
e11b0b16 | 658 | "RMDIR", "RENME", "RNMTO", "OPEN", "CLOSE", "LYOUT", "TRUNC", |
e377988e | 659 | "SATTR", "XATTR", "HSM", "MTIME", "CTIME", "ATIME", |
d7e09d03 PT |
660 | }; |
661 | ||
662 | if (type >= 0 && type < CL_LAST) | |
663 | return changelog_str[type]; | |
664 | return NULL; | |
665 | } | |
666 | ||
667 | /* per-record flags */ | |
668 | #define CLF_VERSION 0x1000 | |
669 | #define CLF_EXT_VERSION 0x2000 | |
670 | #define CLF_FLAGSHIFT 12 | |
671 | #define CLF_FLAGMASK ((1U << CLF_FLAGSHIFT) - 1) | |
672 | #define CLF_VERMASK (~CLF_FLAGMASK) | |
673 | /* Anything under the flagmask may be per-type (if desired) */ | |
674 | /* Flags for unlink */ | |
675 | #define CLF_UNLINK_LAST 0x0001 /* Unlink of last hardlink */ | |
676 | #define CLF_UNLINK_HSM_EXISTS 0x0002 /* File has something in HSM */ | |
677 | /* HSM cleaning needed */ | |
678 | /* Flags for rename */ | |
a7a9ed4b JL |
679 | #define CLF_RENAME_LAST 0x0001 /* rename unlink last hardlink of |
680 | * target | |
681 | */ | |
682 | #define CLF_RENAME_LAST_EXISTS 0x0002 /* rename unlink last hardlink of target | |
683 | * has an archive in backend | |
684 | */ | |
d7e09d03 PT |
685 | |
686 | /* Flags for HSM */ | |
687 | /* 12b used (from high weight to low weight): | |
688 | * 2b for flags | |
689 | * 3b for event | |
690 | * 7b for error code | |
691 | */ | |
692 | #define CLF_HSM_ERR_L 0 /* HSM return code, 7 bits */ | |
693 | #define CLF_HSM_ERR_H 6 | |
694 | #define CLF_HSM_EVENT_L 7 /* HSM event, 3 bits, see enum hsm_event */ | |
695 | #define CLF_HSM_EVENT_H 9 | |
696 | #define CLF_HSM_FLAG_L 10 /* HSM flags, 2 bits, 1 used, 1 spare */ | |
697 | #define CLF_HSM_FLAG_H 11 | |
698 | #define CLF_HSM_SPARE_L 12 /* 4 spare bits */ | |
699 | #define CLF_HSM_SPARE_H 15 | |
700 | #define CLF_HSM_LAST 15 | |
701 | ||
702 | /* Remove bits higher than _h, then extract the value | |
c56e256d OD |
703 | * between _h and _l by shifting lower weigth to bit 0. |
704 | */ | |
d7e09d03 PT |
705 | #define CLF_GET_BITS(_b, _h, _l) (((_b << (CLF_HSM_LAST - _h)) & 0xFFFF) \ |
706 | >> (CLF_HSM_LAST - _h + _l)) | |
707 | ||
708 | #define CLF_HSM_SUCCESS 0x00 | |
709 | #define CLF_HSM_MAXERROR 0x7E | |
710 | #define CLF_HSM_ERROVERFLOW 0x7F | |
711 | ||
712 | #define CLF_HSM_DIRTY 1 /* file is dirty after HSM request end */ | |
713 | ||
714 | /* 3 bits field => 8 values allowed */ | |
715 | enum hsm_event { | |
716 | HE_ARCHIVE = 0, | |
717 | HE_RESTORE = 1, | |
718 | HE_CANCEL = 2, | |
719 | HE_RELEASE = 3, | |
720 | HE_REMOVE = 4, | |
721 | HE_STATE = 5, | |
722 | HE_SPARE1 = 6, | |
723 | HE_SPARE2 = 7, | |
724 | }; | |
725 | ||
726 | static inline enum hsm_event hsm_get_cl_event(__u16 flags) | |
727 | { | |
728 | return CLF_GET_BITS(flags, CLF_HSM_EVENT_H, CLF_HSM_EVENT_L); | |
729 | } | |
730 | ||
731 | static inline void hsm_set_cl_event(int *flags, enum hsm_event he) | |
732 | { | |
733 | *flags |= (he << CLF_HSM_EVENT_L); | |
734 | } | |
735 | ||
736 | static inline __u16 hsm_get_cl_flags(int flags) | |
737 | { | |
738 | return CLF_GET_BITS(flags, CLF_HSM_FLAG_H, CLF_HSM_FLAG_L); | |
739 | } | |
740 | ||
741 | static inline void hsm_set_cl_flags(int *flags, int bits) | |
742 | { | |
743 | *flags |= (bits << CLF_HSM_FLAG_L); | |
744 | } | |
745 | ||
746 | static inline int hsm_get_cl_error(int flags) | |
747 | { | |
748 | return CLF_GET_BITS(flags, CLF_HSM_ERR_H, CLF_HSM_ERR_L); | |
749 | } | |
750 | ||
751 | static inline void hsm_set_cl_error(int *flags, int error) | |
752 | { | |
753 | *flags |= (error << CLF_HSM_ERR_L); | |
754 | } | |
755 | ||
cd94f231 | 756 | #define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 1 + \ |
910827f1 | 757 | sizeof(struct changelog_ext_rec)) |
d7e09d03 PT |
758 | |
759 | struct changelog_rec { | |
760 | __u16 cr_namelen; | |
761 | __u16 cr_flags; /**< (flags&CLF_FLAGMASK)|CLF_VERSION */ | |
762 | __u32 cr_type; /**< \a changelog_rec_type */ | |
763 | __u64 cr_index; /**< changelog record number */ | |
764 | __u64 cr_prev; /**< last index for this target fid */ | |
765 | __u64 cr_time; | |
766 | union { | |
d8f6bc9a | 767 | struct lu_fid cr_tfid; /**< target fid */ |
d7e09d03 PT |
768 | __u32 cr_markerflags; /**< CL_MARK flags */ |
769 | }; | |
d8f6bc9a | 770 | struct lu_fid cr_pfid; /**< parent fid */ |
d7e09d03 | 771 | char cr_name[0]; /**< last element */ |
ae127bf3 | 772 | } __packed; |
d7e09d03 PT |
773 | |
774 | /* changelog_ext_rec is 2*sizeof(lu_fid) bigger than changelog_rec, to save | |
775 | * space, only rename uses changelog_ext_rec, while others use changelog_rec to | |
776 | * store records. | |
777 | */ | |
778 | struct changelog_ext_rec { | |
779 | __u16 cr_namelen; | |
780 | __u16 cr_flags; /**< (flags & CLF_FLAGMASK) | | |
c56e256d OD |
781 | * CLF_EXT_VERSION |
782 | */ | |
d7e09d03 PT |
783 | __u32 cr_type; /**< \a changelog_rec_type */ |
784 | __u64 cr_index; /**< changelog record number */ | |
785 | __u64 cr_prev; /**< last index for this target fid */ | |
786 | __u64 cr_time; | |
787 | union { | |
d8f6bc9a | 788 | struct lu_fid cr_tfid; /**< target fid */ |
d7e09d03 PT |
789 | __u32 cr_markerflags; /**< CL_MARK flags */ |
790 | }; | |
d8f6bc9a OD |
791 | struct lu_fid cr_pfid; /**< target parent fid */ |
792 | struct lu_fid cr_sfid; /**< source fid, or zero */ | |
793 | struct lu_fid cr_spfid; /**< source parent fid, or zero */ | |
d7e09d03 | 794 | char cr_name[0]; /**< last element */ |
ae127bf3 | 795 | } __packed; |
d7e09d03 PT |
796 | |
797 | #define CHANGELOG_REC_EXTENDED(rec) \ | |
798 | (((rec)->cr_flags & CLF_VERMASK) == CLF_EXT_VERSION) | |
799 | ||
800 | static inline int changelog_rec_size(struct changelog_rec *rec) | |
801 | { | |
b2952d62 | 802 | return CHANGELOG_REC_EXTENDED(rec) ? sizeof(struct changelog_ext_rec) : |
d7e09d03 PT |
803 | sizeof(*rec); |
804 | } | |
805 | ||
806 | static inline char *changelog_rec_name(struct changelog_rec *rec) | |
807 | { | |
808 | return CHANGELOG_REC_EXTENDED(rec) ? | |
b2952d62 | 809 | ((struct changelog_ext_rec *)rec)->cr_name : rec->cr_name; |
d7e09d03 PT |
810 | } |
811 | ||
812 | static inline int changelog_rec_snamelen(struct changelog_ext_rec *rec) | |
813 | { | |
814 | return rec->cr_namelen - strlen(rec->cr_name) - 1; | |
815 | } | |
816 | ||
817 | static inline char *changelog_rec_sname(struct changelog_ext_rec *rec) | |
818 | { | |
819 | return rec->cr_name + strlen(rec->cr_name) + 1; | |
820 | } | |
821 | ||
822 | struct ioc_changelog { | |
823 | __u64 icc_recno; | |
824 | __u32 icc_mdtindex; | |
825 | __u32 icc_id; | |
826 | __u32 icc_flags; | |
827 | }; | |
828 | ||
829 | enum changelog_message_type { | |
830 | CL_RECORD = 10, /* message is a changelog_rec */ | |
831 | CL_EOF = 11, /* at end of current changelog */ | |
832 | }; | |
833 | ||
834 | /********* Misc **********/ | |
835 | ||
836 | struct ioc_data_version { | |
837 | __u64 idv_version; | |
838 | __u64 idv_flags; /* See LL_DV_xxx */ | |
839 | }; | |
c9f6bb96 | 840 | |
e1798006 JX |
841 | #define LL_DV_RD_FLUSH BIT(0) /* Flush dirty pages from clients */ |
842 | #define LL_DV_WR_FLUSH BIT(1) /* Flush all caching pages from clients */ | |
d7e09d03 PT |
843 | |
844 | #ifndef offsetof | |
1d8cb70c | 845 | # define offsetof(typ, memb) ((unsigned long)((char *)&(((typ *)0)->memb))) |
d7e09d03 PT |
846 | #endif |
847 | ||
848 | #define dot_lustre_name ".lustre" | |
849 | ||
d7e09d03 PT |
850 | /********* HSM **********/ |
851 | ||
852 | /** HSM per-file state | |
853 | * See HSM_FLAGS below. | |
854 | */ | |
855 | enum hsm_states { | |
856 | HS_EXISTS = 0x00000001, | |
857 | HS_DIRTY = 0x00000002, | |
858 | HS_RELEASED = 0x00000004, | |
859 | HS_ARCHIVED = 0x00000008, | |
860 | HS_NORELEASE = 0x00000010, | |
861 | HS_NOARCHIVE = 0x00000020, | |
862 | HS_LOST = 0x00000040, | |
863 | }; | |
864 | ||
865 | /* HSM user-setable flags. */ | |
866 | #define HSM_USER_MASK (HS_NORELEASE | HS_NOARCHIVE | HS_DIRTY) | |
867 | ||
868 | /* Other HSM flags. */ | |
869 | #define HSM_STATUS_MASK (HS_EXISTS | HS_LOST | HS_RELEASED | HS_ARCHIVED) | |
870 | ||
871 | /* | |
872 | * All HSM-related possible flags that could be applied to a file. | |
873 | * This should be kept in sync with hsm_states. | |
874 | */ | |
875 | #define HSM_FLAGS_MASK (HSM_USER_MASK | HSM_STATUS_MASK) | |
876 | ||
877 | /** | |
878 | * HSMÂ request progress state | |
879 | */ | |
880 | enum hsm_progress_states { | |
881 | HPS_WAITING = 1, | |
882 | HPS_RUNNING = 2, | |
883 | HPS_DONE = 3, | |
884 | }; | |
c9f6bb96 | 885 | |
d7e09d03 PT |
886 | #define HPS_NONE 0 |
887 | ||
888 | static inline char *hsm_progress_state2name(enum hsm_progress_states s) | |
889 | { | |
890 | switch (s) { | |
891 | case HPS_WAITING: return "waiting"; | |
892 | case HPS_RUNNING: return "running"; | |
893 | case HPS_DONE: return "done"; | |
894 | default: return "unknown"; | |
895 | } | |
896 | } | |
897 | ||
898 | struct hsm_extent { | |
899 | __u64 offset; | |
900 | __u64 length; | |
ae127bf3 | 901 | } __packed; |
d7e09d03 PT |
902 | |
903 | /** | |
904 | * Current HSM states of a Lustre file. | |
905 | * | |
906 | * This structure purpose is to be sent to user-space mainly. It describes the | |
907 | * current HSM flags and in-progress action. | |
908 | */ | |
909 | struct hsm_user_state { | |
910 | /** Current HSM states, from enum hsm_states. */ | |
911 | __u32 hus_states; | |
912 | __u32 hus_archive_id; | |
913 | /** The current undergoing action, if there is one */ | |
914 | __u32 hus_in_progress_state; | |
915 | __u32 hus_in_progress_action; | |
916 | struct hsm_extent hus_in_progress_location; | |
917 | char hus_extended_info[]; | |
918 | }; | |
919 | ||
920 | struct hsm_state_set_ioc { | |
921 | struct lu_fid hssi_fid; | |
922 | __u64 hssi_setmask; | |
923 | __u64 hssi_clearmask; | |
924 | }; | |
925 | ||
926 | /* | |
927 | * This structure describes the current in-progress action for a file. | |
f16192ed | 928 | * it is returned to user space and send over the wire |
d7e09d03 PT |
929 | */ |
930 | struct hsm_current_action { | |
931 | /** The current undergoing action, if there is one */ | |
932 | /* state is one of hsm_progress_states */ | |
933 | __u32 hca_state; | |
934 | /* action is one of hsm_user_action */ | |
935 | __u32 hca_action; | |
936 | struct hsm_extent hca_location; | |
937 | }; | |
938 | ||
939 | /***** HSM user requests ******/ | |
940 | /* User-generated (lfs/ioctl) request types */ | |
941 | enum hsm_user_action { | |
942 | HUA_NONE = 1, /* no action (noop) */ | |
943 | HUA_ARCHIVE = 10, /* copy to hsm */ | |
944 | HUA_RESTORE = 11, /* prestage */ | |
945 | HUA_RELEASE = 12, /* drop ost objects */ | |
946 | HUA_REMOVE = 13, /* remove from archive */ | |
947 | HUA_CANCEL = 14 /* cancel a request */ | |
948 | }; | |
949 | ||
950 | static inline char *hsm_user_action2name(enum hsm_user_action a) | |
951 | { | |
952 | switch (a) { | |
953 | case HUA_NONE: return "NOOP"; | |
954 | case HUA_ARCHIVE: return "ARCHIVE"; | |
955 | case HUA_RESTORE: return "RESTORE"; | |
956 | case HUA_RELEASE: return "RELEASE"; | |
957 | case HUA_REMOVE: return "REMOVE"; | |
958 | case HUA_CANCEL: return "CANCEL"; | |
959 | default: return "UNKNOWN"; | |
960 | } | |
961 | } | |
962 | ||
963 | /* | |
964 | * List of hr_flags (bit field) | |
965 | */ | |
966 | #define HSM_FORCE_ACTION 0x0001 | |
967 | /* used by CT, connot be set by user */ | |
968 | #define HSM_GHOST_COPY 0x0002 | |
969 | ||
970 | /** | |
971 | * Contains all the fixed part of struct hsm_user_request. | |
972 | * | |
973 | */ | |
974 | struct hsm_request { | |
975 | __u32 hr_action; /* enum hsm_user_action */ | |
976 | __u32 hr_archive_id; /* archive id, used only with HUA_ARCHIVE */ | |
977 | __u64 hr_flags; /* request flags */ | |
978 | __u32 hr_itemcount; /* item count in hur_user_item vector */ | |
979 | __u32 hr_data_len; | |
980 | }; | |
981 | ||
982 | struct hsm_user_item { | |
d8f6bc9a OD |
983 | struct lu_fid hui_fid; |
984 | struct hsm_extent hui_extent; | |
ae127bf3 | 985 | } __packed; |
d7e09d03 PT |
986 | |
987 | struct hsm_user_request { | |
988 | struct hsm_request hur_request; | |
989 | struct hsm_user_item hur_user_item[0]; | |
990 | /* extra data blob at end of struct (after all | |
991 | * hur_user_items), only use helpers to access it | |
992 | */ | |
ae127bf3 | 993 | } __packed; |
d7e09d03 PT |
994 | |
995 | /** Return pointer to data field in a hsm user request */ | |
996 | static inline void *hur_data(struct hsm_user_request *hur) | |
997 | { | |
49880263 | 998 | return &hur->hur_user_item[hur->hur_request.hr_itemcount]; |
d7e09d03 PT |
999 | } |
1000 | ||
6b2eb32e NC |
1001 | /** |
1002 | * Compute the current length of the provided hsm_user_request. This returns -1 | |
1003 | * instead of an errno because ssize_t is defined to be only [ -1, SSIZE_MAX ] | |
1004 | * | |
1005 | * return -1 on bounds check error. | |
1006 | */ | |
1007 | static inline ssize_t hur_len(struct hsm_user_request *hur) | |
d7e09d03 | 1008 | { |
6b2eb32e NC |
1009 | __u64 size; |
1010 | ||
1011 | /* can't overflow a __u64 since hr_itemcount is only __u32 */ | |
1012 | size = offsetof(struct hsm_user_request, hur_user_item[0]) + | |
1013 | (__u64)hur->hur_request.hr_itemcount * | |
1014 | sizeof(hur->hur_user_item[0]) + hur->hur_request.hr_data_len; | |
1015 | ||
1016 | if (size != (ssize_t)size) | |
1017 | return -1; | |
1018 | ||
1019 | return size; | |
d7e09d03 PT |
1020 | } |
1021 | ||
1022 | /****** HSM RPCs to copytool *****/ | |
1023 | /* Message types the copytool may receive */ | |
1024 | enum hsm_message_type { | |
1025 | HMT_ACTION_LIST = 100, /* message is a hsm_action_list */ | |
1026 | }; | |
1027 | ||
1028 | /* Actions the copytool may be instructed to take for a given action_item */ | |
1029 | enum hsm_copytool_action { | |
1030 | HSMA_NONE = 10, /* no action */ | |
1031 | HSMA_ARCHIVE = 20, /* arbitrary offset */ | |
1032 | HSMA_RESTORE = 21, | |
1033 | HSMA_REMOVE = 22, | |
1034 | HSMA_CANCEL = 23 | |
1035 | }; | |
1036 | ||
1037 | static inline char *hsm_copytool_action2name(enum hsm_copytool_action a) | |
1038 | { | |
1039 | switch (a) { | |
1040 | case HSMA_NONE: return "NOOP"; | |
1041 | case HSMA_ARCHIVE: return "ARCHIVE"; | |
1042 | case HSMA_RESTORE: return "RESTORE"; | |
1043 | case HSMA_REMOVE: return "REMOVE"; | |
1044 | case HSMA_CANCEL: return "CANCEL"; | |
1045 | default: return "UNKNOWN"; | |
1046 | } | |
1047 | } | |
1048 | ||
1049 | /* Copytool item action description */ | |
1050 | struct hsm_action_item { | |
1051 | __u32 hai_len; /* valid size of this struct */ | |
1052 | __u32 hai_action; /* hsm_copytool_action, but use known size */ | |
d8f6bc9a OD |
1053 | struct lu_fid hai_fid; /* Lustre FID to operated on */ |
1054 | struct lu_fid hai_dfid; /* fid used for data access */ | |
d7e09d03 PT |
1055 | struct hsm_extent hai_extent; /* byte range to operate on */ |
1056 | __u64 hai_cookie; /* action cookie from coordinator */ | |
1057 | __u64 hai_gid; /* grouplock id */ | |
1058 | char hai_data[0]; /* variable length */ | |
ae127bf3 | 1059 | } __packed; |
d7e09d03 PT |
1060 | |
1061 | /* | |
1062 | * helper function which print in hexa the first bytes of | |
1063 | * hai opaque field | |
1064 | * \param hai [IN] record to print | |
1065 | * \param buffer [OUT] output buffer | |
1066 | * \param len [IN] max buffer len | |
1067 | * \retval buffer | |
1068 | */ | |
1069 | static inline char *hai_dump_data_field(struct hsm_action_item *hai, | |
1070 | char *buffer, int len) | |
1071 | { | |
1072 | int i, sz, data_len; | |
1073 | char *ptr; | |
1074 | ||
1075 | ptr = buffer; | |
1076 | sz = len; | |
1077 | data_len = hai->hai_len - sizeof(*hai); | |
9d0b2b7a | 1078 | for (i = 0 ; (i < data_len) && (sz > 0) ; i++) { |
d7e09d03 PT |
1079 | int cnt; |
1080 | ||
1081 | cnt = snprintf(ptr, sz, "%.2X", | |
1082 | (unsigned char)hai->hai_data[i]); | |
1083 | ptr += cnt; | |
1084 | sz -= cnt; | |
1085 | } | |
1086 | *ptr = '\0'; | |
1087 | return buffer; | |
1088 | } | |
1089 | ||
1090 | /* Copytool action list */ | |
1091 | #define HAL_VERSION 1 | |
1092 | #define HAL_MAXSIZE LNET_MTU /* bytes, used in userspace only */ | |
1093 | struct hsm_action_list { | |
1094 | __u32 hal_version; | |
1095 | __u32 hal_count; /* number of hai's to follow */ | |
1096 | __u64 hal_compound_id; /* returned by coordinator */ | |
1097 | __u64 hal_flags; | |
1098 | __u32 hal_archive_id; /* which archive backend */ | |
1099 | __u32 padding1; | |
1100 | char hal_fsname[0]; /* null-terminated */ | |
1101 | /* struct hsm_action_item[hal_count] follows, aligned on 8-byte | |
18ecab0d | 1102 | * boundaries. See hai_first |
c56e256d | 1103 | */ |
ae127bf3 | 1104 | } __packed; |
d7e09d03 PT |
1105 | |
1106 | #ifndef HAVE_CFS_SIZE_ROUND | |
e9570b49 | 1107 | static inline int cfs_size_round(int val) |
d7e09d03 PT |
1108 | { |
1109 | return (val + 7) & (~0x7); | |
1110 | } | |
c9f6bb96 | 1111 | |
d7e09d03 PT |
1112 | #define HAVE_CFS_SIZE_ROUND |
1113 | #endif | |
1114 | ||
1115 | /* Return pointer to first hai in action list */ | |
18ecab0d | 1116 | static inline struct hsm_action_item *hai_first(struct hsm_action_list *hal) |
d7e09d03 PT |
1117 | { |
1118 | return (struct hsm_action_item *)(hal->hal_fsname + | |
1119 | cfs_size_round(strlen(hal-> \ | |
5d0d422e PT |
1120 | hal_fsname) |
1121 | + 1)); | |
d7e09d03 | 1122 | } |
c9f6bb96 | 1123 | |
d7e09d03 | 1124 | /* Return pointer to next hai */ |
aff9d8e8 | 1125 | static inline struct hsm_action_item *hai_next(struct hsm_action_item *hai) |
d7e09d03 PT |
1126 | { |
1127 | return (struct hsm_action_item *)((char *)hai + | |
1128 | cfs_size_round(hai->hai_len)); | |
1129 | } | |
1130 | ||
1131 | /* Return size of an hsm_action_list */ | |
1132 | static inline int hal_size(struct hsm_action_list *hal) | |
1133 | { | |
1134 | int i, sz; | |
1135 | struct hsm_action_item *hai; | |
1136 | ||
5d0d422e | 1137 | sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname) + 1); |
18ecab0d | 1138 | hai = hai_first(hal); |
18dfaebf | 1139 | for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) |
d7e09d03 | 1140 | sz += cfs_size_round(hai->hai_len); |
18dfaebf JL |
1141 | |
1142 | return sz; | |
d7e09d03 PT |
1143 | } |
1144 | ||
a720b790 JL |
1145 | /* HSM file import |
1146 | * describe the attributes to be set on imported file | |
1147 | */ | |
1148 | struct hsm_user_import { | |
1149 | __u64 hui_size; | |
1150 | __u64 hui_atime; | |
1151 | __u64 hui_mtime; | |
1152 | __u32 hui_atime_ns; | |
1153 | __u32 hui_mtime_ns; | |
1154 | __u32 hui_uid; | |
1155 | __u32 hui_gid; | |
1156 | __u32 hui_mode; | |
1157 | __u32 hui_archive_id; | |
1158 | }; | |
1159 | ||
d7e09d03 PT |
1160 | /* Copytool progress reporting */ |
1161 | #define HP_FLAG_COMPLETED 0x01 | |
1162 | #define HP_FLAG_RETRY 0x02 | |
1163 | ||
1164 | struct hsm_progress { | |
d8f6bc9a | 1165 | struct lu_fid hp_fid; |
d7e09d03 PT |
1166 | __u64 hp_cookie; |
1167 | struct hsm_extent hp_extent; | |
1168 | __u16 hp_flags; | |
1169 | __u16 hp_errval; /* positive val */ | |
1170 | __u32 padding; | |
1171 | }; | |
1172 | ||
d7e09d03 PT |
1173 | struct hsm_copy { |
1174 | __u64 hc_data_version; | |
1175 | __u16 hc_flags; | |
1176 | __u16 hc_errval; /* positive val */ | |
1177 | __u32 padding; | |
1178 | struct hsm_action_item hc_hai; | |
1179 | }; | |
1180 | ||
1181 | /** @} lustreuser */ | |
1182 | ||
1183 | #endif /* _LUSTRE_USER_H */ |