OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [LINUX_2_4_26_OR32/] [linux/] [linux-2.4/] [fs/] [intermezzo/] [sysctl.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2
 * vim:expandtab:shiftwidth=8:tabstop=8:
3
 *
4
 *  Copyright (C) 1999 Peter J. Braam <braam@clusterfs.com>
5
 *
6
 *   This file is part of InterMezzo, http://www.inter-mezzo.org.
7
 *
8
 *   InterMezzo is free software; you can redistribute it and/or
9
 *   modify it under the terms of version 2 of the GNU General Public
10
 *   License as published by the Free Software Foundation.
11
 *
12
 *   InterMezzo is distributed in the hope that it will be useful,
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *   GNU General Public License for more details.
16
 *
17
 *   You should have received a copy of the GNU General Public License
18
 *   along with InterMezzo; if not, write to the Free Software
19
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
 *
21
 *  Sysctrl entries for Intermezzo!
22
 */
23
 
24
#define __NO_VERSION__
25
#include <linux/config.h> /* for CONFIG_PROC_FS */
26
#include <linux/module.h>
27
#include <linux/sched.h>
28
#include <linux/mm.h>
29
#include <linux/sysctl.h>
30
#include <linux/swapctl.h>
31
#include <linux/proc_fs.h>
32
#include <linux/slab.h>
33
#include <linux/vmalloc.h>
34
#include <linux/stat.h>
35
#include <linux/ctype.h>
36
#include <linux/init.h>
37
#include <asm/bitops.h>
38
#include <asm/segment.h>
39
#include <asm/uaccess.h>
40
#include <linux/utsname.h>
41
#include <linux/blk.h>
42
 
43
 
44
#include <linux/intermezzo_fs.h>
45
#include <linux/intermezzo_psdev.h>
46
 
47
/* /proc entries */
48
 
49
#ifdef CONFIG_PROC_FS
50
struct proc_dir_entry *proc_fs_intermezzo;
51
int intermezzo_mount_get_info( char * buffer, char ** start, off_t offset,
52
                               int length)
53
{
54
        int len=0;
55
 
56
        /* this works as long as we are below 1024 characters! */
57
        *start = buffer + offset;
58
        len -= offset;
59
 
60
        if ( len < 0 )
61
                return -EINVAL;
62
 
63
        return len;
64
}
65
 
66
#endif
67
 
68
 
69
/* SYSCTL below */
70
 
71
static struct ctl_table_header *intermezzo_table_header = NULL;
72
/* 0x100 to avoid any chance of collisions at any point in the tree with
73
 * non-directories
74
 */
75
#define PSDEV_INTERMEZZO  (0x100)
76
 
77
#define PSDEV_DEBUG        1      /* control debugging */
78
#define PSDEV_TRACE        2      /* control enter/leave pattern */
79
#define PSDEV_TIMEOUT      3      /* timeout on upcalls to become intrble */
80
#define PSDEV_HARD         4      /* mount type "hard" or "soft" */
81
#define PSDEV_NO_FILTER    5      /* controls presto_chk */
82
#define PSDEV_NO_JOURNAL   6      /* controls presto_chk */
83
#define PSDEV_NO_UPCALL    7      /* controls lento_upcall */
84
#define PSDEV_ERRORVAL     8      /* controls presto_debug_fail_blkdev */
85
#define PSDEV_EXCL_GID     9      /* which GID is ignored by presto */
86
#define PSDEV_BYTES_TO_CLOSE 11   /* bytes to write before close */
87
 
88
/* These are global presto control options */
89
#define PRESTO_PRIMARY_CTLCNT 2
90
static struct ctl_table presto_table[ PRESTO_PRIMARY_CTLCNT + MAX_CHANNEL + 1] =
91
{
92
        {PSDEV_DEBUG, "debug", &presto_debug, sizeof(int), 0644, NULL, &proc_dointvec},
93
        {PSDEV_TRACE, "trace", &presto_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
94
};
95
 
96
/*
97
 * Intalling the sysctl entries: strategy
98
 * - have templates for each /proc/sys/intermezzo/ entry
99
 *   such an entry exists for each /dev/presto
100
 *    (proto_channel_entry)
101
 * - have a template for the contents of such directories
102
 *    (proto_psdev_table)
103
 * - have the master table (presto_table)
104
 *
105
 * When installing, malloc, memcpy and fix up the pointers to point to
106
 * the appropriate constants in izo_channels[your_minor]
107
 */
108
 
109
static ctl_table proto_psdev_table[] = {
110
        {PSDEV_HARD, "hard", 0, sizeof(int), 0644, NULL, &proc_dointvec},
111
        {PSDEV_NO_FILTER, "no_filter", 0, sizeof(int), 0644, NULL, &proc_dointvec},
112
        {PSDEV_NO_JOURNAL, "no_journal", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
113
        {PSDEV_NO_UPCALL, "no_upcall", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
114
        {PSDEV_TIMEOUT, "timeout", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
115
#ifdef PRESTO_DEBUG
116
        {PSDEV_ERRORVAL, "errorval", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
117
#endif
118
        { 0 }
119
};
120
 
121
static ctl_table proto_channel_entry = {
122
        PSDEV_INTERMEZZO, 0,  NULL, 0, 0555, 0,
123
};
124
 
125
static ctl_table intermezzo_table[2] = {
126
        {PSDEV_INTERMEZZO, "intermezzo",    NULL, 0, 0555, presto_table},
127
        {0}
128
};
129
 
130
/* support for external setting and getting of opts. */
131
/* particularly via ioctl. The Right way to do this is via sysctl,
132
 * but that will have to wait until intermezzo gets its own nice set of
133
 * sysctl IDs
134
 */
135
/* we made these separate as setting may in future be more restricted
136
 * than getting
137
 */
138
#ifdef RON_MINNICH
139
int dosetopt(int minor, struct psdev_opt *opt)
140
{
141
        int retval = 0;
142
        int newval = opt->optval;
143
 
144
        ENTRY;
145
 
146
        switch(opt->optname) {
147
 
148
        case PSDEV_TIMEOUT:
149
                izo_channels[minor].uc_timeout = newval;
150
                break;
151
 
152
        case PSDEV_HARD:
153
                izo_channels[minor].uc_hard = newval;
154
                break;
155
 
156
        case PSDEV_NO_FILTER:
157
                izo_channels[minor].uc_no_filter = newval;
158
                break;
159
 
160
        case PSDEV_NO_JOURNAL:
161
                izo_channels[minor].uc_no_journal = newval;
162
                break;
163
 
164
        case PSDEV_NO_UPCALL:
165
                izo_channels[minor].uc_no_upcall = newval;
166
                break;
167
 
168
#ifdef PRESTO_DEBUG
169
        case PSDEV_ERRORVAL: {
170
                /* If we have a positive arg, set a breakpoint for that
171
                 * value.  If we have a negative arg, make that device
172
                 * read-only.  FIXME  It would be much better to only
173
                 * allow setting the underlying device read-only for the
174
                 * current presto cache.
175
                 */
176
                int errorval = izo_channels[minor].uc_errorval;
177
                if (errorval < 0) {
178
                        if (newval == 0)
179
                                set_device_ro(-errorval, 0);
180
                        else
181
                                CERROR("device %s already read only\n",
182
                                       kdevname(-errorval));
183
                } else {
184
                        if (newval < 0)
185
                                set_device_ro(-newval, 1);
186
                        izo_channels[minor].uc_errorval = newval;
187
                        CDEBUG(D_PSDEV, "setting errorval to %d\n", newval);
188
                }
189
 
190
                break;
191
        }
192
#endif
193
 
194
        case PSDEV_TRACE:
195
        case PSDEV_DEBUG:
196
        case PSDEV_BYTES_TO_CLOSE:
197
        default:
198
                CDEBUG(D_PSDEV,
199
                       "ioctl: dosetopt: minor %d, bad optname 0x%x, \n",
200
                       minor, opt->optname);
201
 
202
                retval = -EINVAL;
203
        }
204
 
205
        EXIT;
206
        return retval;
207
}
208
 
209
int dogetopt(int minor, struct psdev_opt *opt)
210
{
211
        int retval = 0;
212
 
213
        ENTRY;
214
 
215
        switch(opt->optname) {
216
 
217
        case PSDEV_TIMEOUT:
218
                opt->optval = izo_channels[minor].uc_timeout;
219
                break;
220
 
221
        case PSDEV_HARD:
222
                opt->optval = izo_channels[minor].uc_hard;
223
                break;
224
 
225
        case PSDEV_NO_FILTER:
226
                opt->optval = izo_channels[minor].uc_no_filter;
227
                break;
228
 
229
        case PSDEV_NO_JOURNAL:
230
                opt->optval = izo_channels[minor].uc_no_journal;
231
                break;
232
 
233
        case PSDEV_NO_UPCALL:
234
                opt->optval = izo_channels[minor].uc_no_upcall;
235
                break;
236
 
237
#ifdef PSDEV_DEBUG
238
        case PSDEV_ERRORVAL: {
239
                int errorval = izo_channels[minor].uc_errorval;
240
                if (errorval < 0 && is_read_only(-errorval))
241
                        CERROR("device %s has been set read-only\n",
242
                               kdevname(-errorval));
243
                opt->optval = izo_channels[minor].uc_errorval;
244
                break;
245
        }
246
#endif
247
 
248
        case PSDEV_TRACE:
249
        case PSDEV_DEBUG:
250
        case PSDEV_BYTES_TO_CLOSE:
251
        default:
252
                CDEBUG(D_PSDEV,
253
                       "ioctl: dogetopt: minor %d, bad optval 0x%x, \n",
254
                       minor, opt->optname);
255
 
256
                retval = -EINVAL;
257
        }
258
 
259
        EXIT;
260
        return retval;
261
}
262
#endif
263
 
264
 
265
/* allocate the tables for the presto devices. We need
266
 * sizeof(proto_channel_table)/sizeof(proto_channel_table[0])
267
 * entries for each dev
268
 */
269
int /* __init */ init_intermezzo_sysctl(void)
270
{
271
        int i;
272
        int total_dev = MAX_CHANNEL;
273
        int entries_per_dev = sizeof(proto_psdev_table) /
274
                sizeof(proto_psdev_table[0]);
275
        int total_entries = entries_per_dev * total_dev;
276
        ctl_table *dev_ctl_table;
277
 
278
        PRESTO_ALLOC(dev_ctl_table, sizeof(ctl_table) * total_entries);
279
 
280
        if (! dev_ctl_table) {
281
                CERROR("WARNING: presto couldn't allocate dev_ctl_table\n");
282
                EXIT;
283
                return -ENOMEM;
284
        }
285
 
286
        /* now fill in the entries ... we put the individual presto<x>
287
         * entries at the end of the table, and the per-presto stuff
288
         * starting at the front.  We assume that the compiler makes
289
         * this code more efficient, but really, who cares ... it
290
         * happens once per reboot.
291
         */
292
        for(i = 0; i < total_dev; i++) {
293
                /* entry for this /proc/sys/intermezzo/intermezzo"i" */
294
                ctl_table *psdev = &presto_table[i + PRESTO_PRIMARY_CTLCNT];
295
                /* entries for the individual "files" in this "directory" */
296
                ctl_table *psdev_entries = &dev_ctl_table[i * entries_per_dev];
297
                /* init the psdev and psdev_entries with the prototypes */
298
                *psdev = proto_channel_entry;
299
                memcpy(psdev_entries, proto_psdev_table,
300
                       sizeof(proto_psdev_table));
301
                /* now specialize them ... */
302
                /* the psdev has to point to psdev_entries, and fix the number */
303
                psdev->ctl_name = psdev->ctl_name + i + 1; /* sorry */
304
 
305
                PRESTO_ALLOC((void*)psdev->procname, PROCNAME_SIZE);
306
                if (!psdev->procname) {
307
                        PRESTO_FREE(dev_ctl_table,
308
                                    sizeof(ctl_table) * total_entries);
309
                        return -ENOMEM;
310
                }
311
                sprintf((char *) psdev->procname, "intermezzo%d", i);
312
                /* hook presto into */
313
                psdev->child = psdev_entries;
314
 
315
                /* now for each psdev entry ... */
316
                psdev_entries[0].data = &(izo_channels[i].uc_hard);
317
                psdev_entries[1].data = &(izo_channels[i].uc_no_filter);
318
                psdev_entries[2].data = &(izo_channels[i].uc_no_journal);
319
                psdev_entries[3].data = &(izo_channels[i].uc_no_upcall);
320
                psdev_entries[4].data = &(izo_channels[i].uc_timeout);
321
#ifdef PRESTO_DEBUG
322
                psdev_entries[5].data = &(izo_channels[i].uc_errorval);
323
#endif
324
        }
325
 
326
 
327
#ifdef CONFIG_SYSCTL
328
        if ( !intermezzo_table_header )
329
                intermezzo_table_header =
330
                        register_sysctl_table(intermezzo_table, 0);
331
#endif
332
#ifdef CONFIG_PROC_FS
333
        proc_fs_intermezzo = proc_mkdir("intermezzo", proc_root_fs);
334
        proc_fs_intermezzo->owner = THIS_MODULE;
335
        create_proc_info_entry("mounts", 0, proc_fs_intermezzo,
336
                               intermezzo_mount_get_info);
337
#endif
338
        return 0;
339
}
340
 
341
void cleanup_intermezzo_sysctl(void)
342
{
343
        int total_dev = MAX_CHANNEL;
344
        int entries_per_dev = sizeof(proto_psdev_table) /
345
                sizeof(proto_psdev_table[0]);
346
        int total_entries = entries_per_dev * total_dev;
347
        int i;
348
 
349
#ifdef CONFIG_SYSCTL
350
        if ( intermezzo_table_header )
351
                unregister_sysctl_table(intermezzo_table_header);
352
        intermezzo_table_header = NULL;
353
#endif
354
        for(i = 0; i < total_dev; i++) {
355
                /* entry for this /proc/sys/intermezzo/intermezzo"i" */
356
                ctl_table *psdev = &presto_table[i + PRESTO_PRIMARY_CTLCNT];
357
                PRESTO_FREE(psdev->procname, PROCNAME_SIZE);
358
        }
359
        /* presto_table[PRESTO_PRIMARY_CTLCNT].child points to the
360
         * dev_ctl_table previously allocated in init_intermezzo_psdev()
361
         */
362
        PRESTO_FREE(presto_table[PRESTO_PRIMARY_CTLCNT].child, sizeof(ctl_table) * total_entries);
363
 
364
#if CONFIG_PROC_FS
365
        remove_proc_entry("mounts", proc_fs_intermezzo);
366
        remove_proc_entry("intermezzo", proc_root_fs);
367
#endif
368
}
369
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.