dt_object.c revision 0a3bdb00710bf253ba8ba8f645645f22297c7a04
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
46d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <obd.h>
47d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <dt_object.h>
48d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <linux/list.h>
49d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* fid_be_to_cpu() */
50d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include <lustre_fid.h>
51d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
52d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#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);
387d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(th))
388d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(out, rc = PTR_ERR(th));
389d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
390d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_declare_create(env, dto, at, NULL, dof, th);
391d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
392d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(trans_stop, rc);
393d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
394d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_trans_start_local(env, dt, th);
395d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
396d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(trans_stop, rc);
397d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
398d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_write_lock(env, dto, 0);
399d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (dt_object_exists(dto))
400d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(unlock, rc = 0);
401d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
402d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	CDEBUG(D_OTHER, "create new object "DFID"\n", PFID(fid));
403d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
404d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_create(env, dto, at, NULL, dof, th);
405d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
406d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(unlock, rc);
407d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(dt_object_exists(dto));
408d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taounlock:
409d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_write_unlock(env, dto);
410d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taotrans_stop:
411d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_trans_stop(env, dt, th);
412d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
413d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
414d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lu_object_put(env, &dto->do_lu);
4150a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return ERR_PTR(rc);
416d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
4170a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return dto;
418d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
419d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_find_or_create);
420d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
421d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* dt class init function. */
422d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_global_init(void)
423d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
424d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int result;
425d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
426d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LU_CONTEXT_KEY_INIT(&dt_key);
427d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	result = lu_context_key_register(&dt_key);
428d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return result;
429d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
430d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
431d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_global_fini(void)
432d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
433d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lu_context_key_degister(&dt_key);
434d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
435d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
436d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
437d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Generic read helper. May return an error for partial reads.
438d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
439d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env  lustre environment
440d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param dt   object to be read
441d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param buf  lu_buf to be filled, with buffer pointer and length
442d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param pos position to start reading, updated as data is read
443d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
444d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval real size of data read
445d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -ve errno on failure
446d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
447d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_read(const struct lu_env *env, struct dt_object *dt,
448d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    struct lu_buf *buf, loff_t *pos)
449d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
450d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(dt != NULL, "dt is NULL when we want to read record\n");
451d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return dt->do_body_ops->dbo_read(env, dt, buf, pos, BYPASS_CAPA);
452d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
453d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_read);
454d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
455d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
456d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Read structures of fixed size from storage.  Unlike dt_read(), using
457d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * dt_record_read() will return an error for partial reads.
458d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
459d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env  lustre environment
460d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param dt   object to be read
461d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param buf  lu_buf to be filled, with buffer pointer and length
462d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param pos position to start reading, updated as data is read
463d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
464d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval 0 on successfully reading full buffer
465d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -EFAULT on short read
466d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -ve errno on failure
467d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
468d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_record_read(const struct lu_env *env, struct dt_object *dt,
469d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		   struct lu_buf *buf, loff_t *pos)
470d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
471d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
472d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
473d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(dt != NULL, "dt is NULL when we want to read record\n");
474d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
475d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt->do_body_ops->dbo_read(env, dt, buf, pos, BYPASS_CAPA);
476d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
477d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == buf->lb_len)
478d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = 0;
479d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else if (rc >= 0)
480d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = -EFAULT;
481d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
482d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
483d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_record_read);
484d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
485d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_record_write(const struct lu_env *env, struct dt_object *dt,
486d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    const struct lu_buf *buf, loff_t *pos, struct thandle *th)
487d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
488d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
489d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
490d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(dt != NULL, "dt is NULL when we want to write record\n");
491d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(th != NULL);
492d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(dt->do_body_ops);
493d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(dt->do_body_ops->dbo_write);
494d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt->do_body_ops->dbo_write(env, dt, buf, pos, th, BYPASS_CAPA, 1);
495d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == buf->lb_len)
496d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = 0;
497d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else if (rc >= 0)
498d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = -EFAULT;
499d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
500d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
501d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_record_write);
502d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
503d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
504d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   struct thandle *th)
505d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
506d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_buf vbuf;
507d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *xname = XATTR_NAME_VERSION;
508d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
509d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(o);
510d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_buf = NULL;
511d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_len = sizeof(dt_obj_version_t);
512d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return dt_declare_xattr_set(env, o, &vbuf, xname, 0, th);
513d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
514d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
515d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_declare_version_set);
516d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
517d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid dt_version_set(const struct lu_env *env, struct dt_object *o,
518d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    dt_obj_version_t version, struct thandle *th)
519d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
520d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_buf vbuf;
521d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *xname = XATTR_NAME_VERSION;
522d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
523d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
524d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(o);
525d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_buf = &version;
526d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_len = sizeof(version);
527d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
528d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_xattr_set(env, o, &vbuf, xname, 0, th, BYPASS_CAPA);
529d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0)
530d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CDEBUG(D_INODE, "Can't set version, rc %d\n", rc);
531d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return;
532d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
533d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_version_set);
534d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
535d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taodt_obj_version_t dt_version_get(const struct lu_env *env, struct dt_object *o)
536d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
537d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_buf vbuf;
538d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *xname = XATTR_NAME_VERSION;
539d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_obj_version_t version;
540d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
541d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
542d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(o);
543d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_buf = &version;
544d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	vbuf.lb_len = sizeof(version);
545d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_xattr_get(env, o, &vbuf, xname, BYPASS_CAPA);
546d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc != sizeof(version)) {
547d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CDEBUG(D_INODE, "Can't get version, rc %d\n", rc);
548d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		version = 0;
549d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
550d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return version;
551d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
552d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_version_get);
553d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
554d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* list of all supported index types */
555d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
556d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* directories */
557d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_directory_features;
558d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_directory_features);
559d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
560d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* scrub iterator */
561d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_otable_features;
562d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_otable_features);
563d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
564d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* lfsck */
565d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_lfsck_features = {
566d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
567d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(struct lu_fid),
568d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(struct lu_fid),
569d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(__u8),
570d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(__u8),
571d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
572d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
573d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_lfsck_features);
574d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
575d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* accounting indexes */
576d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_acct_features = {
577d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
578d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(__u64), /* 64-bit uid/gid */
579d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(__u64), /* 64-bit uid/gid */
580d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(struct lquota_acct_rec), /* 16 bytes */
581d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(struct lquota_acct_rec), /* 16 bytes */
582d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
583d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
584d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_acct_features);
585d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
586d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* global quota files */
587d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_quota_glb_features = {
588d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
589d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* a different key would have to be used for per-directory quota */
590d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(__u64), /* 64-bit uid/gid */
591d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(__u64), /* 64-bit uid/gid */
592d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(struct lquota_glb_rec), /* 32 bytes */
593d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(struct lquota_glb_rec), /* 32 bytes */
594d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
595d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
596d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_quota_glb_features);
597d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
598d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* slave quota files */
599d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst struct dt_index_features dt_quota_slv_features = {
600d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_flags		= DT_IND_UPDATE,
601d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* a different key would have to be used for per-directory quota */
602d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_min	= sizeof(__u64), /* 64-bit uid/gid */
603d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_keysize_max	= sizeof(__u64), /* 64-bit uid/gid */
604d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_min	= sizeof(struct lquota_slv_rec), /* 8 bytes */
605d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_recsize_max	= sizeof(struct lquota_slv_rec), /* 8 bytes */
606d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	.dif_ptrsize		= 4
607d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
608d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_quota_slv_features);
609d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
610d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* helper function returning what dt_index_features structure should be used
611d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * based on the FID sequence. This is used by OBD_IDX_READ RPC */
612d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic inline const struct dt_index_features *dt_index_feat_select(__u64 seq,
613d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao								   __u32 mode)
614d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
615d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (seq == FID_SEQ_QUOTA_GLB) {
616d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* global quota index */
617d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!S_ISREG(mode))
618d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* global quota index should be a regular file */
619d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return ERR_PTR(-ENOENT);
620d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return &dt_quota_glb_features;
621d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else if (seq == FID_SEQ_QUOTA) {
622d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* quota slave index */
623d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!S_ISREG(mode))
624d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* slave index should be a regular file */
625d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return ERR_PTR(-ENOENT);
626d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return &dt_quota_slv_features;
627d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else if (seq >= FID_SEQ_NORMAL) {
628d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* object is part of the namespace, verify that it is a
629d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * directory */
630d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!S_ISDIR(mode))
631d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* sorry, we can only deal with directory */
632d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return ERR_PTR(-ENOTDIR);
633d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return &dt_directory_features;
634d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
635d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
636d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return ERR_PTR(-EOPNOTSUPP);
637d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
638d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
639d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
640d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Fill a lu_idxpage with key/record pairs read for transfer via OBD_IDX_READ
641d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * RPC
642d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
643d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env - is the environment passed by the caller
644d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param lp  - is a pointer to the lu_page to fill
645d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param nob - is the maximum number of bytes that should be copied
646d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param iops - is the index operation vector associated with the index object
647d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param it   - is a pointer to the current iterator
648d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param attr - is the index attribute to pass to iops->rec()
649d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param arg  - is a pointer to the idx_info structure
650d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
651d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int dt_index_page_build(const struct lu_env *env, union lu_page *lp,
652d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       int nob, const struct dt_it_ops *iops,
653d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       struct dt_it *it, __u32 attr, void *arg)
654d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
655d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct idx_info		*ii = (struct idx_info *)arg;
656d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lu_idxpage	*lip = &lp->lp_idx;
657d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char			*entry;
658d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			 rc, size;
659d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
660d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* no support for variable key & record size for now */
661d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT((ii->ii_flags & II_FL_VARKEY) == 0);
662d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT((ii->ii_flags & II_FL_VARREC) == 0);
663d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
664d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* initialize the header of the new container */
665d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	memset(lip, 0, LIP_HDR_SIZE);
666d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lip->lip_magic = LIP_MAGIC;
667d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	nob	   -= LIP_HDR_SIZE;
668d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
669d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* compute size needed to store a key/record pair */
670d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	size = ii->ii_recsize + ii->ii_keysize;
671d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((ii->ii_flags & II_FL_NOHASH) == 0)
672d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* add hash if the client wants it */
673d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		size += sizeof(__u64);
674d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
675d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	entry = lip->lip_entries;
676d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	do {
677d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		char		*tmp_entry = entry;
678d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		struct dt_key	*key;
679d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64		 hash;
680d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
681d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* fetch 64-bit hash value */
682d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		hash = iops->store(env, it);
683d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_hash_end = hash;
684d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
685d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_IDX_READ_BREAK)) {
686d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (lip->lip_nr != 0)
687d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				GOTO(out, rc = 0);
688d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
689d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
690d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (nob < size) {
691d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (lip->lip_nr == 0)
692d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				GOTO(out, rc = -EINVAL);
693d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			GOTO(out, rc = 0);
694d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
695d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
696d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if ((ii->ii_flags & II_FL_NOHASH) == 0) {
697d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* client wants to the 64-bit hash value associated with
698d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 * each record */
699d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			memcpy(tmp_entry, &hash, sizeof(hash));
700d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			tmp_entry += sizeof(hash);
701d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
702d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
703d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* then the key value */
704d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(iops->key_size(env, it) == ii->ii_keysize);
705d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		key = iops->key(env, it);
706d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		memcpy(tmp_entry, key, ii->ii_keysize);
707d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		tmp_entry += ii->ii_keysize;
708d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
709d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* and finally the record */
710d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = iops->rec(env, it, (struct dt_rec *)tmp_entry, attr);
711d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc != -ESTALE) {
712d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (rc != 0)
713d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				GOTO(out, rc);
714d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
715d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* hash/key/record successfully copied! */
716d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			lip->lip_nr++;
717d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (unlikely(lip->lip_nr == 1 && ii->ii_count == 0))
718d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				ii->ii_hash_start = hash;
719d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			entry = tmp_entry + ii->ii_recsize;
720d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			nob -= size;
721d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
722d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
723d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* move on to the next record */
724d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		do {
725d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			rc = iops->next(env, it);
726d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		} while (rc == -ESTALE);
727d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
728d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} while (rc == 0);
729d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
730d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	GOTO(out, rc);
731d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
732d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc >= 0 && lip->lip_nr > 0)
733d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* one more container */
734d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_count++;
735d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc > 0)
736d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* no more entries */
737d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_hash_end = II_END_OFF;
738d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
739d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
740d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
741d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
742d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Walk index and fill lu_page containers with key/record pairs
743d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
744d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env - is the environment passed by the caller
745d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param obj - is the index object to parse
746d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param rdpg - is the lu_rdpg descriptor associated with the transfer
747d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param filler - is the callback function responsible for filling a lu_page
748d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *		 with key/record pairs in the format wanted by the caller
749d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param arg    - is an opaq argument passed to the filler function
750d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
751d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval sum (in bytes) of all filled lu_pages
752d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval -ve errno on failure
753d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
754d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_index_walk(const struct lu_env *env, struct dt_object *obj,
755d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		  const struct lu_rdpg *rdpg, dt_index_page_build_t filler,
756d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		  void *arg)
757d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
758d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_it		*it;
759d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	const struct dt_it_ops	*iops;
760d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned int		 pageidx, nob, nlupgs = 0;
761d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			 rc;
762d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
763d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(rdpg->rp_pages != NULL);
764d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(obj->do_index_ops != NULL);
765d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
766d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	nob = rdpg->rp_count;
767d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (nob <= 0)
7680a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EFAULT;
769d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
770d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* Iterate through index and fill containers from @rdpg */
771d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	iops = &obj->do_index_ops->dio_it;
772d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(iops != NULL);
773d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	it = iops->init(env, obj, rdpg->rp_attrs, BYPASS_CAPA);
774d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(it))
7750a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return PTR_ERR(it);
776d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
777d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = iops->load(env, it, rdpg->rp_hash);
778d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == 0) {
779d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/*
780d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * Iterator didn't find record with exactly the key requested.
781d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *
782d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * It is currently either
783d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *
784d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     - positioned above record with key less than
785d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     requested---skip it.
786d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     - or not positioned at all (is in IAM_IT_SKEWED
787d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 *     state)---position it on the next item.
788d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 */
789d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = iops->next(env, it);
790d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else if (rc > 0) {
791d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = 0;
792d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
793d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
794d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* Fill containers one after the other. There might be multiple
795d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * containers per physical page.
796d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *
797d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * At this point and across for-loop:
798d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *  rc == 0 -> ok, proceed.
799d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *  rc >  0 -> end of index.
800d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *  rc <  0 -> error. */
801d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (pageidx = 0; rc == 0 && nob > 0; pageidx++) {
802d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		union lu_page	*lp;
803d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		int		 i;
804d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
805d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(pageidx < rdpg->rp_npages);
806d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lp = kmap(rdpg->rp_pages[pageidx]);
807d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
808d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* fill lu pages */
809d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		for (i = 0; i < LU_PAGE_COUNT; i++, lp++, nob -= LU_PAGE_SIZE) {
810d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			rc = filler(env, lp, min_t(int, nob, LU_PAGE_SIZE),
811d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    iops, it, rdpg->rp_attrs, arg);
812d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (rc < 0)
813d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				break;
814d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* one more lu_page */
815d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			nlupgs++;
816d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (rc > 0)
817d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				/* end of index */
818d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				break;
819d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
820d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		kunmap(rdpg->rp_pages[i]);
821d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
822d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
823d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	iops->put(env, it);
824d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	iops->fini(env, it);
825d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
826d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc >= 0)
827d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = min_t(unsigned int, nlupgs * LU_PAGE_SIZE, rdpg->rp_count);
828d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
8290a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return rc;
830d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
831d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_index_walk);
832d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
833d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
834d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Walk key/record pairs of an index and copy them into 4KB containers to be
835d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * transferred over the network. This is the common handler for OBD_IDX_READ
836d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * RPC processing.
837d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
838d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param env - is the environment passed by the caller
839d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param dev - is the dt_device storing the index
840d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param ii  - is the idx_info structure packed by the client in the
841d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *	      OBD_IDX_READ request
842d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param rdpg - is the lu_rdpg descriptor
843d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
844d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval on success, return sum (in bytes) of all filled containers
845d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \retval appropriate error otherwise.
846d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
847d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint dt_index_read(const struct lu_env *env, struct dt_device *dev,
848d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		  struct idx_info *ii, const struct lu_rdpg *rdpg)
849d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
850d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	const struct dt_index_features	*feat;
851d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_object		*obj;
852d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				 rc;
853d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
854d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* rp_count shouldn't be null and should be a multiple of the container
855d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * size */
856d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rdpg->rp_count <= 0 && (rdpg->rp_count & (LU_PAGE_SIZE - 1)) != 0)
8570a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EFAULT;
858d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
859d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (fid_seq(&ii->ii_fid) >= FID_SEQ_NORMAL)
860d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* we don't support directory transfer via OBD_IDX_READ for the
861d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * time being */
8620a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EOPNOTSUPP;
863d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
864d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!fid_is_quota(&ii->ii_fid))
865d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* block access to all local files except quota files */
8660a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -EPERM;
867d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
868d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* lookup index object subject to the transfer */
869d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	obj = dt_locate(env, dev, &ii->ii_fid);
870d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(obj))
8710a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return PTR_ERR(obj);
872d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (dt_object_exists(obj) == 0)
873d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(out, rc = -ENOENT);
874d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
875d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* fetch index features associated with index object */
876d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	feat = dt_index_feat_select(fid_seq(&ii->ii_fid),
877d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    lu_object_attr(&obj->do_lu));
878d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (IS_ERR(feat))
879d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(out, rc = PTR_ERR(feat));
880d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
881d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* load index feature if not done already */
882d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (obj->do_index_ops == NULL) {
883d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = obj->do_ops->do_index_try(env, obj, feat);
884d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc)
885d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			GOTO(out, rc);
886d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
887d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
888d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* fill ii_flags with supported index features */
889d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_flags &= II_FL_NOHASH;
890d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
891d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_keysize = feat->dif_keysize_max;
892d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((feat->dif_flags & DT_IND_VARKEY) != 0) {
893d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* key size is variable */
894d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_flags |= II_FL_VARKEY;
895d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* we don't support variable key size for the time being */
896d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(out, rc = -EOPNOTSUPP);
897d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
898d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
899d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_recsize = feat->dif_recsize_max;
900d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((feat->dif_flags & DT_IND_VARREC) != 0) {
901d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* record size is variable */
902d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_flags |= II_FL_VARREC;
903d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* we don't support variable record size for the time being */
904d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		GOTO(out, rc = -EOPNOTSUPP);
905d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
906d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
907d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if ((feat->dif_flags & DT_IND_NONUNQ) != 0)
908d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* key isn't necessarily unique */
909d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_flags |= II_FL_NONUNQ;
910d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
911d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_read_lock(env, obj, 0);
912d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* fetch object version before walking the index */
913d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ii->ii_version = dt_version_get(env, obj);
914d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
915d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* walk the index and fill lu_idxpages with key/record pairs */
916d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = dt_index_walk(env, obj, rdpg, dt_index_page_build ,ii);
917d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	dt_read_unlock(env, obj);
918d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
919d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == 0) {
920d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* index is empty */
921d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERT(ii->ii_count == 0);
922d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ii->ii_hash_end = II_END_OFF;
923d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
924d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
925d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	GOTO(out, rc);
926d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
927d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lu_object_put(env, &obj->do_lu);
928d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
929d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
930d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(dt_index_read);
931d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
932d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#ifdef LPROCFS
933d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
934d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
935d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			  int count, int *eof, void *data)
936d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
937d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
938d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
939d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
940d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
9416715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
942d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
9436715e395daec8179db174250631a74c282cb580dJohn L. Hammond		rc = snprintf(page, count, "%u\n",
944d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				(unsigned) osfs.os_bsize);
945d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
946d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
947d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
948d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
949d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_blksize);
950d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
951d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
952d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			      int count, int *eof, void *data)
953d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
954d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
955d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
956d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
957d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
9586715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
959d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 blk_size = osfs.os_bsize >> 10;
960d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64 result = osfs.os_blocks;
961d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
962d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (blk_size >>= 1)
963d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result <<= 1;
964d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
965d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
966d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = snprintf(page, count, LPU64"\n", result);
967d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
968d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
969d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
970d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
971d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_kbytestotal);
972d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
973d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off,
974d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     int count, int *eof, void *data)
975d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
976d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
977d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
978d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
979d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
9806715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
981d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 blk_size = osfs.os_bsize >> 10;
982d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64 result = osfs.os_bfree;
983d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
984d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (blk_size >>= 1)
985d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result <<= 1;
986d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
987d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
988d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = snprintf(page, count, LPU64"\n", result);
989d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
990d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
991d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
992d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
993d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_kbytesfree);
994d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
995d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off,
996d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			      int count, int *eof, void *data)
997d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
998d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
999d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
1000d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1001d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
10026715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
1003d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 blk_size = osfs.os_bsize >> 10;
1004d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u64 result = osfs.os_bavail;
1005d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1006d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (blk_size >>= 1)
1007d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			result <<= 1;
1008d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1009d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
1010d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = snprintf(page, count, LPU64"\n", result);
1011d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1012d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1013d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1014d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1015d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_kbytesavail);
1016d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1017d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
1018d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     int count, int *eof, void *data)
1019d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1020d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
1021d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
1022d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1023d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
10246715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
1025d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
1026d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = snprintf(page, count, LPU64"\n", osfs.os_files);
1027d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1028d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1029d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1030d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1031d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_filestotal);
1032d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1033d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
1034d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			    int count, int *eof, void *data)
1035d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1036d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dt_device *dt = data;
1037d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_statfs osfs;
1038d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1039d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = dt_statfs(NULL, dt, &osfs);
10406715e395daec8179db174250631a74c282cb580dJohn L. Hammond	if (rc == 0) {
1041d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*eof = 1;
1042d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
1043d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1044d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1045d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1046d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1047d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_dt_rd_filesfree);
1048d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1049d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#endif /* LPROCFS */
1050