X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_internal.h;h=1dec8c24133efdf6767b3e95bf11c94b1b41e262;hb=6e6357dbf9a14aaea459f460dbe4f93e52c814d4;hp=dcd29aac073cdaf188cbee6ecc1f6f2e001ba290;hpb=e3a7c58aebafce40323db54bf6056029e5af4a70;p=fs%2Flustre-release.git diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index dcd29aac..1dec8c2 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2011, 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -72,25 +72,34 @@ #include #include #include +#include #include "osd_oi.h" #include "osd_iam.h" +#include "osd_scrub.h" +#include "osd_quota_fmt.h" struct inode; -#define OSD_OII_NOGEN (0) #define OSD_COUNTERS (0) +/* ldiskfs special inode::i_state_flags need to be accessed with + * ldiskfs_{set,clear,test}_inode_state() only */ + +/* OI scrub should skip this inode. */ +#define LDISKFS_STATE_LUSTRE_NOSCRUB 31 + +/* Do not add OI mapping for this inode. */ +#define LDISKFS_STATE_LUSTRE_NO_OI 30 + /** Enable thandle usage statistics */ #define OSD_THANDLE_STATS (0) -#ifdef HAVE_QUOTA_SUPPORT -struct osd_ctxt { - __u32 oc_uid; - __u32 oc_gid; - cfs_kernel_cap_t oc_cap; -}; -#endif +#define MAX_OBJID_GROUP (FID_SEQ_ECHO + 1) + +#define OBJECTS "OBJECTS" +#define ADMIN_USR "admin_quotafile_v2.usr" +#define ADMIN_GRP "admin_quotafile_v2.grp" struct osd_directory { struct iam_container od_container; @@ -124,11 +133,11 @@ struct osd_object { * 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; + struct rw_semaphore oo_ext_idx_sem; + struct rw_semaphore oo_sem; + struct osd_directory *oo_dir; + /** protects inode attributes. */ + 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 @@ -143,54 +152,86 @@ struct osd_object { #endif }; -#ifdef HAVE_LDISKFS_PDO +struct osd_obj_seq { + /* protects on-fly initialization */ + int oos_subdir_count; /* subdir count for each seq */ + struct dentry *oos_root; /* O/ */ + struct dentry **oos_dirs; /* O//d0-dXX */ + obd_seq oos_seq; /* seq number */ + cfs_list_t oos_seq_list; /* list to seq_list */ +}; + +struct osd_obj_map { + struct dentry *om_root; /* dentry for /O */ + rwlock_t om_seq_list_lock; /* lock for seq_list */ + cfs_list_t om_seq_list; /* list head for seq */ + int om_subdir_count; + struct semaphore om_dir_init_sem; +}; + +struct osd_mdobj { + struct dentry *om_root; /* AGENT/ */ + obd_seq om_index; /* mdt index */ + cfs_list_t om_list; /* list to omm_list */ +}; + +struct osd_mdobj_map { + struct dentry *omm_agent_dentry; +}; #define osd_ldiskfs_find_entry(dir, dentry, de, lock) \ ll_ldiskfs_find_entry(dir, dentry, de, lock) #define osd_ldiskfs_add_entry(handle, child, cinode, hlock) \ ldiskfs_add_entry(handle, child, cinode, hlock) -#else /* HAVE_LDISKFS_PDO */ +#define OSD_OTABLE_IT_CACHE_SIZE 128 +#define OSD_OTABLE_IT_CACHE_MASK (~(OSD_OTABLE_IT_CACHE_SIZE - 1)) -struct htree_lock { - int dummy; -}; +struct osd_inconsistent_item { + /* link into osd_scrub::os_inconsistent_items, + * protected by osd_scrub::os_lock. */ + cfs_list_t oii_list; -struct htree_lock_head { - int dummy; -}; + /* The right FID <=> ino#/gen mapping. */ + struct osd_idmap_cache oii_cache; -#define ldiskfs_htree_lock(lock, head, inode, op) do { LBUG(); } while (0) -#define ldiskfs_htree_unlock(lock) do { LBUG(); } while (0) - -static inline struct htree_lock_head *ldiskfs_htree_lock_head_alloc(int dep) -{ - LBUG(); - return NULL; -} - -#define ldiskfs_htree_lock_head_free(lh) do { LBUG(); } while (0) + unsigned int oii_insert:1; /* insert or update mapping. */ +}; -#define LDISKFS_DUMMY_HTREE_LOCK 0xbabecafe +struct osd_otable_cache { + struct osd_idmap_cache ooc_cache[OSD_OTABLE_IT_CACHE_SIZE]; -static inline struct htree_lock *ldiskfs_htree_lock_alloc(void) -{ - return (struct htree_lock *)LDISKFS_DUMMY_HTREE_LOCK; -} + /* Index for next cache slot to be filled. */ + int ooc_producer_idx; -static inline void ldiskfs_htree_lock_free(struct htree_lock *lk) -{ - LASSERT((unsigned long)lk == LDISKFS_DUMMY_HTREE_LOCK); -} + /* Index for next cache slot to be returned by it::next(). */ + int ooc_consumer_idx; -#define HTREE_HBITS_DEF 0 + /* How many items in ooc_cache. */ + int ooc_cached_items; -#define osd_ldiskfs_find_entry(dir, dentry, de, lock) \ - ll_ldiskfs_find_entry(dir, dentry, de) -#define osd_ldiskfs_add_entry(handle, child, cinode, lock) \ - ldiskfs_add_entry(handle, child, cinode) + /* Position for up layer LFSCK iteration pre-loading. */ + __u32 ooc_pos_preload; +}; -#endif /* HAVE_LDISKFS_PDO */ +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. + * If more bits will be introduced in the future and need lock to + * protect, please add comment. */ + unsigned long ooi_used_outside:1, /* Some user out of OSD + * uses the iteration. */ + ooi_all_cached:1, /* No more entries can be + * 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. */ +}; extern const int osd_dto_credits_noquota[]; @@ -201,7 +242,6 @@ struct osd_device { /* super-class */ struct dt_device od_dt_dev; /* information about underlying file system */ - struct lustre_mount_info *od_mount; struct vfsmount *od_mnt; /* object index */ struct osd_oi **od_oi_table; @@ -210,7 +250,8 @@ struct osd_device { /* * Fid Capability */ - unsigned int od_fl_capa:1; + unsigned int od_fl_capa:1, + od_is_md:1; /* set in ->ldo_prepare */ unsigned long od_capa_timeout; __u32 od_capa_alg; struct lustre_capa_key *od_capa_keys; @@ -223,20 +264,17 @@ struct osd_device { */ cfs_time_t od_osfs_age; struct obd_statfs od_statfs; - cfs_spinlock_t od_osfs_lock; + spinlock_t od_osfs_lock; - /** - * The following flag indicates, if it is interop mode or not. - * It will be initialized, using mount param. - */ - __u32 od_iop_mode; + unsigned int od_noscrub:1, + od_handle_nolma:1; - struct fsfilt_operations *od_fsops; + struct fsfilt_operations *od_fsops; + int od_connects; + struct lu_site od_site; - /* - * mapping for legacy OST objids - */ - struct osd_compat_objid *od_ost_map; + struct osd_obj_map *od_ost_map; + struct osd_mdobj_map *od_mdt_map; unsigned long long od_readcache_max_filesize; int od_read_cache; @@ -245,30 +283,24 @@ struct osd_device { struct brw_stats od_brw_stats; cfs_atomic_t od_r_in_flight; cfs_atomic_t od_w_in_flight; -}; -#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);\ - if (((oh)->ot_declare_ ##op) > 0) { \ - ((oh)->ot_declare_ ##op)--; \ - } \ - } -#else -#define OSD_DECLARE_OP(oh, op) -#define OSD_EXEC_OP(oh, op) -#endif + struct mutex od_otable_mutex; + struct osd_otable_it *od_otable_it; + struct osd_scrub od_scrub; + cfs_list_t od_ios_list; + + /* service name associated with the osd device */ + char od_svname[MAX_OBD_NAME]; + char od_mntdev[MAX_OBD_NAME]; + + /* quota slave instance */ + struct qsd_instance *od_quota_slave; +}; /* There are at most 10 uid/gids are affected in a transaction, and * that's rename case: * - 2 for source parent uid & gid; - * - 2 for source child uid & gid ('..' entry update when the child - * is directory); + * - 2 for source child uid & gid ('..' entry update when child is directory); * - 2 for target parent uid & gid; * - 2 for target child uid & gid (if the target child exists); * - 2 for root uid & gid (last_rcvd, llog, etc); @@ -278,6 +310,23 @@ struct osd_device { */ #define OSD_MAX_UGID_CNT 10 +enum { + OSD_OT_ATTR_SET = 0, + OSD_OT_PUNCH = 1, + OSD_OT_XATTR_SET = 2, + OSD_OT_CREATE = 3, + OSD_OT_DESTROY = 4, + OSD_OT_REF_ADD = 5, + OSD_OT_REF_DEL = 6, + OSD_OT_WRITE = 7, + OSD_OT_INSERT = 8, + OSD_OT_DELETE = 9, + OSD_OT_QUOTA = 10, + OSD_OT_MAX = 11 +}; + +#define OSD_TRACK_DECLARES + struct osd_thandle { struct thandle ot_super; handle_t *ot_handle; @@ -289,20 +338,7 @@ struct osd_thandle { unsigned short ot_id_cnt; unsigned short ot_id_type; uid_t ot_id_array[OSD_MAX_UGID_CNT]; - -#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 - + struct lquota_trans *ot_quota_trans; #if OSD_THANDLE_STATS /** time when this handle was allocated */ cfs_time_t oth_alloced; @@ -409,6 +445,28 @@ struct osd_it_iam { struct iam_iterator oi_it; }; +struct osd_quota_leaf { + cfs_list_t oql_link; + uint oql_blk; +}; + +/** + * Iterator's in-memory data structure for quota file. + */ +struct osd_it_quota { + struct osd_object *oiq_obj; + /** tree blocks path to where the entry is stored */ + uint oiq_blk[LUSTRE_DQTREEDEPTH + 1]; + /** on-disk offset for current key where quota record can be found */ + loff_t oiq_offset; + /** identifier for current quota record */ + __u64 oiq_id; + /** the record index in the leaf/index block */ + uint oiq_index[LUSTRE_DQTREEDEPTH + 1]; + /** list of already processed leaf blocks */ + cfs_list_t oiq_list; +}; + #define MAX_BLOCKS_PER_PAGE (CFS_PAGE_SIZE / 512) struct osd_iobuf { @@ -426,6 +484,7 @@ struct osd_iobuf { 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 osd_thread_info { @@ -441,7 +500,9 @@ struct osd_thread_info { 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; /* @@ -470,11 +531,13 @@ struct osd_thread_info { /** osd iterator context used for iterator session */ - union { - struct osd_it_iam oti_it; - /** ldiskfs iterator data structure, see osd_it_ea_{init, fini} */ - struct osd_it_ea oti_it_ea; - }; + union { + struct osd_it_iam oti_it; + /* ldiskfs iterator data structure, + * see osd_it_ea_{init, fini} */ + struct osd_it_ea oti_it_ea; + 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; @@ -495,6 +558,7 @@ struct osd_thread_info { long long oti_alignment_lieutenant_colonel; }; + struct osd_idmap_cache oti_cache; int oti_r_locks; int oti_w_locks; @@ -502,18 +566,42 @@ struct osd_thread_info { /** used in osd_fid_set() to put xattr */ struct lu_buf oti_buf; /** used in osd_ea_fid_set() to set fid into common ea */ - struct lustre_mdt_attrs oti_mdt_attrs; + union { + struct lustre_mdt_attrs oti_mdt_attrs; + /* 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]; -#ifdef HAVE_QUOTA_SUPPORT - struct osd_ctxt oti_ctxt; -#endif struct lu_env oti_obj_delete_tx_env; #define OSD_FID_REC_SZ 32 char oti_ldp[OSD_FID_REC_SZ]; char oti_ldp2[OSD_FID_REC_SZ]; + + /* used by quota code */ + union { + struct if_dqblk oti_dqblk; + struct if_dqinfo oti_dqinfo; + }; + struct lquota_id_info oti_qi; + struct lquota_trans oti_quota_trans; + union lquota_rec oti_quota_rec; + __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_cred[OSD_OT_MAX]; + bool oti_rollback; +#endif + + char oti_name[48]; }; extern int ldiskfs_pdo; @@ -523,9 +611,6 @@ extern int ldiskfs_pdo; void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars); int osd_procfs_init(struct osd_device *osd, const char *name); int osd_procfs_fini(struct osd_device *osd); -void osd_lprocfs_time_start(const struct lu_env *env); -void osd_lprocfs_time_end(const struct lu_env *env, - struct osd_device *osd, int op); void osd_brw_stats_update(struct osd_device *osd, struct osd_iobuf *iobuf); #endif @@ -533,31 +618,85 @@ int osd_statfs(const struct lu_env *env, struct dt_device *dev, struct obd_statfs *sfs); int osd_object_auth(const struct lu_env *env, struct dt_object *dt, 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); - -int osd_compat_init(struct osd_device *dev); -void osd_compat_fini(struct osd_device *dev); -int osd_compat_objid_lookup(struct osd_thread_info *info, - struct osd_device *osd, - const struct lu_fid *fid, struct osd_inode_id *id); -int osd_compat_objid_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_compat_objid_delete(struct osd_thread_info *info, - struct osd_device *osd, - const struct lu_fid *fid, struct thandle *th); -int osd_compat_spec_lookup(struct osd_thread_info *info, - struct osd_device *osd, - const struct lu_fid *fid, struct osd_inode_id *id); -int osd_compat_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); +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); +int osd_get_lma(struct osd_thread_info *info, struct inode *inode, + struct dentry *dentry, struct lustre_mdt_attrs *lma); + +int osd_obj_map_init(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); +int osd_obj_map_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_map_delete(struct osd_thread_info *info, struct osd_device *osd, + const struct lu_fid *fid, struct thandle *th); +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); + +void osd_scrub_file_reset(struct osd_scrub *scrub, __u8 *uuid, __u64 flags); +int osd_scrub_file_store(struct osd_scrub *scrub); +char *osd_lf_fid2name(const struct lu_fid *fid); +int osd_scrub_start(struct osd_device *dev); +int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev); +void osd_scrub_cleanup(const struct lu_env *env, struct osd_device *dev); +int osd_oii_insert(struct osd_device *dev, struct osd_idmap_cache *oic, + int insert); +int osd_oii_lookup(struct osd_device *dev, const struct lu_fid *fid, + struct osd_inode_id *id); +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); + +/* 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, + struct osd_it_quota *it); +int walk_block_dqentry(const struct lu_env *env, struct osd_object *obj, + int type, uint blk, uint index, + struct osd_it_quota *it); +loff_t find_tree_dqentry(const struct lu_env *env, + struct osd_object *obj, int type, + qid_t dqid, uint blk, int depth, + struct osd_it_quota *it); +/* osd_quota.c */ +int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh, + struct lquota_id_info *qi, bool allocated, int *flags); +int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid, + long long space, struct osd_thandle *oh, + bool is_blk, bool allocated, int *flags, bool force); +const struct dt_rec *osd_quota_pack(struct osd_object *obj, + const struct dt_rec *rec, + union lquota_rec *quota_rec); +void osd_quota_unpack(struct osd_object *obj, const struct dt_rec *rec); +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 || + feat == &dt_quota_busr_features || + feat == &dt_quota_igrp_features || + feat == &dt_quota_bgrp_features) ? true : false; +} /* * Invariants, assertions. @@ -585,15 +724,25 @@ static inline int osd_invariant(const struct osd_object *obj) #define osd_invariant(obj) (1) #endif +#define OSD_MAX_CACHE_SIZE OBD_OBJECT_EOF + +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(!fid_is_idif(fid)); - LASSERT(!fid_is_igif(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)]; + 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); + /* 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)]; } extern const struct lu_device_operations osd_lu_ops; @@ -622,7 +771,7 @@ static inline struct osd_device *osd_obj2dev(const struct osd_object *o) static inline struct super_block *osd_sb(const struct osd_device *dev) { - return dev->od_mount->lmi_mnt->mnt_sb; + return dev->od_mnt->mnt_sb; } static inline int osd_object_is_root(const struct osd_object *obj) @@ -651,6 +800,17 @@ static inline journal_t *osd_journal(const struct osd_device *dev) return LDISKFS_SB(osd_sb(dev))->s_journal; } +static inline struct seq_server_site *osd_seq_site(struct osd_device *osd) +{ + return osd->od_dt_dev.dd_lu_dev.ld_site->ld_seq_site; +} + +static inline char *osd_name(struct osd_device *osd) +{ + 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; @@ -688,6 +848,8 @@ static inline void osd_ipd_put(const struct lu_env *env, } 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, + int write_NUL, loff_t *offs, handle_t *handle); static inline struct dentry *osd_child_dentry_by_inode(const struct lu_env *env, @@ -709,6 +871,78 @@ struct dentry *osd_child_dentry_by_inode(const struct lu_env *env, return child_dentry; } +#ifdef OSD_TRACK_DECLARES +extern int osd_trans_declare_op2rb[]; + +static inline void osd_trans_declare_op(const struct lu_env *env, + struct osd_thandle *oh, + unsigned int op, int credits) +{ + 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; + oh->ot_credits += credits; +} + +static inline void osd_trans_exec_op(const struct lu_env *env, + struct thandle *th, unsigned int op) +{ + struct osd_thread_info *oti = osd_oti_get(env); + struct osd_thandle *oh = container_of(th, struct osd_thandle, + ot_super); + unsigned int rb; + + LASSERT(oh->ot_handle != NULL); + LASSERT(op < OSD_OT_MAX); + + if (likely(!oti->oti_rollback && oti->oti_declare_ops[op] > 0)) { + oti->oti_declare_ops[op]--; + oti->oti_declare_ops_rb[op]++; + } else { + /* 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); + oti->oti_declare_ops_rb[rb]--; + } +} + +static inline void osd_trans_declare_rb(const struct lu_env *env, + struct thandle *th, unsigned int op) +{ + struct osd_thread_info *oti = osd_oti_get(env); + struct osd_thandle *oh = container_of(th, struct osd_thandle, + 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; +} + +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) +{ +} +#endif + /** * Helper function to pack the fid, ldiskfs stores fid in packed format. */ @@ -739,5 +973,31 @@ int osd_fid_unpack(struct lu_fid *fid, const struct osd_fid_pack *pack) return result; } +/** + * Quota/Accounting handling + */ +extern const struct dt_index_operations osd_acct_index_ops; +int osd_acct_obj_lookup(struct osd_thread_info *info, struct osd_device *osd, + const struct lu_fid *fid, struct osd_inode_id *id); + +/* copy from fs/ext4/dir.c */ +static inline int is_32bit_api(void) +{ +#ifdef CONFIG_COMPAT + return is_compat_task(); +#else + return (BITS_PER_LONG == 32); +#endif +} + +static inline loff_t ldiskfs_get_htree_eof(struct file *filp) +{ + if ((filp->f_mode & FMODE_32BITHASH) || + (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) + return LDISKFS_HTREE_EOF_32BIT; + else + return LDISKFS_HTREE_EOF_64BIT; +} + #endif /* __KERNEL__ */ #endif /* _OSD_INTERNAL_H */