inode.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  2.  * vim:expandtab:shiftwidth=8:tabstop=8:
  3.  *
  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>
  8.  *
  9.  *   This file is part of InterMezzo, http://www.inter-mezzo.org.
  10.  *
  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.
  14.  *
  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.
  19.  *
  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.
  23.  *
  24.  * Super block/filesystem wide operations
  25.  */
  26. #define __NO_VERSION__
  27. #include <linux/module.h>
  28. #include <linux/kernel.h>
  29. #include <linux/mm.h>
  30. #include <linux/string.h>
  31. #include <linux/stat.h>
  32. #include <linux/errno.h>
  33. #include <linux/locks.h>
  34. #include <linux/unistd.h>
  35. #include <asm/system.h>
  36. #include <asm/uaccess.h>
  37. #include <linux/fs.h>
  38. #include <linux/stat.h>
  39. #include <linux/errno.h>
  40. #include <linux/locks.h>
  41. #include <linux/string.h>
  42. #include <asm/uaccess.h>
  43. #include <linux/slab.h>
  44. #include <linux/vmalloc.h>
  45. #include <asm/segment.h>
  46. #include <linux/intermezzo_fs.h>
  47. #include <linux/intermezzo_psdev.h>
  48. extern void presto_free_cache(struct presto_cache *);
  49. void presto_set_ops(struct inode *inode, struct  filter_fs *filter)
  50. {
  51.         ENTRY; 
  52.         if (!inode || is_bad_inode(inode))
  53.                 return;
  54.         if (S_ISREG(inode->i_mode)) {
  55.                 if ( !filter_c2cfiops(filter) ) {
  56.                        filter_setup_file_ops(filter, 
  57.                                              inode, &presto_file_iops,
  58.                                              &presto_file_fops);
  59.                 }
  60.                 inode->i_op = filter_c2ufiops(filter);
  61.                 inode->i_fop = filter_c2uffops(filter);
  62.                 CDEBUG(D_INODE, "set file methods for %ld to %pn",
  63.                        inode->i_ino, inode->i_op);
  64.         } else if (S_ISDIR(inode->i_mode)) {
  65.                 inode->i_op = filter_c2udiops(filter);
  66.                 inode->i_fop = filter_c2udfops(filter);
  67.                 CDEBUG(D_INODE, "set dir methods for %ld to %p ioctl %pn",
  68.                        inode->i_ino, inode->i_op, inode->i_fop->ioctl);
  69.         } else if (S_ISLNK(inode->i_mode)) {
  70.                 if ( !filter_c2csiops(filter)) {
  71.                         filter_setup_symlink_ops(filter, 
  72.                                                  inode,
  73.                                                  &presto_sym_iops, 
  74.                                                  &presto_sym_fops);
  75.                 }
  76.                 inode->i_op = filter_c2usiops(filter);
  77.                 inode->i_fop = filter_c2usfops(filter);
  78.                 CDEBUG(D_INODE, "set link methods for %ld to %pn",
  79.                        inode->i_ino, inode->i_op);
  80.         }
  81.         EXIT;
  82. }
  83. void presto_read_inode(struct inode *inode)
  84. {
  85.         struct presto_cache *cache;
  86.         cache = presto_get_cache(inode);
  87.         if ( !cache ) {
  88.                 CERROR("PRESTO: BAD, BAD: cannot find cachen");
  89.                 make_bad_inode(inode);
  90.                 return ;
  91.         }
  92.         filter_c2csops(cache->cache_filter)->read_inode(inode);
  93.         CDEBUG(D_INODE, "presto_read_inode: ino %ld, gid %dn", 
  94.                inode->i_ino, inode->i_gid);
  95.         presto_set_ops(inode, cache->cache_filter); 
  96.         /* XXX handle special inodes here or not - probably not? */
  97. }
  98. static void presto_put_super(struct super_block *sb)
  99. {
  100.         struct presto_cache *cache;
  101.         struct upc_channel *channel;
  102.         struct super_operations *sops;
  103.         struct list_head *lh;
  104.         int err;
  105.         ENTRY;
  106.         cache = presto_cache_find(sb->s_dev);
  107.         if (!cache) {
  108.                 EXIT;
  109.                 goto exit;
  110.         }
  111.         channel = &izo_channels[presto_c2m(cache)];
  112.         sops = filter_c2csops(cache->cache_filter);
  113.         err = izo_clear_all_fsetroots(cache); 
  114.         if (err) { 
  115.                 CERROR("%s: err %dn", __FUNCTION__, err);
  116.         }
  117.         PRESTO_FREE(cache->cache_vfsmount, sizeof(struct vfsmount));
  118.         /* look at kill_super - fsync_super is not exported GRRR but 
  119.            probably not needed */ 
  120.         unlock_super(sb);
  121.         shrink_dcache_parent(cache->cache_root); 
  122.         dput(cache->cache_root); 
  123.         //fsync_super(sb); 
  124.         lock_super(sb);
  125.         if (sops->write_super)
  126.                 sops->write_super(sb); 
  127.         if (sops->put_super)
  128.                 sops->put_super(sb);
  129.         /* free any remaining async upcalls when the filesystem is unmounted */
  130.         spin_lock(&channel->uc_lock);
  131.         lh = channel->uc_pending.next;
  132.         while ( lh != &channel->uc_pending) {
  133.                 struct upc_req *req;
  134.                 req = list_entry(lh, struct upc_req, rq_chain);
  135.                 /* assignment must be here: we are about to free &lh */
  136.                 lh = lh->next;
  137.                 if ( ! (req->rq_flags & REQ_ASYNC) ) 
  138.                         continue;
  139.                 list_del(&(req->rq_chain));
  140.                 PRESTO_FREE(req->rq_data, req->rq_bufsize);
  141.                 PRESTO_FREE(req, sizeof(struct upc_req));
  142.         }
  143.         list_del(&cache->cache_channel_list); 
  144.         spin_unlock(&channel->uc_lock);
  145.         presto_free_cache(cache);
  146. exit:
  147.         CDEBUG(D_MALLOC, "after umount: kmem %ld, vmem %ldn",
  148.                presto_kmemory, presto_vmemory);
  149.         MOD_DEC_USE_COUNT;
  150.         return ;
  151. }
  152. struct super_operations presto_super_ops = {
  153.         .read_inode    = presto_read_inode,
  154.         .put_super     = presto_put_super,
  155. };
  156. /* symlinks can be chowned */
  157. struct inode_operations presto_sym_iops = {
  158.         .setattr       = presto_setattr
  159. };
  160. /* NULL for now */
  161. struct file_operations presto_sym_fops;