* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
CFS_MODULE_PARM(ldiskfs_pdo, "i", int, 0644,
"ldiskfs with parallel directory operations");
+int ldiskfs_track_declares_assert;
+CFS_MODULE_PARM(ldiskfs_track_declares_assert, "i", int, 0644,
+ "LBUG during tracking of declares");
+
static const char dot[] = ".";
static const char dotdot[] = "..";
static const char remote_obj_dir[] = "REM_OBJ_DIR";
static const struct dt_index_operations osd_index_iam_ops;
static const struct dt_index_operations osd_index_ea_ops;
-#ifdef OSD_TRACK_DECLARES
int osd_trans_declare_op2rb[] = {
[OSD_OT_ATTR_SET] = OSD_OT_ATTR_SET,
[OSD_OT_PUNCH] = OSD_OT_MAX,
[OSD_OT_DELETE] = OSD_OT_INSERT,
[OSD_OT_QUOTA] = OSD_OT_MAX,
};
-#endif
static int osd_has_index(const struct osd_object *obj)
{
const char *name, void *buf, int len)
{
dentry->d_inode = inode;
+ dentry->d_sb = inode->i_sb;
return inode->i_op->getxattr(dentry, name, buf, len);
}
{
int rc;
- rc = __osd_xattr_get(inode, dentry, XATTR_NAME_LMA, (void *)lma,
- sizeof(*lma));
- if (rc == -ERANGE) {
- /* try with old lma size */
- rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA,
- info->oti_mdt_attrs_old,
- LMA_OLD_SIZE);
- if (rc > 0)
- memcpy(lma, info->oti_mdt_attrs_old, sizeof(*lma));
- }
+ CLASSERT(LMA_OLD_SIZE >= sizeof(*lma));
+ rc = __osd_xattr_get(inode, dentry, XATTR_NAME_LMA,
+ info->oti_mdt_attrs_old, LMA_OLD_SIZE);
if (rc > 0) {
+ if ((void *)lma != (void *)info->oti_mdt_attrs_old)
+ memcpy(lma, info->oti_mdt_attrs_old, sizeof(*lma));
+ rc = 0;
+ lustre_lma_swab(lma);
/* Check LMA compatibility */
- if (lma->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP)) {
- CWARN("%.16s: unsupported incompat LMA feature(s) "
- "%lu/%#x\n",
+ if (lma->lma_incompat & ~LMA_INCOMPAT_SUPP) {
+ CWARN("%.16s: unsupported incompat LMA feature(s) %#x "
+ "for fid = "DFID", ino = %lu\n",
LDISKFS_SB(inode->i_sb)->s_es->s_volume_name,
- inode->i_ino, le32_to_cpu(lma->lma_incompat) &
- ~LMA_INCOMPAT_SUPP);
- rc = -ENOSYS;
- } else {
- lustre_lma_swab(lma);
- rc = 0;
+ lma->lma_incompat & ~LMA_INCOMPAT_SUPP,
+ PFID(&lma->lma_self_fid), inode->i_ino);
+ rc = -EOPNOTSUPP;
}
} else if (rc == 0) {
rc = -ENODATA;
(LOHA_EXISTS | (obj->oo_inode->i_mode & S_IFMT));
}
+static int osd_check_lma(const struct lu_env *env, struct osd_object *obj)
+{
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs;
+ int rc;
+ ENTRY;
+
+ CLASSERT(LMA_OLD_SIZE >= sizeof(*lma));
+ rc = __osd_xattr_get(obj->oo_inode, &info->oti_obj_dentry,
+ XATTR_NAME_LMA, info->oti_mdt_attrs_old,
+ LMA_OLD_SIZE);
+ if (rc > 0) {
+ rc = 0;
+ lustre_lma_swab(lma);
+ if (unlikely((lma->lma_incompat & ~LMA_INCOMPAT_SUPP) ||
+ CFS_FAIL_CHECK(OBD_FAIL_OSD_LMA_INCOMPAT))) {
+ rc = -EOPNOTSUPP;
+ CWARN("%s: unsupported incompat LMA feature(s) %#x for "
+ "fid = "DFID", ino = %lu: rc = %d\n",
+ osd_obj2dev(obj)->od_svname,
+ lma->lma_incompat & ~LMA_INCOMPAT_SUPP,
+ PFID(lu_object_fid(&obj->oo_dt.do_lu)),
+ obj->oo_inode->i_ino, rc);
+ }
+ if (unlikely(!lu_fid_eq(lu_object_fid(&obj->oo_dt.do_lu),
+ &lma->lma_self_fid))) {
+ CDEBUG(D_INODE, "%s: FID "DFID" != self_fid "DFID"\n",
+ osd_obj2dev(obj)->od_svname,
+ PFID(lu_object_fid(&obj->oo_dt.do_lu)),
+ PFID(&lma->lma_self_fid));
+ if (obj->oo_inode != NULL) {
+ iput(obj->oo_inode);
+ obj->oo_inode = NULL;
+ }
+ rc = -ESTALE;
+ }
+ } else if (rc == -ENODATA) {
+ /* haven't initialize LMA xattr */
+ rc = 0;
+ }
+
+ RETURN(rc);
+}
+
/*
* Concurrency: no concurrent access is possible that early in object
* life-cycle.
result = osd_fid_lookup(env, obj, lu_object_fid(l), conf);
obj->oo_dt.do_body_ops = &osd_body_ops_new;
- if (result == 0 && obj->oo_inode != NULL)
+ if (result == 0 && obj->oo_inode != NULL) {
+ result = osd_check_lma(env, obj);
+ if (result != 0)
+ return result;
+
osd_object_init0(obj);
+ }
LINVRNT(osd_invariant(obj));
return result;
CFS_INIT_LIST_HEAD(&oh->ot_dcb_list);
osd_th_alloced(oh);
-#ifdef OSD_TRACK_DECLARES
memset(oti->oti_declare_ops, 0,
sizeof(oti->oti_declare_ops));
memset(oti->oti_declare_ops_rb, 0,
memset(oti->oti_declare_ops_cred, 0,
sizeof(oti->oti_declare_ops_cred));
oti->oti_rollback = false;
-#endif
}
RETURN(th);
}
GOTO(out, rc);
if (unlikely(osd_param_is_not_sane(dev, th))) {
-#ifdef OSD_TRACK_DECLARES
static unsigned long last_printed;
static int last_credits;
-#endif
CWARN("%.16s: too many transaction credits (%d > %d)\n",
LDISKFS_SB(osd_sb(dev))->s_es->s_volume_name,
oh->ot_credits,
osd_journal(dev)->j_max_transaction_buffers);
-#ifdef OSD_TRACK_DECLARES
CWARN(" create: %u/%u, delete: %u/%u, destroy: %u/%u\n",
oti->oti_declare_ops[OSD_OT_CREATE],
oti->oti_declare_ops_cred[OSD_OT_CREATE],
last_credits = oh->ot_credits;
last_printed = jiffies;
}
-#endif
/* XXX Limit the credits to 'max_transaction_buffers', and
* let the underlying filesystem to catch the error if
* we really need so many credits.
int rc;
if (fid_is_idif(fid)) {
- range->lsr_flags = LU_SEQ_RANGE_OST;
+ fld_range_set_ost(range);
range->lsr_index = fid_idif_ost_idx(fid);
return 0;
}
if (!fid_seq_in_fldb(fid_seq(fid))) {
- range->lsr_flags = LU_SEQ_RANGE_MDT;
+ fld_range_set_mdt(range);
if (ss != NULL)
/* FIXME: If ss is NULL, it suppose not get lsr_index
* at all */
}
LASSERT(ss != NULL);
- range->lsr_flags = -1;
+ fld_range_set_any(range);
rc = fld_server_lookup(env, ss->ss_server_fld, fid_seq(fid), range);
if (rc != 0) {
- CERROR("%s can not find "DFID": rc = %d\n",
+ CERROR("%s: cannot find FLD range for "DFID": rc = %d\n",
osd_name(osd), PFID(fid), rc);
}
return rc;
LASSERT(oh->ot_handle == NULL);
LASSERT(inode);
- osd_trans_declare_op(env, oh, OSD_OT_DELETE,
+ osd_trans_declare_op(env, oh, OSD_OT_DESTROY,
osd_dto_credits_noquota[DTO_OBJECT_DELETE]);
/* Recycle idle OI leaf may cause additional three OI blocks
* to be changed. */
- osd_trans_declare_op(env, oh, OSD_OT_DESTROY,
+ osd_trans_declare_op(env, oh, OSD_OT_DELETE,
osd_dto_credits_noquota[DTO_INDEX_DELETE] + 3);
-
/* one less inode */
rc = osd_declare_inode_qid(env, inode->i_uid, inode->i_gid, -1, oh,
false, true, NULL, false);
if (unlikely(fid_is_acct(fid)))
RETURN(-EPERM);
- /* Parallel control for OI scrub. For most of cases, there is no
- * lock contention. So it will not affect unlink performance. */
- mutex_lock(&inode->i_mutex);
if (S_ISDIR(inode->i_mode)) {
LASSERT(osd_inode_unlinked(inode) || inode->i_nlink == 1);
/* it will check/delete the inode from remote parent,
osd_trans_exec_op(env, th, OSD_OT_DESTROY);
result = osd_oi_delete(osd_oti_get(env), osd, fid, th);
- mutex_unlock(&inode->i_mutex);
/* XXX: add to ext3 orphan list */
/* rc = ext3_orphan_add(handle_t *handle, struct inode *inode) */
static int osd_object_ref_add(const struct lu_env *env,
struct dt_object *dt, struct thandle *th)
{
- struct osd_object *obj = osd_dt_obj(dt);
- struct inode *inode = obj->oo_inode;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct inode *inode = obj->oo_inode;
+ bool need_dirty = false;
+ int rc = 0;
LINVRNT(osd_invariant(obj));
LASSERT(dt_object_exists(dt) && !dt_object_remote(dt));
osd_trans_exec_op(env, th, OSD_OT_REF_ADD);
- /*
- * DIR_NLINK feature is set for compatibility reasons if:
- * 1) nlinks > LDISKFS_LINK_MAX, or
- * 2) nlinks == 2, since this indicates i_nlink was previously 1.
+ /* This based on ldiskfs_inc_count(), which is not exported.
+ *
+ * The DIR_NLINK feature allows directories to exceed LDISKFS_LINK_MAX
+ * (65000) subdirectories by storing "1" in i_nlink if the link count
+ * would otherwise overflow. Directory tranversal tools understand
+ * that (st_nlink == 1) indicates that the filesystem dose not track
+ * hard links count on the directory, and will not abort subdirectory
+ * scanning early once (st_nlink - 2) subdirs have been found.
*
- * It is easier to always set this flag (rather than check and set),
- * since it has less overhead, and the superblock will be dirtied
- * at some point. Both e2fsprogs and any Lustre-supported ldiskfs
- * do not actually care whether this flag is set or not.
+ * This also has to properly handle the case of inodes with nlink == 0
+ * in case they are being linked into the PENDING directory
*/
spin_lock(&obj->oo_guard);
- /* inc_nlink from 0 may cause WARN_ON */
- if(inode->i_nlink == 0)
+ if (unlikely(!S_ISDIR(inode->i_mode) &&
+ inode->i_nlink >= LDISKFS_LINK_MAX)) {
+ /* MDD should have checked this, but good to be safe */
+ rc = -EMLINK;
+ } else if (unlikely(inode->i_nlink == 0 ||
+ (S_ISDIR(inode->i_mode) &&
+ inode->i_nlink >= LDISKFS_LINK_MAX))) {
+ /* inc_nlink from 0 may cause WARN_ON */
set_nlink(inode, 1);
- else
+ need_dirty = true;
+ } else if (!S_ISDIR(inode->i_mode) ||
+ (S_ISDIR(inode->i_mode) && inode->i_nlink >= 2)) {
inc_nlink(inode);
- if (S_ISDIR(inode->i_mode) && inode->i_nlink > 1) {
- if (inode->i_nlink >= LDISKFS_LINK_MAX ||
- inode->i_nlink == 2)
- set_nlink(inode, 1);
- }
+ need_dirty = true;
+ } /* else (S_ISDIR(inode->i_mode) && inode->i_nlink == 1) { ; } */
+
LASSERT(inode->i_nlink <= LDISKFS_LINK_MAX);
spin_unlock(&obj->oo_guard);
- ll_dirty_inode(inode, I_DIRTY_DATASYNC);
+
+ if (need_dirty)
+ ll_dirty_inode(inode, I_DIRTY_DATASYNC);
+
LINVRNT(osd_invariant(obj));
- return 0;
+ return rc;
}
static int osd_declare_object_ref_del(const struct lu_env *env,
spin_lock(&obj->oo_guard);
LASSERT(inode->i_nlink > 0);
- drop_nlink(inode);
- /* If this is/was a many-subdir directory (nlink > LDISKFS_LINK_MAX)
- * then the nlink count is 1. Don't let it be set to 0 or the directory
- * inode will be deleted incorrectly. */
- if (S_ISDIR(inode->i_mode) && inode->i_nlink == 0)
- set_nlink(inode, 1);
- spin_unlock(&obj->oo_guard);
- ll_dirty_inode(inode, I_DIRTY_DATASYNC);
- LINVRNT(osd_invariant(obj));
+
+ /* This based on ldiskfs_dec_count(), which is not exported.
+ *
+ * If a directory already has nlink == 1, then do not drop the nlink
+ * count to 0, even temporarily, to avoid race conditions with other
+ * threads not holding oo_guard seeing i_nlink == 0 in rare cases.
+ *
+ * nlink == 1 means the directory has/had > EXT4_LINK_MAX subdirs.
+ * */
+ if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 1) {
+ drop_nlink(inode);
+
+ spin_unlock(&obj->oo_guard);
+ ll_dirty_inode(inode, I_DIRTY_DATASYNC);
+ LINVRNT(osd_invariant(obj));
+ } else {
+ spin_unlock(&obj->oo_guard);
+ }
return 0;
}
return -EACCES;
dentry->d_inode = inode;
+ dentry->d_sb = inode->i_sb;
return inode->i_op->listxattr(dentry, buf->lb_buf, buf->lb_len);
}
ll_vfs_dq_init(inode);
dentry->d_inode = inode;
+ dentry->d_sb = inode->i_sb;
rc = inode->i_op->removexattr(dentry, name);
return rc;
}
ENTRY;
dentry->d_inode = inode;
+ dentry->d_sb = inode->i_sb;
file->f_dentry = dentry;
file->f_mapping = inode->i_mapping;
file->f_op = inode->i_fop;
down_write(&obj->oo_ext_idx_sem);
}
- bh = osd_ldiskfs_find_entry(dir, dentry, &de, hlock);
+ bh = ldiskfs_find_entry(dir, &dentry->d_name, &de, hlock);
if (bh) {
__u32 ino = 0;
- /* Tried to delete local agent inode for the entries,
- * If it tries to delete .., which only happens during
- * rename or move the dir to /ORPHAN, even .. might
- * point to the remote parent, but it do not have
- * local agent inode, so we do not need check .. at all,
- * Note: we need delete entry first, then inode to keep
- * lfsck safe. */
+ /* If this is not the ".." entry, it might be a remote DNE
+ * entry and we need to check if the FID is for a remote
+ * MDT. If the FID is not in the directory entry (e.g.
+ * upgraded 1.8 filesystem without dirdata enabled) then
+ * we need to get the FID from the LMA. For a remote directory
+ * there HAS to be an LMA, it cannot be an IGIF inode in this
+ * case.
+ *
+ * Delete the entry before the agent inode in order to
+ * simplify error handling. At worst an error after deleting
+ * the entry first might leak the agent inode afterward. The
+ * reverse would need filesystem abort in case of error deleting
+ * the entry after the agent had been removed, or leave a
+ * dangling entry pointing at a random inode. */
if (strcmp((char *)key, dotdot) != 0) {
LASSERT(de != NULL);
rc = osd_get_fid_from_dentry(de, (struct dt_rec *)fid);
+ /* If Fid is not in dentry, try to get it from LMA */
+ if (rc == -ENODATA) {
+ struct osd_inode_id *id;
+ struct inode *inode;
+
+ /* Before trying to get fid from the inode,
+ * check whether the inode is valid.
+ *
+ * If the inode has been deleted, do not go
+ * ahead to do osd_ea_fid_get, which will set
+ * the inode to bad inode, which might cause
+ * the inode to be deleted uncorrectly */
+ inode = ldiskfs_iget(osd_sb(osd),
+ le32_to_cpu(de->inode));
+ if (IS_ERR(inode)) {
+ CDEBUG(D_INODE, "%s: "DFID"get inode"
+ "error.\n", osd_name(osd),
+ PFID(fid));
+ rc = PTR_ERR(inode);
+ } else {
+ if (likely(inode->i_nlink != 0)) {
+ id = &osd_oti_get(env)->oti_id;
+ rc = osd_ea_fid_get(env, obj,
+ le32_to_cpu(de->inode),
+ fid, id);
+ } else {
+ CDEBUG(D_INFO, "%s: %u "DFID
+ "deleted.\n",
+ osd_name(osd),
+ le32_to_cpu(de->inode),
+ PFID(fid));
+ rc = -ESTALE;
+ }
+ iput(inode);
+ }
+ }
if (rc == 0 &&
unlikely(osd_remote_fid(env, osd, fid)))
/* Need to delete agent inode */
return rc;
}
+static int osd_add_oi_cache(struct osd_thread_info *info,
+ struct osd_device *osd,
+ struct osd_inode_id *id,
+ struct lu_fid *fid)
+{
+ CDEBUG(D_INODE, "add "DFID" %u:%u to info %p\n", PFID(fid),
+ id->oii_ino, id->oii_gen, info);
+ info->oti_cache.oic_lid = *id;
+ info->oti_cache.oic_fid = *fid;
+
+ return 0;
+}
+
/**
* Calls ->lookup() to find dentry. From dentry get inode and
* read inode's ea to get fid. This is required for interoperability
GOTO(out, rc);
}
- oic->oic_lid = *id;
- oic->oic_fid = *fid;
+ rc = osd_add_oi_cache(osd_oti_get(env), osd_obj2dev(obj), id,
+ fid);
+ if (rc != 0)
+ GOTO(out, rc);
if ((scrub->os_pos_current <= ino) &&
((sf->sf_flags & SF_INCONSISTENT) ||
(sf->sf_flags & SF_UPGRADE && fid_is_igif(fid)) ||
struct osd_object *obj = osd_dt_obj(dt);
struct osd_thread_info *info = osd_oti_get(env);
struct osd_it_ea *it = &info->oti_it_ea;
+ struct file *file = &it->oie_file;
struct lu_object *lo = &dt->do_lu;
struct dentry *obj_dentry = &info->oti_it_dentry;
ENTRY;
it->oie_dirent = NULL;
it->oie_buf = info->oti_it_ea_buf;
it->oie_obj = obj;
- it->oie_file.f_pos = 0;
- it->oie_file.f_dentry = obj_dentry;
- if (attr & LUDA_64BITHASH)
- it->oie_file.f_mode |= FMODE_64BITHASH;
- else
- it->oie_file.f_mode |= FMODE_32BITHASH;
- it->oie_file.f_mapping = obj->oo_inode->i_mapping;
- it->oie_file.f_op = obj->oo_inode->i_fop;
- it->oie_file.private_data = NULL;
- lu_object_get(lo);
- RETURN((struct dt_it *) it);
+
+ /* Reset the "file" totally to avoid to reuse any old value from
+ * former readdir handling, the "file->f_pos" should be zero. */
+ memset(file, 0, sizeof(*file));
+ /* Only FMODE_64BITHASH or FMODE_32BITHASH should be set, NOT both. */
+ if (attr & LUDA_64BITHASH)
+ file->f_mode = FMODE_64BITHASH;
+ else
+ file->f_mode = FMODE_32BITHASH;
+ file->f_dentry = obj_dentry;
+ file->f_mapping = obj->oo_inode->i_mapping;
+ file->f_op = obj->oo_inode->i_fop;
+ lu_object_get(lo);
+ RETURN((struct dt_it *) it);
}
/**
GOTO(out_journal, rc);
}
+ /* skip the REMOTE_PARENT_DIR. */
+ if (inode == dev->od_mdt_map->omm_remote_parent->d_inode)
+ GOTO(out_inode, rc = 0);
+
rc = osd_get_lma(info, inode, &info->oti_obj_dentry, lma);
if (rc == 0) {
if (fid_is_sane(fid)) {
if (osd_remote_fid(env, dev, fid))
RETURN(0);
- if (likely(!(attr & LUDA_IGNORE))) {
- oic->oic_lid = *id;
- oic->oic_fid = *fid;
- }
+ if (likely(!(attr & LUDA_IGNORE)))
+ rc = osd_add_oi_cache(oti, dev, id, fid);
if (!(attr & LUDA_VERIFY) &&
(scrub->os_pos_current <= ino) &&
{
ENTRY;
- osd_scrub_cleanup(env, o);
+ /* shutdown quota slave instance associated with the device */
+ if (o->od_quota_slave != NULL) {
+ qsd_fini(env, o->od_quota_slave);
+ o->od_quota_slave = NULL;
+ }
+
+ RETURN(0);
+}
+
+static void osd_umount(const struct lu_env *env, struct osd_device *o)
+{
+ ENTRY;
if (o->od_fsops) {
fsfilt_put_ops(o->od_fsops);
o->od_fsops = NULL;
}
- /* shutdown quota slave instance associated with the device */
- if (o->od_quota_slave != NULL) {
- qsd_fini(env, o->od_quota_slave);
- o->od_quota_slave = NULL;
+ if (o->od_mnt != NULL) {
+ shrink_dcache_sb(osd_sb(o));
+ osd_sync(env, &o->od_dt_dev);
+
+ mntput(o->od_mnt);
+ o->od_mnt = NULL;
}
- RETURN(0);
+ EXIT;
}
static int osd_mount(const struct lu_env *env,
}
static struct lu_device *osd_device_fini(const struct lu_env *env,
- struct lu_device *d)
+ struct lu_device *d)
{
- int rc;
- ENTRY;
-
- rc = osd_shutdown(env, osd_dev(d));
-
- osd_obj_map_fini(osd_dev(d));
-
- shrink_dcache_sb(osd_sb(osd_dev(d)));
- osd_sync(env, lu2dt_dev(d));
-
- rc = osd_procfs_fini(osd_dev(d));
- if (rc) {
- CERROR("proc fini error %d \n", rc);
- RETURN (ERR_PTR(rc));
- }
+ struct osd_device *o = osd_dev(d);
+ ENTRY;
- if (osd_dev(d)->od_mnt) {
- mntput(osd_dev(d)->od_mnt);
- osd_dev(d)->od_mnt = NULL;
- }
+ osd_procfs_fini(o);
+ osd_shutdown(env, o);
+ osd_scrub_cleanup(env, o);
+ osd_obj_map_fini(o);
+ osd_umount(env, o);
- RETURN(NULL);
+ RETURN(NULL);
}
static int osd_device_init0(const struct lu_env *env,
if (rc)
GOTO(out_capa, rc);
- CFS_INIT_LIST_HEAD(&o->od_ios_list);
- /* setup scrub, including OI files initialization */
- rc = osd_scrub_setup(env, o);
- if (rc < 0)
- GOTO(out_mnt, rc);
-
cplen = strlcpy(o->od_svname, lustre_cfg_string(cfg, 4),
sizeof(o->od_svname));
if (cplen >= sizeof(o->od_svname)) {
rc = osd_obj_map_init(env, o);
if (rc != 0)
- GOTO(out_scrub, rc);
+ GOTO(out_mnt, rc);
rc = lu_site_init(&o->od_site, l);
- if (rc)
+ if (rc != 0)
GOTO(out_compat, rc);
o->od_site.ls_bottom_dev = l;
rc = lu_site_init_finish(&o->od_site);
- if (rc)
+ if (rc != 0)
+ GOTO(out_site, rc);
+
+ CFS_INIT_LIST_HEAD(&o->od_ios_list);
+ /* setup scrub, including OI files initialization */
+ rc = osd_scrub_setup(env, o);
+ if (rc < 0)
GOTO(out_site, rc);
rc = osd_procfs_init(o, o->od_svname);
if (rc != 0) {
CERROR("%s: can't initialize procfs: rc = %d\n",
o->od_svname, rc);
- GOTO(out_site, rc);
+ GOTO(out_scrub, rc);
}
LASSERT(l->ld_site->ls_linkage.next && l->ld_site->ls_linkage.prev);
}
RETURN(0);
+
out_procfs:
osd_procfs_fini(o);
+out_scrub:
+ osd_scrub_cleanup(env, o);
out_site:
lu_site_fini(&o->od_site);
out_compat:
osd_obj_map_fini(o);
-out_scrub:
- osd_scrub_cleanup(env, o);
out_mnt:
- osd_oi_fini(info, o);
- osd_shutdown(env, o);
- mntput(o->od_mnt);
- o->od_mnt = NULL;
+ osd_umount(env, o);
out_capa:
cleanup_capa_hash(o->od_capa_hash);
out:
- RETURN(rc);
+ return rc;
}
static struct lu_device *osd_device_alloc(const struct lu_env *env,
int result = 0;
ENTRY;
- if (dev->ld_site && lu_device_is_md(dev->ld_site->ls_top_dev)) {
- /* MDT/MDD still use old infrastructure to create
- * special files */
- result = llo_local_objects_setup(env, lu2md_dev(pdev),
- lu2dt_dev(dev));
- if (result)
- RETURN(result);
- }
-
if (osd->od_quota_slave != NULL)
/* set up quota slave objects */
result = qsd_prepare(env, osd->od_quota_slave);