Whamcloud - gitweb
4a966407a3a5e985fe56c7d82c01d38610dcdc74
[fs/lustre-release.git] / lustre / include / uapi / linux / lustre / lustre_ostid.h
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
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2017, Intel Corporation.
27  *
28  * Copyright 2015 Cray Inc, all rights reserved.
29  * Author: Ben Evans.
30  *
31  * Define ost_id  associated functions
32  */
33
34 #ifndef _UAPI_LUSTRE_OSTID_H_
35 #define _UAPI_LUSTRE_OSTID_H_
36
37 #include <linux/errno.h>
38 #include <linux/types.h>
39 /*
40  * This is due to us being out of kernel and the way the OpenSFS branch
41  * handles CFLAGS.
42  */
43 #ifdef __KERNEL__
44 #include <uapi/linux/lustre/lustre_fid.h>
45 #else
46 #include <linux/lustre/lustre_fid.h>
47 #endif
48
49 static inline __u64 lmm_oi_id(const struct ost_id *oi)
50 {
51         return oi->oi.oi_id;
52 }
53
54 static inline __u64 lmm_oi_seq(const struct ost_id *oi)
55 {
56         return oi->oi.oi_seq;
57 }
58
59 static inline void lmm_oi_set_seq(struct ost_id *oi, __u64 seq)
60 {
61         oi->oi.oi_seq = seq;
62 }
63
64 static inline void lmm_oi_set_id(struct ost_id *oi, __u64 oid)
65 {
66         oi->oi.oi_id = oid;
67 }
68
69 static inline void lmm_oi_le_to_cpu(struct ost_id *dst_oi,
70                                     const struct ost_id *src_oi)
71 {
72         dst_oi->oi.oi_id = __le64_to_cpu(src_oi->oi.oi_id);
73         dst_oi->oi.oi_seq = __le64_to_cpu(src_oi->oi.oi_seq);
74 }
75
76 static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
77                                     const struct ost_id *src_oi)
78 {
79         dst_oi->oi.oi_id = __cpu_to_le64(src_oi->oi.oi_id);
80         dst_oi->oi.oi_seq = __cpu_to_le64(src_oi->oi.oi_seq);
81 }
82
83 /* extract OST sequence (group) from a wire ost_id (id/seq) pair */
84 static inline __u64 ostid_seq(const struct ost_id *ostid)
85 {
86         if (fid_seq_is_mdt0(ostid->oi.oi_seq))
87                 return FID_SEQ_OST_MDT0;
88
89         if (fid_seq_is_default(ostid->oi.oi_seq))
90                 return FID_SEQ_LOV_DEFAULT;
91
92         if (fid_is_idif(&ostid->oi_fid))
93                 return FID_SEQ_OST_MDT0;
94
95         return fid_seq(&ostid->oi_fid);
96 }
97
98 /* extract OST objid from a wire ost_id (id/seq) pair */
99 static inline __u64 ostid_id(const struct ost_id *ostid)
100 {
101         if (fid_seq_is_mdt0(ostid->oi.oi_seq))
102                 return ostid->oi.oi_id & IDIF_OID_MASK;
103
104         if (fid_seq_is_default(ostid->oi.oi_seq))
105                 return ostid->oi.oi_id;
106
107         if (fid_is_idif(&ostid->oi_fid))
108                 return fid_idif_id(fid_seq(&ostid->oi_fid),
109                                    fid_oid(&ostid->oi_fid), 0);
110
111         return fid_oid(&ostid->oi_fid);
112 }
113
114 static inline void ostid_set_seq(struct ost_id *oi, __u64 seq)
115 {
116         if (fid_seq_is_mdt0(seq) || fid_seq_is_default(seq)) {
117                 oi->oi.oi_seq = seq;
118         } else {
119                 oi->oi_fid.f_seq = seq;
120                 /*
121                  * Note: if f_oid + f_ver is zero, we need init it
122                  * to be 1, otherwise, ostid_seq will treat this
123                  * as old ostid (oi_seq == 0)
124                  */
125                 if (!oi->oi_fid.f_oid && !oi->oi_fid.f_ver)
126                         oi->oi_fid.f_oid = LUSTRE_FID_INIT_OID;
127         }
128 }
129
130 static inline void ostid_set_seq_mdt0(struct ost_id *oi)
131 {
132         ostid_set_seq(oi, FID_SEQ_OST_MDT0);
133 }
134
135 static inline void ostid_set_seq_echo(struct ost_id *oi)
136 {
137         ostid_set_seq(oi, FID_SEQ_ECHO);
138 }
139
140 static inline void ostid_set_seq_llog(struct ost_id *oi)
141 {
142         ostid_set_seq(oi, FID_SEQ_LLOG);
143 }
144
145 static inline void ostid_cpu_to_le(const struct ost_id *src_oi,
146                                    struct ost_id *dst_oi)
147 {
148         if (fid_seq_is_mdt0(src_oi->oi.oi_seq)) {
149                 dst_oi->oi.oi_id = __cpu_to_le64(src_oi->oi.oi_id);
150                 dst_oi->oi.oi_seq = __cpu_to_le64(src_oi->oi.oi_seq);
151         } else {
152                 fid_cpu_to_le(&dst_oi->oi_fid, &src_oi->oi_fid);
153         }
154 }
155
156 static inline void ostid_le_to_cpu(const struct ost_id *src_oi,
157                                    struct ost_id *dst_oi)
158 {
159         if (fid_seq_is_mdt0(src_oi->oi.oi_seq)) {
160                 dst_oi->oi.oi_id = __le64_to_cpu(src_oi->oi.oi_id);
161                 dst_oi->oi.oi_seq = __le64_to_cpu(src_oi->oi.oi_seq);
162         } else {
163                 fid_le_to_cpu(&dst_oi->oi_fid, &src_oi->oi_fid);
164         }
165 }
166
167 /**
168  * Sigh, because pre-2.4 uses
169  * struct lov_mds_md_v1 {
170  *      ........
171  *      __u64 lmm_object_id;
172  *      __u64 lmm_object_seq;
173  *      ......
174  *      }
175  * to identify the LOV(MDT) object, and lmm_object_seq will
176  * be normal_fid, which make it hard to combine these conversion
177  * to ostid_to FID. so we will do lmm_oi/fid conversion separately
178  *
179  * We can tell the lmm_oi by this way,
180  * 1.8: lmm_object_id = {inode}, lmm_object_gr = 0
181  * 2.1: lmm_object_id = {oid < 128k}, lmm_object_seq = FID_SEQ_NORMAL
182  * 2.4: lmm_oi.f_seq = FID_SEQ_NORMAL, lmm_oi.f_oid = {oid < 128k},
183  *      lmm_oi.f_ver = 0
184  *
185  * But currently lmm_oi/lsm_oi does not have any "real" usages,
186  * except for printing some information, and the user can always
187  * get the real FID from LMA, besides this multiple case check might
188  * make swab more complicate. So we will keep using id/seq for lmm_oi.
189  */
190
191 static inline void fid_to_lmm_oi(const struct lu_fid *fid,
192                                  struct ost_id *oi)
193 {
194         oi->oi.oi_id = fid_oid(fid);
195         oi->oi.oi_seq = fid_seq(fid);
196 }
197
198 /**
199  * Unpack an OST object id/seq (group) into a FID.  This is needed for
200  * converting all obdo, lmm, lsm, etc. 64-bit id/seq pairs into proper
201  * FIDs.  Note that if an id/seq is already in FID/IDIF format it will
202  * be passed through unchanged.  Only legacy OST objects in "group 0"
203  * will be mapped into the IDIF namespace so that they can fit into the
204  * struct lu_fid fields without loss.
205  */
206 static inline int ostid_to_fid(struct lu_fid *fid, const struct ost_id *ostid,
207                                __u32 ost_idx)
208 {
209         __u64 seq = ostid_seq(ostid);
210
211         if (ost_idx > 0xffff)
212                 return -EBADF;
213
214         if (fid_seq_is_mdt0(seq)) {
215                 __u64 oid = ostid_id(ostid);
216
217                 /* This is a "legacy" (old 1.x/2.early) OST object in "group 0"
218                  * that we map into the IDIF namespace.  It allows up to 2^48
219                  * objects per OST, as this is the object namespace that has
220                  * been in production for years.  This can handle create rates
221                  * of 1M objects/s/OST for 9 years, or combinations thereof.
222                  */
223                 if (oid >= IDIF_MAX_OID)
224                         return -EBADF;
225
226                 fid->f_seq = fid_idif_seq(oid, ost_idx);
227                 /* truncate to 32 bits by assignment */
228                 fid->f_oid = oid;
229                 /* in theory, not currently used */
230                 fid->f_ver = oid >> 48;
231         } else if (!fid_seq_is_default(seq)) {
232                 /* This is either an IDIF object, which identifies objects
233                  * across all OSTs, or a regular FID.  The IDIF namespace
234                  * maps legacy OST objects into the FID namespace.  In both
235                  * cases, we just pass the FID through, no conversion needed.
236                  */
237                 if (ostid->oi_fid.f_ver)
238                         return -EBADF;
239
240                 *fid = ostid->oi_fid;
241         }
242
243         return 0;
244 }
245 #endif /* _UAPI_LUSTRE_OSTID_H_ */