* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
/* struct dirent64 */
#include <linux/dirent.h>
+#include <ldiskfs/ldiskfs_config.h>
#include <ldiskfs/ldiskfs.h>
#include <ldiskfs/ldiskfs_jbd2.h>
-#ifdef HAVE_LDISKFS_JOURNAL_CALLBACK_ADD
-# define journal_callback ldiskfs_journal_cb_entry
-# define osd_journal_callback_set(handle, func, jcb) \
- ldiskfs_journal_callback_add(handle, func, jcb)
-#else
-# define osd_journal_callback_set(handle, func, jcb) \
- jbd2_journal_callback_set(handle, func, jcb)
-#endif
/* fsfilt_{get|put}_ops */
#include <lustre_fsfilt.h>
};
struct osd_mdobj_map {
- struct dentry *omm_agent_dentry;
+ struct dentry *omm_remote_parent;
};
#define osd_ldiskfs_find_entry(dir, dentry, de, lock) \
#define osd_ldiskfs_add_entry(handle, child, cinode, hlock) \
ldiskfs_add_entry(handle, child, cinode, hlock)
-#define OSD_OTABLE_IT_CACHE_SIZE 128
+#define OSD_OTABLE_IT_CACHE_SIZE 64
#define OSD_OTABLE_IT_CACHE_MASK (~(OSD_OTABLE_IT_CACHE_SIZE - 1))
struct osd_inconsistent_item {
struct osd_otable_it {
struct osd_device *ooi_dev;
- pid_t ooi_pid;
struct osd_otable_cache ooi_cache;
/* The following bits can be updated/checked w/o lock protection.
* filled into cache. */
ooi_user_ready:1, /* The user out of OSD is
* ready to iterate. */
- ooi_waiting:1, /* it::next is waiting. */
- ooi_stopping:1; /* Someone is stopping
- * the iteration. */
+ ooi_waiting:1; /* it::next is waiting. */
};
-extern const int osd_dto_credits_noquota[];
-
/*
* osd device.
*/
* Fid Capability
*/
unsigned int od_fl_capa:1,
- od_is_md:1; /* set in ->ldo_prepare */
+ od_maybe_new:1,
+ od_noscrub:1,
+ od_dirent_journal:1,
+ od_igif_inoi:1,
+ od_check_ff:1,
+ od_is_ost:1;
+
unsigned long od_capa_timeout;
__u32 od_capa_alg;
struct lustre_capa_key *od_capa_keys;
struct obd_statfs od_statfs;
spinlock_t od_osfs_lock;
- unsigned int od_noscrub:1,
- od_handle_nolma:1;
-
struct fsfilt_operations *od_fsops;
int od_connects;
struct lu_site od_site;
OSD_OT_WRITE = 7,
OSD_OT_INSERT = 8,
OSD_OT_DELETE = 9,
- OSD_OT_QUOTA = 10,
- OSD_OT_MAX = 11
+ OSD_OT_UPDATE = 10,
+ OSD_OT_QUOTA = 11,
+ OSD_OT_MAX = 12
};
-#define OSD_TRACK_DECLARES
-
struct osd_thandle {
struct thandle ot_super;
handle_t *ot_handle;
- struct journal_callback ot_jcb;
+ struct ldiskfs_journal_cb_entry ot_jcb;
cfs_list_t ot_dcb_list;
- /* Link to the device, for debugging. */
- struct lu_ref_link *ot_dev_link;
+ /* Link to the device, for debugging. */
+ struct lu_ref_link ot_dev_link;
unsigned short ot_credits;
unsigned short ot_id_cnt;
unsigned short ot_id_type;
* there would be one ext3 readdir for every mdd readdir page.
*/
-#define OSD_IT_EA_BUFSIZE (CFS_PAGE_SIZE + CFS_PAGE_SIZE/4)
+#define OSD_IT_EA_BUFSIZE (PAGE_CACHE_SIZE + PAGE_CACHE_SIZE/4)
/**
* This is iterator's in-memory data structure in interoperability
cfs_list_t oiq_list;
};
-#define MAX_BLOCKS_PER_PAGE (CFS_PAGE_SIZE / 512)
+#define MAX_BLOCKS_PER_PAGE (PAGE_CACHE_SIZE / 512)
struct osd_iobuf {
- cfs_waitq_t dr_wait;
- cfs_atomic_t dr_numreqs; /* number of reqs being processed */
- int dr_max_pages;
- int dr_npages;
- int dr_error;
- int dr_frags;
- unsigned int dr_ignore_quota:1;
- unsigned int dr_elapsed_valid:1; /* we really did count time */
- unsigned int dr_rw:1;
- struct page *dr_pages[PTLRPC_MAX_BRW_PAGES];
- unsigned long dr_blocks[PTLRPC_MAX_BRW_PAGES*MAX_BLOCKS_PER_PAGE];
- unsigned long dr_start_time;
- unsigned long dr_elapsed; /* how long io took */
- struct osd_device *dr_dev;
+ cfs_waitq_t dr_wait;
+ cfs_atomic_t dr_numreqs; /* number of reqs being processed */
+ int dr_max_pages;
+ int dr_npages;
+ int dr_error;
+ int dr_frags;
+ unsigned int dr_ignore_quota:1;
+ unsigned int dr_elapsed_valid:1; /* we really did count time */
+ unsigned int dr_rw:1;
+ struct lu_buf dr_pg_buf;
+ struct page **dr_pages;
+ struct lu_buf dr_bl_buf;
+ unsigned long *dr_blocks;
+ unsigned long dr_start_time;
+ unsigned long dr_elapsed; /* how long io took */
+ struct osd_device *dr_dev;
unsigned int dr_init_at; /* the line iobuf was initialized */
};
struct lu_fid oti_fid;
struct lu_fid oti_fid2;
+ struct lu_fid oti_fid3;
struct osd_inode_id oti_id;
struct osd_inode_id oti_id2;
+ struct osd_inode_id oti_id3;
struct ost_id oti_ostid;
/*
struct osd_it_quota oti_it_quota;
};
- /** pre-allocated buffer used by oti_it_ea, size OSD_IT_EA_BUFSIZE */
- void *oti_it_ea_buf;
+ /** pre-allocated buffer used by oti_it_ea, size OSD_IT_EA_BUFSIZE */
+ void *oti_it_ea_buf;
- cfs_kstatfs_t oti_ksfs;
+ struct kstatfs oti_ksfs;
/** IAM iterator for index operation. */
struct iam_iterator oti_idx_it;
/* old LMA for compatibility */
char oti_mdt_attrs_old[LMA_OLD_SIZE];
};
- /** 0-copy IO */
- struct osd_iobuf oti_iobuf;
- struct inode oti_inode;
- int oti_created[PTLRPC_MAX_BRW_PAGES];
- struct lu_env oti_obj_delete_tx_env;
+ /** 0-copy IO */
+ struct osd_iobuf oti_iobuf;
+ struct inode oti_inode;
#define OSD_FID_REC_SZ 32
- char oti_ldp[OSD_FID_REC_SZ];
- char oti_ldp2[OSD_FID_REC_SZ];
+ char oti_ldp[OSD_FID_REC_SZ];
+ char oti_ldp2[OSD_FID_REC_SZ];
/* used by quota code */
union {
+#ifdef HAVE_DQUOT_FS_DISK_QUOTA
+ struct fs_disk_quota oti_fdq;
+#else
struct if_dqblk oti_dqblk;
+#endif
struct if_dqinfo oti_dqinfo;
};
struct lquota_id_info oti_qi;
__u64 oti_quota_id;
struct lu_seq_range oti_seq_range;
-#ifdef OSD_TRACK_DECLARES
/* Tracking for transaction credits, to allow debugging and optimizing
* cases where a large number of credits are being allocated for
* single transaction. */
- unsigned char oti_declare_ops[OSD_OT_MAX];
- unsigned char oti_declare_ops_rb[OSD_OT_MAX];
+ unsigned short oti_declare_ops[OSD_OT_MAX];
+ unsigned short oti_declare_ops_rb[OSD_OT_MAX];
unsigned short oti_declare_ops_cred[OSD_OT_MAX];
bool oti_rollback;
-#endif
char oti_name[48];
+ union {
+ struct filter_fid_old oti_ff;
+ struct filter_fid oti_ff_new;
+ };
};
extern int ldiskfs_pdo;
+static inline int __osd_xattr_get(struct inode *inode, struct dentry *dentry,
+ const char *name, void *buf, int len)
+{
+ dentry->d_inode = inode;
+ dentry->d_sb = inode->i_sb;
+ return inode->i_op->getxattr(dentry, name, buf, len);
+}
+
+static inline int __osd_xattr_set(struct osd_thread_info *info,
+ struct inode *inode, const char *name,
+ const void *buf, int buflen, int fl)
+{
+ struct dentry *dentry = &info->oti_child_dentry;
+
+ ll_vfs_dq_init(inode);
+ dentry->d_inode = inode;
+ dentry->d_sb = inode->i_sb;
+ return inode->i_op->setxattr(dentry, name, buf, buflen, fl);
+}
+
#ifdef LPROCFS
/* osd_lproc.c */
void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars);
struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev,
struct osd_inode_id *id);
int osd_ea_fid_set(struct osd_thread_info *info, struct inode *inode,
- const struct lu_fid *fid);
+ const struct lu_fid *fid, __u32 compat, __u32 incompat);
int osd_get_lma(struct osd_thread_info *info, struct inode *inode,
struct dentry *dentry, struct lustre_mdt_attrs *lma);
+int osd_add_oi_cache(struct osd_thread_info *info, struct osd_device *osd,
+ struct osd_inode_id *id, const struct lu_fid *fid);
+int osd_get_idif(struct osd_thread_info *info, struct inode *inode,
+ struct dentry *dentry, struct lu_fid *fid);
-int osd_obj_map_init(struct osd_device *osd);
+int osd_obj_map_init(const struct lu_env *env, struct osd_device *osd);
void osd_obj_map_fini(struct osd_device *dev);
int osd_obj_map_lookup(struct osd_thread_info *info, struct osd_device *osd,
const struct lu_fid *fid, struct osd_inode_id *id);
struct thandle *th);
int osd_obj_map_delete(struct osd_thread_info *info, struct osd_device *osd,
const struct lu_fid *fid, struct thandle *th);
+int osd_obj_map_update(struct osd_thread_info *info, struct osd_device *osd,
+ const struct lu_fid *fid, const struct osd_inode_id *id,
+ struct thandle *th);
+int osd_obj_map_recover(struct osd_thread_info *info, struct osd_device *osd,
+ struct inode *src_parent, struct dentry *src_child,
+ const struct lu_fid *fid);
int osd_obj_spec_lookup(struct osd_thread_info *info, struct osd_device *osd,
const struct lu_fid *fid, struct osd_inode_id *id);
int osd_obj_spec_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 osd_obj_spec_update(struct osd_thread_info *info, struct osd_device *osd,
+ const struct lu_fid *fid, const struct osd_inode_id *id,
+ struct thandle *th);
void osd_scrub_file_reset(struct osd_scrub *scrub, __u8 *uuid, __u64 flags);
int osd_scrub_file_store(struct osd_scrub *scrub);
int osd_scrub_dump(struct osd_device *dev, char *buf, int len);
int osd_fld_lookup(const struct lu_env *env, struct osd_device *osd,
- const struct lu_fid *fid, struct lu_seq_range *range);
-struct dentry *osd_agent_lookup(struct osd_mdobj_map *omm, int index);
-struct dentry *osd_agent_load(const struct osd_device *osd, int mdt_index,
- int create);
-
-int osd_delete_agent_inode(const struct lu_env *env, struct osd_device *osd,
- struct osd_object *obj, struct osd_thandle *oh);
-int osd_create_agent_inode(const struct lu_env *env, struct osd_device *osd,
- struct osd_object *obj, struct osd_thandle *oh);
-
+ obd_seq seq, struct lu_seq_range *range);
+
+int osd_delete_from_remote_parent(const struct lu_env *env,
+ struct osd_device *osd,
+ struct osd_object *obj,
+ struct osd_thandle *oh);
+int osd_add_to_remote_parent(const struct lu_env *env, struct osd_device *osd,
+ struct osd_object *obj, struct osd_thandle *oh);
+int osd_lookup_in_remote_parent(struct osd_thread_info *oti,
+ struct osd_device *osd,
+ const struct lu_fid *fid,
+ struct osd_inode_id *id);
+
+int osd_ost_seq_exists(struct osd_thread_info *info, struct osd_device *osd,
+ __u64 seq);
/* osd_quota_fmt.c */
int walk_tree_dqentry(const struct lu_env *env, struct osd_object *obj,
int type, uint blk, int depth, uint index,
int osd_quota_migration(const struct lu_env *env, struct dt_object *dt,
const struct dt_index_features *feat);
-/* osd_compat.c */
-struct osd_obj_seq *osd_seq_load(struct osd_device *osd, obd_seq seq);
-
static inline bool is_quota_glb_feat(const struct dt_index_features *feat)
{
return (feat == &dt_quota_iusr_features ||
{
LASSERTF(!fid_is_idif(fid), DFID"\n", PFID(fid));
LASSERTF(!fid_is_last_id(fid), DFID"\n", PFID(fid));
- LASSERT(osd->od_oi_table != NULL && osd->od_oi_count >= 1);
+ LASSERTF(osd->od_oi_table != NULL && osd->od_oi_count >= 1,
+ DFID"\n", PFID(fid));
/* 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[osd_oi_fid2idx(osd, fid)];
return osd->od_dt_dev.dd_lu_dev.ld_obd->obd_name;
}
-
extern const struct dt_body_operations osd_body_ops;
extern struct lu_context_key osd_key;
return child_dentry;
}
-#ifdef OSD_TRACK_DECLARES
extern int osd_trans_declare_op2rb[];
+extern int ldiskfs_track_declares_assert;
static inline void osd_trans_declare_op(const struct lu_env *env,
struct osd_thandle *oh,
struct osd_thread_info *oti = osd_oti_get(env);
LASSERT(oh->ot_handle == NULL);
- LASSERT(op < OSD_OT_MAX);
-
- oti->oti_declare_ops[op]++;
- oti->oti_declare_ops_cred[op] += credits;
+ if (unlikely(op >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERT(op < OSD_OT_MAX);
+ else {
+ CWARN("%s: Invalid operation index %d\n",
+ osd_name(oti->oti_dev), op);
+ libcfs_debug_dumpstack(NULL);
+ }
+ } else {
+ oti->oti_declare_ops[op]++;
+ oti->oti_declare_ops_cred[op] += credits;
+ }
oh->ot_credits += credits;
}
unsigned int rb;
LASSERT(oh->ot_handle != NULL);
- LASSERT(op < OSD_OT_MAX);
+ if (unlikely(op >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERT(op < OSD_OT_MAX);
+ else {
+ CWARN("%s: Invalid operation index %d\n",
+ osd_name(oti->oti_dev), op);
+ libcfs_debug_dumpstack(NULL);
+ return;
+ }
+ }
if (likely(!oti->oti_rollback && oti->oti_declare_ops[op] > 0)) {
oti->oti_declare_ops[op]--;
/* all future updates are considered rollback */
oti->oti_rollback = true;
rb = osd_trans_declare_op2rb[op];
- LASSERTF(rb < OSD_OT_MAX, "op = %u\n", op);
- LASSERTF(oti->oti_declare_ops_rb[rb] > 0, "rb = %u\n", rb);
+ if (unlikely(rb >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERTF(rb < OSD_OT_MAX, "rb = %u\n", rb);
+ else {
+ CWARN("%s: Invalid rollback index %d\n",
+ osd_name(oti->oti_dev), rb);
+ libcfs_debug_dumpstack(NULL);
+ return;
+ }
+ }
+ if (unlikely(oti->oti_declare_ops_rb[rb] == 0)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERTF(oti->oti_declare_ops_rb[rb] > 0,
+ "rb = %u\n", rb);
+ else {
+ CWARN("%s: Overflow in tracking declares for "
+ "index, rb = %d\n",
+ osd_name(oti->oti_dev), rb);
+ libcfs_debug_dumpstack(NULL);
+ return;
+ }
+ }
oti->oti_declare_ops_rb[rb]--;
}
}
ot_super);
LASSERT(oh->ot_handle != NULL);
- LASSERT(op < OSD_OT_MAX);
-
- oti->oti_declare_ops_rb[op]++;
-}
-#else
-static inline void osd_trans_declare_op(const struct lu_env *env,
- struct osd_thandle *oh,
- unsigned int op, int credits)
-{
- oh->ot_credits += credits;
-}
+ if (unlikely(op >= OSD_OT_MAX)) {
+ if (unlikely(ldiskfs_track_declares_assert))
+ LASSERT(op < OSD_OT_MAX);
+ else {
+ CWARN("%s: Invalid operation index %d\n",
+ osd_name(oti->oti_dev), op);
+ libcfs_debug_dumpstack(NULL);
+ }
-static inline void osd_trans_exec_op(const struct lu_env *env,
- struct thandle *th, unsigned int op)
-{
-}
-
-static inline void osd_trans_declare_rb(const struct lu_env *env,
- struct thandle *th, unsigned int op)
-{
+ } else {
+ oti->oti_declare_ops_rb[op]++;
+ }
}
-#endif
/**
* Helper function to pack the fid, ldiskfs stores fid in packed format.
return LDISKFS_HTREE_EOF_64BIT;
}
+static inline int fid_is_internal(const struct lu_fid *fid)
+{
+ return (!fid_is_namespace_visible(fid) && !fid_is_idif(fid));
+}
#endif /* __KERNEL__ */
#endif /* _OSD_INTERNAL_H */