1d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
2d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER START
3d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
4d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
6d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is free software; you can redistribute it and/or modify
7d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * it under the terms of the GNU General Public License version 2 only,
8d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * as published by the Free Software Foundation.
9d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
10d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is distributed in the hope that it will be useful, but
11d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * WITHOUT ANY WARRANTY; without even the implied warranty of
12d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * General Public License version 2 for more details (a copy is included
14d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * in the LICENSE file that accompanied this code).
15d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
16d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * You should have received a copy of the GNU General Public License
17d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * version 2 along with this program; If not, see
18d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
20d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * CA 95054 USA or visit www.sun.com if you need additional information or
22d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * have any questions.
23d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
24d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER END
25d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
26d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
27d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Use is subject to license terms.
29d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
30d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2011, 2012, Intel Corporation.
31d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
32d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
33d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This file is part of Lustre, http://www.lustre.org/
34d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Lustre is a trademark of Sun Microsystems, Inc.
35d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
36d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * lustre/obdclass/dt_object.c
37d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
38d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Dt Object.
39d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Generic functions from dt_object.h
40d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
41d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Author: Nikita Danilov <nikita@clusterfs.com>
42d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
43d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
44d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define DEBUG_SUBSYSTEM S_CLASS
45d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
46610f73773a8d263f2a6efa21a18cedafa3f2763bGreg Kroah-Hartman#include "../include/obd.h"
47610f73773a8d263f2a6efa21a18cedafa3f2763bGreg Kroah-Hartman#include "../include/dt_object.h"
48d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/list.h>
49d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* fid_be_to_cpu() */
50610f73773a8d263f2a6efa21a18cedafa3f2763bGreg Kroah-Hartman#include "../include/lustre_fid.h"
51d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
52610f73773a8d263f2a6efa21a18cedafa3f2763bGreg Kroah-Hartman#include "../include/lustre_quota.h"
53d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
54d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* context key constructor/destructor: dt_global_key_init, dt_global_key_fini */
55d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoLU_KEY_INIT(dt_global, struct dt_thread_info);
56d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoLU_KEY_FINI(dt_global, struct dt_thread_info);
57d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
58d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct lu_context_key dt_key = {
59d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.lct_tags = LCT_MD_THREAD | LCT_DT_THREAD | LCT_MG_THREAD | LCT_LOCAL,
60d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.lct_init = dt_global_key_init,
61d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.lct_fini = dt_global_key_fini
62d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
63d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_key);
64d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
65d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* no lock is necessary to protect the list, because call-backs
66d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * are added during system startup. Please refer to "struct dt_device".
67d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
68d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_txn_callback_add(struct dt_device *dev, struct dt_txn_callback *cb)
69d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
70d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	list_add(&cb->dtc_linkage, &dev->dd_txn_callbacks);
71d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
72d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_txn_callback_add);
73d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
74d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_txn_callback_del(struct dt_device *dev, struct dt_txn_callback *cb)
75d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
76d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	list_del_init(&cb->dtc_linkage);
77d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
78d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_txn_callback_del);
79d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
80d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_txn_hook_start(const struct lu_env *env,
81d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		      struct dt_device *dev, struct thandle *th)
82d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
83d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = 0;
84d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_txn_callback *cb;
85d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
86d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (th->th_local)
87d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
88d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
89d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	list_for_each_entry(cb, &dev->dd_txn_callbacks, dtc_linkage) {
90d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (cb->dtc_txn_start == NULL ||
91d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    !(cb->dtc_tag & env->le_ctx.lc_tags))
92d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			continue;
93d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = cb->dtc_txn_start(env, th, cb->dtc_cookie);
94d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc < 0)
95d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			break;
96d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
97d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
98d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
99d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_txn_hook_start);
100d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
101d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn)
102d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
103d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device       *dev = txn->th_dev;
104d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_txn_callback *cb;
105d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		     rc = 0;
106d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
107d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (txn->th_local)
108d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
109d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
110d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	list_for_each_entry(cb, &dev->dd_txn_callbacks, dtc_linkage) {
111d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (cb->dtc_txn_stop == NULL ||
112d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    !(cb->dtc_tag & env->le_ctx.lc_tags))
113d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			continue;
114d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = cb->dtc_txn_stop(env, txn, cb->dtc_cookie);
115d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc < 0)
116d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			break;
117d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
118d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
119d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
120d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_txn_hook_stop);
121d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
122d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_txn_hook_commit(struct thandle *txn)
123d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
124d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_txn_callback *cb;
125d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
126d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (txn->th_local)
127d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return;
128d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
129d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	list_for_each_entry(cb, &txn->th_dev->dd_txn_callbacks,
130d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				dtc_linkage) {
131d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (cb->dtc_txn_commit)
132d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			cb->dtc_txn_commit(txn, cb->dtc_cookie);
133d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
134d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
135d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_txn_hook_commit);
136d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
137d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_device_init(struct dt_device *dev, struct lu_device_type *t)
138d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
139d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
140d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	INIT_LIST_HEAD(&dev->dd_txn_callbacks);
141d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return lu_device_init(&dev->dd_lu_dev, t);
142d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
143d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_device_init);
144d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
145d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_device_fini(struct dt_device *dev)
146d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
147d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lu_device_fini(&dev->dd_lu_dev);
148d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
149d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_device_fini);
150d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
151d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_object_init(struct dt_object *obj,
152d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		   struct lu_object_header *h, struct lu_device *d)
153d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
154d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
155d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return lu_object_init(&obj->do_lu, h, d);
156d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
157d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_object_init);
158d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
159d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_object_fini(struct dt_object *obj)
160d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
161d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lu_object_fini(&obj->do_lu);
162d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
163d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_object_fini);
164d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
165d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_try_as_dir(const struct lu_env *env, struct dt_object *obj)
166d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
167d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (obj->do_index_ops == NULL)
168d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		obj->do_ops->do_index_try(env, obj, &dt_directory_features);
169d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return obj->do_index_ops != NULL;
170d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
171d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_try_as_dir);
172d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
173d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoenum dt_format_type dt_mode_to_dft(__u32 mode)
174d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
175d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	enum dt_format_type result;
176d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
177d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	switch (mode & S_IFMT) {
178d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case S_IFDIR:
179d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		result = DFT_DIR;
180d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
181d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case S_IFREG:
182d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		result = DFT_REGULAR;
183d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
184d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case S_IFLNK:
185d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		result = DFT_SYM;
186d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
187d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case S_IFCHR:
188d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case S_IFBLK:
189d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case S_IFIFO:
190d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case S_IFSOCK:
191d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		result = DFT_NODE;
192d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
193d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	default:
194d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LBUG();
195d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
196d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
197d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return result;
198d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
199d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_mode_to_dft);
200d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
201d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
202d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * lookup fid for object named \a name in directory \a dir.
203d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
204d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
205d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_lookup_dir(const struct lu_env *env, struct dt_object *dir,
206d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		  const char *name, struct lu_fid *fid)
207d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
208d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (dt_try_as_dir(env, dir))
209d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return dt_lookup(env, dir, (struct dt_rec *)fid,
210d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 (const struct dt_key *)name, BYPASS_CAPA);
211d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return -ENOTDIR;
212d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
213d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_lookup_dir);
214d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
215d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* this differs from dt_locate by top_dev as parameter
216d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * but not one from lu_site */
217d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct dt_object *dt_locate_at(const struct lu_env *env,
218d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       struct dt_device *dev, const struct lu_fid *fid,
219d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       struct lu_device *top_dev)
220d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
221d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_object *lo, *n;
222d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
223d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lo = lu_object_find_at(env, top_dev, fid, NULL);
224d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(lo))
225d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return (void *)lo;
226d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
227d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(lo != NULL);
228d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
229d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	list_for_each_entry(n, &lo->lo_header->loh_layers, lo_linkage) {
230d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (n->lo_dev == &dev->dd_lu_dev)
231d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return container_of0(n, struct dt_object, do_lu);
232d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
233d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return ERR_PTR(-ENOENT);
234d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
235d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_locate_at);
236d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
237d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
238d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * find a object named \a entry in given \a dfh->dfh_o directory.
239d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
240d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int dt_find_entry(const struct lu_env *env, const char *entry, void *data)
241d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
242d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_find_hint  *dfh = data;
243d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device     *dt = dfh->dfh_dt;
244d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_fid	*fid = dfh->dfh_fid;
245d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object     *obj = dfh->dfh_o;
246d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		   result;
247d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
248d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	result = dt_lookup_dir(env, obj, entry, fid);
249d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lu_object_put(env, &obj->do_lu);
250d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (result == 0) {
251d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		obj = dt_locate(env, dt, fid);
252d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (IS_ERR(obj))
253d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result = PTR_ERR(obj);
254d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
255d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dfh->dfh_o = obj;
256d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return result;
257d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
258d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
259d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
260d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Abstract function which parses path name. This function feeds
261d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * path component to \a entry_func.
262d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
263d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_path_parser(const struct lu_env *env,
264d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		   char *path, dt_entry_func_t entry_func,
265d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		   void *data)
266d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
267d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *e;
268d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = 0;
269d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
270d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	while (1) {
271d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		e = strsep(&path, "/");
272d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (e == NULL)
273d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			break;
274d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
275d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (e[0] == 0) {
276d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (!path || path[0] == '\0')
277d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				break;
278d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			continue;
279d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
280d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = entry_func(env, e, data);
281d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc)
282d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			break;
283d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
284d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
285d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
286d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
287d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
288d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct dt_object *
289d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taodt_store_resolve(const struct lu_env *env, struct dt_device *dt,
290d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 const char *path, struct lu_fid *fid)
291d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
292d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_thread_info *info = dt_info(env);
293d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_find_hint   *dfh = &info->dti_dfh;
294d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object      *obj;
295d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char		      *local = info->dti_buf;
296d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		       result;
297d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
298d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
299d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dfh->dfh_dt = dt;
300d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dfh->dfh_fid = fid;
301d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
302d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	strncpy(local, path, DT_MAX_PATH);
303d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	local[DT_MAX_PATH - 1] = '\0';
304d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
305d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	result = dt->dd_ops->dt_root_get(env, dt, fid);
306d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (result == 0) {
307d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		obj = dt_locate(env, dt, fid);
308d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!IS_ERR(obj)) {
309d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			dfh->dfh_o = obj;
310d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result = dt_path_parser(env, local, dt_find_entry, dfh);
311d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (result != 0)
312d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				obj = ERR_PTR(result);
313d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			else
314d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				obj = dfh->dfh_o;
315d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
316d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
317d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		obj = ERR_PTR(result);
318d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
319d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return obj;
320d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
321d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_store_resolve);
322d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
323d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct dt_object *dt_reg_open(const struct lu_env *env,
324d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     struct dt_device *dt,
325d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     struct dt_object *p,
326d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     const char *name,
327d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     struct lu_fid *fid)
328d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
329d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object *o;
330d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int result;
331d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
332d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	result = dt_lookup_dir(env, p, name, fid);
333d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (result == 0){
334d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		o = dt_locate(env, dt, fid);
335d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
336d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else
337d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		o = ERR_PTR(result);
338d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
339d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return o;
340d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
341d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
342d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
343d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Open dt object named \a filename from \a dirname directory.
344d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *      \param  dt      dt device
345d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *      \param  fid     on success, object fid is stored in *fid
346d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
347d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct dt_object *dt_store_open(const struct lu_env *env,
348d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				struct dt_device *dt,
349d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				const char *dirname,
350d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				const char *filename,
351d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				struct lu_fid *fid)
352d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
353d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object *file;
354d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object *dir;
355d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
356d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dir = dt_store_resolve(env, dt, dirname, fid);
357d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!IS_ERR(dir)) {
358d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		file = dt_reg_open(env, dt, dir,
359d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				   filename, fid);
360d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lu_object_put(env, &dir->do_lu);
361d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
362d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		file = dir;
363d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
364d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return file;
365d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
366d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_store_open);
367d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
368d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct dt_object *dt_find_or_create(const struct lu_env *env,
369d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    struct dt_device *dt,
370d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    const struct lu_fid *fid,
371d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    struct dt_object_format *dof,
372d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    struct lu_attr *at)
373d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
374d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object *dto;
375d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct thandle *th;
376d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
377d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
378d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dto = dt_locate(env, dt, fid);
379d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(dto))
3800a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return dto;
381d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
382d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(dto != NULL);
383d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (dt_object_exists(dto))
3840a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return dto;
385d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
386d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	th = dt_trans_create(env, dt);
387d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	if (IS_ERR(th)) {
388d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		rc = PTR_ERR(th);
389d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto out;
390d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	}
391d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
392d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_declare_create(env, dto, at, NULL, dof, th);
393d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
394d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto trans_stop;
395d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
396d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_trans_start_local(env, dt, th);
397d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
398d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto trans_stop;
399d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
400d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_write_lock(env, dto, 0);
401d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	if (dt_object_exists(dto)) {
402d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		rc = 0;
403d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto unlock;
404d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	}
405d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
406d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	CDEBUG(D_OTHER, "create new object "DFID"\n", PFID(fid));
407d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
408d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_create(env, dto, at, NULL, dof, th);
409d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
410d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto unlock;
411d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(dt_object_exists(dto));
412d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taounlock:
413d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_write_unlock(env, dto);
414d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taotrans_stop:
415d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_trans_stop(env, dt, th);
416d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
417d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
418d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lu_object_put(env, &dto->do_lu);
4190a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return ERR_PTR(rc);
420d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
4210a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return dto;
422d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
423d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_find_or_create);
424d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
425d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* dt class init function. */
426d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_global_init(void)
427d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
428d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int result;
429d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
430d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LU_CONTEXT_KEY_INIT(&dt_key);
431d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	result = lu_context_key_register(&dt_key);
432d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return result;
433d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
434d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
435d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_global_fini(void)
436d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
437d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lu_context_key_degister(&dt_key);
438d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
439d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
440d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
441d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Generic read helper. May return an error for partial reads.
442d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
443d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env  lustre environment
444d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param dt   object to be read
445d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param buf  lu_buf to be filled, with buffer pointer and length
446d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param pos position to start reading, updated as data is read
447d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
448d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval real size of data read
449d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -ve errno on failure
450d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
451d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_read(const struct lu_env *env, struct dt_object *dt,
452d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    struct lu_buf *buf, loff_t *pos)
453d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
454d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(dt != NULL, "dt is NULL when we want to read record\n");
455d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return dt->do_body_ops->dbo_read(env, dt, buf, pos, BYPASS_CAPA);
456d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
457d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_read);
458d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
459d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
460d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Read structures of fixed size from storage.  Unlike dt_read(), using
461d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * dt_record_read() will return an error for partial reads.
462d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
463d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env  lustre environment
464d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param dt   object to be read
465d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param buf  lu_buf to be filled, with buffer pointer and length
466d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param pos position to start reading, updated as data is read
467d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
468d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval 0 on successfully reading full buffer
469d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -EFAULT on short read
470d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -ve errno on failure
471d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
472d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_record_read(const struct lu_env *env, struct dt_object *dt,
473d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		   struct lu_buf *buf, loff_t *pos)
474d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
475d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
476d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
477d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(dt != NULL, "dt is NULL when we want to read record\n");
478d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
479d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt->do_body_ops->dbo_read(env, dt, buf, pos, BYPASS_CAPA);
480d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
481d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == buf->lb_len)
482d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = 0;
483d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else if (rc >= 0)
484d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = -EFAULT;
485d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
486d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
487d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_record_read);
488d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
489d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_record_write(const struct lu_env *env, struct dt_object *dt,
490d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    const struct lu_buf *buf, loff_t *pos, struct thandle *th)
491d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
492d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
493d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
494d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(dt != NULL, "dt is NULL when we want to write record\n");
495d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(th != NULL);
496d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(dt->do_body_ops);
497d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(dt->do_body_ops->dbo_write);
498d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt->do_body_ops->dbo_write(env, dt, buf, pos, th, BYPASS_CAPA, 1);
499d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == buf->lb_len)
500d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = 0;
501d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else if (rc >= 0)
502d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = -EFAULT;
503d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
504d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
505d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_record_write);
506d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
507d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
508d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   struct thandle *th)
509d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
510d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_buf vbuf;
511d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *xname = XATTR_NAME_VERSION;
512d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
513d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(o);
514d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_buf = NULL;
515d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_len = sizeof(dt_obj_version_t);
516d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return dt_declare_xattr_set(env, o, &vbuf, xname, 0, th);
517d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
518d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
519d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_declare_version_set);
520d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
521d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_version_set(const struct lu_env *env, struct dt_object *o,
522d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    dt_obj_version_t version, struct thandle *th)
523d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
524d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_buf vbuf;
525d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *xname = XATTR_NAME_VERSION;
526d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
527d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
528d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(o);
529d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_buf = &version;
530d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_len = sizeof(version);
531d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
532d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_xattr_set(env, o, &vbuf, xname, 0, th, BYPASS_CAPA);
533d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0)
534d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CDEBUG(D_INODE, "Can't set version, rc %d\n", rc);
535d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return;
536d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
537d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_version_set);
538d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
539d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taodt_obj_version_t dt_version_get(const struct lu_env *env, struct dt_object *o)
540d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
541d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_buf vbuf;
542d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *xname = XATTR_NAME_VERSION;
543d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_obj_version_t version;
544d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
545d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
546d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(o);
547d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_buf = &version;
548d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_len = sizeof(version);
549d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_xattr_get(env, o, &vbuf, xname, BYPASS_CAPA);
550d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc != sizeof(version)) {
551d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CDEBUG(D_INODE, "Can't get version, rc %d\n", rc);
552d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		version = 0;
553d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
554d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return version;
555d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
556d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_version_get);
557d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
558d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* list of all supported index types */
559d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
560d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* directories */
561d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_directory_features;
562d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_directory_features);
563d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
564d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* scrub iterator */
565d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_otable_features;
566d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_otable_features);
567d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
568d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* lfsck */
569d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_lfsck_features = {
570d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
571d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(struct lu_fid),
572d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(struct lu_fid),
573d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(__u8),
574d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(__u8),
575d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
576d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
577d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_lfsck_features);
578d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
579d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* accounting indexes */
580d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_acct_features = {
581d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
582d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(__u64), /* 64-bit uid/gid */
583d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(__u64), /* 64-bit uid/gid */
584d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(struct lquota_acct_rec), /* 16 bytes */
585d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(struct lquota_acct_rec), /* 16 bytes */
586d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
587d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
588d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_acct_features);
589d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
590d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* global quota files */
591d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_quota_glb_features = {
592d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
593d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* a different key would have to be used for per-directory quota */
594d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(__u64), /* 64-bit uid/gid */
595d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(__u64), /* 64-bit uid/gid */
596d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(struct lquota_glb_rec), /* 32 bytes */
597d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(struct lquota_glb_rec), /* 32 bytes */
598d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
599d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
600d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_quota_glb_features);
601d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
602d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* slave quota files */
603d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_quota_slv_features = {
604d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
605d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* a different key would have to be used for per-directory quota */
606d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(__u64), /* 64-bit uid/gid */
607d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(__u64), /* 64-bit uid/gid */
608d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(struct lquota_slv_rec), /* 8 bytes */
609d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(struct lquota_slv_rec), /* 8 bytes */
610d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
611d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
612d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_quota_slv_features);
613d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
614d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* helper function returning what dt_index_features structure should be used
615d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * based on the FID sequence. This is used by OBD_IDX_READ RPC */
616d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic inline const struct dt_index_features *dt_index_feat_select(__u64 seq,
617d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao								   __u32 mode)
618d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
619d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (seq == FID_SEQ_QUOTA_GLB) {
620d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* global quota index */
621d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!S_ISREG(mode))
622d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* global quota index should be a regular file */
623d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return ERR_PTR(-ENOENT);
624d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return &dt_quota_glb_features;
625d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else if (seq == FID_SEQ_QUOTA) {
626d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* quota slave index */
627d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!S_ISREG(mode))
628d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* slave index should be a regular file */
629d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return ERR_PTR(-ENOENT);
630d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return &dt_quota_slv_features;
631d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else if (seq >= FID_SEQ_NORMAL) {
632d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* object is part of the namespace, verify that it is a
633d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * directory */
634d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!S_ISDIR(mode))
635d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* sorry, we can only deal with directory */
636d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return ERR_PTR(-ENOTDIR);
637d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return &dt_directory_features;
638d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
639d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
640d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return ERR_PTR(-EOPNOTSUPP);
641d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
642d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
643d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
644d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Fill a lu_idxpage with key/record pairs read for transfer via OBD_IDX_READ
645d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * RPC
646d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
647d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env - is the environment passed by the caller
648d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param lp  - is a pointer to the lu_page to fill
649d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param nob - is the maximum number of bytes that should be copied
650d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param iops - is the index operation vector associated with the index object
651d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param it   - is a pointer to the current iterator
652d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param attr - is the index attribute to pass to iops->rec()
653d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param arg  - is a pointer to the idx_info structure
654d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
655d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int dt_index_page_build(const struct lu_env *env, union lu_page *lp,
656d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       int nob, const struct dt_it_ops *iops,
657d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       struct dt_it *it, __u32 attr, void *arg)
658d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
659d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct idx_info		*ii = (struct idx_info *)arg;
660d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_idxpage	*lip = &lp->lp_idx;
661d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char			*entry;
662d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			 rc, size;
663d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
664d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* no support for variable key & record size for now */
665d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT((ii->ii_flags & II_FL_VARKEY) == 0);
666d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT((ii->ii_flags & II_FL_VARREC) == 0);
667d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
668d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* initialize the header of the new container */
669d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	memset(lip, 0, LIP_HDR_SIZE);
670d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lip->lip_magic = LIP_MAGIC;
671d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	nob	   -= LIP_HDR_SIZE;
672d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
673d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* compute size needed to store a key/record pair */
674d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	size = ii->ii_recsize + ii->ii_keysize;
675d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((ii->ii_flags & II_FL_NOHASH) == 0)
676d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* add hash if the client wants it */
677d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		size += sizeof(__u64);
678d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
679d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	entry = lip->lip_entries;
680d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	do {
681d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		char		*tmp_entry = entry;
682d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		struct dt_key	*key;
683d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64		 hash;
684d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
685d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* fetch 64-bit hash value */
686d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		hash = iops->store(env, it);
687d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_hash_end = hash;
688d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
689d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_IDX_READ_BREAK)) {
690d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall			if (lip->lip_nr != 0) {
691d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall				rc = 0;
692d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall				goto out;
693d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall			}
694d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
695d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
696d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (nob < size) {
697d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (lip->lip_nr == 0)
69809c8a87ce62e858a048ca958faffc16acacfbc4eJulia Lawall				rc = -EINVAL;
69909c8a87ce62e858a048ca958faffc16acacfbc4eJulia Lawall			else
70009c8a87ce62e858a048ca958faffc16acacfbc4eJulia Lawall				rc = 0;
70109c8a87ce62e858a048ca958faffc16acacfbc4eJulia Lawall			goto out;
702d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
703d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
704d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if ((ii->ii_flags & II_FL_NOHASH) == 0) {
705d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* client wants to the 64-bit hash value associated with
706d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 * each record */
707d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			memcpy(tmp_entry, &hash, sizeof(hash));
708d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			tmp_entry += sizeof(hash);
709d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
710d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
711d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* then the key value */
712d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(iops->key_size(env, it) == ii->ii_keysize);
713d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		key = iops->key(env, it);
714d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		memcpy(tmp_entry, key, ii->ii_keysize);
715d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		tmp_entry += ii->ii_keysize;
716d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
717d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* and finally the record */
718d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = iops->rec(env, it, (struct dt_rec *)tmp_entry, attr);
719d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc != -ESTALE) {
720d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (rc != 0)
721d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall				goto out;
722d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
723d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* hash/key/record successfully copied! */
724d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			lip->lip_nr++;
725d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (unlikely(lip->lip_nr == 1 && ii->ii_count == 0))
726d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				ii->ii_hash_start = hash;
727d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			entry = tmp_entry + ii->ii_recsize;
728d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			nob -= size;
729d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
730d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
731d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* move on to the next record */
732d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		do {
733d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			rc = iops->next(env, it);
734d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		} while (rc == -ESTALE);
735d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
736d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} while (rc == 0);
737d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
738d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	goto out;
739d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
740d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc >= 0 && lip->lip_nr > 0)
741d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* one more container */
742d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_count++;
743d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc > 0)
744d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* no more entries */
745d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_hash_end = II_END_OFF;
746d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
747d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
748d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
749d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
750d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Walk index and fill lu_page containers with key/record pairs
751d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
752d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env - is the environment passed by the caller
753d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param obj - is the index object to parse
754d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param rdpg - is the lu_rdpg descriptor associated with the transfer
755d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param filler - is the callback function responsible for filling a lu_page
756d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *		 with key/record pairs in the format wanted by the caller
757d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param arg    - is an opaq argument passed to the filler function
758d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
759d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval sum (in bytes) of all filled lu_pages
760d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -ve errno on failure
761d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
762d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_index_walk(const struct lu_env *env, struct dt_object *obj,
763d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		  const struct lu_rdpg *rdpg, dt_index_page_build_t filler,
764d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		  void *arg)
765d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
766d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_it		*it;
767d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	const struct dt_it_ops	*iops;
768d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned int		 pageidx, nob, nlupgs = 0;
769d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			 rc;
770d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
771d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(rdpg->rp_pages != NULL);
772d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(obj->do_index_ops != NULL);
773d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
774d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	nob = rdpg->rp_count;
775d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (nob <= 0)
7760a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EFAULT;
777d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
778d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* Iterate through index and fill containers from @rdpg */
779d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	iops = &obj->do_index_ops->dio_it;
780d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(iops != NULL);
781d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	it = iops->init(env, obj, rdpg->rp_attrs, BYPASS_CAPA);
782d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(it))
7830a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return PTR_ERR(it);
784d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
785d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = iops->load(env, it, rdpg->rp_hash);
786d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == 0) {
787d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/*
788d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * Iterator didn't find record with exactly the key requested.
789d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *
790d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * It is currently either
791d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *
792d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     - positioned above record with key less than
793d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     requested---skip it.
794d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     - or not positioned at all (is in IAM_IT_SKEWED
795d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     state)---position it on the next item.
796d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 */
797d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = iops->next(env, it);
798d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else if (rc > 0) {
799d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = 0;
800d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
801d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
802d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* Fill containers one after the other. There might be multiple
803d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * containers per physical page.
804d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *
805d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * At this point and across for-loop:
806d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *  rc == 0 -> ok, proceed.
807d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *  rc >  0 -> end of index.
808d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *  rc <  0 -> error. */
809d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (pageidx = 0; rc == 0 && nob > 0; pageidx++) {
810d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		union lu_page	*lp;
811d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		int		 i;
812d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
813d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(pageidx < rdpg->rp_npages);
814d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lp = kmap(rdpg->rp_pages[pageidx]);
815d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
816d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* fill lu pages */
817d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		for (i = 0; i < LU_PAGE_COUNT; i++, lp++, nob -= LU_PAGE_SIZE) {
818d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			rc = filler(env, lp, min_t(int, nob, LU_PAGE_SIZE),
819d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    iops, it, rdpg->rp_attrs, arg);
820d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (rc < 0)
821d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				break;
822d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* one more lu_page */
823d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			nlupgs++;
824d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (rc > 0)
825d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				/* end of index */
826d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				break;
827d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
828d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		kunmap(rdpg->rp_pages[i]);
829d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
830d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
831d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	iops->put(env, it);
832d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	iops->fini(env, it);
833d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
834d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc >= 0)
835d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = min_t(unsigned int, nlupgs * LU_PAGE_SIZE, rdpg->rp_count);
836d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
8370a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return rc;
838d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
839d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_index_walk);
840d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
841d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
842d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Walk key/record pairs of an index and copy them into 4KB containers to be
843d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * transferred over the network. This is the common handler for OBD_IDX_READ
844d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * RPC processing.
845d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
846d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env - is the environment passed by the caller
847d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param dev - is the dt_device storing the index
848d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param ii  - is the idx_info structure packed by the client in the
849d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *	      OBD_IDX_READ request
850d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param rdpg - is the lu_rdpg descriptor
851d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
852d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval on success, return sum (in bytes) of all filled containers
853d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval appropriate error otherwise.
854d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
855d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_index_read(const struct lu_env *env, struct dt_device *dev,
856d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		  struct idx_info *ii, const struct lu_rdpg *rdpg)
857d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
858d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	const struct dt_index_features	*feat;
859d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object		*obj;
860d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				 rc;
861d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
862d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* rp_count shouldn't be null and should be a multiple of the container
863d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * size */
864d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rdpg->rp_count <= 0 && (rdpg->rp_count & (LU_PAGE_SIZE - 1)) != 0)
8650a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EFAULT;
866d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
867d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (fid_seq(&ii->ii_fid) >= FID_SEQ_NORMAL)
868d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* we don't support directory transfer via OBD_IDX_READ for the
869d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * time being */
8700a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EOPNOTSUPP;
871d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
872d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!fid_is_quota(&ii->ii_fid))
873d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* block access to all local files except quota files */
8740a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPERM;
875d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
876d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* lookup index object subject to the transfer */
877d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	obj = dt_locate(env, dev, &ii->ii_fid);
878d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(obj))
8790a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return PTR_ERR(obj);
880d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	if (dt_object_exists(obj) == 0) {
881d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		rc = -ENOENT;
882d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto out;
883d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	}
884d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
885d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* fetch index features associated with index object */
886d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	feat = dt_index_feat_select(fid_seq(&ii->ii_fid),
887d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    lu_object_attr(&obj->do_lu));
888d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	if (IS_ERR(feat)) {
889d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		rc = PTR_ERR(feat);
890d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto out;
891d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	}
892d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
893d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* load index feature if not done already */
894d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (obj->do_index_ops == NULL) {
895d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = obj->do_ops->do_index_try(env, obj, feat);
896d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc)
897d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall			goto out;
898d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
899d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
900d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* fill ii_flags with supported index features */
901d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_flags &= II_FL_NOHASH;
902d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
903d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_keysize = feat->dif_keysize_max;
904d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((feat->dif_flags & DT_IND_VARKEY) != 0) {
905d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* key size is variable */
906d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_flags |= II_FL_VARKEY;
907d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* we don't support variable key size for the time being */
908d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		rc = -EOPNOTSUPP;
909d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto out;
910d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
911d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
912d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_recsize = feat->dif_recsize_max;
913d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((feat->dif_flags & DT_IND_VARREC) != 0) {
914d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* record size is variable */
915d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_flags |= II_FL_VARREC;
916d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* we don't support variable record size for the time being */
917d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		rc = -EOPNOTSUPP;
918d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall		goto out;
919d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
920d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
921d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((feat->dif_flags & DT_IND_NONUNQ) != 0)
922d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* key isn't necessarily unique */
923d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_flags |= II_FL_NONUNQ;
924d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
925d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_read_lock(env, obj, 0);
926d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* fetch object version before walking the index */
927d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_version = dt_version_get(env, obj);
928d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
929d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* walk the index and fill lu_idxpages with key/record pairs */
930d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_index_walk(env, obj, rdpg, dt_index_page_build ,ii);
931d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_read_unlock(env, obj);
932d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
933d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == 0) {
934d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* index is empty */
935d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(ii->ii_count == 0);
936d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_hash_end = II_END_OFF;
937d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
938d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
939d212afd9458a04f6c16f3d5d701593b915d526b0Julia Lawall	goto out;
940d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
941d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lu_object_put(env, &obj->do_lu);
942d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
943d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
944d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_index_read);
945d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
946f267cdb464bcab7be965fa2a513675d9ad1e90f6Greg Kroah-Hartman#if defined (CONFIG_PROC_FS)
947d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
948d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
949d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			  int count, int *eof, void *data)
950d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
951d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
952d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
953d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
954d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
9556715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
956d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
9576715e395daec8179db174250631a74c282cb580dJohn L. Hammond		rc = snprintf(page, count, "%u\n",
958d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				(unsigned) osfs.os_bsize);
959d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
960d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
961d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
962d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
963d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_blksize);
964d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
965d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
966d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			      int count, int *eof, void *data)
967d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
968d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
969d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
970d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
971d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
9726715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
973d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 blk_size = osfs.os_bsize >> 10;
974d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64 result = osfs.os_blocks;
975d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
976d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (blk_size >>= 1)
977d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result <<= 1;
978d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
979d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
980b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman		rc = snprintf(page, count, "%llu\n", result);
981d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
982d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
983d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
984d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
985d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_kbytestotal);
986d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
987d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off,
988d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     int count, int *eof, void *data)
989d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
990d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
991d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
992d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
993d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
9946715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
995d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 blk_size = osfs.os_bsize >> 10;
996d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64 result = osfs.os_bfree;
997d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
998d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (blk_size >>= 1)
999d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result <<= 1;
1000d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1001d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
1002b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman		rc = snprintf(page, count, "%llu\n", result);
1003d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1004d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1005d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1006d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1007d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_kbytesfree);
1008d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1009d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off,
1010d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			      int count, int *eof, void *data)
1011d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1012d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
1013d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
1014d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1015d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
10166715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
1017d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 blk_size = osfs.os_bsize >> 10;
1018d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64 result = osfs.os_bavail;
1019d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1020d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (blk_size >>= 1)
1021d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result <<= 1;
1022d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1023d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
1024b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman		rc = snprintf(page, count, "%llu\n", result);
1025d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1026d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1027d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1028d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1029d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_kbytesavail);
1030d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1031d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
1032d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     int count, int *eof, void *data)
1033d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1034d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
1035d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
1036d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1037d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
10386715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
1039d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
1040b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman		rc = snprintf(page, count, "%llu\n", osfs.os_files);
1041d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1042d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1043d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1044d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1045d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_filestotal);
1046d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1047d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
1048d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			    int count, int *eof, void *data)
1049d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1050d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
1051d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
1052d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1053d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
10546715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
1055d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
1056b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman		rc = snprintf(page, count, "%llu\n", osfs.os_ffree);
1057d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1058d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1059d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1060d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1061d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_filesfree);
1062d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1063f267cdb464bcab7be965fa2a513675d9ad1e90f6Greg Kroah-Hartman#endif /* CONFIG_PROC_FS */
1064