1) Abstract some common functions in OSD layer.
2) Call lu_object_put() in osd_object_find() under failure case.
3) Do not release buffer_head until all the needed contents have
been accessed in osd_oi_index_create_one().
Signed-off-by: Fan Yong <yong.fan@whamcloud.com>
Change-Id: I3e6880271ee73ec2c4638b02c7e9c55fc827bdf3
Reviewed-on: http://review.whamcloud.com/2551
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
#include <lvfs.h>
#include "osd_internal.h"
+#include "osd_oi.h"
struct osd_compat_objid_seq {
/* protects on-fly initialization */
inode = &info->oti_inode;
inode->i_sb = osd_sb(osd);
- inode->i_ino = id->oii_ino;
- inode->i_generation = id->oii_gen;
+ osd_id_to_inode(inode, id);
child = &info->oti_child_dentry;
child->d_name.hash = 0;
struct dentry *d;
struct dentry *d_seq;
struct ost_id *ostid = &info->oti_ostid;
- int rc = 0;
int dirn;
char name[32];
struct ldiskfs_dir_entry_2 *de;
struct buffer_head *bh;
struct inode *dir;
+ struct inode *inode;
ENTRY;
/* on the very first lookup we find and open directories */
bh = osd_ldiskfs_find_entry(dir, d_seq, &de, NULL);
UNLOCK_INODE_MUTEX(dir);
- rc = -ENOENT;
- if (bh) {
- struct inode *inode;
-
- id->oii_ino = le32_to_cpu(de->inode);
- brelse(bh);
+ if (bh == NULL)
+ RETURN(-ENOENT);
- id->oii_gen = OSD_OII_NOGEN;
- inode = osd_iget(info, dev, id);
+ osd_id_gen(id, le32_to_cpu(de->inode), OSD_OII_NOGEN);
+ brelse(bh);
- if (IS_ERR(inode))
- GOTO(cleanup, rc = PTR_ERR(inode));
- rc = 0;
- id->oii_gen = inode->i_generation;
- iput(inode);
- }
+ inode = osd_iget(info, dev, id);
+ if (IS_ERR(inode))
+ RETURN(PTR_ERR(inode));
-cleanup:
- RETURN(rc);
+ iput(inode);
+ RETURN(0);
}
int osd_compat_objid_insert(struct osd_thread_info *info,
struct osd_inode_id *id)
{
struct dentry *dentry;
+ struct inode *inode;
char *name;
int rc = -ENOENT;
ENTRY;
if (name == NULL || strlen(name) == 0)
RETURN(-ENOENT);
- dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name));
- if (!IS_ERR(dentry)) {
- if (dentry->d_inode) {
- if (is_bad_inode(dentry->d_inode)) {
- rc = -EIO;
- } else {
- id->oii_ino = dentry->d_inode->i_ino;
- id->oii_gen = dentry->d_inode->i_generation;
- rc = 0;
- }
- }
- dput(dentry);
- }
+ dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name));
+ if (!IS_ERR(dentry)) {
+ inode = dentry->d_inode;
+ if (inode) {
+ if (is_bad_inode(inode)) {
+ rc = -EIO;
+ } else {
+ osd_id_gen(id, inode->i_ino,
+ inode->i_generation);
+ rc = 0;
+ }
+ }
+ dput(dentry);
+ }
- RETURN(rc);
+ RETURN(rc);
}
-
}
}
+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
void lu_igif_to_id(const struct lu_fid *fid, struct osd_inode_id *id)
{
- LASSERT(fid_is_igif(fid));
- id->oii_ino = lu_igif_ino(fid);
- id->oii_gen = lu_igif_gen(fid);
+ LASSERT(fid_is_igif(fid));
+ osd_id_gen(id, lu_igif_ino(fid), lu_igif_gen(fid));
}
-
struct inode;
-#define OSD_OII_NOGEN (0)
#define OSD_COUNTERS (0)
/** Enable thandle usage statistics */
struct htree_lock *oti_hlock;
struct lu_fid oti_fid;
- struct osd_inode_id oti_id;
+ struct lu_fid oti_fid2;
+ struct osd_inode_id oti_id;
+ struct osd_inode_id oti_id2;
struct ost_id oti_ostid;
/*
struct lustre_capa *capa, __u64 opc);
void osd_declare_qid(struct dt_object *dt, struct osd_thandle *oh,
int type, uid_t id, struct inode *inode);
-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 *osd_iget_fid(struct osd_thread_info *info, struct osd_device *dev,
+ struct osd_inode_id *id, struct lu_fid *fid);
int osd_compat_init(struct osd_device *dev);
void osd_compat_fini(struct osd_device *dev);
#define osd_invariant(obj) (1)
#endif
+extern const struct dt_index_operations osd_otable_ops;
+
+static inline int osd_oi_fid2idx(struct osd_device *dev,
+ const struct lu_fid *fid)
+{
+ return fid->f_seq & (dev->od_oi_count - 1);
+}
+
static inline struct osd_oi *osd_fid2oi(struct osd_device *osd,
const struct lu_fid *fid)
{
LASSERT(osd->od_oi_table != NULL && osd->od_oi_count >= 1);
/* It can work even od_oi_count equals to 1 although it's unexpected,
* the only reason we set it to 1 is for performance measurement */
- return osd->od_oi_table[fid->f_seq & (osd->od_oi_count - 1)];
+ return osd->od_oi_table[osd_oi_fid2idx(osd, fid)];
}
extern const struct lu_device_operations osd_lu_ops;
}
int osd_ldiskfs_read(struct inode *inode, void *buf, int size, loff_t *offs);
+int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize,
+ loff_t *offs, handle_t *handle);
static inline
struct dentry *osd_child_dentry_by_inode(const struct lu_env *env,
return 0;
}
-static int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize,
- loff_t *offs, handle_t *handle)
+int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize,
+ loff_t *offs, handle_t *handle)
{
struct buffer_head *bh = NULL;
loff_t offset = *offs;
/* fid_cpu_to_be() */
#include <lustre_fid.h>
+#include <dt_object.h>
#include "osd_oi.h"
/* osd_lookup(), struct osd_thread_info */
#include "osd_internal.h"
#include "osd_igif.h"
-#include "dt_object.h"
-
-#define OSD_OI_FID_NR (1UL << OSD_OI_FID_OID_BITS)
-#define OSD_OI_FID_NR_MAX (1UL << OSD_OI_FID_OID_BITS_MAX)
static unsigned int osd_oi_count = OSD_OI_FID_NR;
CFS_MODULE_PARM(osd_oi_count, "i", int, 0444,
}
static int osd_oi_index_create_one(struct osd_thread_info *info,
- struct osd_device *osd, const char *name,
- struct dt_index_features *feat)
+ struct osd_device *osd, const char *name,
+ struct dt_index_features *feat)
{
- const struct lu_env *env = info->oti_env;
- struct osd_inode_id *id = &info->oti_id;
- struct buffer_head *bh;
- struct inode *inode;
- struct ldiskfs_dir_entry_2 *de;
- struct dentry *dentry;
- struct inode *dir;
- handle_t *jh;
- int rc;
-
- dentry = osd_child_dentry_by_inode(env, osd_sb(osd)->s_root->d_inode,
- name, strlen(name));
- dir = osd_sb(osd)->s_root->d_inode;
- bh = osd_ldiskfs_find_entry(dir, dentry, &de, NULL);
- if (bh) {
- brelse(bh);
-
- id->oii_ino = le32_to_cpu(de->inode);
- id->oii_gen = OSD_OII_NOGEN;
-
- inode = osd_iget(info, osd, id);
- if (!IS_ERR(inode)) {
- iput(inode);
- RETURN(-EEXIST);
- }
- RETURN(PTR_ERR(inode));
- }
-
- jh = ldiskfs_journal_start_sb(osd_sb(osd), 100);
- LASSERT(!IS_ERR(jh));
-
- inode = ldiskfs_create_inode(jh, osd_sb(osd)->s_root->d_inode,
- (S_IFREG | S_IRUGO | S_IWUSR));
- LASSERT(!IS_ERR(inode));
-
- if (feat->dif_flags & DT_IND_VARKEY)
- rc = iam_lvar_create(inode, feat->dif_keysize_max,
- feat->dif_ptrsize, feat->dif_recsize_max,
- jh);
- else
- rc = iam_lfix_create(inode, feat->dif_keysize_max,
- feat->dif_ptrsize, feat->dif_recsize_max,
- jh);
-
- dentry = osd_child_dentry_by_inode(env, osd_sb(osd)->s_root->d_inode,
- name, strlen(name));
- rc = osd_ldiskfs_add_entry(jh, dentry, inode, NULL);
- LASSERT(rc == 0);
-
- ldiskfs_journal_stop(jh);
- iput(inode);
-
- return rc;
+ const struct lu_env *env = info->oti_env;
+ struct osd_inode_id *id = &info->oti_id;
+ struct buffer_head *bh;
+ struct inode *inode;
+ struct ldiskfs_dir_entry_2 *de;
+ struct dentry *dentry;
+ struct super_block *sb = osd_sb(osd);
+ struct inode *dir = sb->s_root->d_inode;
+ handle_t *jh;
+ int rc;
+
+ dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name));
+ bh = osd_ldiskfs_find_entry(dir, dentry, &de, NULL);
+ if (bh) {
+ osd_id_gen(id, le32_to_cpu(de->inode), OSD_OII_NOGEN);
+ brelse(bh);
+ inode = osd_iget(info, osd, id);
+ if (!IS_ERR(inode)) {
+ iput(inode);
+ inode = ERR_PTR(-EEXIST);
+ }
+ return PTR_ERR(inode);
+ }
+
+ jh = ldiskfs_journal_start_sb(sb, 100);
+ if (IS_ERR(jh))
+ return PTR_ERR(jh);
+
+ inode = ldiskfs_create_inode(jh, dir, (S_IFREG | S_IRUGO | S_IWUSR));
+ if (IS_ERR(inode)) {
+ ldiskfs_journal_stop(jh);
+ return PTR_ERR(inode);
+ }
+
+ if (feat->dif_flags & DT_IND_VARKEY)
+ rc = iam_lvar_create(inode, feat->dif_keysize_max,
+ feat->dif_ptrsize, feat->dif_recsize_max,
+ jh);
+ else
+ rc = iam_lfix_create(inode, feat->dif_keysize_max,
+ feat->dif_ptrsize, feat->dif_recsize_max,
+ jh);
+ dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name));
+ rc = osd_ldiskfs_add_entry(jh, dentry, inode, NULL);
+ ldiskfs_journal_stop(jh);
+ iput(inode);
+ return rc;
}
static struct inode *osd_oi_index_open(struct osd_thread_info *info,
rc = osd_oi_index_create_one(info, osd, name, f);
if (rc)
- RETURN(ERR_PTR(rc));
+ return ERR_PTR(rc);
dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name));
if (IS_ERR(dentry))
RETURN(rc);
}
+int __osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
+ const struct lu_fid *fid, struct osd_inode_id *id)
+{
+ struct lu_fid *oi_fid = &info->oti_fid2;
+ int rc;
+
+ fid_cpu_to_be(oi_fid, fid);
+ rc = osd_oi_iam_lookup(info, osd_fid2oi(osd, fid), (struct dt_rec *)id,
+ (const struct dt_key *)oi_fid);
+ if (rc > 0) {
+ osd_id_unpack(id, id);
+ rc = 0;
+ } else if (rc == 0) {
+ rc = -ENOENT;
+ }
+ return rc;
+}
+
int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
const struct lu_fid *fid, struct osd_inode_id *id)
{
- struct lu_fid *oi_fid = &info->oti_fid;
- const struct dt_key *key;
int rc = 0;
if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG) {
rc = osd_compat_objid_lookup(info, osd, fid, id);
} else if (fid_is_igif(fid)) {
lu_igif_to_id(fid, id);
- rc = 0;
} else if (fid_is_fs_root(fid)) {
- struct inode *inode = osd_sb(osd)->s_root->d_inode;
-
- id->oii_ino = inode->i_ino;
- id->oii_gen = inode->i_generation;
- } else {
+ osd_id_gen(id, osd_sb(osd)->s_root->d_inode->i_ino,
+ osd_sb(osd)->s_root->d_inode->i_generation);
+ } else {
if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE))
return osd_compat_spec_lookup(info, osd, fid, id);
- fid_cpu_to_be(oi_fid, fid);
- key = (struct dt_key *)oi_fid;
-
- rc = osd_oi_iam_lookup(info, osd_fid2oi(osd, fid),
- (struct dt_rec *)id, key);
-
- if (rc > 0) {
- id->oii_ino = be32_to_cpu(id->oii_ino);
- id->oii_gen = be32_to_cpu(id->oii_gen);
- rc = 0;
- } else if (rc == 0) {
- rc = -ENOENT;
- }
+ rc = __osd_oi_lookup(info, osd, fid, id);
}
return rc;
}
static int osd_oi_iam_insert(struct osd_thread_info *oti, struct osd_oi *oi,
- const struct dt_rec *rec, const struct dt_key *key,
- struct thandle *th, int ignore_quota)
+ const struct dt_rec *rec, const struct dt_key *key,
+ struct thandle *th)
{
struct iam_container *bag;
struct iam_rec *iam_rec = (struct iam_rec *)oti->oti_ldp;
LASSERT(oh->ot_handle != NULL);
LASSERT(oh->ot_handle->h_transaction != NULL);
#ifdef HAVE_QUOTA_SUPPORT
- if (ignore_quota)
- cfs_cap_raise(CFS_CAP_SYS_RESOURCE);
- else
- cfs_cap_lower(CFS_CAP_SYS_RESOURCE);
+ cfs_cap_raise(CFS_CAP_SYS_RESOURCE);
#endif
if (S_ISDIR(oi->oi_inode->i_mode))
osd_fid_pack((struct osd_fid_pack *)iam_rec, rec,
}
int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd,
- const struct lu_fid *fid, const struct osd_inode_id *id0,
- struct thandle *th, int ignore_quota)
+ const struct lu_fid *fid, const struct osd_inode_id *id,
+ struct thandle *th)
{
- struct lu_fid *oi_fid = &info->oti_fid;
- struct osd_inode_id *id;
- const struct dt_key *key;
+ struct lu_fid *oi_fid = &info->oti_fid2;
+ struct osd_inode_id *oi_id = &info->oti_id2;
if (fid_is_igif(fid) || unlikely(fid_seq(fid) == FID_SEQ_DOT_LUSTRE))
return 0;
if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG)
- return osd_compat_objid_insert(info, osd, fid, id0, th);
+ return osd_compat_objid_insert(info, osd, fid, id, th);
/* Server mount should not depends on OI files */
if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE))
- return osd_compat_spec_insert(info, osd, fid, id0, th);
-
- fid_cpu_to_be(oi_fid, fid);
- key = (struct dt_key *)oi_fid;
+ return osd_compat_spec_insert(info, osd, fid, id, th);
- id = &info->oti_id;
- id->oii_ino = cpu_to_be32(id0->oii_ino);
- id->oii_gen = cpu_to_be32(id0->oii_gen);
-
- return osd_oi_iam_insert(info, osd_fid2oi(osd, fid),
- (struct dt_rec *)id, key, th, ignore_quota);
+ fid_cpu_to_be(oi_fid, fid);
+ osd_id_pack(oi_id, id);
+ return osd_oi_iam_insert(info, osd_fid2oi(osd, fid),
+ (const struct dt_rec *)oi_id,
+ (const struct dt_key *)oi_fid, th);
}
static int osd_oi_iam_delete(struct osd_thread_info *oti, struct osd_oi *oi,
}
int osd_oi_delete(struct osd_thread_info *info,
- struct osd_device *osd, const struct lu_fid *fid,
- struct thandle *th)
+ struct osd_device *osd, const struct lu_fid *fid,
+ struct thandle *th)
{
- struct lu_fid *oi_fid = &info->oti_fid;
- const struct dt_key *key;
-
- LASSERT(fid_seq(fid) != FID_SEQ_LOCAL_FILE);
+ struct lu_fid *oi_fid = &info->oti_fid2;
- if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG)
- return osd_compat_objid_delete(info, osd, fid, th);
+ LASSERT(fid_seq(fid) != FID_SEQ_LOCAL_FILE);
- fid_cpu_to_be(oi_fid, fid);
- key = (struct dt_key *)oi_fid;
+ if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG)
+ return osd_compat_objid_delete(info, osd, fid, th);
- return osd_oi_iam_delete(info, osd_fid2oi(osd, fid), key, th);
+ fid_cpu_to_be(oi_fid, fid);
+ return osd_oi_iam_delete(info, osd_fid2oi(osd, fid),
+ (const struct dt_key *)oi_fid, th);
}
-int osd_oi_mod_init()
+int osd_oi_mod_init(void)
{
if (osd_oi_count == 0 || osd_oi_count > OSD_OI_FID_NR_MAX)
osd_oi_count = OSD_OI_FID_NR;
#include <lu_object.h>
#include <md_object.h>
+#define OSD_OI_FID_NR (1UL << OSD_OI_FID_OID_BITS)
+#define OSD_OI_FID_NR_MAX (1UL << OSD_OI_FID_OID_BITS_MAX)
+
+#define OSD_OII_NOGEN (0)
+
struct lu_fid;
struct osd_thread_info;
struct lu_site;
* Storage cookie. Datum uniquely identifying inode on the underlying file
* system.
*
- * XXX Currently this is ext2/ext3/ldiskfs specific thing. In the future this
- * should be generalized to work with other local file systems.
+ * osd_inode_id is the internal ldiskfs identifier for an object. It should
+ * not be visible outside of the osd-ldiskfs. Other OSDs may have different
+ * identifiers, so this cannot form any part of the OSD API.
*/
struct osd_inode_id {
- __u32 oii_ino; /* inode number */
- __u32 oii_gen; /* inode generation */
+ __u32 oii_ino; /* inode number */
+ __u32 oii_gen; /* inode generation */
};
+static inline void osd_id_pack(struct osd_inode_id *tgt,
+ const struct osd_inode_id *src)
+{
+ tgt->oii_ino = cpu_to_be32(src->oii_ino);
+ tgt->oii_gen = cpu_to_be32(src->oii_gen);
+}
+
+static inline void osd_id_unpack(struct osd_inode_id *tgt,
+ struct osd_inode_id *src)
+{
+ tgt->oii_ino = be32_to_cpu(src->oii_ino);
+ tgt->oii_gen = be32_to_cpu(src->oii_gen);
+}
+
+static inline void osd_id_gen(struct osd_inode_id *id, __u32 ino, __u32 gen)
+{
+ id->oii_ino = ino;
+ id->oii_gen = gen;
+}
+
+static inline void osd_id_to_inode(struct inode *inode,
+ const struct osd_inode_id *id)
+{
+ inode->i_ino = id->oii_ino;
+ inode->i_generation = id->oii_gen;
+}
+
+static inline int osd_id_eq(const struct osd_inode_id *id0,
+ const struct osd_inode_id *id1)
+{
+ return (id0->oii_ino == id1->oii_ino) &&
+ (id0->oii_gen == id1->oii_gen ||
+ id0->oii_gen == OSD_OII_NOGEN ||
+ id1->oii_gen == OSD_OII_NOGEN);
+}
+
int osd_oi_mod_init(void);
int osd_oi_init(struct osd_thread_info *info, struct osd_device *osd);
void osd_oi_fini(struct osd_thread_info *info, struct osd_device *osd);
+int __osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
+ const struct lu_fid *fid, struct osd_inode_id *id);
int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd,
- const struct lu_fid *fid, struct osd_inode_id *id);
+ const struct lu_fid *fid, struct osd_inode_id *id);
int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd,
- const struct lu_fid *fid, const struct osd_inode_id *id,
- struct thandle *th, int ingore_quota);
+ const struct lu_fid *fid, const struct osd_inode_id *id,
+ struct thandle *th);
int osd_oi_delete(struct osd_thread_info *info,
- struct osd_device *osd, const struct lu_fid *fid,
- struct thandle *th);
+ struct osd_device *osd, const struct lu_fid *fid,
+ struct thandle *th);
#endif /* __KERNEL__ */
#endif /* _OSD_OI_H */