Diff for /linux-2.6-xfs/mainline-patches/linux-2.6/xfs_vfs.c between versions 1.2 and 1.3

version 1.2, 2007/01/16 14:53:53 version 1.3, 2007/01/16 14:56:58
Line 0 Line 1
   Definition of vfs_get_inode for ioops module.
   Add behaviour module support.
   
   --- /tmp/diff_prompt.12865.update_only  2006-12-15 22:49:16.949849328 +1100
   +++ linux-2.6/xfs_vfs.c 2006-12-15 17:48:29.000000000 +1100
   @@ -183,6 +183,19 @@
           return ((*bhvtovfsops(next)->vfs_quotactl)(next, cmd, id, addr));
    }
    
   +struct inode *
   +vfs_get_inode(
   +       struct bhv_desc         *bdp,
   +       xfs_ino_t               ino,
   +       int                     fl)
   +{
   +       struct bhv_desc         *next = bdp;
   +
   +       while (! (bhvtovfsops(next))->vfs_get_inode)
   +               next = BHV_NEXTNULL(next);
   +       return ((*bhvtovfsops(next)->vfs_get_inode)(next, ino, fl));
   +}
   +
    void
    vfs_init_vnode(
           struct bhv_desc         *bdp,
   @@ -262,18 +275,6 @@
    }
    
    void
   -vfs_insertops(
   -       struct bhv_vfs          *vfsp,
   -       struct bhv_module_vfsops *vfsops)
   -{
   -       struct bhv_desc         *bdp;
   -
   -       bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP);
   -       bhv_desc_init(bdp, NULL, vfsp, vfsops);
   -       bhv_insert(&vfsp->vfs_bh, bdp);
   -}
   -
   -void
    vfs_insertbhv(
           struct bhv_vfs          *vfsp,
           struct bhv_desc         *bdp,
   @@ -284,6 +285,99 @@
           bhv_insert_initial(&vfsp->vfs_bh, bdp);
    }
    
   +/*
   + * Implementation for behaviours-as-modules
   + */
   +
   +typedef struct bhv_module_list {
   +       struct list_head        bm_list;
   +       struct module *         bm_module;
   +       const char *            bm_name;
   +       void *                  bm_ops;
   +} bhv_module_list_t;
   +
   +static DEFINE_SPINLOCK(bhv_lock);
   +static struct list_head bhv_list = LIST_HEAD_INIT(bhv_list);
   +
   +void
   +bhv_module_init(
   +       const char              *name,
   +       struct module           *module,
   +       const void              *ops)
   +{
   +       bhv_module_list_t       *bm, *entry, *n;
   +
   +       bm = kmem_alloc(sizeof(struct bhv_module_list), KM_SLEEP);
   +       INIT_LIST_HEAD(&bm->bm_list);
   +       bm->bm_module = module;
   +       bm->bm_name = name;
   +       bm->bm_ops = (void *)ops;
   +
   +       spin_lock(&bhv_lock);
   +       list_for_each_entry_safe(entry, n, &bhv_list, bm_list)
   +               BUG_ON(strcmp(entry->bm_name, name) == 0);
   +       list_add(&bm->bm_list, &bhv_list);
   +       spin_unlock(&bhv_lock);
   +}
   +
   +void
   +bhv_module_exit(
   +       const char              *name)
   +{
   +       bhv_module_list_t       *entry, *n;
   +
   +       spin_lock(&bhv_lock);
   +       list_for_each_entry_safe(entry, n, &bhv_list, bm_list)
   +               if (strcmp(entry->bm_name, name) == 0)
   +                       list_del(&entry->bm_list);
   +       spin_unlock(&bhv_lock);
   +}
   +
   +STATIC void *
   +bhv_insert_module(
   +       const char              *name,
   +       const char              *modname)
   +{
   +       bhv_module_list_t       *entry, *n;
   +       void                    *ops = NULL;
   +
   +       spin_lock(&bhv_lock);
   +       list_for_each_entry_safe(entry, n, &bhv_list, bm_list)
   +               if (strcmp(entry->bm_name, name) == 0 &&
   +                   try_module_get(entry->bm_module))
   +                       ops = entry->bm_ops;
   +       spin_unlock(&bhv_lock);
   +       return ops;
   +}
   +
   +STATIC void
   +bhv_remove_module(
   +       const char              *name)
   +{
   +       bhv_module_list_t       *entry, *n;
   +
   +       spin_lock(&bhv_lock);
   +       list_for_each_entry_safe(entry, n, &bhv_list, bm_list)
   +               if (strcmp(entry->bm_name, name) == 0)
   +                   module_put(entry->bm_module);
   +       spin_unlock(&bhv_lock);
   +}
   +
   +STATIC void *
   +bhv_lookup_module(
   +       const char              *name,
   +       const char              *module)
   +{
   +       void                    *ops;
   +
   +       ops = bhv_insert_module(name, module);
   +       if (!ops && module) {
   +               request_module("%s", module);
   +               ops = bhv_insert_module(name, module);
   +       }
   +       return ops;
   +}
   +
    void
    bhv_remove_vfsops(
           struct bhv_vfs          *vfsp,
   @@ -292,10 +386,14 @@
           struct bhv_desc         *bhv;
    
           bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos);
   -       if (!bhv)
   -               return;
   -       bhv_remove(&vfsp->vfs_bh, bhv);
   -       kmem_free(bhv, sizeof(*bhv));
   +       if (bhv) {
   +               struct bhv_module       *bm;
   +
   +               bm = (bhv_module_t *) BHV_PDATA(bhv);
   +               bhv_remove(&vfsp->vfs_bh, bhv);
   +               bhv_remove_module(bm->bm_name);
   +               kmem_free(bhv, sizeof(*bhv));
   +       }
    }
    
    void
   @@ -307,6 +405,7 @@
    
           bhv_remove_vfsops(vfsp, VFS_POSITION_QM);
           bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
   +       bhv_remove_vfsops(vfsp, VFS_POSITION_IO);
           if (!freebase)
                   return;
           mp = XFS_VFSTOM(vfsp);
   @@ -315,6 +414,25 @@
    }
    
    void
   +bhv_get_vfsops(
   +       struct bhv_vfs          *vfsp,
   +       const char              *name,
   +       const char              *module)
   +{
   +       struct bhv_vfsops       *ops;
   +
   +       ops = (struct bhv_vfsops *) bhv_lookup_module(name, module);
   +       if (ops) {
   +               struct bhv_module       *bm;
   +
   +               bm = kmem_alloc(sizeof(struct bhv_module), KM_SLEEP);
   +               bm->bm_name = name;
   +               bhv_desc_init(&bm->bm_desc, bm, vfsp, ops);
   +               bhv_insert(&vfsp->vfs_bh, &bm->bm_desc);
   +       }
   +}
   +
   +void
    bhv_insert_all_vfsops(
           struct bhv_vfs          *vfsp)
    {
   @@ -322,6 +440,10 @@
    
           mp = xfs_mount_init();
           vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
   -       vfs_insertdmapi(vfsp);
   -       vfs_insertquota(vfsp);
   +       bhv_get_vfsops(vfsp, XFS_DMOPS,
   +               xfs_probe_dmapi ? XFS_DM_MODULE : NULL);
   +       bhv_get_vfsops(vfsp, XFS_QMOPS,
   +               xfs_probe_quota ? XFS_QM_MODULE : NULL);
   +       bhv_get_vfsops(vfsp, XFS_IOOPS,
   +               xfs_probe_ioops ? XFS_IO_MODULE : NULL);
    }

Removed from v.1.2  
changed lines
  Added in v.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>