X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_handler.c;h=c561425f3f5d98b540976d504ca8283b4100e497;hb=7805b45f1182ed21198c0cd2000ffe93b7de5340;hp=e0c1337914aa4bc89e2fb8488f0a6b6bbe3610cb;hpb=20553c985a518ebc1d5da2a1ddf44c4eec3db044;p=fs%2Flustre-release.git diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index e0c1337..c561425 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -39,6 +39,7 @@ #define DEBUG_SUBSYSTEM S_OSD +#include #include #include #include @@ -209,14 +210,14 @@ osd_idc_add(const struct lu_env *env, struct osd_device *osd, i = oti->oti_ins_cache_size * 2; if (i == 0) i = OSD_INS_CACHE_SIZE; - OBD_ALLOC(idc, sizeof(*idc) * i); + OBD_ALLOC_PTR_ARRAY(idc, i); if (idc == NULL) return ERR_PTR(-ENOMEM); if (oti->oti_ins_cache != NULL) { memcpy(idc, oti->oti_ins_cache, oti->oti_ins_cache_used * sizeof(*idc)); - OBD_FREE(oti->oti_ins_cache, - oti->oti_ins_cache_used * sizeof(*idc)); + OBD_FREE_PTR_ARRAY(oti->oti_ins_cache, + oti->oti_ins_cache_used); } oti->oti_ins_cache = idc; oti->oti_ins_cache_size = i; @@ -477,6 +478,7 @@ int osd_ldiskfs_add_entry(struct osd_thread_info *info, struct osd_device *osd, struct lustre_ost_attrs *loa = &info->oti_ost_attrs; struct inode *parent = child->d_parent->d_inode; struct lu_fid *fid = NULL; + char fidstr[FID_LEN + 1] = "unknown"; rc2 = osd_get_lma(info, parent, child->d_parent, loa); if (!rc2) { @@ -493,19 +495,18 @@ int osd_ldiskfs_add_entry(struct osd_thread_info *info, struct osd_device *osd, } if (fid != NULL) - /* below message is checked in sanity.sh test_129 */ - CWARN("%s: directory (inode: %lu, FID: "DFID") %s maximum entry limit\n", - osd_name(osd), parent->i_ino, PFID(fid), - rc == -ENOSPC ? "has reached" : "is approaching"); - else - /* below message is checked in sanity.sh test_129 */ - CWARN("%s: directory (inode: %lu, FID: unknown) %s maximum entry limit\n", - osd_name(osd), parent->i_ino, - rc == -ENOSPC ? "has reached" : "is approaching"); + snprintf(fidstr, sizeof(fidstr), DFID, PFID(fid)); + + /* below message is checked in sanity.sh test_129 */ + if (rc == -ENOSPC) { + CWARN("%s: directory (inode: %lu, FID: %s) has reached max size limit\n", + osd_name(osd), parent->i_ino, fidstr); + } else { + rc = 0; /* ignore such error now */ + CWARN("%s: directory (inode: %lu, FID: %s) is approaching max size limit\n", + osd_name(osd), parent->i_ino, fidstr); + } - /* ignore such error now */ - if (rc == -ENOBUFS) - rc = 0; } return rc; @@ -956,8 +957,7 @@ static int osd_check_lmv(struct osd_thread_info *oti, struct osd_device *dev, { struct lu_buf *buf = &oti->oti_big_buf; struct dentry *dentry = &oti->oti_obj_dentry; - struct file *filp = &oti->oti_file; - const struct file_operations *fops; + struct file *filp; struct lmv_mds_md_v1 *lmv1; struct osd_check_lmv_buf oclb = { .ctx.actor = osd_stripe_dir_filldir, @@ -1002,18 +1002,7 @@ again: if (le32_to_cpu(lmv1->lmv_magic) != LMV_MAGIC_V1) GOTO(out, rc = 0); - fops = inode->i_fop; - dentry->d_inode = inode; - dentry->d_sb = inode->i_sb; - filp->f_pos = 0; - filp->f_path.dentry = dentry; - filp->f_flags |= O_NOATIME; - filp->f_mode = FMODE_64BITHASH | FMODE_NONOTIFY; - filp->f_mapping = inode->i_mapping; - filp->f_op = fops; - filp->private_data = NULL; - filp->f_cred = current_cred(); - filp->f_inode = inode; + filp = osd_quasi_file(oti->oti_env, inode); rc = osd_security_file_alloc(filp); if (rc) goto out; @@ -1023,7 +1012,7 @@ again: rc = iterate_dir(filp, &oclb.ctx); } while (rc >= 0 && oclb.oclb_items > 0 && !oclb.oclb_found && filp->f_pos != LDISKFS_HTREE_EOF_64BIT); - fops->release(inode, filp); + inode->i_fop->release(inode, filp); out: if (rc < 0) @@ -1178,17 +1167,19 @@ trigger: } } - if (thread_is_running(&scrub->os_thread)) { + if (scrub->os_running) { if (scrub->os_partial_scan && !scrub->os_in_join) goto join; - if (IS_ERR_OR_NULL(inode) || result) + osd_add_oi_cache(info, dev, id, fid); + if (IS_ERR_OR_NULL(inode) || result) { + osd_oii_insert(dev, oic, result == -ENOENT); GOTO(out, result = -EINPROGRESS); + } LASSERT(remote); LASSERT(obj->oo_inode == inode); - osd_add_oi_cache(info, dev, id, fid); osd_oii_insert(dev, oic, true); goto found; } @@ -1211,13 +1202,15 @@ join: if (rc1 && rc1 != -EALREADY) GOTO(out, result = -EREMCHG); - if (IS_ERR_OR_NULL(inode) || result) + osd_add_oi_cache(info, dev, id, fid); + if (IS_ERR_OR_NULL(inode) || result) { + osd_oii_insert(dev, oic, result == -ENOENT); GOTO(out, result = -EINPROGRESS); + } LASSERT(remote); LASSERT(obj->oo_inode == inode); - osd_add_oi_cache(info, dev, id, fid); osd_oii_insert(dev, oic, true); goto found; @@ -1436,6 +1429,7 @@ static int osd_object_init(const struct lu_env *env, struct lu_object *l, result = 0; } } + obj->oo_dirent_count = LU_DIRENT_COUNT_UNSET; LINVRNT(osd_invariant(obj)); return result; @@ -1589,11 +1583,8 @@ static void osd_object_free(const struct lu_env *env, struct lu_object *l) ldiskfs_htree_lock_head_free(obj->oo_hl_head); /* obj doesn't contain an lu_object_header, so we don't need call_rcu */ OBD_FREE_PTR(obj); - if (unlikely(h)) { - lu_object_header_fini(h); - OBD_FREE_PRE(h, sizeof(*h), "kfreed"); - kfree_rcu(h, loh_rcu); - } + if (unlikely(h)) + lu_object_header_free(h); } /* @@ -1615,16 +1606,6 @@ static void osd_index_fini(struct osd_object *o) } } -/* - * Concurrency: no concurrent access is possible that late in object - * life-cycle (for all existing callers, that is. New callers have to provide - * their own locking.) - */ -static int osd_inode_unlinked(const struct inode *inode) -{ - return inode->i_nlink == 0; -} - enum { OSD_TXN_OI_DELETE_CREDITS = 20, OSD_TXN_INODE_DELETE_CREDITS = 20 @@ -1711,7 +1692,7 @@ static int osd_param_is_not_sane(const struct osd_device *dev, static void osd_trans_commit_cb(struct super_block *sb, struct ldiskfs_journal_cb_entry *jcb, int error) { - struct osd_thandle *oh = container_of0(jcb, struct osd_thandle, ot_jcb); + struct osd_thandle *oh = container_of(jcb, struct osd_thandle, ot_jcb); struct thandle *th = &oh->ot_super; struct lu_device *lud = &th->th_dev->dd_lu_dev; struct dt_txn_commit_cb *dcb, *tmp; @@ -1796,7 +1777,7 @@ void osd_trans_dump_creds(const struct lu_env *env, struct thandle *th) struct osd_thread_info *oti = osd_oti_get(env); struct osd_thandle *oh; - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh != NULL); CWARN(" create: %u/%u/%u, destroy: %u/%u/%u\n", @@ -1855,7 +1836,7 @@ static int osd_trans_start(const struct lu_env *env, struct dt_device *d, LASSERT(current->journal_info == NULL); - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh != NULL); LASSERT(oh->ot_handle == NULL); @@ -1984,7 +1965,7 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt, ENTRY; - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); remove_agents = oh->ot_remove_agents; @@ -2033,7 +2014,7 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt, OBD_FREE_PTR(oh); } - osd_trunc_unlock_all(&truncates); + osd_trunc_unlock_all(env, &truncates); /* inform the quota slave device that the transaction is stopping */ qsd_op_end(env, qsd, qtrans); @@ -2069,8 +2050,8 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt, static int osd_trans_cb_add(struct thandle *th, struct dt_txn_commit_cb *dcb) { - struct osd_thandle *oh = container_of0(th, struct osd_thandle, - ot_super); + struct osd_thandle *oh = container_of(th, struct osd_thandle, + ot_super); LASSERT(dcb->dcb_magic == TRANS_COMMIT_CB_MAGIC); LASSERT(&dcb->dcb_func != NULL); @@ -2109,6 +2090,9 @@ static void osd_object_delete(const struct lu_env *env, struct lu_object *l) if (!inode) return; + if (osd_has_index(obj) && obj->oo_dt.do_index_ops == &osd_index_iam_ops) + ldiskfs_set_inode_flag(inode, LDISKFS_INODE_JOURNAL_DATA); + uid = i_uid_read(inode); gid = i_gid_read(inode); projid = i_projid_read(inode); @@ -2206,9 +2190,9 @@ int osd_statfs(const struct lu_env *env, struct dt_device *d, statfs_pack(sfs, ksfs); if (unlikely(sb->s_flags & SB_RDONLY)) - sfs->os_state |= OS_STATE_READONLY; + sfs->os_state |= OS_STATFS_READONLY; - sfs->os_state |= osd->od_nonrotational ? OS_STATE_NONROT : 0; + sfs->os_state |= osd->od_nonrotational ? OS_STATFS_NONROT : 0; if (ldiskfs_has_feature_extents(sb)) sfs->os_maxbytes = sb->s_maxbytes; @@ -2594,11 +2578,12 @@ static void osd_inode_getattr(const struct lu_env *env, attr->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE | LA_SIZE | LA_BLOCKS | LA_UID | LA_GID | LA_PROJID | LA_FLAGS | LA_NLINK | LA_RDEV | - LA_BLKSIZE | LA_TYPE; + LA_BLKSIZE | LA_TYPE | LA_BTIME; attr->la_atime = inode->i_atime.tv_sec; attr->la_mtime = inode->i_mtime.tv_sec; attr->la_ctime = inode->i_ctime.tv_sec; + attr->la_btime = LDISKFS_I(inode)->i_crtime.tv_sec; attr->la_mode = inode->i_mode; attr->la_size = i_size_read(inode); attr->la_blocks = inode->i_blocks; @@ -2619,10 +2604,71 @@ static void osd_inode_getattr(const struct lu_env *env, attr->la_flags |= LUSTRE_PROJINHERIT_FL; } +static int osd_dirent_count(const struct lu_env *env, struct dt_object *dt, + u64 *count) +{ + struct osd_object *obj = osd_dt_obj(dt); + const struct dt_it_ops *iops; + struct dt_it *it; + int rc; + + ENTRY; + + LASSERT(S_ISDIR(obj->oo_inode->i_mode)); + LASSERT(fid_is_namespace_visible(lu_object_fid(&obj->oo_dt.do_lu))); + + if (obj->oo_dirent_count != LU_DIRENT_COUNT_UNSET) { + *count = obj->oo_dirent_count; + RETURN(0); + } + + /* directory not initialized yet */ + if (!dt->do_index_ops) { + *count = 0; + RETURN(0); + } + + iops = &dt->do_index_ops->dio_it; + it = iops->init(env, dt, LUDA_64BITHASH); + if (IS_ERR(it)) + RETURN(PTR_ERR(it)); + + rc = iops->load(env, it, 0); + if (rc < 0) { + if (rc == -ENODATA) { + rc = 0; + *count = 0; + } + GOTO(out, rc); + } + if (rc > 0) + rc = iops->next(env, it); + + for (*count = 0; rc == 0 || rc == -ESTALE; rc = iops->next(env, it)) { + if (rc == -ESTALE) + continue; + + if (iops->key_size(env, it) == 0) + continue; + + (*count)++; + } + if (rc == 1) { + obj->oo_dirent_count = *count; + rc = 0; + } +out: + iops->put(env, it); + iops->fini(env, it); + + RETURN(rc); +} + static int osd_attr_get(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr) { struct osd_object *obj = osd_dt_obj(dt); + int rc = 0; if (unlikely(!dt_object_exists(dt))) return -ENOENT; @@ -2638,9 +2684,17 @@ static int osd_attr_get(const struct lu_env *env, struct dt_object *dt, attr->la_valid |= LA_FLAGS; attr->la_flags |= LUSTRE_ORPHAN_FL; } + if (obj->oo_lma_flags & LUSTRE_ENCRYPT_FL) { + attr->la_valid |= LA_FLAGS; + attr->la_flags |= LUSTRE_ENCRYPT_FL; + } spin_unlock(&obj->oo_guard); - return 0; + if (S_ISDIR(obj->oo_inode->i_mode) && + fid_is_namespace_visible(lu_object_fid(&dt->do_lu))) + rc = osd_dirent_count(env, dt, &attr->la_dirent_count); + + return rc; } static int osd_declare_attr_qid(const struct lu_env *env, @@ -2723,7 +2777,7 @@ static int osd_declare_attr_set(const struct lu_env *env, obj = osd_dt_obj(dt); LASSERT(osd_invariant(obj)); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); osd_trans_declare_op(env, oh, OSD_OT_ATTR_SET, @@ -2838,6 +2892,13 @@ static int osd_inode_setattr(const struct lu_env *env, /* always keep S_NOCMTIME */ inode->i_flags = ll_ext_to_inode_flags(attr->la_flags) | S_NOCMTIME; +#if defined(S_ENCRYPTED) + /* Always remove S_ENCRYPTED, because ldiskfs must not be + * aware of encryption status. It is just stored into LMA + * so that it can be forwared to client side. + */ + inode->i_flags &= ~S_ENCRYPTED; +#endif /* * Ext4 did not transfer inherit flags from * @inode->i_flags to raw inode i_flags when writing @@ -2852,7 +2913,8 @@ static int osd_inode_setattr(const struct lu_env *env, } #ifdef HAVE_PROJECT_QUOTA -static int osd_transfer_project(struct inode *inode, __u32 projid) +static int osd_transfer_project(struct inode *inode, __u32 projid, + struct thandle *handle) { struct super_block *sb = inode->i_sb; struct ldiskfs_inode_info *ei = LDISKFS_I(inode); @@ -2884,9 +2946,18 @@ static int osd_transfer_project(struct inode *inode, __u32 projid) raw_inode = ldiskfs_raw_inode(&iloc); if (!LDISKFS_FITS_IN_INODE(raw_inode, ei, i_projid)) { - err = -EOVERFLOW; - brelse(iloc.bh); - return err; + struct osd_thandle *oh = container_of(handle, + struct osd_thandle, + ot_super); + /** + * try to expand inode size automatically. + */ + ldiskfs_mark_inode_dirty(oh->ot_handle, inode); + if (!LDISKFS_FITS_IN_INODE(raw_inode, ei, i_projid)) { + err = -EOVERFLOW; + brelse(iloc.bh); + return err; + } } brelse(iloc.bh); @@ -2903,7 +2974,8 @@ static int osd_transfer_project(struct inode *inode, __u32 projid) } #endif -static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr) +static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr, + struct thandle *handle) { int rc; @@ -2938,7 +3010,7 @@ static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr) if (attr->la_valid & LA_PROJID && attr->la_projid != i_projid_read(inode)) { #ifdef HAVE_PROJECT_QUOTA - rc = osd_transfer_project(inode, attr->la_projid); + rc = osd_transfer_project(inode, attr->la_projid, handle); #else rc = -ENOTSUPP; #endif @@ -2989,7 +3061,7 @@ static int osd_attr_set(const struct lu_env *env, if (unlikely(ipd == NULL)) RETURN(-ENOMEM); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); rc = iam_update(oh->ot_handle, bag, (const struct iam_key *)fid1, (const struct iam_rec *)id, ipd); @@ -2999,7 +3071,7 @@ static int osd_attr_set(const struct lu_env *env, inode = obj->oo_inode; - rc = osd_quota_transfer(inode, attr); + rc = osd_quota_transfer(inode, attr, handle); if (rc) return rc; @@ -3139,6 +3211,8 @@ static int osd_mkdir(struct osd_thread_info *info, struct osd_object *obj, oth = container_of(th, struct osd_thandle, ot_super); LASSERT(oth->ot_handle->h_transaction != NULL); + if (fid_is_namespace_visible(lu_object_fid(&obj->oo_dt.do_lu))) + obj->oo_dirent_count = 0; result = osd_mkfile(info, obj, mode, hint, th, attr); return result; @@ -3285,7 +3359,8 @@ static void osd_ah_init(const struct lu_env *env, struct dt_allocation_hint *ah, } static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj, - struct lu_attr *attr, struct dt_object_format *dof) + struct lu_attr *attr, struct dt_object_format *dof, + struct thandle *handle) { struct inode *inode = obj->oo_inode; __u64 valid = attr->la_valid; @@ -3302,7 +3377,7 @@ static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj, if ((valid & LA_MTIME) && (attr->la_mtime == inode->i_mtime.tv_sec)) attr->la_valid &= ~LA_MTIME; - result = osd_quota_transfer(inode, attr); + result = osd_quota_transfer(inode, attr, handle); if (result) return; @@ -3353,7 +3428,7 @@ static int __osd_create(struct osd_thread_info *info, struct osd_object *obj, } if (likely(result == 0)) { - osd_attr_init(info, obj, attr, dof); + osd_attr_init(info, obj, attr, dof, th); osd_object_init0(obj); } @@ -3381,7 +3456,7 @@ static int __osd_oi_insert(const struct lu_env *env, struct osd_object *obj, LASSERT(obj->oo_inode != NULL); - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle); osd_trans_exec_op(env, th, OSD_OT_INSERT); @@ -3447,7 +3522,7 @@ static int osd_declare_create(const struct lu_env *env, struct dt_object *dt, LASSERT(handle != NULL); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); /* @@ -3505,7 +3580,7 @@ static int osd_declare_destroy(const struct lu_env *env, struct dt_object *dt, if (inode == NULL) RETURN(-ENOENT); - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); osd_trans_declare_op(env, oh, OSD_OT_DESTROY, @@ -3556,7 +3631,7 @@ static int osd_destroy(const struct lu_env *env, struct dt_object *dt, ENTRY; - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle); LASSERT(inode); LASSERT(!lu_object_is_dying(dt->do_lu.lo_header)); @@ -3572,8 +3647,10 @@ static int osd_destroy(const struct lu_env *env, struct dt_object *dt, } if (S_ISDIR(inode->i_mode)) { - LASSERT(osd_inode_unlinked(inode) || inode->i_nlink == 1 || - inode->i_nlink == 2); + if (inode->i_nlink > 2) + CERROR("%s: directory "DFID" ino %lu link count is %u at unlink. run e2fsck to repair\n", + osd_name(osd), PFID(fid), inode->i_ino, + inode->i_nlink); spin_lock(&obj->oo_guard); clear_nlink(inode); @@ -3777,6 +3854,7 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env, struct osd_thread_info *info = osd_oti_get(env); struct inode *local; struct osd_thandle *oh; + uid_t own[2] = {0, 0}; int rc; ENTRY; @@ -3785,8 +3863,7 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env, oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle->h_transaction != NULL); - local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type, - NULL); + local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type, own); if (IS_ERR(local)) { CERROR("%s: create local error %d\n", osd_name(osd), (int)PTR_ERR(local)); @@ -3818,7 +3895,7 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env, #ifdef HAVE_PROJECT_QUOTA if (LDISKFS_I(pobj->oo_inode)->i_flags & LUSTRE_PROJINHERIT_FL && i_projid_read(pobj->oo_inode) != 0) { - rc = osd_transfer_project(local, 0); + rc = osd_transfer_project(local, 0, th); if (rc) { CERROR("%s: quota transfer failed: rc = %d. Is project " "quota enforcement enabled on the ldiskfs " @@ -4015,7 +4092,7 @@ static int osd_declare_ref_add(const struct lu_env *env, struct dt_object *dt, /* it's possible that object doesn't exist yet */ LASSERT(handle != NULL); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); osd_trans_declare_op(env, oh, OSD_OT_REF_ADD, @@ -4045,7 +4122,7 @@ static int osd_ref_add(const struct lu_env *env, struct dt_object *dt, LASSERT(osd_is_write_locked(env, obj)); LASSERT(th != NULL); - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle != NULL); osd_trans_exec_op(env, th, OSD_OT_REF_ADD); @@ -4093,7 +4170,7 @@ static int osd_declare_ref_del(const struct lu_env *env, struct dt_object *dt, LASSERT(!dt_object_remote(dt)); LASSERT(handle != NULL); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); osd_trans_declare_op(env, oh, OSD_OT_REF_DEL, @@ -4121,7 +4198,10 @@ static int osd_ref_del(const struct lu_env *env, struct dt_object *dt, LASSERT(osd_is_write_locked(env, obj)); LASSERT(th != NULL); - oh = container_of0(th, struct osd_thandle, ot_super); + if (OBD_FAIL_CHECK(OBD_FAIL_OSD_REF_DEL)) + return -EIO; + + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle != NULL); osd_trans_exec_op(env, th, OSD_OT_REF_DEL); @@ -4272,7 +4352,7 @@ static int osd_declare_xattr_set(const struct lu_env *env, LASSERT(handle != NULL); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); if (strcmp(name, XATTR_NAME_LMA) == 0) { @@ -4411,7 +4491,7 @@ static int osd_xattr_set_pfid(const struct lu_env *env, struct osd_object *obj, /* Remove old PFID EA entry firstly. */ dquot_initialize(inode); - rc = osd_removexattr(dentry, inode, XATTR_NAME_FID); + rc = ll_vfs_removexattr(dentry, inode, XATTR_NAME_FID); if (rc == -ENODATA) { if ((fl & LU_XATTR_REPLACE) && !(fl & LU_XATTR_CREATE)) RETURN(rc); @@ -4491,7 +4571,7 @@ static int osd_xattr_handle_linkea(const struct lu_env *env, ENTRY; - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle != NULL); rc = linkea_init_with_rec(&ldata); @@ -4660,7 +4740,7 @@ static int osd_declare_xattr_del(const struct lu_env *env, LASSERT(!dt_object_remote(dt)); LASSERT(handle != NULL); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); osd_trans_declare_op(env, oh, OSD_OT_XATTR_SET, @@ -4717,7 +4797,7 @@ static int osd_xattr_del(const struct lu_env *env, struct dt_object *dt, dquot_initialize(inode); dentry->d_inode = inode; dentry->d_sb = inode->i_sb; - rc = osd_removexattr(dentry, inode, name); + rc = ll_vfs_removexattr(dentry, inode, name); } osd_trans_exec_check(env, handle, OSD_OT_XATTR_SET); @@ -4735,20 +4815,11 @@ static int osd_object_sync(const struct lu_env *env, struct dt_object *dt, { struct osd_object *obj = osd_dt_obj(dt); struct inode *inode = obj->oo_inode; - struct osd_thread_info *info = osd_oti_get(env); - struct dentry *dentry = &info->oti_obj_dentry; - struct file *file = &info->oti_file; + struct file *file = osd_quasi_file(env, inode); int rc; ENTRY; - dentry->d_inode = inode; - dentry->d_sb = inode->i_sb; - file->f_path.dentry = dentry; - file->f_mapping = inode->i_mapping; - file->f_op = inode->i_fop; - file->f_inode = inode; - rc = vfs_fsync_range(file, start, end, 0); RETURN(rc); @@ -4961,7 +5032,7 @@ static int osd_index_declare_iam_delete(const struct lu_env *env, { struct osd_thandle *oh; - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); /* Recycle may cause additional three blocks to be changed. */ @@ -5009,7 +5080,7 @@ static int osd_index_iam_delete(const struct lu_env *env, struct dt_object *dt, if (unlikely(ipd == NULL)) RETURN(-ENOMEM); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle != NULL); LASSERT(oh->ot_handle->h_transaction != NULL); @@ -5040,7 +5111,7 @@ static int osd_index_declare_ea_delete(const struct lu_env *env, LASSERT(!dt_object_remote(dt)); LASSERT(handle != NULL); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); credits = osd_dto_credits_noquota[DTO_INDEX_DELETE]; @@ -5202,11 +5273,21 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt, } else { rc = PTR_ERR(bh); } + + if (!rc && fid_is_namespace_visible(lu_object_fid(&dt->do_lu)) && + obj->oo_dirent_count != LU_DIRENT_COUNT_UNSET) { + /* NB, dirent count may not be accurate, because it's counted + * without lock. + */ + if (obj->oo_dirent_count) + obj->oo_dirent_count--; + else + obj->oo_dirent_count = LU_DIRENT_COUNT_UNSET; + } if (hlock != NULL) ldiskfs_htree_unlock(hlock); else up_write(&obj->oo_ext_idx_sem); - GOTO(out, rc); out: LASSERT(osd_invariant(obj)); @@ -5293,7 +5374,7 @@ static int osd_index_declare_iam_insert(const struct lu_env *env, LASSERT(handle != NULL); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); osd_trans_declare_op(env, oh, OSD_OT_INSERT, @@ -5343,7 +5424,7 @@ static int osd_index_iam_insert(const struct lu_env *env, struct dt_object *dt, if (unlikely(ipd == NULL)) RETURN(-ENOMEM); - oh = container_of0(th, struct osd_thandle, ot_super); + oh = container_of(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle != NULL); LASSERT(oh->ot_handle->h_transaction != NULL); if (S_ISDIR(obj->oo_inode->i_mode)) { @@ -5541,6 +5622,10 @@ static int osd_ea_add_rec(const struct lu_env *env, struct osd_object *pobj, hlock, th); } } + if (!rc && fid_is_namespace_visible(lu_object_fid(&pobj->oo_dt.do_lu)) + && pobj->oo_dirent_count != LU_DIRENT_COUNT_UNSET) + pobj->oo_dirent_count++; + if (hlock != NULL) ldiskfs_htree_unlock(hlock); else @@ -5566,8 +5651,7 @@ osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev, if (!fid_is_norm(fid) && !fid_is_igif(fid)) RETURN(0); - if (thread_is_running(&scrub->os_thread) && - scrub->os_pos_current > id->oii_ino) + if (scrub->os_running && scrub->os_pos_current > id->oii_ino) RETURN(0); if (dev->od_auto_scrub_interval == AS_NEVER || @@ -5608,7 +5692,7 @@ again: insert = false; trigger: - if (thread_is_running(&scrub->os_thread)) { + if (scrub->os_running) { if (inode == NULL) { inode = osd_iget(oti, dev, id); /* The inode has been removed (by race maybe). */ @@ -5934,7 +6018,7 @@ static int osd_index_declare_ea_insert(const struct lu_env *env, LASSERT(fid != NULL); LASSERT(rec1->rec_type != 0); - oh = container_of0(handle, struct osd_thandle, ot_super); + oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle == NULL); credits = osd_dto_credits_noquota[DTO_INDEX_INSERT]; @@ -6094,6 +6178,7 @@ static int osd_index_ea_insert(const struct lu_env *env, struct dt_object *dt, iput(child_inode); LASSERT(osd_invariant(obj)); osd_trans_exec_check(env, th, OSD_OT_INSERT); + RETURN(rc); } @@ -7189,8 +7274,6 @@ static inline int osd_it_ea_rec(const struct lu_env *env, rc = osd_ea_fid_get(env, obj, ino, fid, id); } - } else { - osd_id_gen(id, ino, OSD_OII_NOGEN); } } @@ -7200,15 +7283,6 @@ static inline int osd_it_ea_rec(const struct lu_env *env, it->oie_dirent->oied_namelen, it->oie_dirent->oied_type, attr); - if (rc < 0) - RETURN(rc); - - if (osd_remote_fid(env, dev, fid)) - RETURN(0); - - if (likely(!(attr & (LUDA_IGNORE | LUDA_UNKNOWN)) && rc == 0)) - osd_add_oi_cache(oti, dev, id, fid); - RETURN(rc > 0 ? 0 : rc); } @@ -7374,8 +7448,8 @@ static void osd_key_fini(const struct lu_context *ctx, __free_page(page); } } - OBD_FREE(info->oti_dio_pages, - sizeof(struct page *) * PTLRPC_MAX_BRW_PAGES); + OBD_FREE_PTR_ARRAY_LARGE(info->oti_dio_pages, + PTLRPC_MAX_BRW_PAGES); } if (info->oti_inode != NULL) @@ -7389,7 +7463,7 @@ static void osd_key_fini(const struct lu_context *ctx, lu_buf_free(&info->oti_big_buf); if (idc != NULL) { LASSERT(info->oti_ins_cache_size > 0); - OBD_FREE(idc, sizeof(*idc) * info->oti_ins_cache_size); + OBD_FREE_PTR_ARRAY(idc, info->oti_ins_cache_size); info->oti_ins_cache = NULL; info->oti_ins_cache_size = 0; } @@ -7577,7 +7651,7 @@ static int osd_mount(const struct lu_env *env, *options = '\0'; if (opts != NULL) { /* strip out the options for back compatiblity */ - static char *sout[] = { + static const char * const sout[] = { "mballoc", "iopen", "noiopen", @@ -7884,10 +7958,8 @@ static struct lu_device *osd_device_free(const struct lu_env *env, /* XXX: make osd top device in order to release reference */ d->ld_site->ls_top_dev = d; lu_site_purge(env, d->ld_site, -1); - if (!cfs_hash_is_empty(d->ld_site->ls_obj_hash)) { - LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_ERROR, NULL); - lu_site_print(env, d->ld_site, &msgdata, lu_cdebug_printer); - } + lu_site_print(env, d->ld_site, &d->ld_site->ls_obj_hash.nelems, + D_ERROR, lu_cdebug_printer); lu_site_fini(&o->od_site); dt_device_fini(&o->od_dt_dev); OBD_FREE_PTR(o); @@ -8059,10 +8131,18 @@ static int osd_prepare(const struct lu_env *env, struct lu_device *pdev, RETURN(result); } -static int osd_fid_alloc(const struct lu_env *env, struct obd_export *exp, - struct lu_fid *fid, struct md_op_data *op_data) +/** + * Implementation of lu_device_operations::ldo_fid_alloc() for OSD + * + * Allocate FID. + * + * see include/lu_object.h for the details. + */ +static int osd_fid_alloc(const struct lu_env *env, struct lu_device *d, + struct lu_fid *fid, struct lu_object *parent, + const struct lu_name *name) { - struct osd_device *osd = osd_dev(exp->exp_obd->obd_lu_dev); + struct osd_device *osd = osd_dev(d); return seq_client_alloc_fid(env, osd->od_cl_seq, fid); } @@ -8081,6 +8161,7 @@ const struct lu_device_operations osd_lu_ops = { .ldo_process_config = osd_process_config, .ldo_recovery_complete = osd_recovery_complete, .ldo_prepare = osd_prepare, + .ldo_fid_alloc = osd_fid_alloc, }; static const struct lu_device_type_operations osd_device_type_ops = { @@ -8119,7 +8200,6 @@ static const struct obd_ops osd_obd_device_ops = { .o_owner = THIS_MODULE, .o_connect = osd_obd_connect, .o_disconnect = osd_obd_disconnect, - .o_fid_alloc = osd_fid_alloc, .o_health_check = osd_health_check, };