📄 super.c
字号:
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook University * Copyright (c) 1997-2000 Columbia University * * For specific licensing information, see the COPYING file distributed with * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. * * This Copyright notice must be kept intact and distributed with all * fistgen sources INCLUDING sources generated by fistgen. *//* * $Id: super.c,v 1.22 2002/12/27 20:19:03 ezk Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H */#ifdef FISTGEN# include "fist_wrapfs.h"#endif /* FISTGEN */#include "fist.h"#include "wrapfs.h"STATIC voidwrapfs_read_inode(inode_t *inode){ print_entry_location(); itopd(inode) = kmalloc(sizeof(struct wrapfs_inode_info), GFP_KERNEL); itohi(inode) = NULL;#ifdef FIST_FILTER_SCA itopd(inode)->idx_file = NULL; memset(&(itopd(inode)->hdr), 0, sizeof(struct scafs_header));#endif /* FIST_FILTER_SCA */ inode->i_version = ++event; /* increment inode version */ inode->i_op = &wrapfs_iops; inode->i_fop = &wrapfs_fops; inode->i_mapping->a_ops = &wrapfs_aops; print_exit_location();}#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)/* * No need to call write_inode() on the lower inode, as it * will have been marked 'dirty' anyway. But we might need * to write some of our own stuff to disk. */STATIC voidwrapfs_write_inode(inode_t *inode){ print_entry_location();#ifdef FIST_FILTER_SCA wrapfs_idx_write(inode);#endif /* FIST_FILTER_SCA */ print_exit_location();}#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */#ifdef FIST_DEBUG/* * We don't need to do anything special when our reference count * is decremented. The actual clean-up (when the refcount is 0) * will be done in clear_inode() which is called separately. */STATIC voidwrapfs_put_inode(inode_t *inode){ print_entry_location(); fist_dprint(8, __FUNCTION__ " i_count = %d, i_nlink = %d\n", inode->i_count, inode->i_nlink); print_exit_location();}#endif /* FIST_DEBUG */#ifdef FIST_DEBUG/* * we now define delete_inode, because there are two VFS paths that may * destroy an inode: one of them calls clear inode before doing everything * else that's needed, and the other is fine. This way we truncate the inode * size (and its pages) and then clear our own inode, which will do an iput * on our and the lower inode. */STATIC voidwrapfs_delete_inode(inode_t *inode){ print_entry_location(); fist_checkinode(inode, "wrapfs_delete_inode IN"); inode->i_size = 0; /* every f/s seems to do that */ clear_inode(inode); print_exit_location();}#endif /* FIST_DEBUG */STATIC voidwrapfs_put_super(super_block_t *sb){ print_entry_location(); if (stopd(sb)) { mntput(stopd(sb)->hidden_mnt); kfree_s(stopd(sb), sizeof(struct wrapfs_sb_info)); stopd(sb) = NULL; } fist_dprint(6, "wrapfs: released super\n"); print_exit_location();}#ifdef NOT_NEEDED/* * This is called in do_umount before put_super. * The superblock lock is not held yet. * We probably do not need to define this or call write_super * on the hidden_sb, because sync_supers() will get to hidden_sb * sooner or later. But it is also called from file_fsync()... */STATIC voidwrapfs_write_super(super_block_t *sb){ return;}#endif /* NOT_NEEDED */STATIC intwrapfs_statfs(super_block_t *sb, struct statfs *buf){ int err = 0; super_block_t *hidden_sb = stohs(sb); print_entry_location(); err = vfs_statfs(hidden_sb, buf); print_exit_status(err); return err;}/* * XXX: not implemented. This is not allowed yet. * Should we call this on the hidden_sb? Probably not. */STATIC intwrapfs_remount_fs(super_block_t *sb, int *flags, char *data){ return -ENOSYS;}/* * Called by iput() when the inode reference count reached zero * and the inode is not hashed anywhere. Used to clear anything * that needs to be, before the inode is completely destroyed and put * on the inode free list. */STATIC voidwrapfs_clear_inode(inode_t *inode){#ifdef FIST_FILTER_SCA int i; struct scafs_header *hdr;#endif /* FIST_FILTER_SCA */ print_entry_location(); fist_checkinode(inode, "wrapfs_clear_inode IN"); /* * Decrement a reference to a hidden_inode, which was incremented * by our read_inode when it was created initially. */ iput(itohi(inode)); // XXX: why this assertion fails? // because it doesn't like us // ASSERT((inode->i_state & I_DIRTY) == 0);#ifdef FIST_FILTER_SCA if (itopd(inode)->idx_file != NULL) wrapfs_idx_release(inode); hdr = &itopd(inode)->hdr; if (hdr->num_alloc > 0) { /* then offsets were allocated */ fist_print_scafs_header("CLEAR_INODE", hdr); for (i = 0; i < hdr->num_pageslots; i++) free_page((unsigned long) hdr->offsets[i]); kfree(hdr->offsets); }#endif /* FIST_FILTER_SCA */ kfree_s(itopd(inode), sizeof(struct wrapfs_inode_info)); itopd(inode) = NULL; print_exit_location();}/* * Called in do_umount() if the MNT_FORCE flag was used and this * function is defined. See comment in linux/fs/super.c:do_umount(). * Used only in nfs, to kill any pending RPC tasks, so that subsequent * code can actually succeed and won't leave tasks that need handling. * * PS. I wonder if this is somehow useful to undo damage that was * left in the kernel after a user level file server (such as amd) * dies. */STATIC voidwrapfs_umount_begin(super_block_t *sb){ super_block_t *hidden_sb = stohs(sb); print_entry_location(); if (hidden_sb->s_op->umount_begin) hidden_sb->s_op->umount_begin(hidden_sb); print_exit_location();}struct super_operations wrapfs_sops ={ read_inode: wrapfs_read_inode,#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) write_inode: wrapfs_write_inode,#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */#ifdef FIST_DEBUG put_inode: wrapfs_put_inode, delete_inode: wrapfs_delete_inode,#endif /* FIST_DEBUG */ put_super: wrapfs_put_super, statfs: wrapfs_statfs, remount_fs: wrapfs_remount_fs, clear_inode: wrapfs_clear_inode, umount_begin: wrapfs_umount_begin,};/* * Local variables: * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -