4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 021110-1307, USA
24 * Copyright (c) 2013, 2017, Intel Corporation.
25 * Use is subject to license terms.
27 * Author: Di Wang <di.wang@intel.com>
31 #include <lustre_linkea.h>
33 int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf)
35 ldata->ld_buf = lu_buf_check_and_alloc(buf, PAGE_SIZE);
36 if (ldata->ld_buf->lb_buf == NULL)
38 ldata->ld_leh = ldata->ld_buf->lb_buf;
39 ldata->ld_leh->leh_magic = LINK_EA_MAGIC;
40 ldata->ld_leh->leh_reccount = 0;
41 ldata->ld_leh->leh_len = sizeof(struct link_ea_header);
42 ldata->ld_leh->leh_overflow_time = 0;
43 ldata->ld_leh->leh_padding = 0;
46 EXPORT_SYMBOL(linkea_data_new);
48 int linkea_init(struct linkea_data *ldata)
50 struct link_ea_header *leh;
52 LASSERT(ldata->ld_buf != NULL);
53 leh = ldata->ld_buf->lb_buf;
54 if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
55 leh->leh_magic = LINK_EA_MAGIC;
56 leh->leh_reccount = __swab32(leh->leh_reccount);
57 leh->leh_len = __swab64(leh->leh_len);
58 leh->leh_overflow_time = __swab32(leh->leh_overflow_time);
59 leh->leh_padding = __swab32(leh->leh_padding);
60 /* individual entries are swabbed by linkea_entry_unpack() */
63 if (leh->leh_magic != LINK_EA_MAGIC)
66 if (leh->leh_reccount == 0 && leh->leh_overflow_time == 0)
72 EXPORT_SYMBOL(linkea_init);
74 int linkea_init_with_rec(struct linkea_data *ldata)
78 rc = linkea_init(ldata);
79 if (!rc && ldata->ld_leh->leh_reccount == 0)
84 EXPORT_SYMBOL(linkea_init_with_rec);
87 * Pack a link_ea_entry.
88 * All elements are stored as chars to avoid alignment issues.
89 * Numbers are always big-endian
90 * \retval record length
92 int linkea_entry_pack(struct link_ea_entry *lee, const struct lu_name *lname,
93 const struct lu_fid *pfid)
99 if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_MUL_REF))
101 if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_LINKEA_CRASH))
103 fid_cpu_to_be(&tmpfid, &tmpfid);
104 memcpy(&lee->lee_parent_fid, &tmpfid, sizeof(tmpfid));
105 memcpy(lee->lee_name, lname->ln_name, lname->ln_namelen);
106 reclen = sizeof(struct link_ea_entry) + lname->ln_namelen;
108 lee->lee_reclen[0] = (reclen >> 8) & 0xff;
109 lee->lee_reclen[1] = reclen & 0xff;
112 EXPORT_SYMBOL(linkea_entry_pack);
114 void linkea_entry_unpack(const struct link_ea_entry *lee, int *reclen,
115 struct lu_name *lname, struct lu_fid *pfid)
117 LASSERT(lee != NULL);
119 *reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1];
120 memcpy(pfid, &lee->lee_parent_fid, sizeof(*pfid));
121 fid_be_to_cpu(pfid, pfid);
123 lname->ln_name = lee->lee_name;
124 lname->ln_namelen = *reclen - sizeof(struct link_ea_entry);
127 EXPORT_SYMBOL(linkea_entry_unpack);
129 bool linkea_will_overflow(struct linkea_data *ldata,
130 const struct lu_name *lname)
132 struct link_ea_header *leh = ldata->ld_leh;
133 int reclen = lname->ln_namelen + sizeof(struct link_ea_entry);
135 if (unlikely(leh->leh_len + reclen > MAX_LINKEA_SIZE))
139 EXPORT_SYMBOL(linkea_will_overflow);
142 * Add a record to the end of link ea buf
144 int linkea_add_buf(struct linkea_data *ldata, const struct lu_name *lname,
145 const struct lu_fid *pfid, bool err_on_overflow)
147 struct link_ea_header *leh = ldata->ld_leh;
150 LASSERT(leh != NULL);
152 if (lname == NULL || pfid == NULL)
155 reclen = lname->ln_namelen + sizeof(struct link_ea_entry);
156 if (unlikely(leh->leh_len + reclen > MAX_LINKEA_SIZE)) {
157 /* Use 32-bits to save the overflow time, although it will
158 * shrink the ktime_get_real_seconds() returned 64-bits value
159 * to 32-bits value, it is still quite large and can be used
160 * for about 140 years. That is enough.
162 leh->leh_overflow_time = ktime_get_real_seconds();
163 if (unlikely(leh->leh_overflow_time == 0))
164 leh->leh_overflow_time++;
166 CDEBUG(D_INODE, "No enough space to hold linkea entry '"
167 DFID": %.*s' at %u\n", PFID(pfid), lname->ln_namelen,
168 lname->ln_name, leh->leh_overflow_time);
169 return err_on_overflow ? -EOVERFLOW : 0;
172 if (leh->leh_len + reclen > ldata->ld_buf->lb_len) {
173 if (lu_buf_check_and_grow(ldata->ld_buf,
174 leh->leh_len + reclen) < 0)
177 leh = ldata->ld_leh = ldata->ld_buf->lb_buf;
180 ldata->ld_lee = ldata->ld_buf->lb_buf + leh->leh_len;
181 ldata->ld_reclen = linkea_entry_pack(ldata->ld_lee, lname, pfid);
182 leh->leh_len += ldata->ld_reclen;
186 "New link_ea name '"DFID":<encrypted (%d)>' is added\n",
187 PFID(pfid), lname->ln_namelen);
189 CDEBUG(D_INODE, "New link_ea name '"DFID":%.*s' is added\n",
190 PFID(pfid), lname->ln_namelen, lname->ln_name);
193 EXPORT_SYMBOL(linkea_add_buf);
195 /** Del the current record from the link ea buf */
196 void linkea_del_buf(struct linkea_data *ldata, const struct lu_name *lname,
199 LASSERT(ldata->ld_leh != NULL && ldata->ld_lee != NULL);
200 LASSERT(ldata->ld_leh->leh_reccount > 0);
202 ldata->ld_leh->leh_reccount--;
203 ldata->ld_leh->leh_len -= ldata->ld_reclen;
204 memmove(ldata->ld_lee, (char *)ldata->ld_lee + ldata->ld_reclen,
205 (char *)ldata->ld_leh + ldata->ld_leh->leh_len -
206 (char *)ldata->ld_lee);
209 "Old link_ea name '<encrypted (%d)>' is removed\n",
212 CDEBUG(D_INODE, "Old link_ea name '%.*s' is removed\n",
213 lname->ln_namelen, lname->ln_name);
215 if ((char *)ldata->ld_lee >= ((char *)ldata->ld_leh +
216 ldata->ld_leh->leh_len))
217 ldata->ld_lee = NULL;
219 EXPORT_SYMBOL(linkea_del_buf);
221 int linkea_links_new(struct linkea_data *ldata, struct lu_buf *buf,
222 const struct lu_name *cname, const struct lu_fid *pfid)
226 rc = linkea_data_new(ldata, buf);
228 rc = linkea_add_buf(ldata, cname, pfid, false);
232 EXPORT_SYMBOL(linkea_links_new);
235 * Mark the linkEA as overflow with current timestamp,
236 * and remove the last linkEA entry.
238 * Return the new linkEA size.
240 int linkea_overflow_shrink(struct linkea_data *ldata)
242 struct link_ea_header *leh;
243 struct lu_name tname;
247 leh = ldata->ld_leh = ldata->ld_buf->lb_buf;
248 if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
249 leh->leh_magic = LINK_EA_MAGIC;
250 leh->leh_reccount = __swab32(leh->leh_reccount);
251 leh->leh_overflow_time = __swab32(leh->leh_overflow_time);
252 leh->leh_padding = __swab32(leh->leh_padding);
255 LASSERT(leh->leh_reccount > 0);
257 leh->leh_len = sizeof(struct link_ea_header);
259 if (unlikely(leh->leh_reccount == 0))
262 leh->leh_overflow_time = ktime_get_real_seconds();
263 if (unlikely(leh->leh_overflow_time == 0))
264 leh->leh_overflow_time++;
265 ldata->ld_reclen = 0;
266 ldata->ld_lee = (struct link_ea_entry *)(leh + 1);
267 for (count = 0; count < leh->leh_reccount; count++) {
268 linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen,
270 leh->leh_len += ldata->ld_reclen;
271 ldata->ld_lee = (struct link_ea_entry *)((char *)ldata->ld_lee +
275 linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen, &tname, &tfid);
276 CDEBUG(D_INODE, "No enough space to hold the last linkea entry '"
277 DFID": %.*s', shrink it, left %d linkea entries, size %llu\n",
278 PFID(&tfid), tname.ln_namelen, tname.ln_name,
279 leh->leh_reccount, leh->leh_len);
283 EXPORT_SYMBOL(linkea_overflow_shrink);
286 * Check if such a link exists in linkEA.
288 * \param ldata link data the search to be done on
289 * \param lname name in the parent's directory entry pointing to this object
290 * \param pfid parent fid the link to be found for
293 * \retval -ENOENT link does not exist
294 * \retval -ve on error
296 int linkea_links_find(struct linkea_data *ldata, const struct lu_name *lname,
297 const struct lu_fid *pfid)
299 struct lu_name tmpname;
300 struct lu_fid tmpfid;
303 LASSERT(ldata->ld_leh != NULL);
305 /* link #0, if leh_reccount == 0 we skip the loop and return -ENOENT */
306 if (likely(ldata->ld_leh->leh_reccount > 0))
307 ldata->ld_lee = (struct link_ea_entry *)(ldata->ld_leh + 1);
309 for (count = 0; count < ldata->ld_leh->leh_reccount; count++) {
310 linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen,
312 if (tmpname.ln_namelen == lname->ln_namelen &&
313 lu_fid_eq(&tmpfid, pfid) &&
314 (strncmp(tmpname.ln_name, lname->ln_name,
315 tmpname.ln_namelen) == 0))
317 ldata->ld_lee = (struct link_ea_entry *)((char *)ldata->ld_lee +
321 if (count == ldata->ld_leh->leh_reccount) {
322 CDEBUG(D_INODE, "Old link_ea name '%.*s' not found\n",
323 lname->ln_namelen, lname->ln_name);
324 ldata->ld_lee = NULL;
325 ldata->ld_reclen = 0;
330 EXPORT_SYMBOL(linkea_links_find);