Whamcloud - gitweb
LU-10308 misc: update Intel copyright messages for 2017
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_oi.c
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) 2012, 2017, Intel Corporation.
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/osd/osd_oi.c
33  *
34  * Object Index.
35  *
36  * Author: Nikita Danilov <nikita@clusterfs.com>
37  */
38
39 #define DEBUG_SUBSYSTEM S_OSD
40
41 #include <linux/module.h>
42
43 /*
44  * struct OBD_{ALLOC,FREE}*()
45  * OBD_FAIL_CHECK
46  */
47 #include <obd.h>
48 #include <obd_support.h>
49
50 /* fid_cpu_to_be() */
51 #include <lustre_fid.h>
52 #include <dt_object.h>
53 #include <lustre_scrub.h>
54
55 #include "osd_oi.h"
56 /* osd_lookup(), struct osd_thread_info */
57 #include "osd_internal.h"
58
59 unsigned int osd_oi_count = OSD_OI_FID_NR;
60 module_param(osd_oi_count, int, 0444);
61 MODULE_PARM_DESC(osd_oi_count, "Number of Object Index containers to be created, it's only valid for new filesystem.");
62
63 static struct dt_index_features oi_feat = {
64         .dif_flags       = DT_IND_UPDATE,
65         .dif_recsize_min = sizeof(struct osd_inode_id),
66         .dif_recsize_max = sizeof(struct osd_inode_id),
67         .dif_ptrsize     = 4
68 };
69
70 #define OSD_OI_NAME_BASE        "oi.16"
71
72 static void osd_oi_table_put(struct osd_thread_info *info,
73                              struct osd_oi **oi_table, unsigned oi_count)
74 {
75         struct iam_container *bag;
76         int                   i;
77
78         for (i = 0; i < oi_count; i++) {
79                 if (oi_table[i] == NULL)
80                         continue;
81
82                 LASSERT(oi_table[i]->oi_inode != NULL);
83
84                 bag = &(oi_table[i]->oi_dir.od_container);
85                 if (bag->ic_object == oi_table[i]->oi_inode)
86                         iam_container_fini(bag);
87                 iput(oi_table[i]->oi_inode);
88                 oi_table[i]->oi_inode = NULL;
89                 OBD_FREE_PTR(oi_table[i]);
90                 oi_table[i] = NULL;
91         }
92 }
93
94 static int osd_oi_index_create_one(struct osd_thread_info *info,
95                                    struct osd_device *osd, const char *name,
96                                    struct dt_index_features *feat)
97 {
98         const struct lu_env             *env = info->oti_env;
99         struct osd_inode_id             *id  = &info->oti_id;
100         struct buffer_head              *bh;
101         struct inode                    *inode;
102         struct ldiskfs_dir_entry_2      *de;
103         struct dentry                   *dentry;
104         struct super_block              *sb  = osd_sb(osd);
105         struct inode                    *dir = sb->s_root->d_inode;
106         handle_t                        *jh;
107         int                              rc;
108
109         dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name));
110         bh = osd_ldiskfs_find_entry(dir, &dentry->d_name, &de, NULL, NULL);
111         if (!IS_ERR(bh)) {
112                 osd_id_gen(id, le32_to_cpu(de->inode), OSD_OII_NOGEN);
113                 brelse(bh);
114                 inode = osd_iget(info, osd, id);
115                 if (!IS_ERR(inode)) {
116                         iput(inode);
117                         inode = ERR_PTR(-EEXIST);
118                 }
119                 return PTR_ERR(inode);
120         }
121
122         if (osd->od_dt_dev.dd_rdonly)
123                 RETURN(-EROFS);
124
125         jh = osd_journal_start_sb(sb, LDISKFS_HT_MISC, 100);
126         if (IS_ERR(jh))
127                 return PTR_ERR(jh);
128
129         inode = ldiskfs_create_inode(jh, dir, (S_IFREG | S_IRUGO | S_IWUSR));
130         if (IS_ERR(inode)) {
131                 ldiskfs_journal_stop(jh);
132                 return PTR_ERR(inode);
133         }
134
135         ldiskfs_set_inode_state(inode, LDISKFS_STATE_LUSTRE_NOSCRUB);
136         unlock_new_inode(inode);
137
138         if (feat->dif_flags & DT_IND_VARKEY)
139                 rc = iam_lvar_create(inode, feat->dif_keysize_max,
140                                      feat->dif_ptrsize, feat->dif_recsize_max,
141                                      jh);
142         else
143                 rc = iam_lfix_create(inode, feat->dif_keysize_max,
144                                      feat->dif_ptrsize, feat->dif_recsize_max,
145                                      jh);
146         dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name));
147         rc = osd_ldiskfs_add_entry(info, osd, jh, dentry, inode, NULL);
148         ldiskfs_journal_stop(jh);
149         iput(inode);
150         return rc;
151 }
152
153 static struct inode *osd_oi_index_open(struct osd_thread_info *info,
154                                        struct osd_device *osd,
155                                        const char *name,
156                                        struct dt_index_features *f,
157                                        bool create)
158 {
159         struct dentry *dentry;
160         struct inode  *inode;
161         int            rc;
162
163         dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name));
164         if (IS_ERR(dentry))
165                 return (void *) dentry;
166
167         if (dentry->d_inode) {
168                 LASSERT(!is_bad_inode(dentry->d_inode));
169                 inode = dentry->d_inode;
170                 atomic_inc(&inode->i_count);
171                 dput(dentry);
172                 return inode;
173         }
174
175         /* create */
176         dput(dentry);
177         shrink_dcache_parent(osd_sb(osd)->s_root);
178         if (!create)
179                 return ERR_PTR(-ENOENT);
180
181         rc = osd_oi_index_create_one(info, osd, name, f);
182         if (rc)
183                 return ERR_PTR(rc);
184
185         dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name));
186         if (IS_ERR(dentry))
187                 return (void *) dentry;
188
189         if (dentry->d_inode) {
190                 LASSERT(!is_bad_inode(dentry->d_inode));
191                 inode = dentry->d_inode;
192                 atomic_inc(&inode->i_count);
193                 dput(dentry);
194                 return inode;
195         }
196
197         return ERR_PTR(-ENOENT);
198 }
199
200 /**
201  * Open an OI(Ojbect Index) container.
202  *
203  * \param       name    Name of OI container
204  * \param       objp    Pointer of returned OI
205  *
206  * \retval      0       success
207  * \retval      -ve     failure
208  */
209 static int osd_oi_open(struct osd_thread_info *info, struct osd_device *osd,
210                        char *name, struct osd_oi **oi_slot, bool create)
211 {
212         struct osd_directory *dir;
213         struct iam_container *bag;
214         struct inode         *inode;
215         struct osd_oi        *oi;
216         int                   rc;
217
218         ENTRY;
219
220         oi_feat.dif_keysize_min = sizeof(struct lu_fid);
221         oi_feat.dif_keysize_max = sizeof(struct lu_fid);
222
223         inode = osd_oi_index_open(info, osd, name, &oi_feat, create);
224         if (IS_ERR(inode))
225                 RETURN(PTR_ERR(inode));
226
227         if (!osd->od_dt_dev.dd_rdonly) {
228                 /* 'What the @fid is' is not imporatant, because these objects
229                  * have no OI mappings, and only are visible inside the OSD.*/
230                 lu_igif_build(&info->oti_fid, inode->i_ino,
231                               inode->i_generation);
232                 rc = osd_ea_fid_set(info, inode, &info->oti_fid,
233                                     LMAC_NOT_IN_OI, 0);
234                 if (rc)
235                         GOTO(out_inode, rc);
236         }
237
238         OBD_ALLOC_PTR(oi);
239         if (oi == NULL)
240                 GOTO(out_inode, rc = -ENOMEM);
241
242         oi->oi_inode = inode;
243         dir = &oi->oi_dir;
244
245         bag = &dir->od_container;
246         rc = iam_container_init(bag, &dir->od_descr, inode);
247         if (rc < 0)
248                 GOTO(out_free, rc);
249
250         rc = iam_container_setup(bag);
251         if (rc < 0)
252                 GOTO(out_container, rc);
253
254         *oi_slot = oi;
255         RETURN(0);
256
257 out_container:
258         iam_container_fini(bag);
259 out_free:
260         OBD_FREE_PTR(oi);
261 out_inode:
262         iput(inode);
263         return rc;
264 }
265
266 /**
267  * Open OI(Object Index) table.
268  * If \a oi_count is zero, which means caller doesn't know how many OIs there
269  * will be, this function can either return 0 for new filesystem, or number
270  * of OIs on existed filesystem.
271  *
272  * If \a oi_count is non-zero, which means caller does know number of OIs on
273  * filesystem, this function should return the exactly same number on
274  * success, or error code in failure.
275  *
276  * \param     oi_count  Number of expected OI containers
277  * \param     create    Create OIs if doesn't exist
278  *
279  * \retval    +ve       number of opened OI containers
280  * \retval      0       no OI containers found
281  * \retval    -ve       failure
282  */
283 static int
284 osd_oi_table_open(struct osd_thread_info *info, struct osd_device *osd,
285                   struct osd_oi **oi_table, unsigned oi_count, bool create)
286 {
287         struct scrub_file *sf = &osd->od_scrub.os_scrub.os_file;
288         int                count = 0;
289         int                rc = 0;
290         int                i;
291         ENTRY;
292
293         /* NB: oi_count != 0 means that we have already created/known all OIs
294          * and have known exact number of OIs. */
295         LASSERT(oi_count <= OSD_OI_FID_NR_MAX);
296
297         for (i = 0; i < (oi_count != 0 ? oi_count : OSD_OI_FID_NR_MAX); i++) {
298                 char name[12];
299
300                 if (oi_table[i] != NULL) {
301                         count++;
302                         continue;
303                 }
304
305                 sprintf(name, "%s.%d", OSD_OI_NAME_BASE, i);
306                 rc = osd_oi_open(info, osd, name, &oi_table[i], create);
307                 if (rc == 0) {
308                         count++;
309                         continue;
310                 }
311
312                 if (rc == -ENOENT && create == false) {
313                         if (oi_count == 0)
314                                 return count;
315
316                         rc = 0;
317                         ldiskfs_set_bit(i, sf->sf_oi_bitmap);
318                         continue;
319                 }
320
321                 CERROR("%s: can't open %s: rc = %d\n",
322                        osd_dev2name(osd), name, rc);
323                 if (oi_count > 0)
324                         CERROR("%s: expect to open total %d OI files.\n",
325                                osd_dev2name(osd), oi_count);
326                 break;
327         }
328
329         if (rc < 0) {
330                 osd_oi_table_put(info, oi_table, oi_count > 0 ? oi_count : i);
331                 count = rc;
332         }
333
334         RETURN(count);
335 }
336
337 static int osd_remove_oi_one(struct dentry *parent, const char *name,
338                              int namelen)
339 {
340         struct dentry *child;
341         int rc;
342
343         child = ll_lookup_one_len(name, parent, namelen);
344         if (IS_ERR(child)) {
345                 rc = PTR_ERR(child);
346         } else {
347                 rc = ll_vfs_unlink(parent->d_inode, child);
348                 dput(child);
349         }
350
351         return rc == -ENOENT ? 0 : rc;
352 }
353
354 static int osd_remove_ois(struct osd_thread_info *info, struct osd_device *osd)
355 {
356         char name[16];
357         int namelen;
358         int rc;
359         int i;
360
361         if (osd->od_dt_dev.dd_rdonly)
362                 RETURN(-EROFS);
363
364         for (i = 0; i < OSD_OI_FID_NR_MAX; i++) {
365                 namelen = snprintf(name, sizeof(name), "%s.%d",
366                                    OSD_OI_NAME_BASE, i);
367                 rc = osd_remove_oi_one(osd_sb(osd)->s_root, name, namelen);
368                 if (rc != 0) {
369                         CERROR("%s: fail to remove the stale OI file %s: "
370                                "rc = %d\n", osd_dev2name(osd), name, rc);
371                         return rc;
372                 }
373         }
374
375         namelen = snprintf(name, sizeof(name), "%s", OSD_OI_NAME_BASE);
376         rc = osd_remove_oi_one(osd_sb(osd)->s_root, name, namelen);
377         if (rc != 0)
378                 CERROR("%s: fail to remove the stale OI file %s: rc = %d\n",
379                        osd_dev2name(osd), name, rc);
380
381         return rc;
382 }
383
384 int osd_oi_init(struct osd_thread_info *info, struct osd_device *osd,
385                 bool restored)
386 {
387         struct lustre_scrub *scrub = &osd->od_scrub.os_scrub;
388         struct scrub_file *sf = &scrub->os_file;
389         struct osd_oi **oi;
390         int count;
391         int rc;
392         ENTRY;
393
394         if (unlikely(sf->sf_oi_count & (sf->sf_oi_count - 1)) != 0) {
395                 LCONSOLE_WARN("%s: Invalid OI count in scrub file %d\n",
396                               osd_dev2name(osd), sf->sf_oi_count);
397                 sf->sf_oi_count = 0;
398         }
399
400         if (restored) {
401                 rc = osd_remove_ois(info, osd);
402                 if (rc)
403                         RETURN(rc);
404         }
405
406         OBD_ALLOC(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX);
407         if (oi == NULL)
408                 RETURN(-ENOMEM);
409
410         /* try to open existing multiple OIs first */
411         count = osd_oi_table_open(info, osd, oi, sf->sf_oi_count, false);
412         if (count < 0)
413                 GOTO(out, rc = count);
414
415         if (count > 0) {
416                 if (count == sf->sf_oi_count)
417                         GOTO(out, rc = count);
418
419                 if (sf->sf_oi_count == 0) {
420                         if (likely((count & (count - 1)) == 0))
421                                 GOTO(out, rc = count);
422
423                         LCONSOLE_WARN("%s: invalid oi count %d, remove them, "
424                                       "then set it to %d\n", osd_dev2name(osd),
425                                       count, osd_oi_count);
426                         osd_oi_table_put(info, oi, count);
427                         rc = osd_remove_ois(info, osd);
428                         if (rc)
429                                 GOTO(out, rc);
430
431                         sf->sf_oi_count = osd_oi_count;
432                 }
433
434                 scrub_file_reset(scrub, LDISKFS_SB(osd_sb(osd))->s_es->s_uuid,
435                                  SF_RECREATED);
436                 count = sf->sf_oi_count;
437                 goto create;
438         }
439
440         /* if previous failed then try found single OI from old filesystem */
441         rc = osd_oi_open(info, osd, OSD_OI_NAME_BASE, &oi[0], false);
442         if (rc == 0) { /* found single OI from old filesystem */
443                 count = 1;
444                 ldiskfs_clear_bit(0, sf->sf_oi_bitmap);
445                 if (sf->sf_success_count == 0)
446                         /* XXX: There is one corner case that if the OI_scrub
447                          *      file crashed or lost and we regard it upgrade,
448                          *      then we allow IGIF lookup to bypass OI files.
449                          *
450                          *      The risk is that osd_fid_lookup() may found
451                          *      a wrong inode with the given IGIF especially
452                          *      when the MDT has performed file-level backup
453                          *      and restored after former upgrading from 1.8
454                          *      to 2.x. Fortunately, the osd_fid_lookup()can
455                          *      verify the inode to decrease the risk. */
456                         scrub_file_reset(scrub,
457                                          LDISKFS_SB(osd_sb(osd))->s_es->s_uuid,
458                                          SF_UPGRADE);
459                 GOTO(out, rc = 1);
460         } else if (rc != -ENOENT) {
461                 CERROR("%s: can't open %s: rc = %d\n",
462                        osd_dev2name(osd), OSD_OI_NAME_BASE, rc);
463                 GOTO(out, rc);
464         }
465
466         if (sf->sf_oi_count > 0) {
467                 int i;
468
469                 count = sf->sf_oi_count;
470                 memset(sf->sf_oi_bitmap, 0, SCRUB_OI_BITMAP_SIZE);
471                 for (i = 0; i < count; i++)
472                         ldiskfs_set_bit(i, sf->sf_oi_bitmap);
473                 scrub_file_reset(scrub, LDISKFS_SB(osd_sb(osd))->s_es->s_uuid,
474                                  SF_RECREATED);
475         } else {
476                 count = sf->sf_oi_count = osd_oi_count;
477         }
478
479 create:
480         rc = scrub_file_store(info->oti_env, scrub);
481         if (rc < 0) {
482                 osd_oi_table_put(info, oi, count);
483                 GOTO(out, rc);
484         }
485
486         /* No OIs exist, new filesystem, create OI objects */
487         rc = osd_oi_table_open(info, osd, oi, count, true);
488         LASSERT(ergo(rc >= 0, rc == count));
489
490         GOTO(out, rc);
491
492 out:
493         if (rc < 0) {
494                 OBD_FREE(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX);
495         } else {
496                 LASSERTF((rc & (rc - 1)) == 0, "Invalid OI count %d\n", rc);
497
498                 osd->od_oi_table = oi;
499                 osd->od_oi_count = rc;
500                 if (sf->sf_oi_count != rc) {
501                         sf->sf_oi_count = rc;
502                         rc = scrub_file_store(info->oti_env, scrub);
503                         if (rc < 0) {
504                                 osd_oi_table_put(info, oi, count);
505                                 OBD_FREE(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX);
506                         }
507                 } else {
508                         rc = 0;
509                 }
510         }
511
512         return rc;
513 }
514
515 void osd_oi_fini(struct osd_thread_info *info, struct osd_device *osd)
516 {
517         if (unlikely(!osd->od_oi_table))
518                 return;
519
520         osd_oi_table_put(info, osd->od_oi_table, osd->od_oi_count);
521
522         OBD_FREE(osd->od_oi_table,
523                  sizeof(*(osd->od_oi_table)) * OSD_OI_FID_NR_MAX);
524         osd->od_oi_table = NULL;
525 }
526
527 static inline int fid_is_fs_root(const struct lu_fid *fid)
528 {
529         /* Map root inode to special local object FID */
530         return (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE &&
531                          fid_oid(fid) == OSD_FS_ROOT_OID));
532 }
533
534 static int osd_oi_iam_lookup(struct osd_thread_info *oti,
535                              struct osd_oi *oi, struct dt_rec *rec,
536                              const struct dt_key *key)
537 {
538         struct iam_container  *bag;
539         struct iam_iterator   *it = &oti->oti_idx_it;
540         struct iam_path_descr *ipd;
541         int                    rc;
542         ENTRY;
543
544         LASSERT(oi);
545         LASSERT(oi->oi_inode);
546
547         bag = &oi->oi_dir.od_container;
548         ipd = osd_idx_ipd_get(oti->oti_env, bag);
549         if (IS_ERR(ipd))
550                 RETURN(-ENOMEM);
551
552         /* got ipd now we can start iterator. */
553         iam_it_init(it, bag, 0, ipd);
554
555         rc = iam_it_get(it, (struct iam_key *)key);
556         if (rc > 0)
557                 iam_reccpy(&it->ii_path.ip_leaf, (struct iam_rec *)rec);
558         iam_it_put(it);
559         iam_it_fini(it);
560         osd_ipd_put(oti->oti_env, bag, ipd);
561
562         LINVRNT(osd_invariant(obj));
563
564         RETURN(rc);
565 }
566
567 int fid_is_on_ost(struct osd_thread_info *info, struct osd_device *osd,
568                   const struct lu_fid *fid, enum oi_check_flags flags)
569 {
570         struct lu_seq_range     *range = &info->oti_seq_range;
571         int                     rc;
572         ENTRY;
573
574         if (flags & OI_KNOWN_ON_OST)
575                 RETURN(1);
576
577         if (unlikely(fid_is_local_file(fid) || fid_is_igif(fid) ||
578                      fid_is_llog(fid)) || fid_is_name_llog(fid) ||
579                      fid_is_quota(fid))
580                 RETURN(0);
581
582         if (fid_is_idif(fid) || fid_is_last_id(fid))
583                 RETURN(1);
584
585         if (!(flags & OI_CHECK_FLD))
586                 RETURN(0);
587
588         if (osd_seq_site(osd)->ss_server_fld == NULL)
589                 RETURN(0);
590
591         rc = osd_fld_lookup(info->oti_env, osd, fid_seq(fid), range);
592         if (rc != 0) {
593                 /* During upgrade, OST FLDB might not be loaded because
594                  * OST FLDB is not created until 2.6, so if some DNE
595                  * filesystem upgrade from 2.5 to 2.7/2.8, they will
596                  * not be able to find the sequence from local FLDB
597                  * cache see fld_index_init(). */
598                 if (rc == -ENOENT && osd->od_is_ost)
599                         RETURN(1);
600
601                 if (rc != -ENOENT)
602                         CERROR("%s: lookup FLD "DFID": rc = %d\n",
603                                osd_name(osd), PFID(fid), rc);
604                 RETURN(0);
605         }
606
607         if (fld_range_is_ost(range))
608                 RETURN(1);
609
610         RETURN(0);
611 }
612
613 static int __osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
614                            const struct lu_fid *fid, struct osd_inode_id *id)
615 {
616         struct lu_fid *oi_fid = &info->oti_fid2;
617         int            rc;
618
619         fid_cpu_to_be(oi_fid, fid);
620         rc = osd_oi_iam_lookup(info, osd_fid2oi(osd, fid), (struct dt_rec *)id,
621                                (const struct dt_key *)oi_fid);
622         if (rc > 0) {
623                 osd_id_unpack(id, id);
624                 rc = 0;
625         } else if (rc == 0) {
626                 rc = -ENOENT;
627         }
628         return rc;
629 }
630
631 int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
632                   const struct lu_fid *fid, struct osd_inode_id *id,
633                   enum oi_check_flags flags)
634 {
635         if (unlikely(fid_is_last_id(fid)))
636                 return osd_obj_spec_lookup(info, osd, fid, id);
637
638         if (fid_is_on_ost(info, osd, fid, flags) || fid_is_llog(fid))
639                 return osd_obj_map_lookup(info, osd, fid, id);
640
641
642         if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) {
643                 int rc;
644                 if (fid_is_fs_root(fid)) {
645                         osd_id_gen(id, osd_sb(osd)->s_root->d_inode->i_ino,
646                                    osd_sb(osd)->s_root->d_inode->i_generation);
647                         return 0;
648                 }
649                 if (unlikely(fid_is_acct(fid)))
650                         return osd_acct_obj_lookup(info, osd, fid, id);
651
652                 /* For other special FIDs, try OI first, then do spec lookup */
653                 rc = __osd_oi_lookup(info, osd, fid, id);
654                 if (rc == -ENOENT)
655                         return osd_obj_spec_lookup(info, osd, fid, id);
656                 return rc;
657         }
658
659         if (!osd->od_igif_inoi && fid_is_igif(fid)) {
660                 osd_id_gen(id, lu_igif_ino(fid), lu_igif_gen(fid));
661                 return 0;
662         }
663
664         return __osd_oi_lookup(info, osd, fid, id);
665 }
666
667 static int osd_oi_iam_refresh(struct osd_thread_info *oti, struct osd_oi *oi,
668                              const struct dt_rec *rec, const struct dt_key *key,
669                              handle_t *th, bool insert)
670 {
671         struct iam_container    *bag;
672         struct iam_path_descr   *ipd;
673         int                     rc;
674         ENTRY;
675
676         LASSERT(oi);
677         LASSERT(oi->oi_inode);
678         ll_vfs_dq_init(oi->oi_inode);
679
680         bag = &oi->oi_dir.od_container;
681         ipd = osd_idx_ipd_get(oti->oti_env, bag);
682         if (unlikely(ipd == NULL))
683                 RETURN(-ENOMEM);
684
685         LASSERT(th != NULL);
686         LASSERT(th->h_transaction != NULL);
687         if (insert)
688                 rc = iam_insert(th, bag, (const struct iam_key *)key,
689                                 (const struct iam_rec *)rec, ipd);
690         else
691                 rc = iam_update(th, bag, (const struct iam_key *)key,
692                                 (const struct iam_rec *)rec, ipd);
693         osd_ipd_put(oti->oti_env, bag, ipd);
694         LINVRNT(osd_invariant(obj));
695         RETURN(rc);
696 }
697
698 int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd,
699                   const struct lu_fid *fid, const struct osd_inode_id *id,
700                   handle_t *th, enum oi_check_flags flags, bool *exist)
701 {
702         struct lu_fid       *oi_fid = &info->oti_fid2;
703         struct osd_inode_id *oi_id  = &info->oti_id2;
704         int                  rc     = 0;
705
706         if (unlikely(fid_is_last_id(fid)))
707                 return osd_obj_spec_insert(info, osd, fid, id, th);
708
709         if (fid_is_on_ost(info, osd, fid, flags) || fid_is_llog(fid))
710                 return osd_obj_map_insert(info, osd, fid, id, th);
711
712         fid_cpu_to_be(oi_fid, fid);
713         osd_id_pack(oi_id, id);
714         rc = osd_oi_iam_refresh(info, osd_fid2oi(osd, fid),
715                                (const struct dt_rec *)oi_id,
716                                (const struct dt_key *)oi_fid, th, true);
717         if (rc != 0) {
718                 struct inode *inode;
719                 struct lustre_mdt_attrs *lma = &info->oti_ost_attrs.loa_lma;
720
721                 if (rc != -EEXIST)
722                         return rc;
723
724                 rc = osd_oi_lookup(info, osd, fid, oi_id, 0);
725                 if (rc != 0)
726                         return rc;
727
728                 if (unlikely(osd_id_eq(id, oi_id)))
729                         return 1;
730
731                 /* Check whether the mapping for oi_id is valid or not. */
732                 inode = osd_iget(info, osd, oi_id);
733                 if (IS_ERR(inode)) {
734                         rc = PTR_ERR(inode);
735                         if (rc == -ENOENT || rc == -ESTALE)
736                                 goto update;
737                         return rc;
738                 }
739
740                 /* The EA inode should NOT be in OI, old OI scrub may added
741                  * such OI mapping by wrong, replace it. */
742                 if (unlikely(osd_is_ea_inode(inode))) {
743                         iput(inode);
744                         goto update;
745                 }
746
747                 rc = osd_get_lma(info, inode, &info->oti_obj_dentry,
748                                  &info->oti_ost_attrs);
749                 iput(inode);
750                 if (rc == -ENODATA)
751                         goto update;
752
753                 if (rc != 0)
754                         return rc;
755
756                 if (!(lma->lma_compat & LMAC_NOT_IN_OI) &&
757                     lu_fid_eq(fid, &lma->lma_self_fid)) {
758                         CERROR("%s: the FID "DFID" is used by two objects: "
759                                "%u/%u %u/%u\n", osd_dev2name(osd),
760                                PFID(fid), oi_id->oii_ino, oi_id->oii_gen,
761                                id->oii_ino, id->oii_gen);
762                         return -EEXIST;
763                 }
764
765 update:
766                 osd_id_pack(oi_id, id);
767                 rc = osd_oi_iam_refresh(info, osd_fid2oi(osd, fid),
768                                         (const struct dt_rec *)oi_id,
769                                         (const struct dt_key *)oi_fid, th, false);
770                 if (rc != 0)
771                         return rc;
772
773                 if (exist != NULL)
774                         *exist = true;
775         }
776
777         if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE))
778                 rc = osd_obj_spec_insert(info, osd, fid, id, th);
779         return rc;
780 }
781
782 static int osd_oi_iam_delete(struct osd_thread_info *oti, struct osd_oi *oi,
783                              const struct dt_key *key, handle_t *th)
784 {
785         struct iam_container    *bag;
786         struct iam_path_descr   *ipd;
787         int                      rc;
788         ENTRY;
789
790         LASSERT(oi);
791         LASSERT(oi->oi_inode);
792         ll_vfs_dq_init(oi->oi_inode);
793
794         bag = &oi->oi_dir.od_container;
795         ipd = osd_idx_ipd_get(oti->oti_env, bag);
796         if (unlikely(ipd == NULL))
797                 RETURN(-ENOMEM);
798
799         LASSERT(th != NULL);
800         LASSERT(th->h_transaction != NULL);
801
802         rc = iam_delete(th, bag, (const struct iam_key *)key, ipd);
803         osd_ipd_put(oti->oti_env, bag, ipd);
804         LINVRNT(osd_invariant(obj));
805         RETURN(rc);
806 }
807
808 int osd_oi_delete(struct osd_thread_info *info,
809                   struct osd_device *osd, const struct lu_fid *fid,
810                   handle_t *th, enum oi_check_flags flags)
811 {
812         struct lu_fid *oi_fid = &info->oti_fid2;
813
814         /* clear idmap cache */
815         if (lu_fid_eq(fid, &info->oti_cache.oic_fid))
816                 fid_zero(&info->oti_cache.oic_fid);
817
818         if (fid_is_last_id(fid))
819                 return 0;
820
821         if (fid_is_on_ost(info, osd, fid, flags) || fid_is_llog(fid))
822                 return osd_obj_map_delete(info, osd, fid, th);
823
824         fid_cpu_to_be(oi_fid, fid);
825         return osd_oi_iam_delete(info, osd_fid2oi(osd, fid),
826                                  (const struct dt_key *)oi_fid, th);
827 }
828
829 int osd_oi_update(struct osd_thread_info *info, struct osd_device *osd,
830                   const struct lu_fid *fid, const struct osd_inode_id *id,
831                   handle_t *th, enum oi_check_flags flags)
832 {
833         struct lu_fid       *oi_fid = &info->oti_fid2;
834         struct osd_inode_id *oi_id  = &info->oti_id2;
835         int                  rc     = 0;
836
837         if (unlikely(fid_is_last_id(fid)))
838                 return osd_obj_spec_update(info, osd, fid, id, th);
839
840         if (fid_is_on_ost(info, osd, fid, flags) || fid_is_llog(fid))
841                 return osd_obj_map_update(info, osd, fid, id, th);
842
843         fid_cpu_to_be(oi_fid, fid);
844         osd_id_pack(oi_id, id);
845         rc = osd_oi_iam_refresh(info, osd_fid2oi(osd, fid),
846                                (const struct dt_rec *)oi_id,
847                                (const struct dt_key *)oi_fid, th, false);
848         if (rc != 0)
849                 return rc;
850
851         if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE))
852                 rc = osd_obj_spec_update(info, osd, fid, id, th);
853         return rc;
854 }
855
856 int osd_oi_mod_init(void)
857 {
858         if (osd_oi_count == 0 || osd_oi_count > OSD_OI_FID_NR_MAX)
859                 osd_oi_count = OSD_OI_FID_NR;
860
861         if ((osd_oi_count & (osd_oi_count - 1)) != 0) {
862                 LCONSOLE_WARN("Round up oi_count %d to power2 %d\n",
863                               osd_oi_count, size_roundup_power2(osd_oi_count));
864                 osd_oi_count = size_roundup_power2(osd_oi_count);
865         }
866
867         return 0;
868 }