Back to index

avfs  1.0.1
Classes | Defines | Functions | Variables
glassfs.c File Reference
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/namei.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <asm/uaccess.h>

Go to the source code of this file.

Classes

struct  base_entry

Defines

#define GLASSFS_MAGIC   0x28476c61
#define FUSE_MAGIC   0x65735546
#define AVFS_MAGIC_CHAR   '#'
#define OVERLAY_DIR   "/overlay"
#define OVERLAY_DIR_LEN   8

Functions

static struct inode * glassfs_alloc_inode (struct super_block *sb)
static void glassfs_fill_inode (struct inode *inode, int mode, dev_t dev, struct dentry *ndentry, struct vfsmount *nmnt, int is_avfs)
static void change_list (struct list_head *oldlist, struct list_head *newlist)
static void exchange_lists (struct list_head *list1, struct list_head *list2)
static void exchange_files (struct file *file1, struct file *file2)
static int glassfs_open (struct inode *inode, struct file *file)
static int glassfs_open_dir (struct inode *inode, struct file *file)
static int glassfs_release (struct inode *inode, struct file *file)
static int glassfs_readdir (struct file *file, void *buf, filldir_t filler)
static loff_t glassfs_llseek (struct file *file, loff_t offset, int origin)
static int glassfs_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
static int glassfs_fsync (struct file *file, struct dentry *dentry, int datasync)
static int glassfs_flush (struct file *file)
static int is_avfs (const unsigned char *name, unsigned int len)
static char * my_d_path (struct dentry *dentry, struct vfsmount *vfsmnt, struct dentry *root, struct vfsmount *rootmnt, char *buffer, int buflen)
static int lookup_avfs (struct dentry *dentry, struct nameidata *nd, struct vfsmount *nmnt, struct base_entry *be)
static int is_create (struct nameidata *nd)
static struct dentry * glassfs_lookup (struct inode *dir, struct dentry *dentry, struct nameidata *nd)
static int glassfs_permission (struct inode *inode, int mask, struct nameidata *nd)
static int glassfs_create (struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
static int glassfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
static int glassfs_link (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
static int glassfs_symlink (struct inode *dir, struct dentry *dentry, const char *oldname)
static int glassfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
static int glassfs_rename (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
static int glassfs_unlink (struct inode *dir, struct dentry *dentry)
static int glassfs_rmdir (struct inode *dir, struct dentry *dentry)
static int glassfs_getattr (struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
static int glassfs_setattr (struct dentry *dentry, struct iattr *attr)
static int glassfs_setxattr (struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
static ssize_t glassfs_getxattr (struct dentry *dentry, const char *name, void *value, size_t size)
static ssize_t glassfs_listxattr (struct dentry *dentry, char *list, size_t size)
static int glassfs_removexattr (struct dentry *dentry, const char *name)
static int glassfs_statfs (struct super_block *sb, struct kstatfs *buf)
static int glassfs_dentry_revalidate (struct dentry *dentry, struct nameidata *nd)
static int glassfs_readlink (struct dentry *dentry, char __user *buf, int buflen)
static int glassfs_follow_link (struct dentry *dentry, struct nameidata *nd)
static void glassfs_clear_inode (struct inode *inode)
static int glassfs_fill_super (struct super_block *sb, void *data, int silent)
static struct super_blockglassfs_get_sb (struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
static int __init init_glassfs_fs (void)
static void __exit exit_glassfs_fs (void)

Variables

static struct super_operations
static struct inode_operations
static struct file_operations
static struct dentry_operations
static struct file_system_type

Class Documentation

struct base_entry

Definition at line 19 of file glassfs.c.

Class Members
struct dentry * dentry
int is_avfs
struct vfsmount * mnt

Define Documentation

#define AVFS_MAGIC_CHAR   '#'

Definition at line 15 of file glassfs.c.

#define FUSE_MAGIC   0x65735546

Definition at line 13 of file glassfs.c.

#define GLASSFS_MAGIC   0x28476c61

Definition at line 12 of file glassfs.c.

#define OVERLAY_DIR   "/overlay"

Definition at line 16 of file glassfs.c.

#define OVERLAY_DIR_LEN   8

Definition at line 17 of file glassfs.c.


Function Documentation

static void change_list ( struct list_head oldlist,
struct list_head newlist 
) [static]

Definition at line 87 of file glassfs.c.

{
       struct list_head *prev = oldlist->prev;
       struct list_head *next = oldlist->next;
       prev->next = newlist;
       next->prev = newlist;
}

Here is the caller graph for this function:

static void exchange_files ( struct file *  file1,
struct file *  file2 
) [static]

Definition at line 101 of file glassfs.c.

{
       struct file tmp;
       
       exchange_lists(&file1->f_list, &file2->f_list);
       exchange_lists(&file1->f_ep_links, &file2->f_ep_links);

       tmp = *file1;
       *file1 = *file2;
       *file2 = tmp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void exchange_lists ( struct list_head list1,
struct list_head list2 
) [static]

Definition at line 95 of file glassfs.c.

{
       change_list(list1, list2);
       change_list(list2, list1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void __exit exit_glassfs_fs ( void  ) [static]

Definition at line 960 of file glassfs.c.

{
       unregister_filesystem(&glassfs_fs_type);
}
static struct inode* glassfs_alloc_inode ( struct super_block sb) [static, read]

Definition at line 39 of file glassfs.c.

{
       struct base_entry *be;
       struct inode * inode = new_inode(sb);
       if (!inode)
              return NULL;
       
       be = kmalloc(sizeof(struct base_entry), GFP_KERNEL);
       if (!be) {
              iput(inode);
              return NULL;
       }
       inode->u.generic_ip = be;
       be->mnt = NULL;
       be->dentry = NULL;
       
       return inode;
}

Here is the caller graph for this function:

static void glassfs_clear_inode ( struct inode *  inode) [static]

Definition at line 830 of file glassfs.c.

{
       struct base_entry *be = inode->u.generic_ip;
       //printk("glassfs_clear_inode\n");
       dput(be->dentry);
       mntput(be->mnt);
       kfree(be);
}
static int glassfs_create ( struct inode *  dir,
struct dentry *  dentry,
int  mode,
struct nameidata *  nd 
) [static]

Definition at line 412 of file glassfs.c.

{
       int err;
       struct base_entry *be = dir->u.generic_ip;
       struct inode *ndir = be->dentry->d_inode;
       struct dentry *ndentry;
       struct inode *inode = glassfs_alloc_inode(dir->i_sb);
       if (!inode)
              return -ENOMEM;

//     printk("glassfs_create\n");
       down(&ndir->i_sem);
       ndentry = lookup_hash(&dentry->d_name, be->dentry);
       if (IS_ERR(ndentry)) {
              err = PTR_ERR(ndentry);
              ndentry = NULL;
       }
       else
              err = vfs_create(ndir, ndentry, mode, NULL);
       up(&ndir->i_sem);
       if (!err && ndentry->d_inode) {
              struct inode *ninode = ndentry->d_inode;
              glassfs_fill_inode(inode, ninode->i_mode, ninode->i_rdev,
                               ndentry, be->mnt, be->is_avfs);
              d_instantiate(dentry, inode);
       } else
              iput(inode);

       dput(ndentry);

       return err;
}

Here is the call graph for this function:

static int glassfs_dentry_revalidate ( struct dentry *  dentry,
struct nameidata *  nd 
) [static]

Definition at line 775 of file glassfs.c.

{
       struct base_entry *be;
       //printk("glassfs_dentry_revalidate %.*s\n", dentry->d_name.len, dentry->d_name.name);

       if (!dentry->d_inode)
              return 0;

       be = dentry->d_inode->u.generic_ip;
       if (d_unhashed(be->dentry))
              return 0;

       if (be->dentry->d_op && be->dentry->d_op->d_revalidate)
              return be->dentry->d_op->d_revalidate(be->dentry, NULL);
       return 1;
}
static void glassfs_fill_inode ( struct inode *  inode,
int  mode,
dev_t  dev,
struct dentry *  ndentry,
struct vfsmount *  nmnt,
int  is_avfs 
) [static]

Definition at line 58 of file glassfs.c.

{
       struct base_entry *be = inode->u.generic_ip;

       be->dentry = dget(ndentry);
       be->mnt =  mntget(nmnt);
       be->is_avfs = is_avfs;

       inode->i_mode = mode;
       inode->i_rdev = dev;
       
       switch (mode & S_IFMT) {
       default:
              inode->i_op = &glassfs_file_inode_operations;
              inode->i_fop = &glassfs_file_operations;
              break;
       case S_IFDIR:
              inode->i_op = &glassfs_dir_inode_operations;
              inode->i_fop = &glassfs_dir_operations;
              break;
       case S_IFLNK:
              inode->i_op = &glassfs_symlink_inode_operations;
              inode->i_fop = &glassfs_file_operations;
              break;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int glassfs_fill_super ( struct super_block sb,
void *  data,
int  silent 
) [static]

Definition at line 906 of file glassfs.c.

{
       struct inode * inode;
       struct dentry * root;
       struct super_block *nsb;
       struct dentry * nroot;
       struct vfsmount *nmnt;

       inode = glassfs_alloc_inode(sb);
       if (!inode)
              return -ENOMEM;
       read_lock(&current->fs->lock);
       nroot = current->fs->root;
       nmnt = current->fs->rootmnt;
       glassfs_fill_inode(inode, S_IFDIR | 0755, 0, nroot, nmnt, 0);
       read_unlock(&current->fs->lock);
       
       nsb = nmnt->mnt_sb;
       sb->s_blocksize = nsb->s_blocksize;
       sb->s_blocksize_bits = nsb->s_blocksize_bits;
       sb->s_magic = GLASSFS_MAGIC;
       sb->s_op = &glassfs_ops;

       root = d_alloc_root(inode);
       if (!root) {
              iput(inode);
              return -ENOMEM;
       }
       sb->s_fs_info = nsb;
       root->d_op = &glassfs_dentry_operations;

       sb->s_root = root;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int glassfs_flush ( struct file *  file) [static]

Definition at line 198 of file glassfs.c.

{
        //printk("glassfs_flush\n");
        struct file *nfile = file->private_data;
        if (nfile->f_op && nfile->f_op->flush)
                return nfile->f_op->flush(nfile);
        else
                return 0;
}
static int glassfs_follow_link ( struct dentry *  dentry,
struct nameidata *  nd 
) [static]

Definition at line 813 of file glassfs.c.

{
       int err = 0;
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       struct dentry *ndentry = be->dentry;
       struct inode *ninode = ndentry->d_inode;
       
       if (ninode->i_op && ninode->i_op->follow_link) {
              err = security_inode_follow_link(ndentry, nd);
              if (!err) {
                     update_atime(ninode);
                     err = ninode->i_op->follow_link(ndentry, nd);
              }
       }
       return err;
}
static int glassfs_fsync ( struct file *  file,
struct dentry *  dentry,
int  datasync 
) [static]

Definition at line 183 of file glassfs.c.

{
       int err;
       struct file *nfile = file->private_data;
       struct address_space *mapping = nfile->f_mapping;

       if (!nfile->f_op || !nfile->f_op->fsync)
              return -EINVAL;
       down(&mapping->host->i_sem);
       err = nfile->f_op->fsync(nfile, nfile->f_dentry, datasync);
       up(&mapping->host->i_sem);
       return err;
}
static struct super_block* glassfs_get_sb ( struct file_system_type fs_type,
int  flags,
const char *  dev_name,
void *  data 
) [static, read]

Definition at line 941 of file glassfs.c.

{
//     printk("glassfs_get_sb\n");
       return get_sb_nodev(fs_type, flags, data, glassfs_fill_super);
}

Here is the call graph for this function:

static int glassfs_getattr ( struct vfsmount *  mnt,
struct dentry *  dentry,
struct kstat *  stat 
) [static]

Definition at line 667 of file glassfs.c.

{
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       //printk("glassfs_getattr (is avfs: %i)\n", be->is_avfs);
       return vfs_getattr(be->mnt, be->dentry, stat);
}
static ssize_t glassfs_getxattr ( struct dentry *  dentry,
const char *  name,
void *  value,
size_t  size 
) [static]

Definition at line 715 of file glassfs.c.

{
       ssize_t err;
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       struct dentry *ndentry = be->dentry;
       struct inode *ninode = ndentry->d_inode;

       err = -EOPNOTSUPP;
       if (ninode->i_op && ninode->i_op->getxattr) {
              err = security_inode_getxattr(ndentry, (char *) name);
              if (!err)
                     err = ninode->i_op->getxattr(ndentry, name, value, size);
       }
       return err;
}
static int glassfs_ioctl ( struct inode *  inode,
struct file *  file,
unsigned int  cmd,
unsigned long  arg 
) [static]

Definition at line 166 of file glassfs.c.

{
       int err;
       struct file *nfile = file->private_data;

       err = security_file_ioctl(nfile, cmd, arg);
       if (err)
              return err;

       err = -ENOTTY;
       if (nfile->f_op && nfile->f_op->ioctl)
              err = nfile->f_op->ioctl(nfile->f_dentry->d_inode, nfile,
                                    cmd, arg);
       return err;
}
static int glassfs_link ( struct dentry *  old_dentry,
struct inode *  dir,
struct dentry *  new_dentry 
) [static]

Definition at line 478 of file glassfs.c.

{
       int err;
       struct base_entry *be = dir->u.generic_ip;
       struct base_entry *old_be = old_dentry->d_inode->u.generic_ip;
       struct inode *ndir = be->dentry->d_inode;
       struct dentry *new_ndentry;
       struct inode *inode;

       if (be->mnt != old_be->mnt)
              return -EXDEV;

       inode = glassfs_alloc_inode(dir->i_sb);
       if (!inode)
              return -ENOMEM;

//     printk("glassfs_link\n");
       down(&ndir->i_sem);
       new_ndentry = lookup_hash(&new_dentry->d_name, be->dentry);
       if (IS_ERR(new_ndentry)) {
              err = PTR_ERR(new_ndentry);
              new_ndentry = NULL;
       } else 
              err = vfs_link(old_be->dentry, ndir, new_ndentry);
       up(&ndir->i_sem);
       if (!err && new_ndentry->d_inode) {
              struct inode *ninode = new_ndentry->d_inode;
              glassfs_fill_inode(inode, ninode->i_mode, ninode->i_rdev,
                               new_ndentry, be->mnt, be->is_avfs);
              d_instantiate(new_dentry, inode);
       } else
              iput(inode);

       dput(new_ndentry);

       return err;
}

Here is the call graph for this function:

static ssize_t glassfs_listxattr ( struct dentry *  dentry,
char *  list,
size_t  size 
) [static]

Definition at line 731 of file glassfs.c.

{
       ssize_t err;
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       struct dentry *ndentry = be->dentry;
       struct inode *ninode = ndentry->d_inode;

       err = -EOPNOTSUPP;
       if (ninode->i_op && ninode->i_op->listxattr) {
              err = security_inode_listxattr(ndentry);
              if (!err)
                     err = ninode->i_op->listxattr(ndentry, list, size);
       }
       return err;
}
static loff_t glassfs_llseek ( struct file *  file,
loff_t  offset,
int  origin 
) [static]

Definition at line 155 of file glassfs.c.

{
       struct file *nfile = file->private_data;
       loff_t (*fn)(struct file *, loff_t, int);

       fn = default_llseek;
       if (nfile->f_op && nfile->f_op->llseek)
              fn = nfile->f_op->llseek;
       return fn(nfile, offset, origin);
}
static struct dentry* glassfs_lookup ( struct inode *  dir,
struct dentry *  dentry,
struct nameidata *  nd 
) [static, read]

Definition at line 344 of file glassfs.c.

{
       struct base_entry *be = dir->u.generic_ip;
       struct dentry *ndentry;
       struct vfsmount *nmnt;
       struct inode *inode = NULL;
       int curravfs = be->is_avfs;

//     printk("glassfs_lookup\n");
       down(&be->dentry->d_inode->i_sem);
       ndentry = lookup_hash(&dentry->d_name, be->dentry);
       up(&be->dentry->d_inode->i_sem);
       if (IS_ERR(ndentry))
              return ndentry;

       nmnt = mntget(be->mnt);
       if (!is_create(nd) && !ndentry->d_inode && !curravfs && 
          is_avfs(dentry->d_name.name, dentry->d_name.len)) {
              struct base_entry avfsbe;
              int err;
              int total_link_count_save = current->total_link_count;
              err = lookup_avfs(dentry, nd, nmnt, &avfsbe);
              current->total_link_count = total_link_count_save;
              if (!err) {
                     if (avfsbe.dentry->d_inode) {
                            dput(ndentry);
                            mntput(nmnt);
                            ndentry = avfsbe.dentry;
                            nmnt = avfsbe.mnt;
                            curravfs = 1;
                     } else {
                            dput(avfsbe.dentry);
                            mntput(avfsbe.mnt);
                     }
              }
       }

       if (ndentry->d_inode) {
              struct inode *ninode = ndentry->d_inode;
              inode = glassfs_alloc_inode(dir->i_sb);
              if (!inode) {
                     dput(ndentry);
                     mntput(nmnt);
                     return ERR_PTR(-ENOMEM);
              }
              glassfs_fill_inode(inode, ninode->i_mode, ninode->i_rdev,
                               ndentry, nmnt, curravfs);
       }

       dentry->d_op = &glassfs_dentry_operations;
       dput(ndentry);
       mntput(nmnt);
       
       return d_splice_alias(inode, dentry);
}

Here is the call graph for this function:

static int glassfs_mkdir ( struct inode *  dir,
struct dentry *  dentry,
int  mode 
) [static]

Definition at line 446 of file glassfs.c.

{
       int err;
       struct base_entry *be = dir->u.generic_ip;
       struct inode *ndir = be->dentry->d_inode;
       struct dentry *ndentry;
       struct inode *inode = glassfs_alloc_inode(dir->i_sb);
       if (!inode)
              return -ENOMEM;

//     printk("glassfs_mkdir\n");
       down(&ndir->i_sem);
       ndentry = lookup_hash(&dentry->d_name, be->dentry);
       if (IS_ERR(ndentry)) {
              err = PTR_ERR(ndentry);
              ndentry = NULL;
       } else 
              err = vfs_mkdir(ndir, ndentry, mode);
       up(&ndir->i_sem);
       if (!err && ndentry->d_inode) {
              struct inode *ninode = ndentry->d_inode;
              glassfs_fill_inode(inode, ninode->i_mode, ninode->i_rdev,
                               ndentry, be->mnt, be->is_avfs);
              d_instantiate(dentry, inode);
       } else
              iput(inode);

       dput(ndentry);

       return err;
}

Here is the call graph for this function:

static int glassfs_mknod ( struct inode *  dir,
struct dentry *  dentry,
int  mode,
dev_t  dev 
) [static]

Definition at line 550 of file glassfs.c.

{
       int err;
       struct base_entry *be = dir->u.generic_ip;
       struct inode *ndir = be->dentry->d_inode;
       struct dentry *ndentry;
       struct inode *inode = glassfs_alloc_inode(dir->i_sb);
       if (!inode)
              return -ENOMEM;

//     printk("glassfs_mknod\n");
       down(&ndir->i_sem);
       ndentry = lookup_hash(&dentry->d_name, be->dentry);
       if (IS_ERR(ndentry)) {
              err = PTR_ERR(ndentry);
              ndentry = NULL;
       } else 
              err = vfs_mknod(ndir, ndentry, mode, dev);
       up(&ndir->i_sem);
       if (!err && ndentry->d_inode) {
              struct inode *ninode = ndentry->d_inode;
              glassfs_fill_inode(inode, ninode->i_mode, ninode->i_rdev,
                               ndentry, be->mnt, be->is_avfs);
              d_instantiate(dentry, inode);
       } else
              iput(inode);
       
       dput(ndentry);

       return err;
}

Here is the call graph for this function:

static int glassfs_open ( struct inode *  inode,
struct file *  file 
) [static]

Definition at line 113 of file glassfs.c.

{
       struct base_entry *be = inode->u.generic_ip;
       struct vfsmount *nmnt = mntget(be->mnt);
       struct dentry *ndentry = dget(be->dentry);
       struct file *nfile;
       //printk("glassfs_open %.*s\n", ndentry->d_name.len, ndentry->d_name.name);
       nfile = dentry_open(ndentry, nmnt, file->f_flags);
       if (IS_ERR(nfile))
              return PTR_ERR(nfile);

       exchange_files(file, nfile);
       fput(nfile);

       return 0;
}

Here is the call graph for this function:

static int glassfs_open_dir ( struct inode *  inode,
struct file *  file 
) [static]

Definition at line 130 of file glassfs.c.

{
       struct base_entry *be = inode->u.generic_ip;
       struct file *nfile;
       //printk("glassfs_open_dir\n")
       nfile = dentry_open(dget(be->dentry), mntget(be->mnt), file->f_flags);
       if (IS_ERR(nfile))
              return PTR_ERR(nfile);
       
       file->private_data = nfile;
       return 0;
}
static int glassfs_permission ( struct inode *  inode,
int  mask,
struct nameidata *  nd 
) [static]

Definition at line 401 of file glassfs.c.

{
       struct base_entry *be = inode->u.generic_ip;
       struct inode *ninode = be->dentry->d_inode;
//     printk("glassfs_permission\n");
       /* Exec needs i_mode to contain the correct permission bits */
       inode->i_mode = ninode->i_mode;
       return permission(ninode, mask, NULL);
}
static int glassfs_readdir ( struct file *  file,
void *  buf,
filldir_t  filler 
) [static]

Definition at line 149 of file glassfs.c.

{
       struct file *nfile = file->private_data;
       return vfs_readdir(nfile, filler, buf);
}
static int glassfs_readlink ( struct dentry *  dentry,
char __user *  buf,
int  buflen 
) [static]

Definition at line 793 of file glassfs.c.

{

       int err;
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       struct dentry *ndentry = be->dentry;
       struct inode *ninode = ndentry->d_inode;
       
       err = -EINVAL;
       if (ninode->i_op && ninode->i_op->readlink) {
              err = security_inode_readlink(ndentry);
              if (!err) {
                     update_atime(ninode);
                     err = ninode->i_op->readlink(ndentry, buf, buflen);
              }
       }
       return err;
}
static int glassfs_release ( struct inode *  inode,
struct file *  file 
) [static]

Definition at line 143 of file glassfs.c.

{
       struct file *nfile = file->private_data;
       return filp_close(nfile, current->files);
}
static int glassfs_removexattr ( struct dentry *  dentry,
const char *  name 
) [static]

Definition at line 747 of file glassfs.c.

{
       int err;
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       struct dentry *ndentry = be->dentry;
       struct inode *ninode = ndentry->d_inode;

       err = -EOPNOTSUPP;
       if (ninode->i_op && ninode->i_op->removexattr) {
              err = security_inode_removexattr(ndentry, (char *) name);
              if (!err) {
                     /* strange: the security... usually is within
                           the locked region */
                     down(&ninode->i_sem);
                     err = ninode->i_op->removexattr(ndentry, name);
                     up(&ninode->i_sem);
              }
       }
       return err;
}
static int glassfs_rename ( struct inode *  old_dir,
struct dentry *  old_dentry,
struct inode *  new_dir,
struct dentry *  new_dentry 
) [static]

Definition at line 583 of file glassfs.c.

{
       int err;
       struct base_entry *old_be = old_dir->u.generic_ip;
       struct base_entry *new_be = new_dir->u.generic_ip;
       struct inode *old_ndir = old_be->dentry->d_inode;
       struct inode *new_ndir = new_be->dentry->d_inode;
       struct dentry *old_ndentry = NULL;
       struct dentry *new_ndentry = NULL;
       struct dentry *trap;

       if (old_be->mnt != new_be->mnt)
              return -EXDEV;

       trap = lock_rename(new_be->dentry, old_be->dentry);
       old_ndentry = lookup_hash(&old_dentry->d_name, old_be->dentry);
       if (IS_ERR(old_ndentry)) {
              err = PTR_ERR(old_ndentry);
              old_ndentry = NULL;
              goto out;
       }
       if (old_ndentry == trap) {
              err = -EINVAL;
              goto out;
       }
       if (!old_ndentry->d_inode) {
              err = -ENOENT;
              goto out;
       }
              
       new_ndentry = lookup_hash(&new_dentry->d_name, new_be->dentry);
       if (IS_ERR(new_ndentry)) {
              err = PTR_ERR(new_ndentry);
              new_ndentry = NULL;
              goto out;
       }
       if (new_ndentry == trap) {
              err = -ENOTEMPTY;
              goto out;
       }
       err = vfs_rename(old_ndir, old_ndentry, new_ndir, new_ndentry);

  out:
       unlock_rename(new_be->dentry, old_be->dentry);
       dput(new_ndentry);
       dput(old_ndentry);
       
       return err;
}
static int glassfs_rmdir ( struct inode *  dir,
struct dentry *  dentry 
) [static]

Definition at line 651 of file glassfs.c.

{
       int err;
       struct base_entry *dir_be = dir->u.generic_ip;
       struct inode *ndir = dir_be->dentry->d_inode;
       struct base_entry *be = dentry->d_inode->u.generic_ip;

//     printk("glassfs_rmdir\n");
       down(&ndir->i_sem);
       err = vfs_rmdir(ndir, be->dentry);
       up(&ndir->i_sem);
       if (!err)
              dentry->d_inode->i_nlink = 0;
       return err;
}
static int glassfs_setattr ( struct dentry *  dentry,
struct iattr *  attr 
) [static]

Definition at line 675 of file glassfs.c.

{
       int err;
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       struct inode *ninode = be->dentry->d_inode;
       
       if (IS_RDONLY(ninode))
              return -EROFS;

       if (IS_IMMUTABLE(ninode) || IS_APPEND(ninode))
              return -EPERM;

       down(&ninode->i_sem);
       err = notify_change(be->dentry, attr);
       up(&ninode->i_sem);
       return err;
}
static int glassfs_setxattr ( struct dentry *  dentry,
const char *  name,
const void *  value,
size_t  size,
int  flags 
) [static]

Definition at line 693 of file glassfs.c.

{
       int err;
       struct base_entry *be = dentry->d_inode->u.generic_ip;
       struct dentry *ndentry = be->dentry;
       struct inode *ninode = ndentry->d_inode;
       
       err = -EOPNOTSUPP;
       if (ninode->i_op && ninode->i_op->setxattr) {
              down(&ninode->i_sem);
              err = security_inode_setxattr(ndentry, (char *) name, (void *) value, size, flags);
              if (!err) {
                     err = ninode->i_op->setxattr(ndentry, name, value, size, flags);
                     if (!err)
                            security_inode_post_setxattr(ndentry, (char *) name, (void *) value, size, flags);
              }
              up(&ninode->i_sem);
       }
       return err;
}
static int glassfs_statfs ( struct super_block sb,
struct kstatfs *  buf 
) [static]

Definition at line 768 of file glassfs.c.

{
       struct super_block *nsb = sb->s_fs_info;
//     printk("glassfs_statfs\n");
       return vfs_statfs(nsb, buf);
}
static int glassfs_symlink ( struct inode *  dir,
struct dentry *  dentry,
const char *  oldname 
) [static]

Definition at line 517 of file glassfs.c.

{
       int err;
       struct base_entry *be = dir->u.generic_ip;
       struct inode *ndir = be->dentry->d_inode;
       struct dentry *ndentry;
       struct inode *inode = glassfs_alloc_inode(dir->i_sb);
       if (!inode)
              return -ENOMEM;

//     printk("glassfs_symlink\n");
       down(&ndir->i_sem);
       ndentry = lookup_hash(&dentry->d_name, be->dentry);
       if (IS_ERR(ndentry)) {
              err = PTR_ERR(ndentry);
              ndentry = NULL;
       } else 
              err = vfs_symlink(ndir, ndentry, oldname);
       up(&ndir->i_sem);
       if (!err && ndentry->d_inode) {
              struct inode *ninode = ndentry->d_inode;
              glassfs_fill_inode(inode, ninode->i_mode, ninode->i_rdev,
                               ndentry, be->mnt, be->is_avfs);
              d_instantiate(dentry, inode);
       } else
              iput(inode);

       dput(ndentry);

       return err;
}

Here is the call graph for this function:

static int glassfs_unlink ( struct inode *  dir,
struct dentry *  dentry 
) [static]

Definition at line 634 of file glassfs.c.

{
       int err;
       struct base_entry *dir_be = dir->u.generic_ip;
       struct inode *ndir = dir_be->dentry->d_inode;
       struct base_entry *be = dentry->d_inode->u.generic_ip;

//     printk("glassfs_unlink\n");
       down(&ndir->i_sem);
       err = vfs_unlink(ndir, be->dentry);
       up(&ndir->i_sem);
       if (!err)
              dentry->d_inode->i_nlink = 0;
       
       return err;
}
static int __init init_glassfs_fs ( void  ) [static]

Definition at line 955 of file glassfs.c.

{
       return register_filesystem(&glassfs_fs_type);
}
static int is_avfs ( const unsigned char *  name,
unsigned int  len 
) [static]

Definition at line 209 of file glassfs.c.

{
       for (; len--; name++)
              if (*name == (unsigned char) AVFS_MAGIC_CHAR)
                     return 1;
       return 0;
}

Here is the caller graph for this function:

static int is_create ( struct nameidata *  nd) [inline, static]

Definition at line 335 of file glassfs.c.

{
       if (!nd)
              return 1;
       if ((nd->flags & LOOKUP_CREATE) && !(nd->flags & LOOKUP_CONTINUE))
              return 1;
       return 0;
}

Here is the caller graph for this function:

static int lookup_avfs ( struct dentry *  dentry,
struct nameidata *  nd,
struct vfsmount *  nmnt,
struct base_entry be 
) [static]

Definition at line 287 of file glassfs.c.

{
       int err;
       char *page;
       char *path;
       
       err = -ENOMEM;
       page = (char *) __get_free_page(GFP_KERNEL);
       if (page) {
              struct nameidata avfsnd;
              unsigned int offset = PAGE_SIZE - dentry->d_name.len - 2;
              spin_lock(&dcache_lock);
              path = my_d_path(nd->dentry,nd->mnt, nd->mnt->mnt_sb->s_root, nd->mnt, page, offset);
              spin_unlock(&dcache_lock);
              err = -ENAMETOOLONG;
              if (!IS_ERR(path) && page + OVERLAY_DIR_LEN < path) {
                     unsigned int pathlen = strlen(path);
                     path[pathlen] = '/';
                     memcpy(path + pathlen + 1, dentry->d_name.name,
                            dentry->d_name.len);
                     path[1 + pathlen + dentry->d_name.len] = '\0';
                     path -= OVERLAY_DIR_LEN;
                     memcpy(path, OVERLAY_DIR, OVERLAY_DIR_LEN);

                     //printk("lookup_avfs: '%s'\n", path);
                     avfsnd.last_type = LAST_ROOT;
                     avfsnd.flags = 0;
                     avfsnd.mnt = mntget(nmnt);
                     avfsnd.dentry = dget(nmnt->mnt_sb->s_root);

                     err = path_walk(path, &avfsnd);
                     if (!err) {
                            if (avfsnd.dentry->d_sb->s_magic != FUSE_MAGIC) {
                                   printk("glassfs: not an AVFS inode\n");
                                   path_release(&avfsnd);
                                   err = -ENOENT;
                            } else {
                                   be->mnt = avfsnd.mnt;
                                   be->dentry = avfsnd.dentry;
                            }
                     }
              }
              free_page((unsigned long) page);
       }
       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* my_d_path ( struct dentry *  dentry,
struct vfsmount *  vfsmnt,
struct dentry *  root,
struct vfsmount *  rootmnt,
char *  buffer,
int  buflen 
) [static]

Definition at line 218 of file glassfs.c.

{
       char * end = buffer+buflen;
       char * retval;
       int namelen;

       *--end = '\0';
       buflen--;
       if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
              buflen -= 10;
              end -= 10;
              if (buflen < 0)
                     goto Elong;
              memcpy(end, " (deleted)", 10);
       }

       if (buflen < 1)
              goto Elong;
       /* Get '/' right */
       retval = end-1;
       *retval = '/';

       for (;;) {
              struct dentry * parent;

              if (dentry == root && vfsmnt == rootmnt)
                     break;
              if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
                     /* Global root? */
                     spin_lock(&vfsmount_lock);
                     if (vfsmnt->mnt_parent == vfsmnt) {
                            spin_unlock(&vfsmount_lock);
                            goto global_root;
                     }
                     dentry = vfsmnt->mnt_mountpoint;
                     vfsmnt = vfsmnt->mnt_parent;
                     spin_unlock(&vfsmount_lock);
                     continue;
              }
              parent = dentry->d_parent;
              prefetch(parent);
              namelen = dentry->d_name.len;
              buflen -= namelen + 1;
              if (buflen < 0)
                     goto Elong;
              end -= namelen;
              memcpy(end, dentry->d_name.name, namelen);
              *--end = '/';
              retval = end;
              dentry = parent;
       }

       return retval;

global_root:
       namelen = dentry->d_name.len;
       buflen -= namelen;
       if (buflen < 0)
              goto Elong;
       retval -= namelen-1; /* hit the slash */
       memcpy(retval, dentry->d_name.name, namelen);
       return retval;
Elong:
       return ERR_PTR(-ENAMETOOLONG);
}

Here is the caller graph for this function:


Variable Documentation

static struct dentry_operations [static]
Initial value:
 {
       .d_revalidate = glassfs_dentry_revalidate,
}

Definition at line 37 of file glassfs.c.

static struct file_operations [static]
Initial value:
 {
       .llseek              = glassfs_llseek,
       .read         = generic_read_dir, 
       .readdir      = glassfs_readdir,
       .ioctl        = glassfs_ioctl,
       .open         = glassfs_open_dir,
       .flush        = glassfs_flush,
       .release      = glassfs_release,
       .fsync        = glassfs_fsync,
}

Definition at line 33 of file glassfs.c.

struct file_system_type [static]
Initial value:
 {
       .owner        = THIS_MODULE,
       .name         = "glassfs",
       .get_sb              = glassfs_get_sb,
       .kill_sb      = kill_anon_super,
}

Definition at line 948 of file glassfs.c.

static struct inode_operations [static]
Initial value:
 {
       .create              = glassfs_create,
       .lookup              = glassfs_lookup,
       .link         = glassfs_link,
       .unlink              = glassfs_unlink,
       .symlink      = glassfs_symlink,
       .mkdir        = glassfs_mkdir,
       .rmdir        = glassfs_rmdir,
       .mknod        = glassfs_mknod,
       .rename              = glassfs_rename,
       .permission   = glassfs_permission,
       .getattr      = glassfs_getattr,
       .setattr      = glassfs_setattr,
       .setxattr     = glassfs_setxattr,
       .getxattr     = glassfs_getxattr,
       .listxattr    = glassfs_listxattr,
       .removexattr  = glassfs_removexattr,
}

Definition at line 32 of file glassfs.c.

static struct super_operations [static]
Initial value:
 {
       .statfs              = glassfs_statfs,
       .clear_inode  = glassfs_clear_inode,
}

Definition at line 31 of file glassfs.c.