1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk> and
5 * Michael Callahan <callahan@maths.ox.ac.uk>
6 * Copyright (C) 1999 Carnegie Mellon University
7 * Rewritten for Linux 2.1. Peter Braam <braam@cs.cmu.edu>
9 * This file is part of InterMezzo, http://www.inter-mezzo.org.
11 * InterMezzo is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * InterMezzo is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with InterMezzo; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Super block/filesystem wide operations
27 #include <linux/module.h>
28 #include <linux/kernel.h>
30 #include <linux/string.h>
31 #include <linux/stat.h>
32 #include <linux/errno.h>
33 #include <linux/unistd.h>
35 #include <asm/system.h>
36 #include <asm/uaccess.h>
39 #include <linux/slab.h>
40 #include <linux/vmalloc.h>
41 #include <asm/segment.h>
43 #include "intermezzo_fs.h"
44 #include "intermezzo_psdev.h"
46 extern void presto_free_cache(struct presto_cache *);
48 void presto_set_ops(struct inode *inode, struct filter_fs *filter)
52 if (!inode || is_bad_inode(inode))
55 if (S_ISREG(inode->i_mode)) {
56 if ( !filter_c2cfiops(filter) ) {
57 filter_setup_file_ops(filter,
58 inode, &presto_file_iops,
61 inode->i_op = filter_c2ufiops(filter);
62 inode->i_fop = filter_c2uffops(filter);
63 CDEBUG(D_INODE, "set file methods for %ld to %p\n",
64 inode->i_ino, inode->i_op);
65 } else if (S_ISDIR(inode->i_mode)) {
66 inode->i_op = filter_c2udiops(filter);
67 inode->i_fop = filter_c2udfops(filter);
68 CDEBUG(D_INODE, "set dir methods for %ld to %p ioctl %p\n",
69 inode->i_ino, inode->i_op, inode->i_fop->ioctl);
70 } else if (S_ISLNK(inode->i_mode)) {
71 if ( !filter_c2csiops(filter)) {
72 filter_setup_symlink_ops(filter,
77 inode->i_op = filter_c2usiops(filter);
78 inode->i_fop = filter_c2usfops(filter);
79 CDEBUG(D_INODE, "set link methods for %ld to %p\n",
80 inode->i_ino, inode->i_op);
85 void presto_read_inode(struct inode *inode)
87 struct presto_cache *cache;
89 cache = presto_get_cache(inode);
91 CERROR("PRESTO: BAD, BAD: cannot find cache\n");
92 make_bad_inode(inode);
96 filter_c2csops(cache->cache_filter)->read_inode(inode);
98 CDEBUG(D_INODE, "presto_read_inode: ino %ld, gid %d\n",
99 inode->i_ino, inode->i_gid);
101 presto_set_ops(inode, cache->cache_filter);
102 /* XXX handle special inodes here or not - probably not? */
105 static void presto_put_super(struct super_block *sb)
107 struct presto_cache *cache;
108 struct upc_channel *channel;
109 struct super_operations *sops;
110 struct list_head *lh;
114 cache = presto_cache_find(sb);
119 channel = &izo_channels[presto_c2m(cache)];
120 sops = filter_c2csops(cache->cache_filter);
121 err = izo_clear_all_fsetroots(cache);
123 CERROR("%s: err %d\n", __FUNCTION__, err);
125 PRESTO_FREE(cache->cache_vfsmount, sizeof(struct vfsmount));
127 /* look at kill_super - fsync_super is not exported GRRR but
128 probably not needed */
130 shrink_dcache_parent(cache->cache_root);
131 dput(cache->cache_root);
135 if (sops->write_super)
136 sops->write_super(sb);
141 /* free any remaining async upcalls when the filesystem is unmounted */
142 spin_lock(&channel->uc_lock);
143 lh = channel->uc_pending.next;
144 while ( lh != &channel->uc_pending) {
146 req = list_entry(lh, struct upc_req, rq_chain);
148 /* assignment must be here: we are about to free &lh */
150 if ( ! (req->rq_flags & REQ_ASYNC) )
152 list_del(&(req->rq_chain));
153 PRESTO_FREE(req->rq_data, req->rq_bufsize);
154 PRESTO_FREE(req, sizeof(struct upc_req));
156 list_del(&cache->cache_channel_list);
157 spin_unlock(&channel->uc_lock);
159 presto_free_cache(cache);
162 CDEBUG(D_MALLOC, "after umount: kmem %ld, vmem %ld\n",
163 presto_kmemory, presto_vmemory);
167 struct super_operations presto_super_ops = {
168 .read_inode = presto_read_inode,
169 .put_super = presto_put_super,
173 /* symlinks can be chowned */
174 struct inode_operations presto_sym_iops = {
175 .setattr = presto_setattr
179 struct file_operations presto_sym_fops;