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