1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002, 2003 Cluster File Systems, Inc.
5 * Author: Hariharan Thantry <thantry@users.sourceforge.net>
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <linux/config.h>
25 #include <linux/module.h>
26 #include <linux/version.h>
27 #include <linux/slab.h>
28 #include <linux/types.h>
30 #define DEBUG_SUBSYSTEM S_CLASS
31 #include <linux/obd_class.h>
32 #include <linux/lprocfs_status.h>
36 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
39 struct proc_dir_entry* temp;
45 while (temp != NULL) {
46 if (!strcmp(temp->name, name))
54 /* lprocfs API calls */
56 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
59 if ((root == NULL) || (list == NULL))
63 struct proc_dir_entry *cur_root, *proc;
64 char *pathcopy, *cur, *next;
65 int pathsize = strlen(list->name)+1;
70 /* need copy of path for strsep */
71 OBD_ALLOC(pathcopy, pathsize);
76 strcpy(pathcopy, list->name);
78 while (cur_root && (cur = strsep(&next, "/"))) {
79 if (*cur =='\0') /* skip double/trailing "/" */
82 proc = lprocfs_srch(cur_root, cur);
83 CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
84 cur_root->name, cur, next,
85 (proc ? "exists" : "new"));
87 cur_root = (proc ? proc :
88 proc_mkdir(cur, cur_root));
90 proc = create_proc_entry(cur, 0444, cur_root);
93 OBD_FREE(pathcopy, pathsize);
95 if ((cur_root==NULL) || (proc==NULL)) {
96 CERROR("LprocFS: No memory to create /proc entry %s",
101 proc->read_proc = list->read_fptr;
102 proc->write_proc = list->write_fptr;
103 proc->data = (list->data ? list->data : data);
109 void lprocfs_remove(struct proc_dir_entry* root)
111 struct proc_dir_entry *temp = root;
112 struct proc_dir_entry *rm_entry;
113 struct proc_dir_entry *parent = root->parent;
121 remove_proc_entry(rm_entry->name, rm_entry->parent);
127 struct proc_dir_entry *lprocfs_register(const char *name,
128 struct proc_dir_entry *parent,
129 struct lprocfs_vars *list, void *data)
131 struct proc_dir_entry *newchild;
133 newchild = lprocfs_srch(parent, name);
135 CERROR(" Lproc: Attempting to register %s more than once \n",
140 newchild = proc_mkdir(name, parent);
141 if (newchild && list) {
142 int rc = lprocfs_add_vars(newchild, list, data);
144 lprocfs_remove(newchild);
151 /* Generic callbacks */
153 int lprocfs_rd_u64(char *page, char **start, off_t off,
154 int count, int *eof, void *data)
157 return snprintf(page, count, LPU64"\n", *(__u64 *)data);
160 int lprocfs_rd_uuid(char* page, char **start, off_t off, int count,
161 int *eof, void *data)
163 struct obd_device* dev = (struct obd_device*)data;
166 return snprintf(page, count, "%s\n", dev->obd_uuid.uuid);
169 int lprocfs_rd_name(char *page, char **start, off_t off, int count,
170 int *eof, void *data)
172 struct obd_device* dev = (struct obd_device *)data;
175 return snprintf(page, count, "%s\n", dev->obd_name);
178 int lprocfs_rd_blksize(char* page, char **start, off_t off, int count,
179 int *eof, struct statfs *sfs)
183 return snprintf(page, count, "%lu\n", sfs->f_bsize);
186 int lprocfs_rd_kbytestotal(char* page, char **start, off_t off, int count,
187 int *eof, struct statfs *sfs)
189 __u32 blk_size = sfs->f_bsize >> 10;
190 __u64 result = sfs->f_blocks;
192 while (blk_size >>= 1)
196 return snprintf(page, count, LPU64"\n", result);
199 int lprocfs_rd_kbytesfree(char* page, char **start, off_t off, int count,
200 int *eof, struct statfs *sfs)
202 __u32 blk_size = sfs->f_bsize >> 10;
203 __u64 result = sfs->f_bfree;
205 while (blk_size >>= 1)
209 return snprintf(page, count, LPU64"\n", result);
212 int lprocfs_rd_filestotal(char* page, char **start, off_t off, int count,
213 int *eof, struct statfs *sfs)
216 return snprintf(page, count, "%ld\n", sfs->f_files);
219 int lprocfs_rd_filesfree(char* page, char **start, off_t off, int count,
220 int *eof, struct statfs *sfs)
223 return snprintf(page, count, "%ld\n", sfs->f_ffree);
226 int lprocfs_rd_filegroups(char* page, char **start, off_t off, int count,
227 int *eof, struct statfs *sfs)
230 return snprintf(page, count, "unimplemented\n");
233 int lprocfs_rd_server_uuid(char* page, char **start, off_t off, int count,
234 int *eof, void *data)
236 struct obd_device* obd = (struct obd_device*)data;
237 struct client_obd* cli = &obd->u.cli;
238 return snprintf(page, count, "%s\n", cli->cl_target_uuid.uuid);
241 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
242 int *eof, void *data)
244 struct obd_device *obd = (struct obd_device*)data;
245 struct ptlrpc_connection *conn = obd->u.cli.cl_import.imp_connection;
248 return snprintf(page, count, "%s\n", conn->c_remote_uuid.uuid);
251 int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
252 int *eof, void *data)
254 struct obd_type* class = (struct obd_type*) data;
257 return snprintf(page, count, "%d\n", class->typ_refcnt);
260 int lprocfs_obd_attach(struct obd_device *dev, struct lprocfs_vars *list)
263 dev->obd_proc_entry = lprocfs_register(dev->obd_name,
264 dev->obd_type->typ_procroot,
266 if (IS_ERR(dev->obd_proc_entry)) {
267 rc = PTR_ERR(dev->obd_proc_entry);
268 dev->obd_proc_entry = NULL;
273 int lprocfs_obd_detach(struct obd_device *dev)
275 if (dev && dev->obd_proc_entry) {
276 lprocfs_remove(dev->obd_proc_entry);
277 dev->obd_proc_entry = NULL;
284 EXPORT_SYMBOL(lprocfs_register);
285 EXPORT_SYMBOL(lprocfs_remove);
286 EXPORT_SYMBOL(lprocfs_add_vars);
287 EXPORT_SYMBOL(lprocfs_obd_attach);
288 EXPORT_SYMBOL(lprocfs_obd_detach);
290 EXPORT_SYMBOL(lprocfs_rd_u64);
291 EXPORT_SYMBOL(lprocfs_rd_uuid);
292 EXPORT_SYMBOL(lprocfs_rd_name);
293 EXPORT_SYMBOL(lprocfs_rd_server_uuid);
294 EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
295 EXPORT_SYMBOL(lprocfs_rd_numrefs);
297 EXPORT_SYMBOL(lprocfs_rd_blksize);
298 EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
299 EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
300 EXPORT_SYMBOL(lprocfs_rd_filestotal);
301 EXPORT_SYMBOL(lprocfs_rd_filesfree);
302 EXPORT_SYMBOL(lprocfs_rd_filegroups);