* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011 Whamcloud, Inc.
- *
- */
-/*
- * Copyright (c) 2011 Whamcloud, Inc.
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
static const char dotdot[] = "..";
static const char remote_obj_dir[] = "REM_OBJ_DIR";
-struct osd_directory {
- struct iam_container od_container;
- struct iam_descr od_descr;
-};
-
-struct osd_object {
- struct dt_object oo_dt;
- /**
- * Inode for file system object represented by this osd_object. This
- * inode is pinned for the whole duration of lu_object life.
- *
- * Not modified concurrently (either setup early during object
- * creation, or assigned by osd_object_create() under write lock).
- */
- struct inode *oo_inode;
- /**
- * to protect index ops.
- */
- struct htree_lock_head *oo_hl_head;
- cfs_rw_semaphore_t oo_ext_idx_sem;
- cfs_rw_semaphore_t oo_sem;
- struct osd_directory *oo_dir;
- /** protects inode attributes. */
- cfs_spinlock_t oo_guard;
- /**
- * Following two members are used to indicate the presence of dot and
- * dotdot in the given directory. This is required for interop mode
- * (b11826).
- */
- int oo_compat_dot_created;
- int oo_compat_dotdot_created;
-
- const struct lu_env *oo_owner;
-#ifdef CONFIG_LOCKDEP
- struct lockdep_map oo_dep_map;
-#endif
-};
-
static const struct lu_object_operations osd_lu_obj_ops;
-static const struct lu_device_operations osd_lu_ops;
-static struct lu_context_key osd_key;
static const struct dt_object_operations osd_obj_ops;
static const struct dt_object_operations osd_obj_ea_ops;
-static const struct dt_body_operations osd_body_ops;
-static const struct dt_body_operations osd_body_ops_new;
static const struct dt_index_operations osd_index_iam_ops;
static const struct dt_index_operations osd_index_ea_ops;
-#define OSD_TRACK_DECLARES
-#ifdef OSD_TRACK_DECLARES
-#define OSD_DECLARE_OP(oh, op) { \
- LASSERT(oh->ot_handle == NULL); \
- ((oh)->ot_declare_ ##op)++; }
-#define OSD_EXEC_OP(handle, op) { \
- struct osd_thandle *oh; \
- oh = container_of0(handle, struct osd_thandle, ot_super);\
- LASSERT((oh)->ot_declare_ ##op > 0); \
- ((oh)->ot_declare_ ##op)--; }
-#else
-#define OSD_DECLARE_OP(oh, op)
-#define OSD_EXEC_OP(oh, op)
-#endif
-
-struct osd_thandle {
- struct thandle ot_super;
- handle_t *ot_handle;
- struct journal_callback ot_jcb;
- cfs_list_t ot_dcb_list;
- /* Link to the device, for debugging. */
- struct lu_ref_link *ot_dev_link;
- int ot_credits;
-
-#ifdef OSD_TRACK_DECLARES
- unsigned char ot_declare_attr_set;
- unsigned char ot_declare_punch;
- unsigned char ot_declare_xattr_set;
- unsigned char ot_declare_create;
- unsigned char ot_declare_destroy;
- unsigned char ot_declare_ref_add;
- unsigned char ot_declare_ref_del;
- unsigned char ot_declare_write;
- unsigned char ot_declare_insert;
- unsigned char ot_declare_delete;
-#endif
-
-#if OSD_THANDLE_STATS
- /** time when this handle was allocated */
- cfs_time_t oth_alloced;
-
- /** time when this thanle was started */
- cfs_time_t oth_started;
-#endif
-};
-
-/**
- * Basic transaction credit op
- */
-enum dt_txn_op {
- DTO_INDEX_INSERT,
- DTO_INDEX_DELETE,
- DTO_INDEX_UPDATE,
- DTO_OBJECT_CREATE,
- DTO_OBJECT_DELETE,
- DTO_ATTR_SET_BASE,
- DTO_XATTR_SET,
- DTO_LOG_REC, /**< XXX temporary: dt layer knows nothing about llog. */
- DTO_WRITE_BASE,
- DTO_WRITE_BLOCK,
- DTO_ATTR_SET_CHOWN,
-
- DTO_NR
-};
-
-/*
- * Helpers.
- */
-static int lu_device_is_osd(const struct lu_device *d)
-{
- return ergo(d != NULL && d->ld_ops != NULL, d->ld_ops == &osd_lu_ops);
-}
-
-static struct osd_device *osd_dt_dev(const struct dt_device *d)
-{
- LASSERT(lu_device_is_osd(&d->dd_lu_dev));
- return container_of0(d, struct osd_device, od_dt_dev);
-}
-
-static struct osd_device *osd_dev(const struct lu_device *d)
-{
- LASSERT(lu_device_is_osd(d));
- return osd_dt_dev(container_of0(d, struct dt_device, dd_lu_dev));
-}
-
-static struct osd_device *osd_obj2dev(const struct osd_object *o)
-{
- return osd_dev(o->oo_dt.do_lu.lo_dev);
-}
-
-static struct super_block *osd_sb(const struct osd_device *dev)
-{
- return dev->od_mount->lmi_mnt->mnt_sb;
-}
-
-static int osd_object_is_root(const struct osd_object *obj)
-{
- return osd_sb(osd_obj2dev(obj))->s_root->d_inode == obj->oo_inode;
-}
-
-static struct osd_object *osd_obj(const struct lu_object *o)
-{
- LASSERT(lu_device_is_osd(o->lo_dev));
- return container_of0(o, struct osd_object, oo_dt.do_lu);
-}
-
-static struct osd_object *osd_dt_obj(const struct dt_object *d)
-{
- return osd_obj(&d->do_lu);
-}
-
-static struct lu_device *osd2lu_dev(struct osd_device *osd)
-{
- return &osd->od_dt_dev.dd_lu_dev;
-}
-
-static journal_t *osd_journal(const struct osd_device *dev)
-{
- return LDISKFS_SB(osd_sb(dev))->s_journal;
-}
-
static int osd_has_index(const struct osd_object *obj)
{
return obj->oo_dt.do_index_ops != NULL;
static inline void
osd_push_ctxt(const struct lu_env *env, struct osd_ctxt *save)
{
- struct md_ucred *uc = md_ucred(env);
- struct cred *tc;
+ struct md_ucred *uc = md_ucred(env);
+ struct cred *tc;
LASSERT(uc != NULL);
}
#endif
-static inline struct osd_thread_info *osd_oti_get(const struct lu_env *env)
-{
- return lu_context_key_get(&env->le_ctx, &osd_key);
-}
-
/*
* Concurrency: doesn't matter
*/
return 0;
}
+static inline int osd_qid_type(struct osd_thandle *oh, int i)
+{
+ return (oh->ot_id_type & (1 << i)) ? GRPQUOTA : USRQUOTA;
+}
+
+static inline void osd_qid_set_type(struct osd_thandle *oh, int i, int type)
+{
+ oh->ot_id_type |= ((type == GRPQUOTA) ? (1 << i) : 0);
+}
+
+void osd_declare_qid(struct dt_object *dt, struct osd_thandle *oh,
+ int type, uid_t id, struct inode *inode)
+{
+#ifdef CONFIG_QUOTA
+ int i, allocated = 0;
+ struct osd_object *obj;
+
+ LASSERT(dt != NULL);
+ LASSERT(oh != NULL);
+ LASSERTF(oh->ot_id_cnt <= OSD_MAX_UGID_CNT, "count=%u",
+ oh->ot_id_cnt);
+
+ /* id entry is allocated in the quota file */
+ if (inode && inode->i_dquot[type] && inode->i_dquot[type]->dq_off)
+ allocated = 1;
+
+ for (i = 0; i < oh->ot_id_cnt; i++) {
+ if (oh->ot_id_array[i] == id && osd_qid_type(oh, i) == type)
+ return;
+ }
+
+ if (unlikely(i >= OSD_MAX_UGID_CNT)) {
+ CERROR("more than %d uid/gids for a transaction?\n", i);
+ return;
+ }
+
+ oh->ot_id_array[i] = id;
+ osd_qid_set_type(oh, i, type);
+ oh->ot_id_cnt++;
+ obj = osd_dt_obj(dt);
+ oh->ot_credits += (allocated || id == 0) ?
+ 1 : LDISKFS_QUOTA_INIT_BLOCKS(osd_sb(osd_obj2dev(obj)));
+#endif
+}
+
/*
* OSD object methods.
*/
/*
* retrieve object from backend ext fs.
**/
-static 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,
+ const struct osd_inode_id *id)
{
struct inode *inode = NULL;
-#ifdef HAVE_EXT4_LDISKFS
inode = ldiskfs_iget(osd_sb(dev), id->oii_ino);
- if (IS_ERR(inode))
- /* Newer kernels return an error instead of a NULL pointer */
- inode = NULL;
-#else
- inode = iget(osd_sb(dev), id->oii_ino);
-#endif
- if (inode == NULL) {
- CERROR("no inode\n");
- inode = ERR_PTR(-EACCES);
+ 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);
struct lu_device *ldev = obj->oo_dt.do_lu.lo_dev;
struct osd_device *dev;
struct osd_inode_id *id;
- struct osd_oi *oi;
struct inode *inode;
int result;
ENTRY;
info = osd_oti_get(env);
+ LASSERT(info);
dev = osd_dev(ldev);
id = &info->oti_id;
- oi = &dev->od_oi;
if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT))
RETURN(-ENOENT);
- result = osd_oi_lookup(info, oi, fid, id);
+ result = osd_oi_lookup(info, dev, fid, id);
if (result != 0) {
if (result == -ENOENT)
result = 0;
- goto out;
+ GOTO(out, result);
}
inode = osd_iget(info, dev, id);
* place holders for objects yet to be created.
*/
result = PTR_ERR(inode);
- goto out;
+ GOTO(out, result);
}
obj->oo_inode = inode;
}
out:
LINVRNT(osd_invariant(obj));
-
RETURN(result);
}
OBD_FREE_PTR(obj);
}
-/**
- * IAM Iterator
- */
-static struct iam_path_descr *osd_it_ipd_get(const struct lu_env *env,
- const struct iam_container *bag)
-{
- return bag->ic_descr->id_ops->id_ipd_alloc(bag,
- osd_oti_get(env)->oti_it_ipd);
-}
-
-static struct iam_path_descr *osd_idx_ipd_get(const struct lu_env *env,
- const struct iam_container *bag)
-{
- return bag->ic_descr->id_ops->id_ipd_alloc(bag,
- osd_oti_get(env)->oti_idx_ipd);
-}
-
-static void osd_ipd_put(const struct lu_env *env,
- const struct iam_container *bag,
- struct iam_path_descr *ipd)
-{
- bag->ic_descr->id_ops->id_ipd_free(ipd);
-}
-
/*
* Concurrency: no concurrent access is possible that late in object
* life-cycle.
struct dt_device *d)
{
struct osd_thread_info *oti = osd_oti_get(env);
+ struct osd_iobuf *iobuf = &oti->oti_iobuf;
struct osd_thandle *oh;
struct thandle *th;
ENTRY;
+ /* on pending IO in this thread should left from prev. request */
+ LASSERT(cfs_atomic_read(&iobuf->dr_numreqs) == 0);
+
th = ERR_PTR(-ENOMEM);
OBD_ALLOC_GFP(oh, sizeof *oh, CFS_ALLOC_IO);
if (oh != NULL) {
if (rc != 0)
GOTO(out, rc);
- oh->ot_credits += LDISKFS_QUOTA_INIT_BLOCKS(osd_sb(dev));
-
if (!osd_param_is_sane(dev, th)) {
CWARN("%s: too many transaction credits (%d > %d)\n",
d->dd_lu_dev.ld_obd->obd_name, oh->ot_credits,
osd_journal(dev)->j_max_transaction_buffers);
+ /* XXX Limit the credits to 'max_transaction_buffers', and
+ * let the underlying filesystem to catch the error if
+ * we really need so many credits.
+ *
+ * This should be removed when we can calculate the
+ * credits precisely. */
+ oh->ot_credits = osd_journal(dev)->j_max_transaction_buffers;
#ifdef OSD_TRACK_DECLARES
CERROR(" attr_set: %d, punch: %d, xattr_set: %d,\n",
oh->ot_declare_attr_set, oh->ot_declare_punch,
CERROR(" create: %d, ref_add: %d, ref_del: %d, write: %d\n",
oh->ot_declare_create, oh->ot_declare_ref_add,
oh->ot_declare_ref_del, oh->ot_declare_write);
- CERROR(" insert: %d, delete: %d\n",
- oh->ot_declare_insert, oh->ot_declare_delete);
+ CERROR(" insert: %d, delete: %d, destroy: %d\n",
+ oh->ot_declare_insert, oh->ot_declare_delete,
+ oh->ot_declare_destroy);
#endif
}
int rc = 0;
struct osd_thandle *oh;
struct osd_thread_info *oti = osd_oti_get(env);
+ struct osd_iobuf *iobuf = &oti->oti_iobuf;
ENTRY;
OBD_FREE_PTR(oh);
}
+ /* as we want IO to journal and data IO be concurrent, we don't block
+ * awaiting data IO completion in osd_do_bio(), instead we wait here
+ * once transaction is submitted to the journal. all reqular requests
+ * don't do direct IO (except read/write), thus this wait_event becomes
+ * no-op for them.
+ *
+ * IMPORTANT: we have to wait till any IO submited by the thread is
+ * completed otherwise iobuf may be corrupted by different request
+ */
+ cfs_wait_event(iobuf->dr_wait, cfs_atomic_read(&iobuf->dr_numreqs)==0);
+ if (!rc)
+ rc = iobuf->dr_error;
+
RETURN(rc);
}
* Concurrency: shouldn't matter.
*/
-static void osd_ro(const struct lu_env *env, struct dt_device *d)
+static int osd_ro(const struct lu_env *env, struct dt_device *d)
{
struct super_block *sb = osd_sb(osd_dt_dev(d));
+ int rc;
ENTRY;
CERROR("*** setting device %s read-only ***\n", LUSTRE_OSD_NAME);
- __lvfs_set_rdonly(sb->s_bdev, LDISKFS_SB(sb)->journal_bdev);
- EXIT;
+ rc = __lvfs_set_rdonly(sb->s_bdev, LDISKFS_SB(sb)->journal_bdev);
+ RETURN(rc);
}
/*
* Note: we do not count into QUOTA here.
* If we mount with --data_journal we may need more.
*/
-static const int osd_dto_credits_noquota[DTO_NR] = {
+const int osd_dto_credits_noquota[DTO_NR] = {
/**
* Insert/Delete.
* INDEX_EXTRA_TRANS_BLOCKS(8) +
[DTO_ATTR_SET_CHOWN]= 0
};
-/**
- * Note: we count into QUOTA here.
- * If we mount with --data_journal we may need more.
- */
-static const int osd_dto_credits_quota[DTO_NR] = {
- /**
- * INDEX_EXTRA_TRANS_BLOCKS(8) +
- * SINGLEDATA_TRANS_BLOCKS(8) +
- * 2 * QUOTA_TRANS_BLOCKS(2)
- */
- [DTO_INDEX_INSERT] = 20,
- /**
- * INDEX_EXTRA_TRANS_BLOCKS(8) +
- * SINGLEDATA_TRANS_BLOCKS(8) +
- * 2 * QUOTA_TRANS_BLOCKS(2)
- */
- [DTO_INDEX_DELETE] = 20,
- /**
- * Unused now.
- */
- [DTO_INDEX_UPDATE] = 16,
- /*
- * Create a object. Same as create object in EXT3 filesystem.
- * DATA_TRANS_BLOCKS(16) +
- * INDEX_EXTRA_BLOCKS(8) +
- * 3(inode bits, groups, GDT) +
- * 2 * QUOTA_INIT_BLOCKS(25)
- */
- [DTO_OBJECT_CREATE] = 77,
- /*
- * Unused now.
- * DATA_TRANS_BLOCKS(16) +
- * INDEX_EXTRA_BLOCKS(8) +
- * 3(inode bits, groups, GDT) +
- * QUOTA(?)
- */
- [DTO_OBJECT_DELETE] = 27,
- /**
- * Attr set credits.
- * 3 (inode bit, group, GDT) +
- */
- [DTO_ATTR_SET_BASE] = 3,
- /**
- * Xattr set. The same as xattr of EXT3.
- * DATA_TRANS_BLOCKS(16)
- * XXX Note: in original MDS implmentation INDEX_EXTRA_TRANS_BLOCKS are
- * also counted in. Do not know why?
- */
- [DTO_XATTR_SET] = 16,
- [DTO_LOG_REC] = 16,
- /**
- * creadits for inode change during write.
- */
- [DTO_WRITE_BASE] = 3,
- /**
- * credits for single block write.
- */
- [DTO_WRITE_BLOCK] = 16,
- /**
- * Attr set credits for chown.
- * It is added to already set setattr credits
- * 2 * QUOTA_INIT_BLOCKS(25) +
- * 2 * QUOTA_DEL_BLOCKS(9)
- */
- [DTO_ATTR_SET_CHOWN]= 68,
-};
-
static const struct dt_device_operations osd_dt_ops = {
.dt_root_get = osd_root_get,
.dt_statfs = osd_statfs,
RETURN(0);
}
-static int osd_object_auth(const struct lu_env *env, struct dt_object *dt,
- struct lustre_capa *capa, __u64 opc)
+int osd_object_auth(const struct lu_env *env, struct dt_object *dt,
+ struct lustre_capa *capa, __u64 opc)
{
const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
struct osd_device *dev = osd_dev(dt->do_lu.lo_dev);
struct thandle *handle)
{
struct osd_thandle *oh;
+ struct osd_object *obj;
+ LASSERT(dt != NULL);
LASSERT(handle != NULL);
+
+ obj = osd_dt_obj(dt);
LASSERT(osd_invariant(obj));
oh = container_of0(handle, struct osd_thandle, ot_super);
OSD_DECLARE_OP(oh, attr_set);
oh->ot_credits += osd_dto_credits_noquota[DTO_ATTR_SET_BASE];
+ if (attr && attr->la_valid & LA_UID) {
+ if (obj->oo_inode)
+ osd_declare_qid(dt, oh, USRQUOTA, obj->oo_inode->i_uid,
+ obj->oo_inode);
+ osd_declare_qid(dt, oh, USRQUOTA, attr->la_uid, NULL);
+ }
+ if (attr && attr->la_valid & LA_GID) {
+ if (obj->oo_inode)
+ osd_declare_qid(dt, oh, GRPQUOTA, obj->oo_inode->i_gid,
+ obj->oo_inode);
+ osd_declare_qid(dt, oh, GRPQUOTA, attr->la_gid, NULL);
+ }
+
return 0;
}
return 0;
}
-static struct dentry * osd_child_dentry_get(const struct lu_env *env,
- struct osd_object *obj,
- const char *name,
- const int namelen)
+struct dentry *osd_child_dentry_get(const struct lu_env *env,
+ struct osd_object *obj,
+ const char *name, const int namelen)
{
- struct osd_thread_info *info = osd_oti_get(env);
- struct dentry *child_dentry = &info->oti_child_dentry;
- struct dentry *obj_dentry = &info->oti_obj_dentry;
-
- obj_dentry->d_inode = obj->oo_inode;
- obj_dentry->d_sb = osd_sb(osd_obj2dev(obj));
- obj_dentry->d_name.hash = 0;
-
- child_dentry->d_name.hash = 0;
- child_dentry->d_parent = obj_dentry;
- child_dentry->d_name.name = name;
- child_dentry->d_name.len = namelen;
- return child_dentry;
+ return osd_child_dentry_by_inode(env, obj->oo_inode, name, namelen);
}
-
static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
cfs_umode_t mode,
struct dt_allocation_hint *hint,
else
parent = osd->od_obj_area;
- LASSERT(parent != NULL);
- LASSERT(osd_dt_obj(parent)->oo_inode->i_op != NULL);
-
#ifdef HAVE_QUOTA_SUPPORT
osd_push_ctxt(info->oti_env, save);
#endif
inode = ldiskfs_create_inode(oth->ot_handle,
- osd_dt_obj(parent)->oo_inode, mode);
+ parent ? osd_dt_obj(parent)->oo_inode :
+ osd_sb(osd)->s_root->d_inode,
+ mode);
#ifdef HAVE_QUOTA_SUPPORT
osd_pop_ctxt(save);
#endif
id->oii_ino = obj->oo_inode->i_ino;
id->oii_gen = obj->oo_inode->i_generation;
- return osd_oi_insert(info, &osd->od_oi, fid, id, th,
+ return osd_oi_insert(info, osd, fid, id, th,
uc->mu_cap & CFS_CAP_SYS_RESOURCE_MASK);
}
oh = container_of0(handle, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle == NULL);
- OSD_DECLARE_OP(oh, insert);
OSD_DECLARE_OP(oh, create);
oh->ot_credits += osd_dto_credits_noquota[DTO_OBJECT_CREATE];
- oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_INSERT];
+ /* XXX: So far, only normal fid needs be inserted into the oi,
+ * things could be changed later. Revise following code then. */
+ if (fid_is_norm(lu_object_fid(&dt->do_lu))) {
+ OSD_DECLARE_OP(oh, insert);
+ oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_INSERT];
+ }
+ /* If this is directory, then we expect . and .. to be inserted as
+ * well. The one directory block always needs to be created for the
+ * directory, so we could use DTO_WRITE_BASE here (GDT, block bitmap,
+ * block), there is no danger of needing a tree for the first block.
+ */
+ if (attr && S_ISDIR(attr->la_mode)) {
+ OSD_DECLARE_OP(oh, insert);
+ OSD_DECLARE_OP(oh, insert);
+ oh->ot_credits += osd_dto_credits_noquota[DTO_WRITE_BASE];
+ }
- /* if this is directory, then we expect . and ..
- * to be inserted as well */
- OSD_DECLARE_OP(oh, insert);
- OSD_DECLARE_OP(oh, insert);
- oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_INSERT];
+ if (attr) {
+ osd_declare_qid(dt, oh, USRQUOTA, attr->la_uid, NULL);
+ osd_declare_qid(dt, oh, GRPQUOTA, attr->la_gid, NULL);
+ }
return 0;
}
struct dt_object *dt,
struct thandle *th)
{
- struct osd_object *obj = osd_dt_obj(dt);
- struct inode *inode = obj->oo_inode;
- struct osd_thandle *oh;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct inode *inode = obj->oo_inode;
+ struct osd_thandle *oh;
+
ENTRY;
oh = container_of0(th, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle == NULL);
LASSERT(inode);
- LASSERT(!lu_object_is_dying(dt->do_lu.lo_header));
OSD_DECLARE_OP(oh, destroy);
OSD_DECLARE_OP(oh, delete);
oh->ot_credits += osd_dto_credits_noquota[DTO_OBJECT_DELETE];
oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_DELETE];
+ osd_declare_qid(dt, oh, USRQUOTA, inode->i_uid, inode);
+ osd_declare_qid(dt, oh, GRPQUOTA, inode->i_gid, inode);
+
RETURN(0);
}
oh = container_of0(th, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle);
LASSERT(inode);
- LASSERT(osd_inode_unlinked(inode));
+ LASSERT(!lu_object_is_dying(dt->do_lu.lo_header));
+
+ if (S_ISDIR(inode->i_mode)) {
+ LASSERT(osd_inode_unlinked(inode) ||
+ inode->i_nlink == 1);
+ cfs_spin_lock(&obj->oo_guard);
+ inode->i_nlink = 0;
+ cfs_spin_unlock(&obj->oo_guard);
+ inode->i_sb->s_op->dirty_inode(inode);
+ } else {
+ LASSERT(osd_inode_unlinked(inode));
+ }
OSD_EXEC_OP(th, destroy);
- result = osd_oi_delete(osd_oti_get(env), &osd->od_oi, fid, th);
+ result = osd_oi_delete(osd_oti_get(env), osd, fid, th);
/* XXX: add to ext3 orphan list */
/* rc = ext3_orphan_add(handle_t *handle, struct inode *inode) */
struct osd_thread_info *info = osd_oti_get(env);
struct dentry *dentry = &info->oti_child_dentry;
int fs_flags = 0;
- int rc;
+ int rc;
LASSERT(dt_object_exists(dt));
LASSERT(inode->i_op != NULL && inode->i_op->setxattr != NULL);
}
/**
- * Helper function to pack the fid, ldiskfs stores fid in packed format.
- */
-void osd_fid_pack(struct osd_fid_pack *pack, const struct dt_rec *fid,
- struct lu_fid *befider)
-{
- fid_cpu_to_be(befider, (struct lu_fid *)fid);
- memcpy(pack->fp_area, befider, sizeof(*befider));
- pack->fp_len = sizeof(*befider) + 1;
-}
-
-/**
* 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
(struct lu_fid *)fid);
}
-int osd_fid_unpack(struct lu_fid *fid, const struct osd_fid_pack *pack)
-{
- int result;
-
- result = 0;
- switch (pack->fp_len) {
- case sizeof *fid + 1:
- memcpy(fid, pack->fp_area, sizeof *fid);
- fid_be_to_cpu(fid, fid);
- break;
- default:
- CERROR("Unexpected packed fid size: %d\n", pack->fp_len);
- result = -EIO;
- }
- return result;
-}
-
/**
* Try to read the fid from inode ea into dt_rec, if return value
* i.e. rc is +ve, then we got fid, otherwise we will have to form igif
* \retval -ve, on error
*/
static int osd_object_ea_create(const struct lu_env *env, struct dt_object *dt,
- struct lu_attr *attr,
- struct dt_allocation_hint *hint,
- struct dt_object_format *dof,
- struct thandle *th)
+ struct lu_attr *attr,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *th)
{
const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
struct osd_object *obj = osd_dt_obj(dt);
struct osd_thread_info *info = osd_oti_get(env);
- int result;
+ int result;
ENTRY;
}
static int osd_declare_object_ref_add(const struct lu_env *env,
- struct dt_object *dt,
- struct thandle *handle)
+ struct dt_object *dt,
+ struct thandle *handle)
{
struct osd_thandle *oh;
* Concurrency: @dt is write locked.
*/
static int osd_object_ref_add(const struct lu_env *env,
- struct dt_object *dt,
- struct thandle *th)
+ struct dt_object *dt, struct thandle *th)
{
struct osd_object *obj = osd_dt_obj(dt);
- struct inode *inode = obj->oo_inode;
+ struct inode *inode = obj->oo_inode;
LINVRNT(osd_invariant(obj));
LASSERT(dt_object_exists(dt));
OSD_EXEC_OP(th, 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.
+ *
+ * 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.
+ */
cfs_spin_lock(&obj->oo_guard);
- LASSERT(inode->i_nlink < LDISKFS_LINK_MAX);
inode->i_nlink++;
+ if (S_ISDIR(inode->i_mode) && inode->i_nlink > 1) {
+ if (inode->i_nlink >= LDISKFS_LINK_MAX ||
+ inode->i_nlink == 2)
+ inode->i_nlink = 1;
+ }
+ LASSERT(inode->i_nlink < LDISKFS_LINK_MAX);
cfs_spin_unlock(&obj->oo_guard);
inode->i_sb->s_op->dirty_inode(inode);
LINVRNT(osd_invariant(obj));
}
static int osd_declare_object_ref_del(const struct lu_env *env,
- struct dt_object *dt,
- struct thandle *handle)
+ struct dt_object *dt,
+ struct thandle *handle)
{
struct osd_thandle *oh;
/*
* Concurrency: @dt is write locked.
*/
-static int osd_object_ref_del(const struct lu_env *env,
- struct dt_object *dt,
+static int osd_object_ref_del(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 inode *inode = obj->oo_inode;
LINVRNT(osd_invariant(obj));
LASSERT(dt_object_exists(dt));
cfs_spin_lock(&obj->oo_guard);
LASSERT(inode->i_nlink > 0);
inode->i_nlink--;
+ /* 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)
+ inode->i_nlink++;
cfs_spin_unlock(&obj->oo_guard);
inode->i_sb->s_op->dirty_inode(inode);
LINVRNT(osd_invariant(obj));
/*
* Concurrency: @dt is read locked.
*/
-static int osd_xattr_get(const struct lu_env *env,
- struct dt_object *dt,
- struct lu_buf *buf,
- const char *name,
+static int osd_xattr_get(const struct lu_env *env, struct dt_object *dt,
+ struct lu_buf *buf, const char *name,
struct lustre_capa *capa)
{
struct osd_object *obj = osd_dt_obj(dt);
}
-static int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt,
+static int osd_declare_xattr_set(const struct lu_env *env,
+ struct dt_object *dt,
const struct lu_buf *buf, const char *name,
int fl, struct thandle *handle)
{
/*
* Concurrency: @dt is read locked.
*/
-static int osd_xattr_list(const struct lu_env *env,
- struct dt_object *dt,
- struct lu_buf *buf,
- struct lustre_capa *capa)
+static int osd_xattr_list(const struct lu_env *env, struct dt_object *dt,
+ struct lu_buf *buf, struct lustre_capa *capa)
{
struct osd_object *obj = osd_dt_obj(dt);
struct inode *inode = obj->oo_inode;
}
static int osd_declare_xattr_del(const struct lu_env *env,
- struct dt_object *dt,
- const char *name,
- struct thandle *handle)
+ struct dt_object *dt, const char *name,
+ struct thandle *handle)
{
struct osd_thandle *oh;
/*
* Concurrency: @dt is write locked.
*/
-static int osd_xattr_del(const struct lu_env *env,
- struct dt_object *dt,
- const char *name,
- struct thandle *handle,
+static int osd_xattr_del(const struct lu_env *env, struct dt_object *dt,
+ const char *name, struct thandle *handle,
struct lustre_capa *capa)
{
struct osd_object *obj = osd_dt_obj(dt);
static int osd_object_sync(const struct lu_env *env, struct dt_object *dt)
{
- int rc;
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;
+ int rc;
+
ENTRY;
dentry->d_inode = inode;
.do_data_get = osd_data_get,
};
-/*
- * Body operations.
- */
-
-/*
- * XXX: Another layering violation for now.
- *
- * We don't want to use ->f_op->read methods, because generic file write
- *
- * - serializes on ->i_sem, and
- *
- * - does a lot of extra work like balance_dirty_pages(),
- *
- * which doesn't work for globally shared files like /last-received.
- */
-static int osd_ldiskfs_readlink(struct inode *inode, char *buffer, int buflen)
-{
- struct ldiskfs_inode_info *ei = LDISKFS_I(inode);
-
- memcpy(buffer, (char*)ei->i_data, buflen);
-
- return buflen;
-}
-
-static int osd_ldiskfs_read(struct inode *inode, void *buf, int size,
- loff_t *offs)
-{
- struct buffer_head *bh;
- unsigned long block;
- int osize = size;
- int blocksize;
- int csize;
- int boffs;
- int err;
-
- /* prevent reading after eof */
- spin_lock(&inode->i_lock);
- if (i_size_read(inode) < *offs + size) {
- size = i_size_read(inode) - *offs;
- spin_unlock(&inode->i_lock);
- if (size < 0) {
- CDEBUG(D_EXT2, "size %llu is too short to read @%llu\n",
- i_size_read(inode), *offs);
- return -EBADR;
- } else if (size == 0) {
- return 0;
- }
- } else {
- spin_unlock(&inode->i_lock);
- }
-
- blocksize = 1 << inode->i_blkbits;
-
- while (size > 0) {
- block = *offs >> inode->i_blkbits;
- boffs = *offs & (blocksize - 1);
- csize = min(blocksize - boffs, size);
- bh = ldiskfs_bread(NULL, inode, block, 0, &err);
- if (!bh) {
- CERROR("can't read block: %d\n", err);
- return err;
- }
-
- memcpy(buf, bh->b_data + boffs, csize);
- brelse(bh);
-
- *offs += csize;
- buf += csize;
- size -= csize;
- }
- return osize;
-}
-
-static ssize_t osd_read(const struct lu_env *env, struct dt_object *dt,
- struct lu_buf *buf, loff_t *pos,
- struct lustre_capa *capa)
-{
- struct osd_object *obj = osd_dt_obj(dt);
- struct inode *inode = obj->oo_inode;
- int rc;
-
- if (osd_object_auth(env, dt, capa, CAPA_OPC_BODY_READ))
- RETURN(-EACCES);
-
- /* Read small symlink from inode body as we need to maintain correct
- * on-disk symlinks for ldiskfs.
- */
- if (S_ISLNK(obj->oo_dt.do_lu.lo_header->loh_attr) &&
- (buf->lb_len <= sizeof (LDISKFS_I(inode)->i_data)))
- rc = osd_ldiskfs_readlink(inode, buf->lb_buf, buf->lb_len);
- else
- rc = osd_ldiskfs_read(inode, buf->lb_buf, buf->lb_len, pos);
-
- return rc;
-}
-
-static int osd_ldiskfs_writelink(struct inode *inode, char *buffer, int buflen)
-{
-
- memcpy((char*)&LDISKFS_I(inode)->i_data, (char *)buffer,
- buflen);
- LDISKFS_I(inode)->i_disksize = buflen;
- i_size_write(inode, buflen);
- inode->i_sb->s_op->dirty_inode(inode);
-
- return 0;
-}
-
-static 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;
- loff_t new_size = i_size_read(inode);
- unsigned long block;
- int blocksize = 1 << inode->i_blkbits;
- int err = 0;
- int size;
- int boffs;
- int dirty_inode = 0;
-
- while (bufsize > 0) {
- if (bh != NULL)
- brelse(bh);
-
- block = offset >> inode->i_blkbits;
- boffs = offset & (blocksize - 1);
- size = min(blocksize - boffs, bufsize);
- bh = ldiskfs_bread(handle, inode, block, 1, &err);
- if (!bh) {
- CERROR("can't read/create block: %d\n", err);
- break;
- }
-
- err = ldiskfs_journal_get_write_access(handle, bh);
- if (err) {
- CERROR("journal_get_write_access() returned error %d\n",
- err);
- break;
- }
- LASSERTF(boffs + size <= bh->b_size,
- "boffs %d size %d bh->b_size %lu",
- boffs, size, (unsigned long)bh->b_size);
- memcpy(bh->b_data + boffs, buf, size);
- err = ldiskfs_journal_dirty_metadata(handle, bh);
- if (err)
- break;
-
- if (offset + size > new_size)
- new_size = offset + size;
- offset += size;
- bufsize -= size;
- buf += size;
- }
- if (bh)
- brelse(bh);
-
- /* correct in-core and on-disk sizes */
- if (new_size > i_size_read(inode)) {
- spin_lock(&inode->i_lock);
- if (new_size > i_size_read(inode))
- i_size_write(inode, new_size);
- if (i_size_read(inode) > LDISKFS_I(inode)->i_disksize) {
- LDISKFS_I(inode)->i_disksize = i_size_read(inode);
- dirty_inode = 1;
- }
- spin_unlock(&inode->i_lock);
- if (dirty_inode)
- inode->i_sb->s_op->dirty_inode(inode);
- }
-
- if (err == 0)
- *offs = offset;
- return err;
-}
-
-static ssize_t osd_declare_write(const struct lu_env *env, struct dt_object *dt,
- const loff_t size, loff_t pos,
- struct thandle *handle)
-{
- struct osd_thandle *oh;
-
- LASSERT(handle != NULL);
-
- oh = container_of0(handle, struct osd_thandle, ot_super);
- LASSERT(oh->ot_handle == NULL);
-
- OSD_DECLARE_OP(oh, write);
- oh->ot_credits += osd_dto_credits_noquota[DTO_WRITE_BLOCK];
-
- return 0;
-}
-
-static ssize_t osd_write(const struct lu_env *env, struct dt_object *dt,
- const struct lu_buf *buf, loff_t *pos,
- struct thandle *handle, struct lustre_capa *capa,
- int ignore_quota)
-{
- struct osd_object *obj = osd_dt_obj(dt);
- struct inode *inode = obj->oo_inode;
- struct osd_thandle *oh;
- ssize_t result = 0;
-#ifdef HAVE_QUOTA_SUPPORT
- cfs_cap_t save = cfs_curproc_cap_pack();
-#endif
-
- LASSERT(handle != NULL);
-
- if (osd_object_auth(env, dt, capa, CAPA_OPC_BODY_WRITE))
- RETURN(-EACCES);
-
- oh = container_of(handle, struct osd_thandle, ot_super);
- 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);
-#endif
- /* Write small symlink to inode body as we need to maintain correct
- * on-disk symlinks for ldiskfs.
- */
- if(S_ISLNK(obj->oo_dt.do_lu.lo_header->loh_attr) &&
- (buf->lb_len < sizeof (LDISKFS_I(inode)->i_data)))
- result = osd_ldiskfs_writelink(inode, buf->lb_buf, buf->lb_len);
- else
- result = osd_ldiskfs_write_record(inode, buf->lb_buf,
- buf->lb_len, pos,
- oh->ot_handle);
-#ifdef HAVE_QUOTA_SUPPORT
- cfs_curproc_cap_unpack(save);
-#endif
- if (result == 0)
- result = buf->lb_len;
- return result;
-}
-
-/*
- * in some cases we may need declare methods for objects being created
- * e.g., when we create symlink
- */
-static const struct dt_body_operations osd_body_ops_new = {
- .dbo_declare_write = osd_declare_write,
-};
-
-static const struct dt_body_operations osd_body_ops = {
- .dbo_read = osd_read,
- .dbo_declare_write = osd_declare_write,
- .dbo_write = osd_write
-};
-
static int osd_index_declare_iam_delete(const struct lu_env *env,
struct dt_object *dt,
const struct dt_key *key,
*/
static int osd_index_iam_delete(const struct lu_env *env, struct dt_object *dt,
- const struct dt_key *key, struct thandle *handle,
+ const struct dt_key *key,
+ struct thandle *handle,
struct lustre_capa *capa)
{
struct osd_object *obj = osd_dt_obj(dt);
struct osd_thandle *oh;
struct iam_path_descr *ipd;
struct iam_container *bag = &obj->oo_dir->od_container;
- int rc;
+ int rc;
ENTRY;
OSD_DECLARE_OP(oh, delete);
oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_DELETE];
+ LASSERT(osd_dt_obj(dt)->oo_inode);
+ osd_declare_qid(dt, oh, USRQUOTA, osd_dt_obj(dt)->oo_inode->i_uid,
+ osd_dt_obj(dt)->oo_inode);
+ osd_declare_qid(dt, oh, GRPQUOTA, osd_dt_obj(dt)->oo_inode->i_gid,
+ osd_dt_obj(dt)->oo_inode);
+
return 0;
}
struct dt_rec *fid)
{
struct osd_fid_pack *rec;
- int rc = -ENODATA;
+ int rc = -ENODATA;
if (de->file_type & LDISKFS_DIRENT_LUFID) {
rec = (struct osd_fid_pack *) (de->name + de->name_len + 1);
* \retval -ve, on error
*/
static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt,
- const struct dt_key *key, struct thandle *handle,
+ const struct dt_key *key,
+ struct thandle *handle,
struct lustre_capa *capa)
{
struct osd_object *obj = osd_dt_obj(dt);
struct ldiskfs_dir_entry_2 *de;
struct buffer_head *bh;
struct htree_lock *hlock = NULL;
-
- int rc;
+ int rc;
ENTRY;
struct dt_rec *rec, const struct dt_key *key,
struct lustre_capa *capa)
{
- struct osd_object *obj = osd_dt_obj(dt);
- struct iam_path_descr *ipd;
- struct iam_container *bag = &obj->oo_dir->od_container;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct iam_path_descr *ipd;
+ struct iam_container *bag = &obj->oo_dir->od_container;
struct osd_thread_info *oti = osd_oti_get(env);
struct iam_iterator *it = &oti->oti_idx_it;
- struct iam_rec *iam_rec;
- int rc;
+ struct iam_rec *iam_rec;
+ int rc;
+
ENTRY;
LASSERT(osd_invariant(obj));
* \retval -ve failure
*/
static int osd_index_iam_insert(const struct lu_env *env, struct dt_object *dt,
- const struct dt_rec *rec, const struct dt_key *key,
- struct thandle *th, struct lustre_capa *capa,
- int ignore_quota)
+ const struct dt_rec *rec,
+ const struct dt_key *key, struct thandle *th,
+ struct lustre_capa *capa, int ignore_quota)
{
struct osd_object *obj = osd_dt_obj(dt);
struct iam_path_descr *ipd;
cfs_cap_t save = cfs_curproc_cap_pack();
#endif
struct osd_thread_info *oti = osd_oti_get(env);
- struct iam_rec *iam_rec = (struct iam_rec *)oti->oti_ldp;
- int rc;
+ struct iam_rec *iam_rec = (struct iam_rec *)oti->oti_ldp;
+ int rc;
ENTRY;
* \retval -ve, on error
*/
static int __osd_ea_add_rec(struct osd_thread_info *info,
- struct osd_object *pobj,
- struct inode *cinode,
- const char *name,
- const struct dt_rec *fid,
- struct htree_lock *hlock,
- struct thandle *th)
+ struct osd_object *pobj, struct inode *cinode,
+ const char *name, const struct dt_rec *fid,
+ struct htree_lock *hlock, struct thandle *th)
{
struct ldiskfs_dentry_param *ldp;
- struct dentry *child;
- struct osd_thandle *oth;
- int rc;
+ struct dentry *child;
+ struct osd_thandle *oth;
+ int rc;
oth = container_of(th, struct osd_thandle, ot_super);
LASSERT(oth->ot_handle != NULL);
* It will call the appropriate osd_add* function and return the
* value, return by respective functions.
*/
-static int osd_ea_add_rec(const struct lu_env *env,
- struct osd_object *pobj,
- struct inode *cinode,
- const char *name,
- const struct dt_rec *fid,
- struct thandle *th)
-{
- struct osd_thread_info *info = osd_oti_get(env);
- struct htree_lock *hlock;
- int rc;
+static int osd_ea_add_rec(const struct lu_env *env, struct osd_object *pobj,
+ struct inode *cinode, const char *name,
+ const struct dt_rec *fid, struct thandle *th)
+{
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct htree_lock *hlock;
+ int rc;
hlock = pobj->oo_hl_head != NULL ? info->oti_hlock : NULL;
struct buffer_head *bh;
struct lu_fid *fid = (struct lu_fid *) rec;
struct htree_lock *hlock = NULL;
- int ino;
- int rc;
+ int ino;
+ int rc;
LASSERT(dir->i_op != NULL && dir->i_op->lookup != NULL);
struct dt_object *dt,
const struct lu_fid *fid)
{
- struct lu_device *ludev = dt->do_lu.lo_dev;
- struct osd_object *child = NULL;
- struct lu_object *luch;
- struct lu_object *lo;
+ struct lu_device *ludev = dt->do_lu.lo_dev;
+ struct osd_object *child = NULL;
+ struct lu_object *luch;
+ struct lu_object *lo;
luch = lu_object_find(env, ludev, fid, NULL);
if (!IS_ERR(luch)) {
OSD_DECLARE_OP(oh, insert);
oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_INSERT];
+ LASSERT(osd_dt_obj(dt)->oo_inode);
+ osd_declare_qid(dt, oh, USRQUOTA, osd_dt_obj(dt)->oo_inode->i_uid,
+ osd_dt_obj(dt)->oo_inode);
+ osd_declare_qid(dt, oh, GRPQUOTA, osd_dt_obj(dt)->oo_inode->i_gid,
+ osd_dt_obj(dt)->oo_inode);
+
return 0;
}
const struct dt_key *key, struct thandle *th,
struct lustre_capa *capa, int ignore_quota)
{
- struct osd_object *obj = osd_dt_obj(dt);
- struct lu_fid *fid = (struct lu_fid *) rec;
- const char *name = (const char *)key;
- struct osd_object *child;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct lu_fid *fid = (struct lu_fid *) rec;
+ const char *name = (const char *)key;
+ struct osd_object *child;
#ifdef HAVE_QUOTA_SUPPORT
- cfs_cap_t save = cfs_curproc_cap_pack();
+ cfs_cap_t save = cfs_curproc_cap_pack();
#endif
- int rc;
+ int rc;
ENTRY;
__u32 unused,
struct lustre_capa *capa)
{
- struct osd_it_iam *it;
+ struct osd_it_iam *it;
struct osd_thread_info *oti = osd_oti_get(env);
- struct osd_object *obj = osd_dt_obj(dt);
- struct lu_object *lo = &dt->do_lu;
- struct iam_path_descr *ipd;
- struct iam_container *bag = &obj->oo_dir->od_container;
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct lu_object *lo = &dt->do_lu;
+ struct iam_path_descr *ipd;
+ struct iam_container *bag = &obj->oo_dir->od_container;
LASSERT(lu_object_exists(lo));
static void osd_it_iam_fini(const struct lu_env *env, struct dt_it *di)
{
- struct osd_it_iam *it = (struct osd_it_iam *)di;
+ struct osd_it_iam *it = (struct osd_it_iam *)di;
struct osd_object *obj = it->oi_obj;
iam_it_fini(&it->oi_it);
*/
static int osd_it_iam_get(const struct lu_env *env,
- struct dt_it *di, const struct dt_key *key)
+ struct dt_it *di, const struct dt_key *key)
{
struct osd_it_iam *it = (struct osd_it_iam *)di;
return iam_it_key_size(&it->oi_it);
}
-static inline void osd_it_append_attrs(struct lu_dirent*ent,
- __u32 attr,
- int len,
- __u16 type)
+static inline void osd_it_append_attrs(struct lu_dirent *ent, __u32 attr,
+ int len, __u16 type)
{
- struct luda_type *lt;
- const unsigned align = sizeof(struct luda_type) - 1;
+ struct luda_type *lt;
+ const unsigned align = sizeof(struct luda_type) - 1;
/* check if file type is required */
if (attr & LUDA_TYPE) {
*/
static inline void osd_it_pack_dirent(struct lu_dirent *ent,
- struct lu_fid *fid,
- __u64 offset,
- char *name,
- __u16 namelen,
- __u16 type,
- __u32 attr)
+ struct lu_fid *fid, __u64 offset,
+ char *name, __u16 namelen,
+ __u16 type, __u32 attr)
{
fid_cpu_to_le(&ent->lde_fid, fid);
ent->lde_attrs = LUDA_FID;
*/
static int osd_it_iam_rec(const struct lu_env *env,
const struct dt_it *di,
- struct dt_rec *dtrec,
- __u32 attr)
+ struct dt_rec *dtrec, __u32 attr)
{
struct osd_it_iam *it = (struct osd_it_iam *)di;
struct osd_thread_info *info = osd_oti_get(env);
*/
static int osd_it_iam_load(const struct lu_env *env,
- const struct dt_it *di, __u64 hash)
+ const struct dt_it *di, __u64 hash)
{
struct osd_it_iam *it = (struct osd_it_iam *)di;
const struct dt_it *di)
{
struct osd_it_ea *it = (struct osd_it_ea *)di;
- ENTRY;
- RETURN((struct dt_key *)it->oie_dirent->oied_name);
+
+ return (struct dt_key *)it->oie_dirent->oied_name;
}
/**
static int osd_it_ea_key_size(const struct lu_env *env, const struct dt_it *di)
{
struct osd_it_ea *it = (struct osd_it_ea *)di;
- ENTRY;
- RETURN(it->oie_dirent->oied_namelen);
+
+ return it->oie_dirent->oied_namelen;
}
*/
static inline int osd_it_ea_rec(const struct lu_env *env,
const struct dt_it *di,
- struct dt_rec *dtrec,
- __u32 attr)
+ struct dt_rec *dtrec, __u32 attr)
{
struct osd_it_ea *it = (struct osd_it_ea *)di;
struct osd_object *obj = it->oie_obj;
static __u64 osd_it_ea_store(const struct lu_env *env, const struct dt_it *di)
{
struct osd_it_ea *it = (struct osd_it_ea *)di;
- ENTRY;
- RETURN(it->oie_dirent->oied_off);
+
+ return it->oie_dirent->oied_off;
}
/**
/* type constructor/destructor: osd_type_init, osd_type_fini */
LU_TYPE_INIT_FINI(osd, &osd_key);
-static struct lu_context_key osd_key = {
+struct lu_context_key osd_key = {
.lct_tags = LCT_DT_THREAD | LCT_MD_THREAD,
.lct_init = osd_key_init,
.lct_fini = osd_key_fini,
lu_object_put(env, &o->od_obj_area->do_lu);
o->od_obj_area = NULL;
}
- osd_oi_fini(info, &o->od_oi);
+ if (o->od_oi_table != NULL)
+ osd_oi_fini(info, o);
+
+ if (o->od_fsops) {
+ fsfilt_put_ops(o->od_fsops);
+ o->od_fsops = NULL;
+ }
RETURN(0);
}
struct lustre_sb_info *lsi;
ENTRY;
+
+ o->od_fsops = fsfilt_get_ops(mt_str(LDD_MT_LDISKFS));
+ if (o->od_fsops == NULL) {
+ CERROR("Can't find fsfilt_ldiskfs\n");
+ RETURN(-ENOTSUPP);
+ }
+
if (o->od_mount != NULL) {
CERROR("Already mounted (%s)\n", dev);
RETURN(-EEXIST);
ENTRY;
/* 1. initialize oi before any file create or file open */
- result = osd_oi_init(oti, &osd->od_oi,
- &osd->od_dt_dev, lu2md_dev(pdev));
- if (result != 0)
+ result = osd_oi_init(oti, osd);
+ if (result < 0)
RETURN(result);
+ if (!lu_device_is_md(pdev))
+ RETURN(0);
+
lmi = osd->od_mount;
lsi = s2lsi(lmi->lmi_sb);
ldd = lsi->lsi_ldd;
.loo_object_invariant = osd_object_invariant
};
-static const struct lu_device_operations osd_lu_ops = {
+const struct lu_device_operations osd_lu_ops = {
.ldo_object_alloc = osd_object_alloc,
.ldo_process_config = osd_process_config,
.ldo_recovery_complete = osd_recovery_complete,
MODULE_DESCRIPTION("Lustre Object Storage Device ("LUSTRE_OSD_NAME")");
MODULE_LICENSE("GPL");
-cfs_module(osd, "0.0.2", osd_mod_init, osd_mod_exit);
+cfs_module(osd, "0.1.0", osd_mod_init, osd_mod_exit);