Whamcloud - gitweb
5a5d3bca4ca0d8b4ad7bda8f6498d4bbe7f26ed4
[fs/lustre-release.git] / lustre / include / 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, 2014, 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 _LUSTRE_OSTID_H_
35 #define _LUSTRE_OSTID_H_
36
37 #include <libcfs/libcfs.h>
38 #include <lustre/lustre_fid.h>
39 #include <lustre/lustre_idl.h>
40
41 static inline __u64 lmm_oi_id(const struct ost_id *oi)
42 {
43         return oi->oi.oi_id;
44 }
45
46 static inline __u64 lmm_oi_seq(const struct ost_id *oi)
47 {
48         return oi->oi.oi_seq;
49 }
50
51 static inline void lmm_oi_set_seq(struct ost_id *oi, __u64 seq)
52 {
53         oi->oi.oi_seq = seq;
54 }
55
56 static inline void lmm_oi_set_id(struct ost_id *oi, __u64 oid)
57 {
58         oi->oi.oi_id = oid;
59 }
60
61 static inline void lmm_oi_le_to_cpu(struct ost_id *dst_oi,
62                                     const struct ost_id *src_oi)
63 {
64         dst_oi->oi.oi_id = __le64_to_cpu(src_oi->oi.oi_id);
65         dst_oi->oi.oi_seq = __le64_to_cpu(src_oi->oi.oi_seq);
66 }
67
68 static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
69                                     const struct ost_id *src_oi)
70 {
71         dst_oi->oi.oi_id = __cpu_to_le64(src_oi->oi.oi_id);
72         dst_oi->oi.oi_seq = __cpu_to_le64(src_oi->oi.oi_seq);
73 }
74
75 /* extract OST sequence (group) from a wire ost_id (id/seq) pair */
76 static inline __u64 ostid_seq(const struct ost_id *ostid)
77 {
78         if (fid_seq_is_mdt0(ostid->oi.oi_seq))
79                 return FID_SEQ_OST_MDT0;
80
81         if (unlikely(fid_seq_is_default(ostid->oi.oi_seq)))
82                 return FID_SEQ_LOV_DEFAULT;
83
84         if (fid_is_idif(&ostid->oi_fid))
85                 return FID_SEQ_OST_MDT0;
86
87         return fid_seq(&ostid->oi_fid);
88 }
89
90 /* extract OST objid from a wire ost_id (id/seq) pair */
91 static inline __u64 ostid_id(const struct ost_id *ostid)
92 {
93         if (fid_seq_is_mdt0(ostid->oi.oi_seq))
94                 return ostid->oi.oi_id & IDIF_OID_MASK;
95
96         if (unlikely(fid_seq_is_default(ostid->oi.oi_seq)))
97                 return ostid->oi.oi_id;
98
99         if (fid_is_idif(&ostid->oi_fid))
100                 return fid_idif_id(fid_seq(&ostid->oi_fid),
101                                    fid_oid(&ostid->oi_fid), 0);
102
103         return fid_oid(&ostid->oi_fid);
104 }
105
106 static inline void ostid_set_seq(struct ost_id *oi, __u64 seq)
107 {
108         if (fid_seq_is_mdt0(seq) || fid_seq_is_default(seq)) {
109                 oi->oi.oi_seq = seq;
110         } else {
111                 oi->oi_fid.f_seq = seq;
112                 /*
113                  * Note: if f_oid + f_ver is zero, we need init it
114                  * to be 1, otherwise, ostid_seq will treat this
115                  * as old ostid (oi_seq == 0)
116                  */
117                 if (!oi->oi_fid.f_oid && !oi->oi_fid.f_ver)
118                         oi->oi_fid.f_oid = LUSTRE_FID_INIT_OID;
119         }
120 }
121
122 static inline void ostid_set_seq_mdt0(struct ost_id *oi)
123 {
124         ostid_set_seq(oi, FID_SEQ_OST_MDT0);
125 }
126
127 static inline void ostid_set_seq_echo(struct ost_id *oi)
128 {
129         ostid_set_seq(oi, FID_SEQ_ECHO);
130 }
131
132 static inline void ostid_set_seq_llog(struct ost_id *oi)
133 {
134         ostid_set_seq(oi, FID_SEQ_LLOG);
135 }
136
137 /**
138  * Note: we need check oi_seq to decide where to set oi_id,
139  * so oi_seq should always be set ahead of oi_id.
140  */
141 static inline void ostid_set_id(struct ost_id *oi, __u64 oid)
142 {
143         if (fid_seq_is_mdt0(oi->oi.oi_seq)) {
144                 if (oid >= IDIF_MAX_OID) {
145                         CERROR("Bad %llu to set "DOSTID"\n",
146                                 (unsigned long long)oid, POSTID(oi));
147                         return;
148                 }
149                 oi->oi.oi_id = oid;
150         } else if (fid_is_idif(&oi->oi_fid)) {
151                 if (oid >= IDIF_MAX_OID) {
152                         CERROR("Bad %llu to set "DOSTID"\n",
153                                 (unsigned long long)oid, POSTID(oi));
154                         return;
155                 }
156                 oi->oi_fid.f_seq = fid_idif_seq(oid,
157                                                 fid_idif_ost_idx(&oi->oi_fid));
158                 oi->oi_fid.f_oid = oid;
159                 oi->oi_fid.f_ver = oid >> 48;
160         } else {
161                 if (oid > OBIF_MAX_OID) {
162                         CERROR("Bad %llu to set "DOSTID"\n",
163                                 (unsigned long long)oid, POSTID(oi));
164                         return;
165                 }
166                 oi->oi_fid.f_oid = oid;
167         }
168 }
169
170 static inline void ostid_cpu_to_le(const struct ost_id *src_oi,
171                                    struct ost_id *dst_oi)
172 {
173         if (fid_seq_is_mdt0(src_oi->oi.oi_seq)) {
174                 dst_oi->oi.oi_id = __cpu_to_le64(src_oi->oi.oi_id);
175                 dst_oi->oi.oi_seq = __cpu_to_le64(src_oi->oi.oi_seq);
176         } else {
177                 fid_cpu_to_le(&dst_oi->oi_fid, &src_oi->oi_fid);
178         }
179 }
180
181 static inline void ostid_le_to_cpu(const struct ost_id *src_oi,
182                                    struct ost_id *dst_oi)
183 {
184         if (fid_seq_is_mdt0(src_oi->oi.oi_seq)) {
185                 dst_oi->oi.oi_id = __le64_to_cpu(src_oi->oi.oi_id);
186                 dst_oi->oi.oi_seq = __le64_to_cpu(src_oi->oi.oi_seq);
187         } else {
188                 fid_le_to_cpu(&dst_oi->oi_fid, &src_oi->oi_fid);
189         }
190 }
191
192 /* pack any OST FID into an ostid (id/seq) for the wire/disk */
193 static inline int fid_to_ostid(const struct lu_fid *fid, struct ost_id *ostid)
194 {
195         if (unlikely(fid_seq_is_igif(fid->f_seq))) {
196                 CERROR("bad IGIF, "DFID"\n", PFID(fid));
197                 return -EBADF;
198         }
199
200         if (fid_is_idif(fid)) {
201                 ostid_set_seq_mdt0(ostid);
202                 ostid_set_id(ostid, fid_idif_id(fid_seq(fid), fid_oid(fid),
203                                                 fid_ver(fid)));
204         } else {
205                 ostid->oi_fid = *fid;
206         }
207
208         return 0;
209 }
210
211 /**
212  * Sigh, because pre-2.4 uses
213  * struct lov_mds_md_v1 {
214  *      ........
215  *      __u64 lmm_object_id;
216  *      __u64 lmm_object_seq;
217  *      ......
218  *      }
219  * to identify the LOV(MDT) object, and lmm_object_seq will
220  * be normal_fid, which make it hard to combine these conversion
221  * to ostid_to FID. so we will do lmm_oi/fid conversion separately
222  *
223  * We can tell the lmm_oi by this way,
224  * 1.8: lmm_object_id = {inode}, lmm_object_gr = 0
225  * 2.1: lmm_object_id = {oid < 128k}, lmm_object_seq = FID_SEQ_NORMAL
226  * 2.4: lmm_oi.f_seq = FID_SEQ_NORMAL, lmm_oi.f_oid = {oid < 128k},
227  *      lmm_oi.f_ver = 0
228  *
229  * But currently lmm_oi/lsm_oi does not have any "real" usages,
230  * except for printing some information, and the user can always
231  * get the real FID from LMA, besides this multiple case check might
232  * make swab more complicate. So we will keep using id/seq for lmm_oi.
233  */
234
235 static inline void fid_to_lmm_oi(const struct lu_fid *fid,
236                                  struct ost_id *oi)
237 {
238         oi->oi.oi_id = fid_oid(fid);
239         oi->oi.oi_seq = fid_seq(fid);
240 }
241
242 #endif