[go: nahoru, domu]

1/*
2 * GPL HEADER START
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 *
24 * GPL HEADER END
25 */
26/*
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
29 *
30 * Copyright (c) 2011, 2012, Intel Corporation.
31 */
32/*
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
35 */
36
37#ifndef __LUSTRE_DT_OBJECT_H
38#define __LUSTRE_DT_OBJECT_H
39
40/** \defgroup dt dt
41 * Sub-class of lu_object with methods common for "data" objects in OST stack.
42 *
43 * Data objects behave like regular files: you can read/write them, get and
44 * set their attributes. Implementation of dt interface is supposed to
45 * implement some form of garbage collection, normally reference counting
46 * (nlink) based one.
47 *
48 * Examples: osd (lustre/osd) is an implementation of dt interface.
49 * @{
50 */
51
52
53/*
54 * super-class definitions.
55 */
56#include "lu_object.h"
57
58#include "../../include/linux/libcfs/libcfs.h"
59
60struct seq_file;
61struct proc_dir_entry;
62struct lustre_cfg;
63
64struct thandle;
65struct dt_device;
66struct dt_object;
67struct dt_index_features;
68struct niobuf_local;
69struct niobuf_remote;
70struct ldlm_enqueue_info;
71
72typedef enum {
73	MNTOPT_USERXATTR	= 0x00000001,
74	MNTOPT_ACL	      = 0x00000002,
75} mntopt_t;
76
77struct dt_device_param {
78	unsigned	   ddp_max_name_len;
79	unsigned	   ddp_max_nlink;
80	unsigned	   ddp_block_shift;
81	mntopt_t	   ddp_mntopts;
82	unsigned	   ddp_max_ea_size;
83	void	      *ddp_mnt; /* XXX: old code can retrieve mnt -bzzz */
84	int		ddp_mount_type;
85	unsigned long long ddp_maxbytes;
86	/* percentage of available space to reserve for grant error margin */
87	int		ddp_grant_reserved;
88	/* per-inode space consumption */
89	short	      ddp_inodespace;
90	/* per-fragment grant overhead to be used by client for grant
91	 * calculation */
92	int		ddp_grant_frag;
93};
94
95/**
96 * Per-transaction commit callback function
97 */
98struct dt_txn_commit_cb;
99typedef void (*dt_cb_t)(struct lu_env *env, struct thandle *th,
100			struct dt_txn_commit_cb *cb, int err);
101/**
102 * Special per-transaction callback for cases when just commit callback
103 * is needed and per-device callback are not convenient to use
104 */
105#define TRANS_COMMIT_CB_MAGIC	0xa0a00a0a
106#define MAX_COMMIT_CB_STR_LEN	32
107
108struct dt_txn_commit_cb {
109	struct list_head	dcb_linkage;
110	dt_cb_t		dcb_func;
111	__u32		dcb_magic;
112	char		dcb_name[MAX_COMMIT_CB_STR_LEN];
113};
114
115/**
116 * Operations on dt device.
117 */
118struct dt_device_operations {
119	/**
120	 * Return device-wide statistics.
121	 */
122	int   (*dt_statfs)(const struct lu_env *env,
123			   struct dt_device *dev, struct obd_statfs *osfs);
124	/**
125	 * Create transaction, described by \a param.
126	 */
127	struct thandle *(*dt_trans_create)(const struct lu_env *env,
128					   struct dt_device *dev);
129	/**
130	 * Start transaction, described by \a param.
131	 */
132	int   (*dt_trans_start)(const struct lu_env *env,
133				struct dt_device *dev, struct thandle *th);
134	/**
135	 * Finish previously started transaction.
136	 */
137	int   (*dt_trans_stop)(const struct lu_env *env,
138			       struct thandle *th);
139	/**
140	 * Add commit callback to the transaction.
141	 */
142	int   (*dt_trans_cb_add)(struct thandle *th,
143				 struct dt_txn_commit_cb *dcb);
144	/**
145	 * Return fid of root index object.
146	 */
147	int   (*dt_root_get)(const struct lu_env *env,
148			     struct dt_device *dev, struct lu_fid *f);
149	/**
150	 * Return device configuration data.
151	 */
152	void  (*dt_conf_get)(const struct lu_env *env,
153			     const struct dt_device *dev,
154			     struct dt_device_param *param);
155	/**
156	 *  handling device state, mostly for tests
157	 */
158	int   (*dt_sync)(const struct lu_env *env, struct dt_device *dev);
159	int   (*dt_ro)(const struct lu_env *env, struct dt_device *dev);
160	/**
161	  * Start a transaction commit asynchronously
162	  *
163	  * \param env environment
164	  * \param dev dt_device to start commit on
165	  *
166	  * \return 0 success, negative value if error
167	  */
168	 int   (*dt_commit_async)(const struct lu_env *env,
169				  struct dt_device *dev);
170	/**
171	 * Initialize capability context.
172	 */
173	int   (*dt_init_capa_ctxt)(const struct lu_env *env,
174				   struct dt_device *dev,
175				   int mode, unsigned long timeout,
176				   __u32 alg, struct lustre_capa_key *keys);
177};
178
179struct dt_index_features {
180	/** required feature flags from enum dt_index_flags */
181	__u32 dif_flags;
182	/** minimal required key size */
183	size_t dif_keysize_min;
184	/** maximal required key size, 0 if no limit */
185	size_t dif_keysize_max;
186	/** minimal required record size */
187	size_t dif_recsize_min;
188	/** maximal required record size, 0 if no limit */
189	size_t dif_recsize_max;
190	/** pointer size for record */
191	size_t dif_ptrsize;
192};
193
194enum dt_index_flags {
195	/** index supports variable sized keys */
196	DT_IND_VARKEY = 1 << 0,
197	/** index supports variable sized records */
198	DT_IND_VARREC = 1 << 1,
199	/** index can be modified */
200	DT_IND_UPDATE = 1 << 2,
201	/** index supports records with non-unique (duplicate) keys */
202	DT_IND_NONUNQ = 1 << 3,
203	/**
204	 * index support fixed-size keys sorted with natural numerical way
205	 * and is able to return left-side value if no exact value found
206	 */
207	DT_IND_RANGE = 1 << 4,
208};
209
210/**
211 * Features, required from index to support file system directories (mapping
212 * names to fids).
213 */
214extern const struct dt_index_features dt_directory_features;
215extern const struct dt_index_features dt_otable_features;
216extern const struct dt_index_features dt_lfsck_features;
217
218/* index features supported by the accounting objects */
219extern const struct dt_index_features dt_acct_features;
220
221/* index features supported by the quota global indexes */
222extern const struct dt_index_features dt_quota_glb_features;
223
224/* index features supported by the quota slave indexes */
225extern const struct dt_index_features dt_quota_slv_features;
226
227/**
228 * This is a general purpose dt allocation hint.
229 * It now contains the parent object.
230 * It can contain any allocation hint in the future.
231 */
232struct dt_allocation_hint {
233	struct dt_object	   *dah_parent;
234	__u32		       dah_mode;
235};
236
237/**
238 * object type specifier.
239 */
240
241enum dt_format_type {
242	DFT_REGULAR,
243	DFT_DIR,
244	/** for mknod */
245	DFT_NODE,
246	/** for special index */
247	DFT_INDEX,
248	/** for symbolic link */
249	DFT_SYM,
250};
251
252/**
253 * object format specifier.
254 */
255struct dt_object_format {
256	/** type for dt object */
257	enum dt_format_type dof_type;
258	union {
259		struct dof_regular {
260			int striped;
261		} dof_reg;
262		struct dof_dir {
263		} dof_dir;
264		struct dof_node {
265		} dof_node;
266		/**
267		 * special index need feature as parameter to create
268		 * special idx
269		 */
270		struct dof_index {
271			const struct dt_index_features *di_feat;
272		} dof_idx;
273	} u;
274};
275
276enum dt_format_type dt_mode_to_dft(__u32 mode);
277
278typedef __u64 dt_obj_version_t;
279
280/**
281 * Per-dt-object operations.
282 */
283struct dt_object_operations {
284	void  (*do_read_lock)(const struct lu_env *env,
285			      struct dt_object *dt, unsigned role);
286	void  (*do_write_lock)(const struct lu_env *env,
287			       struct dt_object *dt, unsigned role);
288	void  (*do_read_unlock)(const struct lu_env *env,
289				struct dt_object *dt);
290	void  (*do_write_unlock)(const struct lu_env *env,
291				 struct dt_object *dt);
292	int  (*do_write_locked)(const struct lu_env *env,
293				struct dt_object *dt);
294	/**
295	 * Note: following ->do_{x,}attr_{set,get}() operations are very
296	 * similar to ->moo_{x,}attr_{set,get}() operations in struct
297	 * md_object_operations (see md_object.h). These operations are not in
298	 * lu_object_operations, because ->do_{x,}attr_set() versions take
299	 * transaction handle as an argument (this transaction is started by
300	 * caller). We might factor ->do_{x,}attr_get() into
301	 * lu_object_operations, but that would break existing symmetry.
302	 */
303
304	/**
305	 * Return standard attributes.
306	 *
307	 * precondition: lu_object_exists(&dt->do_lu);
308	 */
309	int   (*do_attr_get)(const struct lu_env *env,
310			     struct dt_object *dt, struct lu_attr *attr,
311			     struct lustre_capa *capa);
312	/**
313	 * Set standard attributes.
314	 *
315	 * precondition: dt_object_exists(dt);
316	 */
317	int   (*do_declare_attr_set)(const struct lu_env *env,
318				     struct dt_object *dt,
319				     const struct lu_attr *attr,
320				     struct thandle *handle);
321	int   (*do_attr_set)(const struct lu_env *env,
322			     struct dt_object *dt,
323			     const struct lu_attr *attr,
324			     struct thandle *handle,
325			     struct lustre_capa *capa);
326	/**
327	 * Return a value of an extended attribute.
328	 *
329	 * precondition: dt_object_exists(dt);
330	 */
331	int   (*do_xattr_get)(const struct lu_env *env, struct dt_object *dt,
332			      struct lu_buf *buf, const char *name,
333			      struct lustre_capa *capa);
334	/**
335	 * Set value of an extended attribute.
336	 *
337	 * \a fl - flags from enum lu_xattr_flags
338	 *
339	 * precondition: dt_object_exists(dt);
340	 */
341	int   (*do_declare_xattr_set)(const struct lu_env *env,
342				      struct dt_object *dt,
343				      const struct lu_buf *buf,
344				      const char *name, int fl,
345				      struct thandle *handle);
346	int   (*do_xattr_set)(const struct lu_env *env,
347			      struct dt_object *dt, const struct lu_buf *buf,
348			      const char *name, int fl, struct thandle *handle,
349			      struct lustre_capa *capa);
350	/**
351	 * Delete existing extended attribute.
352	 *
353	 * precondition: dt_object_exists(dt);
354	 */
355	int   (*do_declare_xattr_del)(const struct lu_env *env,
356				      struct dt_object *dt,
357				      const char *name, struct thandle *handle);
358	int   (*do_xattr_del)(const struct lu_env *env,
359			      struct dt_object *dt,
360			      const char *name, struct thandle *handle,
361			      struct lustre_capa *capa);
362	/**
363	 * Place list of existing extended attributes into \a buf (which has
364	 * length len).
365	 *
366	 * precondition: dt_object_exists(dt);
367	 */
368	int   (*do_xattr_list)(const struct lu_env *env,
369			       struct dt_object *dt, struct lu_buf *buf,
370			       struct lustre_capa *capa);
371	/**
372	 * Init allocation hint using parent object and child mode.
373	 * (1) The \a parent might be NULL if this is a partial creation for
374	 *     remote object.
375	 * (2) The type of child is in \a child_mode.
376	 * (3) The result hint is stored in \a ah;
377	 */
378	void  (*do_ah_init)(const struct lu_env *env,
379			    struct dt_allocation_hint *ah,
380			    struct dt_object *parent,
381			    struct dt_object *child,
382			    umode_t child_mode);
383	/**
384	 * Create new object on this device.
385	 *
386	 * precondition: !dt_object_exists(dt);
387	 * postcondition: ergo(result == 0, dt_object_exists(dt));
388	 */
389	int   (*do_declare_create)(const struct lu_env *env,
390				   struct dt_object *dt,
391				   struct lu_attr *attr,
392				   struct dt_allocation_hint *hint,
393				   struct dt_object_format *dof,
394				   struct thandle *th);
395	int   (*do_create)(const struct lu_env *env, struct dt_object *dt,
396			   struct lu_attr *attr,
397			   struct dt_allocation_hint *hint,
398			   struct dt_object_format *dof,
399			   struct thandle *th);
400
401	/**
402	  Destroy object on this device
403	 * precondition: !dt_object_exists(dt);
404	 * postcondition: ergo(result == 0, dt_object_exists(dt));
405	 */
406	int   (*do_declare_destroy)(const struct lu_env *env,
407				    struct dt_object *dt,
408				    struct thandle *th);
409	int   (*do_destroy)(const struct lu_env *env, struct dt_object *dt,
410			    struct thandle *th);
411
412	/**
413	 * Announce that this object is going to be used as an index. This
414	 * operation check that object supports indexing operations and
415	 * installs appropriate dt_index_operations vector on success.
416	 *
417	 * Also probes for features. Operation is successful if all required
418	 * features are supported.
419	 */
420	int   (*do_index_try)(const struct lu_env *env,
421			      struct dt_object *dt,
422			      const struct dt_index_features *feat);
423	/**
424	 * Add nlink of the object
425	 * precondition: dt_object_exists(dt);
426	 */
427	int   (*do_declare_ref_add)(const struct lu_env *env,
428				    struct dt_object *dt, struct thandle *th);
429	int   (*do_ref_add)(const struct lu_env *env,
430			    struct dt_object *dt, struct thandle *th);
431	/**
432	 * Del nlink of the object
433	 * precondition: dt_object_exists(dt);
434	 */
435	int   (*do_declare_ref_del)(const struct lu_env *env,
436				    struct dt_object *dt, struct thandle *th);
437	int   (*do_ref_del)(const struct lu_env *env,
438			    struct dt_object *dt, struct thandle *th);
439
440	struct obd_capa *(*do_capa_get)(const struct lu_env *env,
441					struct dt_object *dt,
442					struct lustre_capa *old,
443					__u64 opc);
444	int (*do_object_sync)(const struct lu_env *env, struct dt_object *obj,
445			      __u64 start, __u64 end);
446	/**
447	 * Get object info of next level. Currently, only get inode from osd.
448	 * This is only used by quota b=16542
449	 * precondition: dt_object_exists(dt);
450	 */
451	int (*do_data_get)(const struct lu_env *env, struct dt_object *dt,
452			   void **data);
453
454	/**
455	 * Lock object.
456	 */
457	int (*do_object_lock)(const struct lu_env *env, struct dt_object *dt,
458			      struct lustre_handle *lh,
459			      struct ldlm_enqueue_info *einfo,
460			      void *policy);
461};
462
463/**
464 * Per-dt-object operations on "file body".
465 */
466struct dt_body_operations {
467	/**
468	 * precondition: dt_object_exists(dt);
469	 */
470	ssize_t (*dbo_read)(const struct lu_env *env, struct dt_object *dt,
471			    struct lu_buf *buf, loff_t *pos,
472			    struct lustre_capa *capa);
473	/**
474	 * precondition: dt_object_exists(dt);
475	 */
476	ssize_t (*dbo_declare_write)(const struct lu_env *env,
477				     struct dt_object *dt,
478				     const loff_t size, loff_t pos,
479				     struct thandle *handle);
480	ssize_t (*dbo_write)(const struct lu_env *env, struct dt_object *dt,
481			     const struct lu_buf *buf, loff_t *pos,
482			     struct thandle *handle, struct lustre_capa *capa,
483			     int ignore_quota);
484	/*
485	 * methods for zero-copy IO
486	 */
487
488	/*
489	 * precondition: dt_object_exists(dt);
490	 * returns:
491	 * < 0 - error code
492	 * = 0 - illegal
493	 * > 0 - number of local buffers prepared
494	 */
495	int (*dbo_bufs_get)(const struct lu_env *env, struct dt_object *dt,
496			    loff_t pos, ssize_t len, struct niobuf_local *lb,
497			    int rw, struct lustre_capa *capa);
498	/*
499	 * precondition: dt_object_exists(dt);
500	 */
501	int (*dbo_bufs_put)(const struct lu_env *env, struct dt_object *dt,
502			    struct niobuf_local *lb, int nr);
503	/*
504	 * precondition: dt_object_exists(dt);
505	 */
506	int (*dbo_write_prep)(const struct lu_env *env, struct dt_object *dt,
507			      struct niobuf_local *lb, int nr);
508	/*
509	 * precondition: dt_object_exists(dt);
510	 */
511	int (*dbo_declare_write_commit)(const struct lu_env *env,
512					struct dt_object *dt,
513					struct niobuf_local *,
514					int, struct thandle *);
515	/*
516	 * precondition: dt_object_exists(dt);
517	 */
518	int (*dbo_write_commit)(const struct lu_env *env, struct dt_object *dt,
519				struct niobuf_local *, int, struct thandle *);
520	/*
521	 * precondition: dt_object_exists(dt);
522	 */
523	int (*dbo_read_prep)(const struct lu_env *env, struct dt_object *dt,
524			     struct niobuf_local *lnb, int nr);
525	int (*dbo_fiemap_get)(const struct lu_env *env, struct dt_object *dt,
526			      struct ll_user_fiemap *fm);
527	/**
528	 * Punch object's content
529	 * precondition: regular object, not index
530	 */
531	int   (*dbo_declare_punch)(const struct lu_env *, struct dt_object *,
532				  __u64, __u64, struct thandle *th);
533	int   (*dbo_punch)(const struct lu_env *env, struct dt_object *dt,
534			  __u64 start, __u64 end, struct thandle *th,
535			  struct lustre_capa *capa);
536};
537
538/**
539 * Incomplete type of index record.
540 */
541struct dt_rec;
542
543/**
544 * Incomplete type of index key.
545 */
546struct dt_key;
547
548/**
549 * Incomplete type of dt iterator.
550 */
551struct dt_it;
552
553/**
554 * Per-dt-object operations on object as index.
555 */
556struct dt_index_operations {
557	/**
558	 * precondition: dt_object_exists(dt);
559	 */
560	int (*dio_lookup)(const struct lu_env *env, struct dt_object *dt,
561			  struct dt_rec *rec, const struct dt_key *key,
562			  struct lustre_capa *capa);
563	/**
564	 * precondition: dt_object_exists(dt);
565	 */
566	int (*dio_declare_insert)(const struct lu_env *env,
567				  struct dt_object *dt,
568				  const struct dt_rec *rec,
569				  const struct dt_key *key,
570				  struct thandle *handle);
571	int (*dio_insert)(const struct lu_env *env, struct dt_object *dt,
572			  const struct dt_rec *rec, const struct dt_key *key,
573			  struct thandle *handle, struct lustre_capa *capa,
574			  int ignore_quota);
575	/**
576	 * precondition: dt_object_exists(dt);
577	 */
578	int (*dio_declare_delete)(const struct lu_env *env,
579				  struct dt_object *dt,
580				  const struct dt_key *key,
581				  struct thandle *handle);
582	int (*dio_delete)(const struct lu_env *env, struct dt_object *dt,
583			  const struct dt_key *key, struct thandle *handle,
584			  struct lustre_capa *capa);
585	/**
586	 * Iterator interface
587	 */
588	struct dt_it_ops {
589		/**
590		 * Allocate and initialize new iterator.
591		 *
592		 * precondition: dt_object_exists(dt);
593		 */
594		struct dt_it *(*init)(const struct lu_env *env,
595				      struct dt_object *dt,
596				      __u32 attr,
597				      struct lustre_capa *capa);
598		void	  (*fini)(const struct lu_env *env,
599				      struct dt_it *di);
600		int	    (*get)(const struct lu_env *env,
601				      struct dt_it *di,
602				      const struct dt_key *key);
603		void	   (*put)(const struct lu_env *env,
604				      struct dt_it *di);
605		int	   (*next)(const struct lu_env *env,
606				      struct dt_it *di);
607		struct dt_key *(*key)(const struct lu_env *env,
608				      const struct dt_it *di);
609		int       (*key_size)(const struct lu_env *env,
610				      const struct dt_it *di);
611		int	    (*rec)(const struct lu_env *env,
612				      const struct dt_it *di,
613				      struct dt_rec *rec,
614				      __u32 attr);
615		__u64	(*store)(const struct lu_env *env,
616				      const struct dt_it *di);
617		int	   (*load)(const struct lu_env *env,
618				      const struct dt_it *di, __u64 hash);
619		int	(*key_rec)(const struct lu_env *env,
620				      const struct dt_it *di, void* key_rec);
621	} dio_it;
622};
623
624enum dt_otable_it_valid {
625	DOIV_ERROR_HANDLE	= 0x0001,
626};
627
628enum dt_otable_it_flags {
629	/* Exit when fail. */
630	DOIF_FAILOUT	= 0x0001,
631
632	/* Reset iteration position to the device beginning. */
633	DOIF_RESET	= 0x0002,
634
635	/* There is up layer component uses the iteration. */
636	DOIF_OUTUSED	= 0x0004,
637};
638
639/* otable based iteration needs to use the common DT interation APIs.
640 * To initialize the iteration, it needs call dio_it::init() firstly.
641 * Here is how the otable based iteration should prepare arguments to
642 * call dt_it_ops::init().
643 *
644 * For otable based iteration, the 32-bits 'attr' for dt_it_ops::init()
645 * is composed of two parts:
646 * low 16-bits is for valid bits, high 16-bits is for flags bits. */
647#define DT_OTABLE_IT_FLAGS_SHIFT	16
648#define DT_OTABLE_IT_FLAGS_MASK 	0xffff0000
649
650struct dt_device {
651	struct lu_device		   dd_lu_dev;
652	const struct dt_device_operations *dd_ops;
653
654	/**
655	 * List of dt_txn_callback (see below). This is not protected in any
656	 * way, because callbacks are supposed to be added/deleted only during
657	 * single-threaded start-up shut-down procedures.
658	 */
659	struct list_head			 dd_txn_callbacks;
660};
661
662int  dt_device_init(struct dt_device *dev, struct lu_device_type *t);
663void dt_device_fini(struct dt_device *dev);
664
665static inline int lu_device_is_dt(const struct lu_device *d)
666{
667	return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT);
668}
669
670static inline struct dt_device * lu2dt_dev(struct lu_device *l)
671{
672	LASSERT(lu_device_is_dt(l));
673	return container_of0(l, struct dt_device, dd_lu_dev);
674}
675
676struct dt_object {
677	struct lu_object		   do_lu;
678	const struct dt_object_operations *do_ops;
679	const struct dt_body_operations   *do_body_ops;
680	const struct dt_index_operations  *do_index_ops;
681};
682
683/*
684 * In-core representation of per-device local object OID storage
685 */
686struct local_oid_storage {
687	/* all initialized llog systems on this node linked by this */
688	struct list_head	  los_list;
689
690	/* how many handle's reference this los has */
691	atomic_t	  los_refcount;
692	struct dt_device *los_dev;
693	struct dt_object *los_obj;
694
695	/* data used to generate new fids */
696	struct mutex	  los_id_lock;
697	__u64		  los_seq;
698	__u32		  los_last_oid;
699};
700
701static inline struct dt_object *lu2dt(struct lu_object *l)
702{
703	LASSERT(l == NULL || IS_ERR(l) || lu_device_is_dt(l->lo_dev));
704	return container_of0(l, struct dt_object, do_lu);
705}
706
707int  dt_object_init(struct dt_object *obj,
708		    struct lu_object_header *h, struct lu_device *d);
709
710void dt_object_fini(struct dt_object *obj);
711
712static inline int dt_object_exists(const struct dt_object *dt)
713{
714	return lu_object_exists(&dt->do_lu);
715}
716
717static inline int dt_object_remote(const struct dt_object *dt)
718{
719	return lu_object_remote(&dt->do_lu);
720}
721
722static inline struct dt_object *lu2dt_obj(struct lu_object *o)
723{
724	LASSERT(ergo(o != NULL, lu_device_is_dt(o->lo_dev)));
725	return container_of0(o, struct dt_object, do_lu);
726}
727
728/**
729 * This is the general purpose transaction handle.
730 * 1. Transaction Life Cycle
731 *      This transaction handle is allocated upon starting a new transaction,
732 *      and deallocated after this transaction is committed.
733 * 2. Transaction Nesting
734 *      We do _NOT_ support nested transaction. So, every thread should only
735 *      have one active transaction, and a transaction only belongs to one
736 *      thread. Due to this, transaction handle need no reference count.
737 * 3. Transaction & dt_object locking
738 *      dt_object locks should be taken inside transaction.
739 * 4. Transaction & RPC
740 *      No RPC request should be issued inside transaction.
741 */
742struct thandle {
743	/** the dt device on which the transactions are executed */
744	struct dt_device *th_dev;
745
746	/** context for this transaction, tag is LCT_TX_HANDLE */
747	struct lu_context th_ctx;
748
749	/** additional tags (layers can add in declare) */
750	__u32	     th_tags;
751
752	/** the last operation result in this transaction.
753	 * this value is used in recovery */
754	__s32	     th_result;
755
756	/** whether we need sync commit */
757	unsigned int		th_sync:1;
758
759	/* local transation, no need to inform other layers */
760	unsigned int		th_local:1;
761
762	/* In DNE, one transaction can be disassemblied into
763	 * updates on several different MDTs, and these updates
764	 * will be attached to th_remote_update_list per target.
765	 * Only single thread will access the list, no need lock
766	 */
767	struct list_head		th_remote_update_list;
768	struct update_request	*th_current_request;
769};
770
771/**
772 * Transaction call-backs.
773 *
774 * These are invoked by osd (or underlying transaction engine) when
775 * transaction changes state.
776 *
777 * Call-backs are used by upper layers to modify transaction parameters and to
778 * perform some actions on for each transaction state transition. Typical
779 * example is mdt registering call-back to write into last-received file
780 * before each transaction commit.
781 */
782struct dt_txn_callback {
783	int (*dtc_txn_start)(const struct lu_env *env,
784			     struct thandle *txn, void *cookie);
785	int (*dtc_txn_stop)(const struct lu_env *env,
786			    struct thandle *txn, void *cookie);
787	void (*dtc_txn_commit)(struct thandle *txn, void *cookie);
788	void		*dtc_cookie;
789	__u32		dtc_tag;
790	struct list_head	   dtc_linkage;
791};
792
793void dt_txn_callback_add(struct dt_device *dev, struct dt_txn_callback *cb);
794void dt_txn_callback_del(struct dt_device *dev, struct dt_txn_callback *cb);
795
796int dt_txn_hook_start(const struct lu_env *env,
797		      struct dt_device *dev, struct thandle *txn);
798int dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn);
799void dt_txn_hook_commit(struct thandle *txn);
800
801int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj);
802
803/**
804 * Callback function used for parsing path.
805 * \see llo_store_resolve
806 */
807typedef int (*dt_entry_func_t)(const struct lu_env *env,
808			    const char *name,
809			    void *pvt);
810
811#define DT_MAX_PATH 1024
812
813int dt_path_parser(const struct lu_env *env,
814		   char *local, dt_entry_func_t entry_func,
815		   void *data);
816
817struct dt_object *
818dt_store_resolve(const struct lu_env *env, struct dt_device *dt,
819		 const char *path, struct lu_fid *fid);
820
821struct dt_object *dt_store_open(const struct lu_env *env,
822				struct dt_device *dt,
823				const char *dirname,
824				const char *filename,
825				struct lu_fid *fid);
826
827struct dt_object *dt_find_or_create(const struct lu_env *env,
828				    struct dt_device *dt,
829				    const struct lu_fid *fid,
830				    struct dt_object_format *dof,
831				    struct lu_attr *attr);
832
833struct dt_object *dt_locate_at(const struct lu_env *env,
834			       struct dt_device *dev,
835			       const struct lu_fid *fid,
836			       struct lu_device *top_dev);
837static inline struct dt_object *
838dt_locate(const struct lu_env *env, struct dt_device *dev,
839	  const struct lu_fid *fid)
840{
841	return dt_locate_at(env, dev, fid, dev->dd_lu_dev.ld_site->ls_top_dev);
842}
843
844
845int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev,
846			   const struct lu_fid *first_fid,
847			   struct local_oid_storage **los);
848void local_oid_storage_fini(const struct lu_env *env,
849			    struct local_oid_storage *los);
850int local_object_fid_generate(const struct lu_env *env,
851			      struct local_oid_storage *los,
852			      struct lu_fid *fid);
853int local_object_declare_create(const struct lu_env *env,
854				struct local_oid_storage *los,
855				struct dt_object *o,
856				struct lu_attr *attr,
857				struct dt_object_format *dof,
858				struct thandle *th);
859int local_object_create(const struct lu_env *env,
860			struct local_oid_storage *los,
861			struct dt_object *o,
862			struct lu_attr *attr, struct dt_object_format *dof,
863			struct thandle *th);
864struct dt_object *local_file_find_or_create(const struct lu_env *env,
865					    struct local_oid_storage *los,
866					    struct dt_object *parent,
867					    const char *name, __u32 mode);
868struct dt_object *local_file_find_or_create_with_fid(const struct lu_env *env,
869						     struct dt_device *dt,
870						     const struct lu_fid *fid,
871						     struct dt_object *parent,
872						     const char *name,
873						     __u32 mode);
874struct dt_object *
875local_index_find_or_create(const struct lu_env *env,
876			   struct local_oid_storage *los,
877			   struct dt_object *parent,
878			   const char *name, __u32 mode,
879			   const struct dt_index_features *ft);
880struct dt_object *
881local_index_find_or_create_with_fid(const struct lu_env *env,
882				    struct dt_device *dt,
883				    const struct lu_fid *fid,
884				    struct dt_object *parent,
885				    const char *name, __u32 mode,
886				    const struct dt_index_features *ft);
887int local_object_unlink(const struct lu_env *env, struct dt_device *dt,
888			struct dt_object *parent, const char *name);
889
890static inline int dt_object_lock(const struct lu_env *env,
891				 struct dt_object *o, struct lustre_handle *lh,
892				 struct ldlm_enqueue_info *einfo,
893				 void *policy)
894{
895	LASSERT(o);
896	LASSERT(o->do_ops);
897	LASSERT(o->do_ops->do_object_lock);
898	return o->do_ops->do_object_lock(env, o, lh, einfo, policy);
899}
900
901int dt_lookup_dir(const struct lu_env *env, struct dt_object *dir,
902		  const char *name, struct lu_fid *fid);
903
904static inline int dt_object_sync(const struct lu_env *env, struct dt_object *o,
905				 __u64 start, __u64 end)
906{
907	LASSERT(o);
908	LASSERT(o->do_ops);
909	LASSERT(o->do_ops->do_object_sync);
910	return o->do_ops->do_object_sync(env, o, start, end);
911}
912
913int dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
914			   struct thandle *th);
915void dt_version_set(const struct lu_env *env, struct dt_object *o,
916		    dt_obj_version_t version, struct thandle *th);
917dt_obj_version_t dt_version_get(const struct lu_env *env, struct dt_object *o);
918
919
920int dt_read(const struct lu_env *env, struct dt_object *dt,
921	    struct lu_buf *buf, loff_t *pos);
922int dt_record_read(const struct lu_env *env, struct dt_object *dt,
923		   struct lu_buf *buf, loff_t *pos);
924int dt_record_write(const struct lu_env *env, struct dt_object *dt,
925		    const struct lu_buf *buf, loff_t *pos, struct thandle *th);
926typedef int (*dt_index_page_build_t)(const struct lu_env *env,
927				     union lu_page *lp, int nob,
928				     const struct dt_it_ops *iops,
929				     struct dt_it *it, __u32 attr, void *arg);
930int dt_index_walk(const struct lu_env *env, struct dt_object *obj,
931		  const struct lu_rdpg *rdpg, dt_index_page_build_t filler,
932		  void *arg);
933int dt_index_read(const struct lu_env *env, struct dt_device *dev,
934		  struct idx_info *ii, const struct lu_rdpg *rdpg);
935
936static inline struct thandle *dt_trans_create(const struct lu_env *env,
937					      struct dt_device *d)
938{
939	LASSERT(d->dd_ops->dt_trans_create);
940	return d->dd_ops->dt_trans_create(env, d);
941}
942
943static inline int dt_trans_start(const struct lu_env *env,
944				 struct dt_device *d, struct thandle *th)
945{
946	LASSERT(d->dd_ops->dt_trans_start);
947	return d->dd_ops->dt_trans_start(env, d, th);
948}
949
950/* for this transaction hooks shouldn't be called */
951static inline int dt_trans_start_local(const struct lu_env *env,
952				       struct dt_device *d, struct thandle *th)
953{
954	LASSERT(d->dd_ops->dt_trans_start);
955	th->th_local = 1;
956	return d->dd_ops->dt_trans_start(env, d, th);
957}
958
959static inline int dt_trans_stop(const struct lu_env *env,
960				struct dt_device *d, struct thandle *th)
961{
962	LASSERT(d->dd_ops->dt_trans_stop);
963	return d->dd_ops->dt_trans_stop(env, th);
964}
965
966static inline int dt_trans_cb_add(struct thandle *th,
967				  struct dt_txn_commit_cb *dcb)
968{
969	LASSERT(th->th_dev->dd_ops->dt_trans_cb_add);
970	dcb->dcb_magic = TRANS_COMMIT_CB_MAGIC;
971	return th->th_dev->dd_ops->dt_trans_cb_add(th, dcb);
972}
973/** @} dt */
974
975
976static inline int dt_declare_record_write(const struct lu_env *env,
977					  struct dt_object *dt,
978					  int size, loff_t pos,
979					  struct thandle *th)
980{
981	int rc;
982
983	LASSERTF(dt != NULL, "dt is NULL when we want to write record\n");
984	LASSERT(th != NULL);
985	LASSERT(dt->do_body_ops);
986	LASSERT(dt->do_body_ops->dbo_declare_write);
987	rc = dt->do_body_ops->dbo_declare_write(env, dt, size, pos, th);
988	return rc;
989}
990
991static inline int dt_declare_create(const struct lu_env *env,
992				    struct dt_object *dt,
993				    struct lu_attr *attr,
994				    struct dt_allocation_hint *hint,
995				    struct dt_object_format *dof,
996				    struct thandle *th)
997{
998	LASSERT(dt);
999	LASSERT(dt->do_ops);
1000	LASSERT(dt->do_ops->do_declare_create);
1001	return dt->do_ops->do_declare_create(env, dt, attr, hint, dof, th);
1002}
1003
1004static inline int dt_create(const struct lu_env *env,
1005				    struct dt_object *dt,
1006				    struct lu_attr *attr,
1007				    struct dt_allocation_hint *hint,
1008				    struct dt_object_format *dof,
1009				    struct thandle *th)
1010{
1011	LASSERT(dt);
1012	LASSERT(dt->do_ops);
1013	LASSERT(dt->do_ops->do_create);
1014	return dt->do_ops->do_create(env, dt, attr, hint, dof, th);
1015}
1016
1017static inline int dt_declare_destroy(const struct lu_env *env,
1018				     struct dt_object *dt,
1019				     struct thandle *th)
1020{
1021	LASSERT(dt);
1022	LASSERT(dt->do_ops);
1023	LASSERT(dt->do_ops->do_declare_destroy);
1024	return dt->do_ops->do_declare_destroy(env, dt, th);
1025}
1026
1027static inline int dt_destroy(const struct lu_env *env,
1028			     struct dt_object *dt,
1029			     struct thandle *th)
1030{
1031	LASSERT(dt);
1032	LASSERT(dt->do_ops);
1033	LASSERT(dt->do_ops->do_destroy);
1034	return dt->do_ops->do_destroy(env, dt, th);
1035}
1036
1037static inline void dt_read_lock(const struct lu_env *env,
1038				struct dt_object *dt,
1039				unsigned role)
1040{
1041	LASSERT(dt);
1042	LASSERT(dt->do_ops);
1043	LASSERT(dt->do_ops->do_read_lock);
1044	dt->do_ops->do_read_lock(env, dt, role);
1045}
1046
1047static inline void dt_write_lock(const struct lu_env *env,
1048				struct dt_object *dt,
1049				unsigned role)
1050{
1051	LASSERT(dt);
1052	LASSERT(dt->do_ops);
1053	LASSERT(dt->do_ops->do_write_lock);
1054	dt->do_ops->do_write_lock(env, dt, role);
1055}
1056
1057static inline void dt_read_unlock(const struct lu_env *env,
1058				struct dt_object *dt)
1059{
1060	LASSERT(dt);
1061	LASSERT(dt->do_ops);
1062	LASSERT(dt->do_ops->do_read_unlock);
1063	dt->do_ops->do_read_unlock(env, dt);
1064}
1065
1066static inline void dt_write_unlock(const struct lu_env *env,
1067				struct dt_object *dt)
1068{
1069	LASSERT(dt);
1070	LASSERT(dt->do_ops);
1071	LASSERT(dt->do_ops->do_write_unlock);
1072	dt->do_ops->do_write_unlock(env, dt);
1073}
1074
1075static inline int dt_write_locked(const struct lu_env *env,
1076				  struct dt_object *dt)
1077{
1078	LASSERT(dt);
1079	LASSERT(dt->do_ops);
1080	LASSERT(dt->do_ops->do_write_locked);
1081	return dt->do_ops->do_write_locked(env, dt);
1082}
1083
1084static inline int dt_attr_get(const struct lu_env *env, struct dt_object *dt,
1085			      struct lu_attr *la, void *arg)
1086{
1087	LASSERT(dt);
1088	LASSERT(dt->do_ops);
1089	LASSERT(dt->do_ops->do_attr_get);
1090	return dt->do_ops->do_attr_get(env, dt, la, arg);
1091}
1092
1093static inline int dt_declare_attr_set(const struct lu_env *env,
1094				      struct dt_object *dt,
1095				      const struct lu_attr *la,
1096				      struct thandle *th)
1097{
1098	LASSERT(dt);
1099	LASSERT(dt->do_ops);
1100	LASSERT(dt->do_ops->do_declare_attr_set);
1101	return dt->do_ops->do_declare_attr_set(env, dt, la, th);
1102}
1103
1104static inline int dt_attr_set(const struct lu_env *env, struct dt_object *dt,
1105			      const struct lu_attr *la, struct thandle *th,
1106			      struct lustre_capa *capa)
1107{
1108	LASSERT(dt);
1109	LASSERT(dt->do_ops);
1110	LASSERT(dt->do_ops->do_attr_set);
1111	return dt->do_ops->do_attr_set(env, dt, la, th, capa);
1112}
1113
1114static inline int dt_declare_ref_add(const struct lu_env *env,
1115				     struct dt_object *dt, struct thandle *th)
1116{
1117	LASSERT(dt);
1118	LASSERT(dt->do_ops);
1119	LASSERT(dt->do_ops->do_declare_ref_add);
1120	return dt->do_ops->do_declare_ref_add(env, dt, th);
1121}
1122
1123static inline int dt_ref_add(const struct lu_env *env,
1124			     struct dt_object *dt, struct thandle *th)
1125{
1126	LASSERT(dt);
1127	LASSERT(dt->do_ops);
1128	LASSERT(dt->do_ops->do_ref_add);
1129	return dt->do_ops->do_ref_add(env, dt, th);
1130}
1131
1132static inline int dt_declare_ref_del(const struct lu_env *env,
1133				     struct dt_object *dt, struct thandle *th)
1134{
1135	LASSERT(dt);
1136	LASSERT(dt->do_ops);
1137	LASSERT(dt->do_ops->do_declare_ref_del);
1138	return dt->do_ops->do_declare_ref_del(env, dt, th);
1139}
1140
1141static inline int dt_ref_del(const struct lu_env *env,
1142			     struct dt_object *dt, struct thandle *th)
1143{
1144	LASSERT(dt);
1145	LASSERT(dt->do_ops);
1146	LASSERT(dt->do_ops->do_ref_del);
1147	return dt->do_ops->do_ref_del(env, dt, th);
1148}
1149
1150static inline struct obd_capa *dt_capa_get(const struct lu_env *env,
1151					   struct dt_object *dt,
1152					   struct lustre_capa *old, __u64 opc)
1153{
1154	LASSERT(dt);
1155	LASSERT(dt->do_ops);
1156	LASSERT(dt->do_ops->do_ref_del);
1157	return dt->do_ops->do_capa_get(env, dt, old, opc);
1158}
1159
1160static inline int dt_bufs_get(const struct lu_env *env, struct dt_object *d,
1161			      struct niobuf_remote *rnb,
1162			      struct niobuf_local *lnb, int rw,
1163			      struct lustre_capa *capa)
1164{
1165	LASSERT(d);
1166	LASSERT(d->do_body_ops);
1167	LASSERT(d->do_body_ops->dbo_bufs_get);
1168	return d->do_body_ops->dbo_bufs_get(env, d, rnb->offset,
1169					    rnb->len, lnb, rw, capa);
1170}
1171
1172static inline int dt_bufs_put(const struct lu_env *env, struct dt_object *d,
1173			      struct niobuf_local *lnb, int n)
1174{
1175	LASSERT(d);
1176	LASSERT(d->do_body_ops);
1177	LASSERT(d->do_body_ops->dbo_bufs_put);
1178	return d->do_body_ops->dbo_bufs_put(env, d, lnb, n);
1179}
1180
1181static inline int dt_write_prep(const struct lu_env *env, struct dt_object *d,
1182				struct niobuf_local *lnb, int n)
1183{
1184	LASSERT(d);
1185	LASSERT(d->do_body_ops);
1186	LASSERT(d->do_body_ops->dbo_write_prep);
1187	return d->do_body_ops->dbo_write_prep(env, d, lnb, n);
1188}
1189
1190static inline int dt_declare_write_commit(const struct lu_env *env,
1191					  struct dt_object *d,
1192					  struct niobuf_local *lnb,
1193					  int n, struct thandle *th)
1194{
1195	LASSERTF(d != NULL, "dt is NULL when we want to declare write\n");
1196	LASSERT(th != NULL);
1197	return d->do_body_ops->dbo_declare_write_commit(env, d, lnb, n, th);
1198}
1199
1200
1201static inline int dt_write_commit(const struct lu_env *env,
1202				  struct dt_object *d, struct niobuf_local *lnb,
1203				  int n, struct thandle *th)
1204{
1205	LASSERT(d);
1206	LASSERT(d->do_body_ops);
1207	LASSERT(d->do_body_ops->dbo_write_commit);
1208	return d->do_body_ops->dbo_write_commit(env, d, lnb, n, th);
1209}
1210
1211static inline int dt_read_prep(const struct lu_env *env, struct dt_object *d,
1212			       struct niobuf_local *lnb, int n)
1213{
1214	LASSERT(d);
1215	LASSERT(d->do_body_ops);
1216	LASSERT(d->do_body_ops->dbo_read_prep);
1217	return d->do_body_ops->dbo_read_prep(env, d, lnb, n);
1218}
1219
1220static inline int dt_declare_punch(const struct lu_env *env,
1221				   struct dt_object *dt, __u64 start,
1222				   __u64 end, struct thandle *th)
1223{
1224	LASSERT(dt);
1225	LASSERT(dt->do_body_ops);
1226	LASSERT(dt->do_body_ops->dbo_declare_punch);
1227	return dt->do_body_ops->dbo_declare_punch(env, dt, start, end, th);
1228}
1229
1230static inline int dt_punch(const struct lu_env *env, struct dt_object *dt,
1231			   __u64 start, __u64 end, struct thandle *th,
1232			   struct lustre_capa *capa)
1233{
1234	LASSERT(dt);
1235	LASSERT(dt->do_body_ops);
1236	LASSERT(dt->do_body_ops->dbo_punch);
1237	return dt->do_body_ops->dbo_punch(env, dt, start, end, th, capa);
1238}
1239
1240static inline int dt_fiemap_get(const struct lu_env *env, struct dt_object *d,
1241				struct ll_user_fiemap *fm)
1242{
1243	LASSERT(d);
1244	if (d->do_body_ops == NULL)
1245		return -EPROTO;
1246	if (d->do_body_ops->dbo_fiemap_get == NULL)
1247		return -EOPNOTSUPP;
1248	return d->do_body_ops->dbo_fiemap_get(env, d, fm);
1249}
1250
1251static inline int dt_statfs(const struct lu_env *env, struct dt_device *dev,
1252			    struct obd_statfs *osfs)
1253{
1254	LASSERT(dev);
1255	LASSERT(dev->dd_ops);
1256	LASSERT(dev->dd_ops->dt_statfs);
1257	return dev->dd_ops->dt_statfs(env, dev, osfs);
1258}
1259
1260static inline int dt_root_get(const struct lu_env *env, struct dt_device *dev,
1261			      struct lu_fid *f)
1262{
1263	LASSERT(dev);
1264	LASSERT(dev->dd_ops);
1265	LASSERT(dev->dd_ops->dt_root_get);
1266	return dev->dd_ops->dt_root_get(env, dev, f);
1267}
1268
1269static inline void dt_conf_get(const struct lu_env *env,
1270			       const struct dt_device *dev,
1271			       struct dt_device_param *param)
1272{
1273	LASSERT(dev);
1274	LASSERT(dev->dd_ops);
1275	LASSERT(dev->dd_ops->dt_conf_get);
1276	return dev->dd_ops->dt_conf_get(env, dev, param);
1277}
1278
1279static inline int dt_sync(const struct lu_env *env, struct dt_device *dev)
1280{
1281	LASSERT(dev);
1282	LASSERT(dev->dd_ops);
1283	LASSERT(dev->dd_ops->dt_sync);
1284	return dev->dd_ops->dt_sync(env, dev);
1285}
1286
1287static inline int dt_ro(const struct lu_env *env, struct dt_device *dev)
1288{
1289	LASSERT(dev);
1290	LASSERT(dev->dd_ops);
1291	LASSERT(dev->dd_ops->dt_ro);
1292	return dev->dd_ops->dt_ro(env, dev);
1293}
1294
1295static inline int dt_declare_insert(const struct lu_env *env,
1296				    struct dt_object *dt,
1297				    const struct dt_rec *rec,
1298				    const struct dt_key *key,
1299				    struct thandle *th)
1300{
1301	LASSERT(dt);
1302	LASSERT(dt->do_index_ops);
1303	LASSERT(dt->do_index_ops->dio_declare_insert);
1304	return dt->do_index_ops->dio_declare_insert(env, dt, rec, key, th);
1305}
1306
1307static inline int dt_insert(const struct lu_env *env,
1308				    struct dt_object *dt,
1309				    const struct dt_rec *rec,
1310				    const struct dt_key *key,
1311				    struct thandle *th,
1312				    struct lustre_capa *capa,
1313				    int noquota)
1314{
1315	LASSERT(dt);
1316	LASSERT(dt->do_index_ops);
1317	LASSERT(dt->do_index_ops->dio_insert);
1318	return dt->do_index_ops->dio_insert(env, dt, rec, key, th,
1319					    capa, noquota);
1320}
1321
1322static inline int dt_declare_xattr_del(const struct lu_env *env,
1323				       struct dt_object *dt,
1324				       const char *name,
1325				       struct thandle *th)
1326{
1327	LASSERT(dt);
1328	LASSERT(dt->do_ops);
1329	LASSERT(dt->do_ops->do_declare_xattr_del);
1330	return dt->do_ops->do_declare_xattr_del(env, dt, name, th);
1331}
1332
1333static inline int dt_xattr_del(const struct lu_env *env,
1334			       struct dt_object *dt, const char *name,
1335			       struct thandle *th,
1336			       struct lustre_capa *capa)
1337{
1338	LASSERT(dt);
1339	LASSERT(dt->do_ops);
1340	LASSERT(dt->do_ops->do_xattr_del);
1341	return dt->do_ops->do_xattr_del(env, dt, name, th, capa);
1342}
1343
1344static inline int dt_declare_xattr_set(const struct lu_env *env,
1345				      struct dt_object *dt,
1346				      const struct lu_buf *buf,
1347				      const char *name, int fl,
1348				      struct thandle *th)
1349{
1350	LASSERT(dt);
1351	LASSERT(dt->do_ops);
1352	LASSERT(dt->do_ops->do_declare_xattr_set);
1353	return dt->do_ops->do_declare_xattr_set(env, dt, buf, name, fl, th);
1354}
1355
1356static inline int dt_xattr_set(const struct lu_env *env,
1357			      struct dt_object *dt, const struct lu_buf *buf,
1358			      const char *name, int fl, struct thandle *th,
1359			      struct lustre_capa *capa)
1360{
1361	LASSERT(dt);
1362	LASSERT(dt->do_ops);
1363	LASSERT(dt->do_ops->do_xattr_set);
1364	return dt->do_ops->do_xattr_set(env, dt, buf, name, fl, th, capa);
1365}
1366
1367static inline int dt_xattr_get(const struct lu_env *env,
1368			      struct dt_object *dt, struct lu_buf *buf,
1369			      const char *name, struct lustre_capa *capa)
1370{
1371	LASSERT(dt);
1372	LASSERT(dt->do_ops);
1373	LASSERT(dt->do_ops->do_xattr_get);
1374	return dt->do_ops->do_xattr_get(env, dt, buf, name, capa);
1375}
1376
1377static inline int dt_xattr_list(const struct lu_env *env,
1378			       struct dt_object *dt, struct lu_buf *buf,
1379			       struct lustre_capa *capa)
1380{
1381	LASSERT(dt);
1382	LASSERT(dt->do_ops);
1383	LASSERT(dt->do_ops->do_xattr_list);
1384	return dt->do_ops->do_xattr_list(env, dt, buf, capa);
1385}
1386
1387static inline int dt_declare_delete(const struct lu_env *env,
1388				    struct dt_object *dt,
1389				    const struct dt_key *key,
1390				    struct thandle *th)
1391{
1392	LASSERT(dt);
1393	LASSERT(dt->do_index_ops);
1394	LASSERT(dt->do_index_ops->dio_declare_delete);
1395	return dt->do_index_ops->dio_declare_delete(env, dt, key, th);
1396}
1397
1398static inline int dt_delete(const struct lu_env *env,
1399			    struct dt_object *dt,
1400			    const struct dt_key *key,
1401			    struct thandle *th,
1402			    struct lustre_capa *capa)
1403{
1404	LASSERT(dt);
1405	LASSERT(dt->do_index_ops);
1406	LASSERT(dt->do_index_ops->dio_delete);
1407	return dt->do_index_ops->dio_delete(env, dt, key, th, capa);
1408}
1409
1410static inline int dt_commit_async(const struct lu_env *env,
1411				  struct dt_device *dev)
1412{
1413	LASSERT(dev);
1414	LASSERT(dev->dd_ops);
1415	LASSERT(dev->dd_ops->dt_commit_async);
1416	return dev->dd_ops->dt_commit_async(env, dev);
1417}
1418
1419static inline int dt_init_capa_ctxt(const struct lu_env *env,
1420				    struct dt_device *dev,
1421				    int mode, unsigned long timeout,
1422				    __u32 alg, struct lustre_capa_key *keys)
1423{
1424	LASSERT(dev);
1425	LASSERT(dev->dd_ops);
1426	LASSERT(dev->dd_ops->dt_init_capa_ctxt);
1427	return dev->dd_ops->dt_init_capa_ctxt(env, dev, mode,
1428					      timeout, alg, keys);
1429}
1430
1431static inline int dt_lookup(const struct lu_env *env,
1432			    struct dt_object *dt,
1433			    struct dt_rec *rec,
1434			    const struct dt_key *key,
1435			    struct lustre_capa *capa)
1436{
1437	int ret;
1438
1439	LASSERT(dt);
1440	LASSERT(dt->do_index_ops);
1441	LASSERT(dt->do_index_ops->dio_lookup);
1442
1443	ret = dt->do_index_ops->dio_lookup(env, dt, rec, key, capa);
1444	if (ret > 0)
1445		ret = 0;
1446	else if (ret == 0)
1447		ret = -ENOENT;
1448	return ret;
1449}
1450
1451#define LU221_BAD_TIME (0x80000000U + 24 * 3600)
1452
1453struct dt_find_hint {
1454	struct lu_fid	*dfh_fid;
1455	struct dt_device     *dfh_dt;
1456	struct dt_object     *dfh_o;
1457};
1458
1459struct dt_thread_info {
1460	char		     dti_buf[DT_MAX_PATH];
1461	struct dt_find_hint      dti_dfh;
1462	struct lu_attr	   dti_attr;
1463	struct lu_fid	    dti_fid;
1464	struct dt_object_format  dti_dof;
1465	struct lustre_mdt_attrs  dti_lma;
1466	struct lu_buf	    dti_lb;
1467	loff_t		   dti_off;
1468};
1469
1470extern struct lu_context_key dt_key;
1471
1472static inline struct dt_thread_info *dt_info(const struct lu_env *env)
1473{
1474	struct dt_thread_info *dti;
1475
1476	dti = lu_context_key_get(&env->le_ctx, &dt_key);
1477	LASSERT(dti);
1478	return dti;
1479}
1480
1481int dt_global_init(void);
1482void dt_global_fini(void);
1483
1484#if defined (CONFIG_PROC_FS)
1485int lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
1486			  int count, int *eof, void *data);
1487int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
1488			      int count, int *eof, void *data);
1489int lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off,
1490			     int count, int *eof, void *data);
1491int lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off,
1492			      int count, int *eof, void *data);
1493int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
1494			     int count, int *eof, void *data);
1495int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
1496			    int count, int *eof, void *data);
1497#endif /* CONFIG_PROC_FS */
1498
1499#endif /* __LUSTRE_DT_OBJECT_H */
1500