}
}
+static int osd_get_lma(struct inode *inode, struct dentry *dentry,
+ struct lustre_mdt_attrs *lma)
+{
+ int rc;
+
+ dentry->d_inode = inode;
+ rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA, (void *)lma,
+ sizeof(*lma));
+ if (rc > 0) {
+ /* Check LMA compatibility */
+ if (lma->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP)) {
+ CWARN("%.16s: unsupported incompat LMA feature(s) "
+ "%lx/%#x\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;
+ }
+ } else if (rc == 0) {
+ rc = -ENODATA;
+ }
+
+ return rc;
+}
+
/*
* retrieve object from backend ext fs.
**/
-struct inode *osd_iget(struct osd_thread_info *info,
- struct osd_device *dev,
- const struct osd_inode_id *id)
+struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev,
+ struct osd_inode_id *id)
+{
+ struct inode *inode = NULL;
+
+ inode = ldiskfs_iget(osd_sb(dev), id->oii_ino);
+ if (IS_ERR(inode)) {
+ CDEBUG(D_INODE, "no inode: ino = %u, rc = %ld\n",
+ id->oii_ino, PTR_ERR(inode));
+ } else if (id->oii_gen != OSD_OII_NOGEN &&
+ inode->i_generation != id->oii_gen) {
+ CDEBUG(D_INODE, "unmatched inode: ino = %u, gen0 = %u, "
+ "gen1 = %u\n",
+ id->oii_ino, id->oii_gen, inode->i_generation);
+ iput(inode);
+ inode = ERR_PTR(-ESTALE);
+ } else if (inode->i_nlink == 0) {
+ /* due to parallel readdir and unlink,
+ * we can have dead inode here. */
+ CDEBUG(D_INODE, "stale inode: ino = %u\n", id->oii_ino);
+ make_bad_inode(inode);
+ iput(inode);
+ inode = ERR_PTR(-ESTALE);
+ } else if (is_bad_inode(inode)) {
+ CWARN("%s: bad inode: ino = %u\n",
+ dev->od_dt_dev.dd_lu_dev.ld_obd->obd_name, id->oii_ino);
+ iput(inode);
+ inode = ERR_PTR(-ENOENT);
+ } else {
+ if (id->oii_gen == OSD_OII_NOGEN)
+ osd_id_gen(id, inode->i_ino, inode->i_generation);
+
+ /* Do not update file c/mtime in ldiskfs.
+ * NB: we don't have any lock to protect this because we don't
+ * have reference on osd_object now, but contention with
+ * another lookup + attr_set can't happen in the tiny window
+ * between if (...) and set S_NOCMTIME. */
+ if (!(inode->i_flags & S_NOCMTIME))
+ inode->i_flags |= S_NOCMTIME;
+ }
+ return inode;
+}
+
+struct inode *osd_iget_fid(struct osd_thread_info *info, struct osd_device *dev,
+ struct osd_inode_id *id, struct lu_fid *fid)
{
- struct inode *inode = NULL;
+ struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs;
+ struct inode *inode;
+ int rc;
- inode = ldiskfs_iget(osd_sb(dev), id->oii_ino);
- if (IS_ERR(inode)) {
- CERROR("Cannot get inode, rc = %li\n", PTR_ERR(inode));
- } else if (id->oii_gen != OSD_OII_NOGEN &&
- inode->i_generation != id->oii_gen) {
- iput(inode);
- inode = ERR_PTR(-ESTALE);
- } else if (inode->i_nlink == 0) {
- /* due to parallel readdir and unlink,
- * we can have dead inode here. */
- CWARN("stale inode\n");
- make_bad_inode(inode);
- iput(inode);
- inode = ERR_PTR(-ESTALE);
- } else if (is_bad_inode(inode)) {
- CERROR("bad inode %lx\n",inode->i_ino);
- iput(inode);
- inode = ERR_PTR(-ENOENT);
- } else {
- /* Do not update file c/mtime in ldiskfs.
- * NB: we don't have any lock to protect this because we don't
- * have reference on osd_object now, but contention with
- * another lookup + attr_set can't happen in the tiny window
- * between if (...) and set S_NOCMTIME. */
- if (!(inode->i_flags & S_NOCMTIME))
- inode->i_flags |= S_NOCMTIME;
- }
- return inode;
+ inode = osd_iget(info, dev, id);
+ if (IS_ERR(inode))
+ return inode;
+
+ rc = osd_get_lma(inode, &info->oti_obj_dentry, lma);
+ if (rc == 0) {
+ *fid = lma->lma_self_fid;
+ } else if (rc == -ENODATA) {
+ LU_IGIF_BUILD(fid, inode->i_ino, inode->i_generation);
+ } else {
+ iput(inode);
+ inode = ERR_PTR(rc);
+ }
+ return inode;
}
static int osd_fid_lookup(const struct lu_env *env,
}
if (!S_ISDIR(inode->i_mode) || !ldiskfs_pdo) /* done */
- goto out;
+ GOTO(out, result = 0);
+
+ LASSERT(obj->oo_hl_head == NULL);
+ obj->oo_hl_head = ldiskfs_htree_lock_head_alloc(HTREE_HBITS_DEF);
+ if (obj->oo_hl_head == NULL) {
+ obj->oo_inode = NULL;
+ iput(inode);
+ GOTO(out, result = -ENOMEM);
+ }
+ GOTO(out, result = 0);
- LASSERT(obj->oo_hl_head == NULL);
- obj->oo_hl_head = ldiskfs_htree_lock_head_alloc(HTREE_HBITS_DEF);
- if (obj->oo_hl_head == NULL) {
- obj->oo_inode = NULL;
- iput(inode);
- result = -ENOMEM;
- }
out:
- LINVRNT(osd_invariant(obj));
- RETURN(result);
+ LINVRNT(osd_invariant(obj));
+ return result;
}
/*
*/
param->ddp_max_name_len = LDISKFS_NAME_LEN;
param->ddp_max_nlink = LDISKFS_LINK_MAX;
- param->ddp_block_shift = osd_sb(osd_dt_dev(dev))->s_blocksize_bits;
+ param->ddp_block_shift = sb->s_blocksize_bits;
param->ddp_mntopts = 0;
if (test_opt(sb, XATTR_USER))
param->ddp_mntopts |= MNTOPT_USERXATTR;
LASSERT(obj->oo_inode != NULL);
LASSERT(uc != NULL);
- id->oii_ino = obj->oo_inode->i_ino;
- id->oii_gen = obj->oo_inode->i_generation;
-
- return osd_oi_insert(info, osd, fid, id, th,
- uc->mu_cap & CFS_CAP_SYS_RESOURCE_MASK);
+ osd_id_gen(id, obj->oo_inode->i_ino, obj->oo_inode->i_generation);
+ return osd_oi_insert(info, osd, fid, id, th);
}
static int osd_declare_object_create(const struct lu_env *env,
}
/**
- * Helper function to form igif
- */
-static inline void osd_igif_get(const struct lu_env *env, struct inode *inode,
- struct lu_fid *fid)
-{
- LU_IGIF_BUILD(fid, inode->i_ino, inode->i_generation);
-}
-
-/**
* ldiskfs supports fid in dirent, it is passed in dentry->d_fsdata.
* lustre 1.8 also uses d_fsdata for passing other info to ldiskfs.
* To have compatilibility with 1.8 ldiskfs driver we need to have
* \retval 0 on success
*/
static int osd_ea_fid_get(const struct lu_env *env, struct osd_object *obj,
- __u32 ino, struct lu_fid *fid)
+ __u32 ino, struct lu_fid *fid)
{
- struct osd_thread_info *info = osd_oti_get(env);
- struct lustre_mdt_attrs *mdt_attrs = &info->oti_mdt_attrs;
- struct lu_device *ldev = obj->oo_dt.do_lu.lo_dev;
- struct dentry *dentry = &info->oti_child_dentry;
- struct osd_inode_id *id = &info->oti_id;
- struct osd_device *dev;
- struct inode *inode;
- int rc;
-
- ENTRY;
- dev = osd_dev(ldev);
-
- id->oii_ino = ino;
- id->oii_gen = OSD_OII_NOGEN;
-
- inode = osd_iget(info, dev, id);
- if (IS_ERR(inode)) {
- rc = PTR_ERR(inode);
- GOTO(out,rc);
- }
- dentry->d_inode = inode;
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct osd_inode_id *id = &info->oti_id;
+ struct inode *inode;
+ ENTRY;
- LASSERT(inode->i_op != NULL && inode->i_op->getxattr != NULL);
- rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA, (void *)mdt_attrs,
- sizeof *mdt_attrs);
-
- /* Check LMA compatibility */
- if (rc > 0 &&
- (mdt_attrs->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP))) {
- CWARN("Inode %lx: Unsupported incompat LMA feature(s) %#x\n",
- inode->i_ino, le32_to_cpu(mdt_attrs->lma_incompat) &
- ~LMA_INCOMPAT_SUPP);
- return -ENOSYS;
- }
+ osd_id_gen(id, ino, OSD_OII_NOGEN);
+ inode = osd_iget_fid(info, osd_obj2dev(obj), id, fid);
+ if (IS_ERR(inode))
+ RETURN(PTR_ERR(inode));
- if (rc > 0) {
- lustre_lma_swab(mdt_attrs);
- memcpy(fid, &mdt_attrs->lma_self_fid, sizeof(*fid));
- rc = 0;
- } else if (rc == -ENODATA) {
- osd_igif_get(env, inode, fid);
- rc = 0;
- }
- iput(inode);
-out:
- RETURN(rc);
+ iput(inode);
+ RETURN(0);
}
/**
LASSERT(th != NULL);
if (osd_object_auth(env, dt, capa, CAPA_OPC_INDEX_INSERT))
- return -EACCES;
+ RETURN(-EACCES);
OSD_EXEC_OP(th, insert);
else
LU_OBJECT_DEBUG(D_ERROR, env, luch,
"lu_object can't be located"
- ""DFID"\n", PFID(fid));
+ DFID"\n", PFID(fid));
if (child == NULL) {
lu_object_put(env, luch);
LU_OBJECT_DEBUG(D_ERROR, env, luch,
"lu_object does not exists "DFID"\n",
PFID(fid));
+ lu_object_put(env, luch);
child = ERR_PTR(-ENOENT);
}
} else