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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [intermezzo/] [methods.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) 2000 Stelias Computing, Inc.
5
 *  Copyright (C) 2000 Red Hat, Inc.
6
 *  Copyright (C) 2000 Mountain View Data, Inc.
7
 *
8
 *  Extended Attribute Support
9
 *  Copyright (C) 2001 Shirish H. Phatak, Tacit Networks, Inc.
10
 *
11
 *   This file is part of InterMezzo, http://www.inter-mezzo.org.
12
 *
13
 *   InterMezzo is free software; you can redistribute it and/or
14
 *   modify it under the terms of version 2 of the GNU General Public
15
 *   License as published by the Free Software Foundation.
16
 *
17
 *   InterMezzo is distributed in the hope that it will be useful,
18
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *   GNU General Public License for more details.
21
 *
22
 *   You should have received a copy of the GNU General Public License
23
 *   along with InterMezzo; if not, write to the Free Software
24
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
 *
26
 */
27
 
28
#include <stdarg.h>
29
 
30
#include <asm/bitops.h>
31
#include <asm/uaccess.h>
32
#include <asm/system.h>
33
 
34
#include <linux/errno.h>
35
#include <linux/fs.h>
36
#include <linux/ext2_fs.h>
37
#include <linux/slab.h>
38
#include <linux/vmalloc.h>
39
#include <linux/sched.h>
40
#include <linux/stat.h>
41
#include <linux/string.h>
42
#include <linux/locks.h>
43
#include <linux/blkdev.h>
44
#include <linux/init.h>
45
#define __NO_VERSION__
46
#include <linux/module.h>
47
 
48
#include <linux/fsfilter.h>
49
#include <linux/intermezzo_fs.h>
50
 
51
 
52
int filter_print_entry = 0;
53
int filter_debug = 0xfffffff;
54
/*
55
 * The function in this file are responsible for setting up the
56
 * correct methods layered file systems like InterMezzo and snapfs
57
 */
58
 
59
 
60
static struct filter_fs filter_oppar[FILTER_FS_TYPES];
61
 
62
/* get to the upper methods (intermezzo, snapfs) */
63
inline struct super_operations *filter_c2usops(struct filter_fs *cache)
64
{
65
        return &cache->o_fops.filter_sops;
66
}
67
 
68
inline struct inode_operations *filter_c2udiops(struct filter_fs *cache)
69
{
70
        return &cache->o_fops.filter_dir_iops;
71
}
72
 
73
 
74
inline struct inode_operations *filter_c2ufiops(struct filter_fs *cache)
75
{
76
        return &cache->o_fops.filter_file_iops;
77
}
78
 
79
inline struct inode_operations *filter_c2usiops(struct filter_fs *cache)
80
{
81
        return &cache->o_fops.filter_sym_iops;
82
}
83
 
84
 
85
inline struct file_operations *filter_c2udfops(struct filter_fs *cache)
86
{
87
        return &cache->o_fops.filter_dir_fops;
88
}
89
 
90
inline struct file_operations *filter_c2uffops(struct filter_fs *cache)
91
{
92
        return &cache->o_fops.filter_file_fops;
93
}
94
 
95
inline struct file_operations *filter_c2usfops(struct filter_fs *cache)
96
{
97
        return &cache->o_fops.filter_sym_fops;
98
}
99
 
100
inline struct dentry_operations *filter_c2udops(struct filter_fs *cache)
101
{
102
        return &cache->o_fops.filter_dentry_ops;
103
}
104
 
105
/* get to the cache (lower) methods */
106
inline struct super_operations *filter_c2csops(struct filter_fs *cache)
107
{
108
        return cache->o_caops.cache_sops;
109
}
110
 
111
inline struct inode_operations *filter_c2cdiops(struct filter_fs *cache)
112
{
113
        return cache->o_caops.cache_dir_iops;
114
}
115
 
116
inline struct inode_operations *filter_c2cfiops(struct filter_fs *cache)
117
{
118
        return cache->o_caops.cache_file_iops;
119
}
120
 
121
inline struct inode_operations *filter_c2csiops(struct filter_fs *cache)
122
{
123
        return cache->o_caops.cache_sym_iops;
124
}
125
 
126
inline struct file_operations *filter_c2cdfops(struct filter_fs *cache)
127
{
128
        return cache->o_caops.cache_dir_fops;
129
}
130
 
131
inline struct file_operations *filter_c2cffops(struct filter_fs *cache)
132
{
133
        return cache->o_caops.cache_file_fops;
134
}
135
 
136
inline struct file_operations *filter_c2csfops(struct filter_fs *cache)
137
{
138
        return cache->o_caops.cache_sym_fops;
139
}
140
 
141
inline struct dentry_operations *filter_c2cdops(struct filter_fs *cache)
142
{
143
        return cache->o_caops.cache_dentry_ops;
144
}
145
 
146
 
147
void filter_setup_journal_ops(struct filter_fs *ops, char *cache_type)
148
{
149
        if ( strlen(cache_type) == strlen("ext2") &&
150
             memcmp(cache_type, "ext2", strlen("ext2")) == 0 ) {
151
#if CONFIG_EXT2_FS
152
                ops->o_trops = &presto_ext2_journal_ops;
153
#else
154
                ops->o_trops = NULL;
155
#endif
156
                FDEBUG(D_SUPER, "ops at %p\n", ops);
157
        }
158
 
159
        if ( strlen(cache_type) == strlen("ext3") &&
160
             memcmp(cache_type, "ext3", strlen("ext3")) == 0 ) {
161
#if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
162
                ops->o_trops = &presto_ext3_journal_ops;
163
#else
164
                ops->o_trops = NULL;
165
#endif
166
                FDEBUG(D_SUPER, "ops at %p\n", ops);
167
        }
168
 
169
        if ( strlen(cache_type) == strlen("tmpfs") &&
170
             memcmp(cache_type, "tmpfs", strlen("tmpfs")) == 0 ) {
171
#if defined(CONFIG_TMPFS)
172
                ops->o_trops = &presto_tmpfs_journal_ops;
173
#else
174
                ops->o_trops = NULL;
175
#endif
176
                FDEBUG(D_SUPER, "ops at %p\n", ops);
177
        }
178
 
179
        if ( strlen(cache_type) == strlen("reiserfs") &&
180
             memcmp(cache_type, "reiserfs", strlen("reiserfs")) == 0 ) {
181
#if 0
182
                /* #if defined(CONFIG_REISERFS_FS) || defined(CONFIG_REISERFS_FS_MODULE) */
183
                ops->o_trops = &presto_reiserfs_journal_ops;
184
#else
185
                ops->o_trops = NULL;
186
#endif
187
                FDEBUG(D_SUPER, "ops at %p\n", ops);
188
        }
189
 
190
        if ( strlen(cache_type) == strlen("xfs") &&
191
             memcmp(cache_type, "xfs", strlen("xfs")) == 0 ) {
192
#if 0
193
/*#if defined(CONFIG_XFS_FS) || defined (CONFIG_XFS_FS_MODULE) */
194
                ops->o_trops = &presto_xfs_journal_ops;
195
#else
196
                ops->o_trops = NULL;
197
#endif
198
                FDEBUG(D_SUPER, "ops at %p\n", ops);
199
        }
200
 
201
        if ( strlen(cache_type) == strlen("obdfs") &&
202
             memcmp(cache_type, "obdfs", strlen("obdfs")) == 0 ) {
203
#if defined(CONFIG_OBDFS_FS) || defined (CONFIG_OBDFS_FS_MODULE)
204
                ops->o_trops = presto_obdfs_journal_ops;
205
#else
206
                ops->o_trops = NULL;
207
#endif
208
                FDEBUG(D_SUPER, "ops at %p\n", ops);
209
        }
210
}
211
 
212
 
213
/* find the cache for this FS */
214
struct filter_fs *filter_get_filter_fs(const char *cache_type)
215
{
216
        struct filter_fs *ops = NULL;
217
        FENTRY;
218
 
219
        if ( strlen(cache_type) == strlen("ext2") &&
220
             memcmp(cache_type, "ext2", strlen("ext2")) == 0 ) {
221
                ops = &filter_oppar[FILTER_FS_EXT2];
222
                FDEBUG(D_SUPER, "ops at %p\n", ops);
223
        }
224
 
225
        if ( strlen(cache_type) == strlen("xfs") &&
226
             memcmp(cache_type, "xfs", strlen("xfs")) == 0 ) {
227
                ops = &filter_oppar[FILTER_FS_XFS];
228
                FDEBUG(D_SUPER, "ops at %p\n", ops);
229
        }
230
 
231
        if ( strlen(cache_type) == strlen("ext3") &&
232
             memcmp(cache_type, "ext3", strlen("ext3")) == 0 ) {
233
                ops = &filter_oppar[FILTER_FS_EXT3];
234
                FDEBUG(D_SUPER, "ops at %p\n", ops);
235
        }
236
 
237
        if ( strlen(cache_type) == strlen("tmpfs") &&
238
             memcmp(cache_type, "tmpfs", strlen("tmpfs")) == 0 ) {
239
                ops = &filter_oppar[FILTER_FS_TMPFS];
240
                FDEBUG(D_SUPER, "ops at %p\n", ops);
241
        }
242
 
243
        if ( strlen(cache_type) == strlen("reiserfs") &&
244
             memcmp(cache_type, "reiserfs", strlen("reiserfs")) == 0 ) {
245
                ops = &filter_oppar[FILTER_FS_REISERFS];
246
                FDEBUG(D_SUPER, "ops at %p\n", ops);
247
        }
248
        if ( strlen(cache_type) == strlen("obdfs") &&
249
             memcmp(cache_type, "obdfs", strlen("obdfs")) == 0 ) {
250
                ops = &filter_oppar[FILTER_FS_OBDFS];
251
                FDEBUG(D_SUPER, "ops at %p\n", ops);
252
        }
253
 
254
        if (ops == NULL) {
255
                CERROR("prepare to die: unrecognized cache type for Filter\n");
256
        }
257
        return ops;
258
        FEXIT;
259
}
260
 
261
 
262
/*
263
 *  Frobnicate the InterMezzo operations
264
 *    this establishes the link between the InterMezzo file system
265
 *    and the underlying file system used for the cache.
266
 */
267
 
268
void filter_setup_super_ops(struct filter_fs *cache, struct super_operations *cache_sops, struct super_operations *filter_sops)
269
{
270
        /* Get ptr to the shared struct snapfs_ops structure. */
271
        struct filter_ops *props = &cache->o_fops;
272
        /* Get ptr to the shared struct cache_ops structure. */
273
        struct cache_ops *caops = &cache->o_caops;
274
 
275
        FENTRY;
276
 
277
        if ( cache->o_flags & FILTER_DID_SUPER_OPS ) {
278
                FEXIT;
279
                return;
280
        }
281
        cache->o_flags |= FILTER_DID_SUPER_OPS;
282
 
283
        /* Set the cache superblock operations to point to the
284
           superblock operations of the underlying file system.  */
285
        caops->cache_sops = cache_sops;
286
 
287
        /*
288
         * Copy the cache (real fs) superblock ops to the "filter"
289
         * superblock ops as defaults. Some will be changed below
290
         */
291
        memcpy(&props->filter_sops, cache_sops, sizeof(*cache_sops));
292
 
293
        /* 'put_super' unconditionally is that of filter */
294
        if (filter_sops->put_super) {
295
                props->filter_sops.put_super = filter_sops->put_super;
296
        }
297
 
298
        if (cache_sops->read_inode) {
299
                props->filter_sops.read_inode = filter_sops->read_inode;
300
                FDEBUG(D_INODE, "setting filter_read_inode, cache_ops %p, cache %p, ri at %p\n",
301
                      cache, cache, props->filter_sops.read_inode);
302
        }
303
 
304
        if (cache_sops->remount_fs)
305
                props->filter_sops.remount_fs = filter_sops->remount_fs;
306
        FEXIT;
307
}
308
 
309
 
310
void filter_setup_dir_ops(struct filter_fs *cache, struct inode *inode, struct inode_operations *filter_iops, struct file_operations *filter_fops)
311
{
312
        struct inode_operations *cache_filter_iops;
313
        struct inode_operations *cache_iops = inode->i_op;
314
        struct file_operations *cache_fops = inode->i_fop;
315
        FENTRY;
316
 
317
        if ( cache->o_flags & FILTER_DID_DIR_OPS ) {
318
                FEXIT;
319
                return;
320
        }
321
        cache->o_flags |= FILTER_DID_DIR_OPS;
322
 
323
        /* former ops become cache_ops */
324
        cache->o_caops.cache_dir_iops = cache_iops;
325
        cache->o_caops.cache_dir_fops = cache_fops;
326
        FDEBUG(D_SUPER, "filter at %p, cache iops %p, iops %p\n",
327
               cache, cache_iops, filter_c2udiops(cache));
328
 
329
        /* setup our dir iops: copy and modify */
330
        memcpy(filter_c2udiops(cache), cache_iops, sizeof(*cache_iops));
331
 
332
        /* abbreviate */
333
        cache_filter_iops = filter_c2udiops(cache);
334
 
335
        /* methods that filter if cache filesystem has these ops */
336
        if (cache_iops->lookup && filter_iops->lookup)
337
                cache_filter_iops->lookup = filter_iops->lookup;
338
        if (cache_iops->create && filter_iops->create)
339
                cache_filter_iops->create = filter_iops->create;
340
        if (cache_iops->link && filter_iops->link)
341
                cache_filter_iops->link = filter_iops->link;
342
        if (cache_iops->unlink && filter_iops->unlink)
343
                cache_filter_iops->unlink = filter_iops->unlink;
344
        if (cache_iops->mkdir && filter_iops->mkdir)
345
                cache_filter_iops->mkdir = filter_iops->mkdir;
346
        if (cache_iops->rmdir && filter_iops->rmdir)
347
                cache_filter_iops->rmdir = filter_iops->rmdir;
348
        if (cache_iops->symlink && filter_iops->symlink)
349
                cache_filter_iops->symlink = filter_iops->symlink;
350
        if (cache_iops->rename && filter_iops->rename)
351
                cache_filter_iops->rename = filter_iops->rename;
352
        if (cache_iops->mknod && filter_iops->mknod)
353
                cache_filter_iops->mknod = filter_iops->mknod;
354
        if (cache_iops->permission && filter_iops->permission)
355
                cache_filter_iops->permission = filter_iops->permission;
356
        if (cache_iops->getattr)
357
                cache_filter_iops->getattr = filter_iops->getattr;
358
        /* Some filesystems do not use a setattr method of their own
359
           instead relying on inode_setattr/write_inode. We still need to
360
           journal these so we make setattr an unconditional operation.
361
           XXX: we should probably check for write_inode. SHP
362
        */
363
        /*if (cache_iops->setattr)*/
364
                cache_filter_iops->setattr = filter_iops->setattr;
365
#ifdef CONFIG_FS_EXT_ATTR
366
        /* For now we assume that posix acls are handled through extended
367
        * attributes. If this is not the case, we must explicitly trap
368
        * posix_set_acl. SHP
369
        */
370
        if (cache_iops->set_ext_attr && filter_iops->set_ext_attr)
371
                cache_filter_iops->set_ext_attr = filter_iops->set_ext_attr;
372
#endif
373
 
374
 
375
        /* copy dir fops */
376
        memcpy(filter_c2udfops(cache), cache_fops, sizeof(*cache_fops));
377
 
378
        /* unconditional filtering operations */
379
        filter_c2udfops(cache)->ioctl = filter_fops->ioctl;
380
 
381
        FEXIT;
382
}
383
 
384
 
385
void filter_setup_file_ops(struct filter_fs *cache, struct inode *inode, struct inode_operations *filter_iops, struct file_operations *filter_fops)
386
{
387
        struct inode_operations *pr_iops;
388
        struct inode_operations *cache_iops = inode->i_op;
389
        struct file_operations *cache_fops = inode->i_fop;
390
        FENTRY;
391
 
392
        if ( cache->o_flags & FILTER_DID_FILE_OPS ) {
393
                FEXIT;
394
                return;
395
        }
396
        cache->o_flags |= FILTER_DID_FILE_OPS;
397
 
398
        /* steal the old ops */
399
        /* former ops become cache_ops */
400
        cache->o_caops.cache_file_iops = cache_iops;
401
        cache->o_caops.cache_file_fops = cache_fops;
402
 
403
        /* abbreviate */
404
        pr_iops = filter_c2ufiops(cache);
405
 
406
        /* setup our dir iops: copy and modify */
407
        memcpy(pr_iops, cache_iops, sizeof(*cache_iops));
408
 
409
        /* copy dir fops */
410
        CERROR("*** cache file ops at %p\n", cache_fops);
411
        memcpy(filter_c2uffops(cache), cache_fops, sizeof(*cache_fops));
412
 
413
        /* assign */
414
        /* See comments above in filter_setup_dir_ops. SHP */
415
        /*if (cache_iops->setattr)*/
416
                pr_iops->setattr = filter_iops->setattr;
417
        if (cache_iops->getattr)
418
                pr_iops->getattr = filter_iops->getattr;
419
        /* XXX Should this be conditional rmr ? */
420
        pr_iops->permission = filter_iops->permission;
421
#ifdef CONFIG_FS_EXT_ATTR
422
        /* For now we assume that posix acls are handled through extended
423
        * attributes. If this is not the case, we must explicitly trap and
424
        * posix_set_acl
425
        */
426
        if (cache_iops->set_ext_attr && filter_iops->set_ext_attr)
427
                pr_iops->set_ext_attr = filter_iops->set_ext_attr;
428
#endif
429
 
430
 
431
        /* unconditional filtering operations */
432
        filter_c2uffops(cache)->open = filter_fops->open;
433
        filter_c2uffops(cache)->release = filter_fops->release;
434
        filter_c2uffops(cache)->write = filter_fops->write;
435
        filter_c2uffops(cache)->ioctl = filter_fops->ioctl;
436
 
437
        FEXIT;
438
}
439
 
440
/* XXX in 2.3 there are "fast" and "slow" symlink ops for ext2 XXX */
441
void filter_setup_symlink_ops(struct filter_fs *cache, struct inode *inode, struct inode_operations *filter_iops, struct file_operations *filter_fops)
442
{
443
        struct inode_operations *pr_iops;
444
        struct inode_operations *cache_iops = inode->i_op;
445
        struct file_operations *cache_fops = inode->i_fop;
446
        FENTRY;
447
 
448
        if ( cache->o_flags & FILTER_DID_SYMLINK_OPS ) {
449
                FEXIT;
450
                return;
451
        }
452
        cache->o_flags |= FILTER_DID_SYMLINK_OPS;
453
 
454
        /* steal the old ops */
455
        cache->o_caops.cache_sym_iops = cache_iops;
456
        cache->o_caops.cache_sym_fops = cache_fops;
457
 
458
        /* abbreviate */
459
        pr_iops = filter_c2usiops(cache);
460
 
461
        /* setup our dir iops: copy and modify */
462
        memcpy(pr_iops, cache_iops, sizeof(*cache_iops));
463
 
464
        /* See comments above in filter_setup_dir_ops. SHP */
465
        /* if (cache_iops->setattr) */
466
                pr_iops->setattr = filter_iops->setattr;
467
        if (cache_iops->getattr)
468
                pr_iops->getattr = filter_iops->getattr;
469
 
470
        /* assign */
471
        /* copy fops - careful for symlinks they might be NULL */
472
        if ( cache_fops ) {
473
                memcpy(filter_c2usfops(cache), cache_fops, sizeof(*cache_fops));
474
        }
475
 
476
        FEXIT;
477
}
478
 
479
void filter_setup_dentry_ops(struct filter_fs *cache,
480
                             struct dentry_operations *cache_dop,
481
                             struct dentry_operations *filter_dop)
482
{
483
        if ( cache->o_flags & FILTER_DID_DENTRY_OPS ) {
484
                FEXIT;
485
                return;
486
        }
487
        cache->o_flags |= FILTER_DID_DENTRY_OPS;
488
 
489
        cache->o_caops.cache_dentry_ops = cache_dop;
490
        memcpy(&cache->o_fops.filter_dentry_ops,
491
               filter_dop, sizeof(*filter_dop));
492
 
493
        if (cache_dop &&  cache_dop != filter_dop && cache_dop->d_revalidate){
494
                CERROR("WARNING: filter overriding revalidation!\n");
495
        }
496
        return;
497
}

powered by: WebSVN 2.1.0

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