1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Intel Corporation
9 * Author: Hariharan Thantry
10 * File Name: lprocfs.c
12 * This code is issued under the GNU General Public License.
13 * See the file COPYING in this distribution
15 * During initialization (of lustre), the following directory materializes
17 * When the first OBD device of a class is created (due to insmod)
19 * /proc/lustre/devices/<device-class> is created.
20 * When an instance of a device is created (during attach) the
21 * directory entry for that instance along with the variables for
22 * that entry gets created. These variables could be counters, string
24 * Each API further describes the functionality offered.
29 #include <linux/config.h>
30 #include <linux/module.h>
31 #include <linux/version.h>
32 #include <linux/proc_fs.h>
33 #include <linux/slab.h>
34 #include <linux/types.h>
36 #define DEBUG_SUBSYSTEM S_CLASS
37 #define MAX_STRING_SIZE 100
39 #include <linux/obd_support.h>
40 #include <linux/obd_class.h>
41 #include <linux/lprocfs.h>
42 #include <linux/string.h>
43 #include <linux/lustre_lib.h>
47 #define DEFAULT_MODE 0644
49 * Tokenizer array. Change this array to include special
50 * characters for string tokenizing
52 char tok[] = {'/', (char)0};
55 * Escape character. To be used in directories that
56 * should not have any counter/variable entries under
57 * them. Used for hierarchical directories
60 char escape_char = '%';
65 extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */
72 static struct proc_dir_entry *proc_lustre_root = 0;
73 static struct proc_dir_entry *proc_lustre_dev_root = 0;
75 /* struct lustre_lock proc_lustre_lock; */
76 /* static struct proc_dir_entry *proc_lustre_conn_root = 0; */
77 char *testStr = "General..";
80 * Link the namespace with the internal array indices for
81 * each device class, only if proc lustre is defined
84 struct namespace_index dir_mdc_index[] = {
85 LPROCFS_DIR_INDEX(mdc, mgmt_setup),
86 LPROCFS_DIR_INDEX(mdc, mgmt_cleanup),
87 LPROCFS_DIR_INDEX(mdc, mgmt_connect),
88 LPROCFS_DIR_INDEX(mdc, mgmt_disconnect),
89 LPROCFS_DIR_INDEX(mdc, reint),
90 LPROCFS_DIR_INDEX(mdc, getstatus),
91 LPROCFS_DIR_INDEX(mdc, getattr),
92 LPROCFS_DIR_INDEX(mdc, setattr),
93 LPROCFS_DIR_INDEX(mdc, open),
94 LPROCFS_DIR_INDEX(mdc, readpage),
95 LPROCFS_DIR_INDEX(mdc, create),
96 LPROCFS_DIR_INDEX(mdc, unlink),
97 LPROCFS_DIR_INDEX(mdc, link),
98 LPROCFS_DIR_INDEX(mdc, rename),
101 struct namespace_index dir_mds_index[] = {
102 LPROCFS_DIR_INDEX(mds, mgmt_setup),
103 LPROCFS_DIR_INDEX(mds, mgmt_cleanup),
104 LPROCFS_DIR_INDEX(mds, mgmt_connect),
105 LPROCFS_DIR_INDEX(mds, mgmt_disconnect),
106 LPROCFS_DIR_INDEX(mds, getstatus),
107 LPROCFS_DIR_INDEX(mds, connect),
108 LPROCFS_DIR_INDEX(mds, disconnect_callback),
109 LPROCFS_DIR_INDEX(mds, getattr),
110 LPROCFS_DIR_INDEX(mds, readpage),
111 LPROCFS_DIR_INDEX(mds, open),
112 LPROCFS_DIR_INDEX(mds, close),
113 LPROCFS_DIR_INDEX(mds, create),
114 LPROCFS_DIR_INDEX(mds, unlink),
115 LPROCFS_DIR_INDEX(mds, link),
116 LPROCFS_DIR_INDEX(mds, rename),
117 LPROCFS_DIR_INDEX(mds, reint_summary),
118 LPROCFS_DIR_INDEX(mds, reint_setattr),
119 LPROCFS_DIR_INDEX(mds, reint_create),
120 LPROCFS_DIR_INDEX(mds, reint_unlink),
121 LPROCFS_DIR_INDEX(mds, reint_link),
122 LPROCFS_DIR_INDEX(mds, reint_rename),
123 LPROCFS_DIR_INDEX(mds, reint_recreate),
126 struct namespace_index dir_osc_index[] = {
127 LPROCFS_DIR_INDEX(osc, mgmt_setup),
128 LPROCFS_DIR_INDEX(osc, mgmt_cleanup),
129 LPROCFS_DIR_INDEX(osc, mgmt_connect),
130 LPROCFS_DIR_INDEX(osc, mgmt_disconnect),
131 LPROCFS_DIR_INDEX(osc, create),
132 LPROCFS_DIR_INDEX(osc, destroy),
133 LPROCFS_DIR_INDEX(osc, getattr),
134 LPROCFS_DIR_INDEX(osc, setattr),
135 LPROCFS_DIR_INDEX(osc, open),
136 LPROCFS_DIR_INDEX(osc, close),
137 LPROCFS_DIR_INDEX(osc, brw),
138 LPROCFS_DIR_INDEX(osc, punch),
139 LPROCFS_DIR_INDEX(osc, summary),
140 LPROCFS_DIR_INDEX(osc, cancel),
143 struct namespace_index dir_ost_index[] = {
144 LPROCFS_DIR_INDEX(ost, mgmt_setup),
145 LPROCFS_DIR_INDEX(ost, mgmt_cleanup),
146 LPROCFS_DIR_INDEX(ost, mgmt_connect),
147 LPROCFS_DIR_INDEX(ost, mgmt_disconnect),
148 LPROCFS_DIR_INDEX(ost, create),
149 LPROCFS_DIR_INDEX(ost, destroy),
150 LPROCFS_DIR_INDEX(ost, getattr),
151 LPROCFS_DIR_INDEX(ost, setattr),
152 LPROCFS_DIR_INDEX(ost, open),
153 LPROCFS_DIR_INDEX(ost, close),
154 LPROCFS_DIR_INDEX(ost, brw),
155 LPROCFS_DIR_INDEX(ost, punch),
156 LPROCFS_DIR_INDEX(ost, summary),
157 LPROCFS_DIR_INDEX(ost, cancel),
158 LPROCFS_DIR_INDEX(ost, getinfo),
161 struct namespace_index dir_lov_index[] = {
162 LPROCFS_DIR_INDEX(lov, mgmt_setup),
163 LPROCFS_DIR_INDEX(lov, mgmt_cleanup),
164 LPROCFS_DIR_INDEX(lov, mgmt_connect),
165 LPROCFS_DIR_INDEX(lov, mgmt_disconnect),
166 LPROCFS_DIR_INDEX(lov, create),
167 LPROCFS_DIR_INDEX(lov, destroy),
168 LPROCFS_DIR_INDEX(lov, getattr),
169 LPROCFS_DIR_INDEX(lov, setattr),
170 LPROCFS_DIR_INDEX(lov, open),
171 LPROCFS_DIR_INDEX(lov, close),
172 LPROCFS_DIR_INDEX(lov, brw),
173 LPROCFS_DIR_INDEX(lov, punch),
174 LPROCFS_DIR_INDEX(lov, summary),
175 LPROCFS_DIR_INDEX(lov, cancel),
176 LPROCFS_DIR_INDEX(lov, getinfo),
179 struct namespace_index dir_obdfilter_index[] = {
180 LPROCFS_DIR_INDEX(obdfilter, mgmt_setup),
181 LPROCFS_DIR_INDEX(obdfilter, mgmt_cleanup),
182 LPROCFS_DIR_INDEX(obdfilter, mgmt_connect),
183 LPROCFS_DIR_INDEX(obdfilter, mgmt_disconnect),
184 LPROCFS_DIR_INDEX(obdfilter, create),
185 LPROCFS_DIR_INDEX(obdfilter, destroy),
186 LPROCFS_DIR_INDEX(obdfilter, getattr),
187 LPROCFS_DIR_INDEX(obdfilter, setattr),
188 LPROCFS_DIR_INDEX(obdfilter, open),
189 LPROCFS_DIR_INDEX(obdfilter, close),
190 LPROCFS_DIR_INDEX(obdfilter, brw),
191 LPROCFS_DIR_INDEX(obdfilter, punch),
192 LPROCFS_DIR_INDEX(obdfilter, summary),
193 LPROCFS_DIR_INDEX(obdfilter, cancel),
194 LPROCFS_DIR_INDEX(obdfilter, getinfo),
197 struct namespace_index dir_ldlm_index[] = {
198 LPROCFS_DIR_INDEX(ldlm, mgmt_setup),
199 LPROCFS_DIR_INDEX(ldlm, mgmt_cleanup),
200 LPROCFS_DIR_INDEX(ldlm, mgmt_connect),
201 LPROCFS_DIR_INDEX(ldlm, mgmt_disconnect),
202 LPROCFS_DIR_INDEX(ldlm, locks_enqueus),
203 LPROCFS_DIR_INDEX(ldlm, locks_cancels),
204 LPROCFS_DIR_INDEX(ldlm, locks_converts),
205 LPROCFS_DIR_INDEX(ldlm, locks_matches),
208 struct namespace_index dir_ptlrpc_index[] = {
209 LPROCFS_DIR_INDEX(ptlrpc, mgmt_setup),
210 LPROCFS_DIR_INDEX(ptlrpc, mgmt_cleanup),
211 LPROCFS_DIR_INDEX(ptlrpc, mgmt_connect),
212 LPROCFS_DIR_INDEX(ptlrpc, mgmt_disconnect),
213 LPROCFS_DIR_INDEX(ptlrpc, counters),
216 struct namespace_index prof_mdc_index[] = {
217 LPROCFS_CNTR_INDEX(mdc, min_time),
218 LPROCFS_CNTR_INDEX(mdc, max_time),
219 LPROCFS_CNTR_INDEX(mdc, sum_time),
220 LPROCFS_CNTR_INDEX(mdc, num_ops),
223 struct namespace_index prof_mds_index[]= {
224 LPROCFS_CNTR_INDEX(mds, min_time),
225 LPROCFS_CNTR_INDEX(mds, max_time),
226 LPROCFS_CNTR_INDEX(mds, sum_time),
227 LPROCFS_CNTR_INDEX(mds, num_ops),
230 struct namespace_index prof_osc_index[]= {
231 LPROCFS_CNTR_INDEX(osc, min_time),
232 LPROCFS_CNTR_INDEX(osc, max_time),
233 LPROCFS_CNTR_INDEX(osc, sum_time),
234 LPROCFS_CNTR_INDEX(osc, num_ops),
237 struct namespace_index prof_ost_index[]= {
238 LPROCFS_CNTR_INDEX(ost, min_time),
239 LPROCFS_CNTR_INDEX(ost, max_time),
240 LPROCFS_CNTR_INDEX(ost, sum_time),
241 LPROCFS_CNTR_INDEX(ost, num_ops),
244 struct namespace_index prof_lov_index[]= {
245 LPROCFS_CNTR_INDEX(lov, min_time),
246 LPROCFS_CNTR_INDEX(lov, max_time),
247 LPROCFS_CNTR_INDEX(lov, sum_time),
248 LPROCFS_CNTR_INDEX(lov, num_ops),
251 struct namespace_index prof_obdfilter_index[]= {
252 LPROCFS_CNTR_INDEX(obdfilter, min_time),
253 LPROCFS_CNTR_INDEX(obdfilter, max_time),
254 LPROCFS_CNTR_INDEX(obdfilter, sum_time),
255 LPROCFS_CNTR_INDEX(obdfilter, num_ops),
258 struct namespace_index prof_ldlm_index[] = {
259 LPROCFS_CNTR_INDEX(ldlm, min_time),
260 LPROCFS_CNTR_INDEX(ldlm, max_time),
261 LPROCFS_CNTR_INDEX(ldlm, sum_time),
262 LPROCFS_CNTR_INDEX(ldlm, num_ops),
263 LPROCFS_CNTR_INDEX(ldlm, num_total),
264 LPROCFS_CNTR_INDEX(ldlm, num_zerolatency),
265 LPROCFS_CNTR_INDEX(ldlm, num_zerolatency_inflight),
266 LPROCFS_CNTR_INDEX(ldlm, num_zerolatency_done),
267 LPROCFS_CNTR_INDEX(ldlm, nonzero_mintime),
268 LPROCFS_CNTR_INDEX(ldlm, nonzero_maxtime),
269 LPROCFS_CNTR_INDEX(ldlm, nonzero_sumtime),
272 struct namespace_index prof_ptlrpc_index[] = {
273 LPROCFS_CNTR_INDEX(ptlrpc, min_time),
274 LPROCFS_CNTR_INDEX(ptlrpc, max_time),
275 LPROCFS_CNTR_INDEX(ptlrpc, sum_time),
276 LPROCFS_CNTR_INDEX(ptlrpc, num_ops),
277 LPROCFS_CNTR_INDEX(ptlrpc, msgs_alloc),
278 LPROCFS_CNTR_INDEX(ptlrpc, msgs_max),
279 LPROCFS_CNTR_INDEX(ptlrpc, recv_count),
280 LPROCFS_CNTR_INDEX(ptlrpc, recv_length),
281 LPROCFS_CNTR_INDEX(ptlrpc, send_count),
282 LPROCFS_CNTR_INDEX(ptlrpc, send_length),
283 LPROCFS_CNTR_INDEX(ptlrpc, portal_kmemory),
287 * Group the device class name, its directory hierarchy and
288 * leaf nodes together
291 struct groupspace_index class_index[] = {
292 LPROCFS_GROUP_CREATE(mdc),
293 LPROCFS_GROUP_CREATE(mds),
294 LPROCFS_GROUP_CREATE(osc),
295 LPROCFS_GROUP_CREATE(ost),
296 LPROCFS_GROUP_CREATE(lov),
297 LPROCFS_GROUP_CREATE(obdfilter),
298 LPROCFS_GROUP_CREATE(ldlm),
299 LPROCFS_GROUP_CREATE(ptlrpc),
304 * API implementations
308 * lprocfs_reg_dev: Registers an instance of the OBD device in the
312 int lprocfs_reg_dev(struct obd_device* device, lprocfs_group_t* namespace,
313 unsigned int cnt_struct_size)
315 unsigned int num_directories = 0;
316 int class_array_index = 0;
318 struct proc_dir_entry* this_dev_root=0;
319 unsigned int i = 0, j = 0;
321 /* Obtain this device root */
322 this_dev_root = lprocfs_mkinitdir(device);
323 if (this_dev_root == 0) {
324 CERROR("Could not create initial directory");
325 return LPROCFS_FAILURE;
329 /* Obtain the class-array index */
330 class_array_index = lprocfs_getclass_idx(class_index,
331 device->obd_type->typ_name);
333 if (class_array_index == LPROCFS_FAILURE) {
334 CERROR("!! Could not find class !! \n");
335 return LPROCFS_FAILURE;
338 /* Create the directory namespace */
339 retval = lprocfs_create_dir_namespace(this_dev_root, namespace,
341 if (retval == LPROCFS_FAILURE) {
342 CERROR("!!Could not create proc directory structure !!\n");
343 return LPROCFS_FAILURE;
346 /* Allocate memory managed by LProcFS for the device. */
347 if (cnt_struct_size != 0) {
348 OBD_ALLOC(device->counters, num_directories*cnt_struct_size);
349 device->cntr_mem_size = num_directories*cnt_struct_size;
353 * Iterate the proc-dir-namespace, obtain corresponding
354 * directory(attribute)
355 * entries. Create the proc-counters from namespace, link them into
358 retval=lprocfs_link_dir_counters(device, this_dev_root, namespace,
359 cnt_struct_size, class_array_index);
361 if (retval == LPROCFS_FAILURE) {
362 CERROR("!! Could not link proc counters to device !!");
363 return LPROCFS_FAILURE;
367 * Test code: This goes into individual modules. strcmp is
368 * unnecessary, since device knows its class. To see the values
369 * from the user space, do a cat on the respective variable
371 if (!(strcmp(device->obd_type->typ_name, "mds"))) {
372 DEV_PROF_START(mds, device, gen, mgmt_setup);
374 for (i = 0; i < 100; i++)
375 for (j = 0; j < 100; j++)
378 DEV_PROF_END(mds, device, gen, mgmt_setup);
380 DEV_PROF_START(mds, device, gen, mgmt_setup);
382 for (i = 0; i < 1000; i++)
383 for (j = 0; j < 1000; j++)
386 DEV_PROF_END(mds, device, gen, mgmt_setup);
389 DEV_PROF_START(mds, device, gen, open);
390 for(i = 0; i < 50; i++){
391 DEV_PROF_START(mds, device, gen, close);
392 for(j=0; j<2000; j++)
394 DEV_PROF_END(mds, device, gen, close);
396 DEV_PROF_END(mds, device, gen, open);
399 if (!(strcmp(device->obd_type->typ_name, "ldlm"))) {
400 DEV_PROF_START(ldlm, device, ldlm, mgmt_connect);
401 for(i = 0; i < 200; i++) {
402 DEV_PROF_START(ldlm, device, ldlm, mgmt_disconnect);
403 for (j = 0; j< 2000; j++)
405 DEV_PROF_END(ldlm, device, ldlm, mgmt_disconnect);
407 DEV_PROF_END(ldlm, device, ldlm, mgmt_connect);
410 return LPROCFS_SUCCESS;
413 int lprocfs_link_dir_counters(struct obd_device* device,
414 struct proc_dir_entry* root,
415 lprocfs_group_t* namespace,
419 struct proc_dir_entry* dir_root=0;
420 lprocfs_group_t* temp;
421 lprocfs_vars_t* fn_ctr;
422 struct namespace_index* cntr_names;
426 unsigned int escape = 0;
431 temp = &namespace[i];
433 if (temp->count_func_namespace == 0)
436 while ((temp->dir_namespace)[j] != 0) {
437 dir_root = lprocfs_add_dir(root,
438 (temp->dir_namespace)[j],
439 (const char*)tok, &escape);
445 dir_idx = lprocfs_get_idx(class_index[cl_idx].directory,
446 (temp->dir_namespace)[j]);
449 fn_ctr = &((temp->count_func_namespace)[k]);
450 if (fn_ctr->read_fptr == 0)
452 cntr_names = class_index[cl_idx].counters;
453 cnt_idx = lprocfs_get_idx(cntr_names,
456 if (lprocfs_add_var(device, dir_root, fn_ctr,
457 dir_idx, cnt_idx, sz,
460 CERROR("Could not create leaf node!");
461 return LPROCFS_FAILURE;
477 return LPROCFS_SUCCESS;
481 int lprocfs_create_dir_namespace(struct proc_dir_entry* root,
482 lprocfs_group_t* namespace,
483 unsigned int *num_dirs)
487 struct proc_dir_entry* dir_root=0;
488 lprocfs_group_t* temp;
489 unsigned int escape = 0;
492 temp = &namespace[i];
493 if (temp->count_func_namespace == 0)
495 while ((temp->dir_namespace)[j] != 0){
496 dir_root = lprocfs_add_dir(root,
497 (temp->dir_namespace)[j],
498 (const char*)tok, &escape);
500 CERROR("!! Could not create dir %s !! \n",
501 (temp->dir_namespace)[j]);
502 return LPROCFS_FAILURE;
504 if (temp->prof_type != e_specific && !escape)
512 return LPROCFS_SUCCESS;
518 int lprocfs_getclass_idx(struct groupspace_index* group, const char* classname)
520 unsigned int idx = 0;
522 while (group[idx].name != "") {
523 if (!strcmp(group[idx].name, classname))
528 return LPROCFS_FAILURE;
531 struct proc_dir_entry* lprocfs_mkinitdir(struct obd_device* device)
533 struct proc_dir_entry* this_dev_root = 0;
534 struct proc_dir_entry* temp_proc = 0;
536 * First check if /proc/lustre exits. If it does not,
537 * instantiate the same and the devices directory
540 if (!proc_lustre_root) {
541 proc_lustre_root = lprocfs_mkdir("lustre", &proc_root);
542 if (!proc_lustre_root) {
543 CERROR(" !! Cannot create /proc/lustre !! \n");
546 proc_lustre_dev_root =
547 lprocfs_mkdir("devices", proc_lustre_root);
549 if (!proc_lustre_dev_root) {
550 CERROR(" !! Cannot create /proc/lustre/devices !! \n");
556 * Check if this is the first instance for a device of
557 * this class in the lprocfs hierarchy.
560 temp_proc = lprocfs_srch(proc_lustre_dev_root,
561 device->obd_type->typ_name);
564 temp_proc = lprocfs_mkdir(device->obd_type->typ_name,
565 proc_lustre_dev_root);
567 CERROR("! Proc dir for device class %s !!\n",
568 device->obd_type->typ_name);
573 * Next create the proc_dir_entry for this instance
576 this_dev_root = lprocfs_mkdir(device->obd_name, temp_proc);
577 if (!this_dev_root) {
578 CERROR("!Can't create proc entry for instance %s !! \n",
583 return this_dev_root;
588 int lprocfs_get_idx(struct namespace_index* class, const char* dir_name)
590 unsigned int index = 0;
591 char temp_string[MAX_STRING_SIZE];
593 /* First replace the string tokenizer with enum character */
594 memset(temp_string, 0, MAX_STRING_SIZE);
595 while (dir_name[index]!='\0' && index < MAX_STRING_SIZE) {
596 if (dir_name[index] != tok[0])
597 temp_string[index] = dir_name[index];
599 temp_string[index] = enum_char;
602 temp_string[index] = '\0';
605 while (class[index].name) {
606 if (!strcmp(class[index].name, temp_string))
611 CDEBUG(D_OTHER, "No profiling for %s\n", temp_string);
618 struct proc_dir_entry* lprocfs_mkdir(const char* dname,
619 struct proc_dir_entry *parent)
621 struct proc_dir_entry *child_dir_entry;
623 child_dir_entry = proc_mkdir(dname, parent);
625 if (!child_dir_entry)
626 CERROR("lustre: failed to create /proc entry %s\n", dname);
628 return child_dir_entry;
632 * Create the variable struct entry for /proc. This will also
633 * register the read/write function pointers with
635 * Returns non-zero on success, zero on failure
638 unsigned int lprocfs_add_var(struct obd_device* device,
639 struct proc_dir_entry* root,
640 lprocfs_vars_t* variable, int dir_idx, int cnt_idx,
641 unsigned int sz, lprofilers_e type)
643 struct proc_dir_entry* new_proc_entry;
645 unsigned int actual_idx;
646 unsigned int blk_size;
648 new_proc_entry = create_proc_entry(variable->name, DEFAULT_MODE, root);
650 return LPROCFS_FAILURE;
652 new_proc_entry->read_proc = variable->read_fptr;
653 new_proc_entry->write_proc = variable->write_fptr;
657 if (device->counters) {
658 if (dir_idx != -1 && cnt_idx != -1) {
659 temp = (__u64*)device->counters;
660 blk_size = ((sz) / (sizeof(__u64)));
661 actual_idx = (dir_idx*blk_size) + cnt_idx;
663 new_proc_entry->data = (__u64*)temp;
671 return LPROCFS_SUCCESS;
677 * Tokenize name, based on tok and end-of-string. Create and return the
678 * new directory entry. Set escape variable if the directory name contained
679 * the escaping character (#)
682 struct proc_dir_entry* lprocfs_add_dir(struct proc_dir_entry *root,
685 unsigned int* escape)
687 struct proc_dir_entry* new_root = 0;
688 struct proc_dir_entry* temp_entry = 0;
689 struct proc_dir_entry* new_entry = 0;
690 char temp_string[MAX_STRING_SIZE];
694 * Remove trailing escaping character
696 memset(temp_string, 0, MAX_STRING_SIZE);
697 if (strlen(string) >= MAX_STRING_SIZE) {
698 CERROR("Directory namespace too long");
702 if (strchr(string, escape_char) != NULL) {
704 strncpy(temp_string,string,strlen(string) - 1);
705 temp_string[strlen(string)] = '\0';
708 strcpy(temp_string, string);
709 temp_string[strlen(string) + 1] = '\0';
712 my_str = strtok(temp_string, tok);
715 while (my_str != NULL) {
716 temp_entry = lprocfs_srch(new_root, my_str);
717 if (temp_entry == 0) {
718 new_entry = lprocfs_mkdir(my_str, new_root);
719 if (new_entry == 0) {
720 CERROR("! Did not create new dir %s !!\n",
728 my_str=strtok(NULL, tok);
735 struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head,
738 struct proc_dir_entry* temp;
743 while (temp != NULL) {
744 if (!strcmp(temp->name, name))
751 #warning FIXME: recursive code is VERY bad in the kernel because of stack limit
752 struct proc_dir_entry* lprocfs_bfs_srch(struct proc_dir_entry* root,
755 struct proc_dir_entry* temp = root;
760 if (!strcmp(temp->name, name))
763 if ((temp = lprocfs_bfs_srch(root->next, name)) != 0)
766 if ((temp = lprocfs_bfs_srch(root->subdir, name)) != 0)
772 int lprocfs_get_nm(char* name, lprocfs_obd_nm_t* collection)
775 while (collection[i].obd_names != 0) {
776 if(!strcmp(collection[i].obd_clname, name))
784 int lprocfs_dereg_dev(struct obd_device* device)
786 struct proc_dir_entry* temp;
789 CDEBUG(D_OTHER, "! LProcfs: Null pointer !\n");
790 return LPROCFS_SUCCESS;
793 if (!(device->obd_name)) {
794 CERROR(" !! Device does not have a name !! \n");
795 return LPROCFS_FAILURE;
798 CDEBUG(D_OTHER, "SEARCH: Device = %s\n", device->obd_name);
800 temp = lprocfs_bfs_srch(proc_lustre_dev_root->subdir, device->obd_name);
802 CERROR("!! No root obtained, device does not exist !!\n");
803 return LPROCFS_FAILURE;
806 lprocfs_remove_all(temp);
809 * Free the memory held by counters
811 if (device->counters)
812 OBD_FREE(device->counters, device->cntr_mem_size);
815 return LPROCFS_SUCCESS;
818 void lprocfs_remove_all(struct proc_dir_entry* root)
820 if (root->subdir != 0)
821 lprocfs_remove_all(root->subdir);
824 lprocfs_remove_all(root->next);
826 if (root->parent != 0)
827 remove_proc_entry(root->name, root->parent);
829 remove_proc_entry(root->name, NULL);
833 int lprocfs_ll_rd(char* page, char **start, off_t off,
834 int count, int *eof, void *data)
837 __u64 *temp = (__u64*)data;
839 len = sprintf(page, "%lld\n", *temp);
844 int rd_other(char* page, char **start, off_t off, int count, int *eof,
847 printk("Hello other");
851 int rd_string(char* page, char **start, off_t off, int count, int *eof,
854 printk("Hello string");
858 int lprocfs_ll_wr(struct file* file, const char *buffer, unsigned long count,
861 printk("Write default");
865 int wr_other(struct file* file, const char *buffer, unsigned long count,
868 printk("Write other");
872 int wr_string(struct file* file, const char *buffer, unsigned long count,
875 printk("Write string");
879 int lprocfs_reg_conn(unsigned int conn_number,
880 struct lprocfs_conn_namespace* namespace)
885 int lprocfs_dereg_conn(unsigned int conn_number)
893 int lprocfs_add_export(unsigned int conn_number, struct obd_device* device)
898 int lprocfs_add_import(unsigned int conn_number, struct obd_device* device)
903 int lprocfs_remove_export(unsigned int conn_number, struct obd_device* device)
908 int lprocfs_remove_import(unsigned int conn_number, struct obd_device* device)