/* * Connect a wrapfs inode dentry/inode with several lower ones. This is * the classic stackable file system "vnode interposition" action. * * @dentry: wrapfs's dentry which interposes on lower one * @sb: wrapfs's super_block * @lower_path: the lower path (caller does path_get/put) */ int wrapfs_interpose(struct dentry *dentry, struct super_block *sb, struct path *lower_path) { int err = 0; struct inode *inode; struct inode *lower_inode; struct super_block *lower_sb; lower_inode = lower_path->dentry->d_inode; lower_sb = wrapfs_lower_super(sb); /* check that the lower file system didn't cross a mount point */ if (lower_inode->i_sb != lower_sb) { err = -EXDEV; goto out; } /* * We allocate our new inode below by calling wrapfs_iget, * which will initialize some of the new inode's fields */ /* inherit lower inode number for wrapfs's inode */ inode = wrapfs_iget(sb, lower_inode); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out; } d_add(dentry, inode); out: return err; }
/* final actions when unmounting a file system */ static void wrapfs_put_super(struct super_block *sb) { struct wrapfs_sb_info *spd; struct super_block *s; #ifdef EXTRA_CREDIT if(dbg_bitmap & DBG_SB_OP) UDBG; #endif spd = WRAPFS_SB(sb); if (!spd) return; /* decrement lower super references */ s = wrapfs_lower_super(sb); wrapfs_set_lower_super(sb, NULL); atomic_dec(&s->s_active); kfree(spd); sb->s_fs_info = NULL; #ifdef EXTRA_CREDIT if(dbg_bitmap & DBG_SB_OP) UDBG_EXIT(0); #endif }
/* * 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. */ static void wrapfs_umount_begin(struct super_block *sb) { struct super_block *lower_sb; lower_sb = wrapfs_lower_super(sb); if (lower_sb && lower_sb->s_op && lower_sb->s_op->umount_begin) lower_sb->s_op->umount_begin(lower_sb); }
/* * 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. */ static void wrapfs_umount_begin(struct super_block *sb) { struct super_block *lower_sb; #ifdef EXTRA_CREDIT if(dbg_bitmap & DBG_SB_OP) UDBG; #endif lower_sb = wrapfs_lower_super(sb); if (lower_sb && lower_sb->s_op && lower_sb->s_op->umount_begin) lower_sb->s_op->umount_begin(lower_sb); #ifdef EXTRA_CREDIT if(dbg_bitmap & DBG_SB_OP) UDBG_EXIT(0); #endif }
/* final actions when unmounting a file system */ static void wrapfs_put_super(struct super_block *sb) { struct wrapfs_sb_info *spd; struct super_block *s; spd = WRAPFS_SB(sb); if (!spd) return; /* decrement lower super references */ s = wrapfs_lower_super(sb); wrapfs_set_lower_super(sb, NULL); atomic_dec(&s->s_active); kfree(spd); sb->s_fs_info = NULL; }
/* Connect a wrapfs inode dentry/inode with several lower ones. This is * the classic stackable file system "vnode interposition" action. * * @dentry: wrapfs's dentry which interposes on lower one * @sb: wrapfs's super_block * @lower_path: the lower path (caller does path_get/put) */ int wrapfs_interpose(struct dentry *dentry, struct super_block *sb, struct path *lower_path) { int err = 0; struct inode *inode; struct inode *lower_inode; struct super_block *lower_sb; lower_inode = lower_path->dentry->d_inode; lower_sb = wrapfs_lower_super(sb); /* check that the lower file system didn't cross a mount point */ if (lower_inode->i_sb != lower_sb) { err = -EXDEV; goto out; } /* * We allocate our new inode below by calling wrapfs_iget, * which will initialize some of the new inode's fields */ /* inherit lower inode number for wrapfs's inode */ inode = wrapfs_new_iget(sb, iunique(sb, 1)); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out; } if (atomic_read(&inode->i_count) > 1) goto out_add; wrapfs_fill_inode(dentry, inode); printk(KERN_INFO" U2fs_interpose success\n"); out_add: d_add(dentry, inode); out: return err; }