patch for SLES 10 SP2

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

patch for SLES 10 SP2

Lino Sanfilippo


Geschäftsführender Gesellschafter: Tjark Auerbach
Sitz der Gesellschaft: Tettnang
Handelsregister: Amtsgericht Ulm, HRB 630992
ALLGEMEINE GESCHÄFTSBEDINGUNGEN
Es gelten unsere Allgemeinen Geschäftsbedingungen
(AGB). Sie finden sie in der jeweils gültigen Fassung
im Internet unter http://www.avira.de/agb
***************************************************
diff -x CVS -rup dazukofs-3.0.0/CHANGELOG dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/CHANGELOG
--- dazukofs-3.0.0/CHANGELOG 2009-02-22 17:51:22.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/CHANGELOG 2009-02-06 17:48:21.000000000 +0100
@@ -2,11 +2,6 @@
  DazukoFS CHANGELOG
 ====================
 
-3.0.0 (2009-02-22)
-- added define for version number output
-- added patches for various other kernels
-
-
 3.0.0-rc4 (2008-11-30)
 - fix incorrect dentry/vfsmnt referencing when access denied
 - fix improper cleanup in several error handling conditions
diff -x CVS -rup dazukofs-3.0.0/ctrl_dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ctrl_dev.c
--- dazukofs-3.0.0/ctrl_dev.c 2009-02-22 17:45:20.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ctrl_dev.c 2009-02-06 18:27:43.000000000 +0100
@@ -21,7 +21,8 @@
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
-#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
 
 #include "event.h"
 #include "dev.h"
@@ -158,7 +159,11 @@ static ssize_t dazukofs_ctrl_write(struc
  return ret;
 }
 
-static struct cdev ctrl_cdev;
+static struct {
+ struct cdev cdev;
+ struct device dev;
+ struct class_device cls_dev;
+} ctrl_dev;
 
 static struct file_operations ctrl_fops = {
  .owner = THIS_MODULE,
@@ -168,38 +173,67 @@ static struct file_operations ctrl_fops
  .write = dazukofs_ctrl_write,
 };
 
+static void dazukofs_ctrl_class_dev_release(struct class_device *dev)
+{
+ // nothing
+}
+
+static void dazukofs_ctrl_dev_release(struct device *dev)
+{
+ // nothing
+}
+
 int dazukofs_ctrl_dev_init(int dev_major, int dev_minor,
    struct class *dazukofs_class)
 {
  int err = 0;
- struct device *dev;
+ dev_t devt;
+
+ devt = MKDEV(dev_major, dev_minor);
 
  /* setup cdev for control */
- cdev_init(&ctrl_cdev, &ctrl_fops);
- ctrl_cdev.owner = THIS_MODULE;
- err = cdev_add(&ctrl_cdev, MKDEV(dev_major, dev_minor), 1);
+ cdev_init(&ctrl_dev.cdev, &ctrl_fops);
+ ctrl_dev.cdev.owner = THIS_MODULE;
+ err = cdev_add(&ctrl_dev.cdev, devt, 1);
  if (err)
- goto error_out1;
+ return err;
 
- /* create control device */
- dev = device_create(dazukofs_class, NULL, MKDEV(dev_major, dev_minor),
-    NULL, "%s.ctrl", DEVICE_NAME);
- if (IS_ERR(dev)) {
- err = PTR_ERR(dev);
- goto error_out2;
- }
 
+ ctrl_dev.dev.parent = &platform_bus;
+ ctrl_dev.dev.release = dazukofs_ctrl_dev_release;
+ snprintf(ctrl_dev.dev.bus_id, BUS_ID_SIZE, "%s.ctrl", DEVICE_NAME);
+
+ err = device_register(&ctrl_dev.dev);
+
+ if (err)
+ goto error_out;
+
+ ctrl_dev.cls_dev.release = dazukofs_ctrl_class_dev_release;
+ ctrl_dev.cls_dev.class = dazukofs_class;
+ ctrl_dev.cls_dev.dev = &ctrl_dev.dev;
+
+ snprintf(ctrl_dev.cls_dev.class_id, BUS_ID_SIZE, "%s.ctrl", DEVICE_NAME);
+ ctrl_dev.cls_dev.devt = devt;
+
+ err = class_device_register(&ctrl_dev.cls_dev);
+
+ if (err)
+ goto error_out2;
+
  return 0;
 
 error_out2:
- cdev_del(&ctrl_cdev);
-error_out1:
+ device_unregister(&ctrl_dev.dev);
+error_out:
+ cdev_del(&ctrl_dev.cdev);
  return err;
 }
 
+
 void dazukofs_ctrl_dev_destroy(int dev_major, int dev_minor,
        struct class *dazukofs_class)
 {
- device_destroy(dazukofs_class, MKDEV(dev_major, dev_minor));
- cdev_del(&ctrl_cdev);
+ class_device_unregister(&ctrl_dev.cls_dev);
+ device_unregister(&ctrl_dev.dev);
+ cdev_del(&ctrl_dev.cdev);
 }
diff -x CVS -rup dazukofs-3.0.0/dazukofs_fs.h dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dazukofs_fs.h
--- dazukofs-3.0.0/dazukofs_fs.h 2009-02-22 17:43:11.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dazukofs_fs.h 2009-07-03 18:02:12.000000000 +0200
@@ -3,7 +3,7 @@
    Copyright (C) 1997-2004 Erez Zadok
    Copyright (C) 2001-2004 Stony Brook University
    Copyright (C) 2004-2007 International Business Machines Corp.
-   Copyright (C) 2008-2009 John Ogness
+   Copyright (C) 2008 John Ogness
      Author: John Ogness <[hidden email]>
 
    This program is free software; you can redistribute it and/or
@@ -24,12 +24,10 @@
 #ifndef __DAZUKOFS_FS_H
 #define __DAZUKOFS_FS_H
 
-#define DAZUKOFS_VERSION "3.0.0"
-
 extern struct kmem_cache *dazukofs_dentry_info_cachep;
 extern struct kmem_cache *dazukofs_file_info_cachep;
 extern struct file_operations dazukofs_main_fops;
-extern const struct file_operations dazukofs_dir_fops;
+extern struct file_operations dazukofs_dir_fops;
 extern struct dentry_operations dazukofs_dops;
 extern struct address_space_operations dazukofs_aops;
 
@@ -59,6 +57,37 @@ struct dazukofs_file_info {
  struct file *lower_file;
 };
 
+void fsstack_copy_inode_size(struct inode *dst, const struct inode *src);
+
+static inline
+void fsstack_copy_attr_atime(struct inode *dst, const struct inode *src)
+{
+ dst->i_atime = src->i_atime;
+}
+
+static inline
+void fsstack_copy_attr_times(struct inode *dst, const struct inode *src)
+{
+ dst->i_atime = src->i_atime;
+ dst->i_mtime = src->i_mtime;
+ dst->i_ctime = src->i_ctime;
+}
+
+static inline
+void fsstack_copy_attr_all(struct inode *dst, const struct inode *src)
+{
+ dst->i_mode = src->i_mode;
+ dst->i_uid = src->i_uid;
+ dst->i_gid = src->i_gid;
+ dst->i_rdev = src->i_rdev;
+ dst->i_atime = src->i_atime;
+ dst->i_mtime = src->i_mtime;
+ dst->i_ctime = src->i_ctime;
+ dst->i_blksize = src->i_blksize;
+ dst->i_blkbits = src->i_blkbits;
+ dst->i_flags = src->i_flags;
+}
+
 static inline
 struct dazukofs_sb_info *GET_SB_INFO(struct super_block *upper_sb)
 {
diff -x CVS -rup dazukofs-3.0.0/dentry.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dentry.c
--- dazukofs-3.0.0/dentry.c 2009-02-22 17:44:22.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dentry.c 2009-02-06 17:48:21.000000000 +0100
@@ -25,7 +25,7 @@
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
-#include <linux/fs_stack.h>
+
 
 #include "dazukofs_fs.h"
 
@@ -65,19 +65,19 @@ static int dazukofs_d_revalidate(struct
 
  lower_mnt = GET_LOWER_MNT(dentry);
 
- vfsmount_save = nd->path.mnt;
- dentry_save = nd->path.dentry;
+ vfsmount_save = nd->mnt;
+ dentry_save = nd->dentry;
 
- nd->path.mnt = mntget(lower_mnt);
- nd->path.dentry = dget(lower_dentry);
+ nd->mnt = mntget(lower_mnt);
+ nd->dentry = dget(lower_dentry);
 
  valid = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
 
  mntput(lower_mnt);
  dput(lower_dentry);
 
- nd->path.mnt = vfsmount_save;
- nd->path.dentry = dentry_save;
+ nd->mnt = vfsmount_save;
+ nd->dentry = dentry_save;
 
  /* update the inode, even if d_revalidate() != 1 */
  if (dentry->d_inode) {
@@ -85,7 +85,7 @@ static int dazukofs_d_revalidate(struct
 
  lower_inode = GET_LOWER_INODE(dentry->d_inode);
 
- fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL);
+ fsstack_copy_attr_all(dentry->d_inode, lower_inode);
  }
 out:
  return valid;
diff -x CVS -rup dazukofs-3.0.0/dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dev.c
--- dazukofs-3.0.0/dev.c 2009-02-22 17:42:25.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dev.c 2009-02-06 17:48:21.000000000 +0100
@@ -21,18 +21,31 @@
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
-#include <linux/uaccess.h>
 
+#include <asm/uaccess.h>
 #include "dazukofs_fs.h"
 #include "event.h"
 #include "dev.h"
 
+
+//static CLASS_DEVICE_ATTR(dev, S_IRUGO, read_devnum, NULL);
+
 static struct class *dazukofs_class;
 
 static int dev_major;
 static int dev_minor_start;
 static int dev_minor_end;
 
+#if 0
+static ssize_t read_devnum(strut class_device *cls_dev, char *buf)
+{
+ dev_t devnum;
+
+ devnum = cls_dev->dev->
+
+}
+#endif
+
 int dazukofs_dev_init(void)
 {
  int err = 0;
diff -x CVS -rup dazukofs-3.0.0/event.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/event.c
--- dazukofs-3.0.0/event.c 2009-02-22 17:44:03.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/event.c 2009-07-03 18:57:12.000000000 +0200
@@ -23,7 +23,7 @@
 #include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
-#include <linux/freezer.h>
+
 
 #include "dev.h"
 #include "dazukofs_fs.h"
@@ -113,21 +113,21 @@ int dazukofs_init_events(void)
  dazukofs_group_cachep =
  kmem_cache_create("dazukofs_group_cache",
   sizeof(struct dazukofs_group), 0,
-  SLAB_HWCACHE_ALIGN, NULL);
+  SLAB_HWCACHE_ALIGN, NULL, NULL);
  if (!dazukofs_group_cachep)
  goto error_out;
 
  dazukofs_event_container_cachep =
  kmem_cache_create("dazukofs_event_container_cache",
   sizeof(struct dazukofs_event_container), 0,
-  SLAB_HWCACHE_ALIGN, NULL);
+  SLAB_HWCACHE_ALIGN, NULL, NULL);
  if (!dazukofs_event_container_cachep)
  goto error_out;
 
  dazukofs_event_cachep =
  kmem_cache_create("dazukofs_event_cache",
   sizeof(struct dazukofs_event), 0,
-  SLAB_HWCACHE_ALIGN, NULL);
+  SLAB_HWCACHE_ALIGN, NULL, NULL);
  if (!dazukofs_event_cachep)
  goto error_out;
 
@@ -162,16 +162,23 @@ static int capture_group_count(int *cach
  return err;
 }
 
-static int get_group_count(void)
+static int get_group_count_interruptible(void)
 {
  int cache = 0;
- int ret = wait_event_freezable(__group_count_queue,
-       capture_group_count(&cache) == 0);
+ int ret = wait_event_interruptible(__group_count_queue,
+ capture_group_count(&cache) == 0);
  if (ret == 0)
  ret = __group_count;
  return ret;
 }
 
+static int get_group_count(void)
+{
+ int cache = 0;
+ wait_event(__group_count_queue, capture_group_count(&cache) == 0);
+ return __group_count;
+}
+
 static void put_group_count(void)
 {
  mutex_lock(&group_count_mutex);
@@ -373,9 +380,10 @@ static struct dazukofs_group *create_gro
 {
  struct dazukofs_group *grp;
 
- grp = kmem_cache_zalloc(dazukofs_group_cachep, GFP_KERNEL);
+ grp = kmem_cache_alloc(dazukofs_group_cachep, GFP_KERNEL);
  if (!grp)
  return NULL;
+ memset(grp, 0, sizeof(*grp));
 
  atomic_set(&grp->use_count, 0);
  grp->group_id = id;
@@ -399,7 +407,7 @@ int dazukofs_add_group(const char *name,
  int already_exists;
  int available_id = 0;
  struct dazukofs_group *grp;
- int grp_count = get_group_count();
+ int grp_count = get_group_count_interruptible();
 
  if (grp_count < 0) {
  ret = grp_count;
@@ -447,7 +455,7 @@ int dazukofs_remove_group(const char *na
  int ret = 0;
  struct dazukofs_group *grp;
  struct list_head *pos;
- int grp_count = get_group_count();
+ int grp_count = get_group_count_interruptible();
 
  if (grp_count < 0) {
  ret = grp_count;
@@ -661,18 +669,24 @@ allocate_event_and_containers(struct daz
 {
  int i;
 
- *evt = kmem_cache_zalloc(dazukofs_event_cachep, GFP_KERNEL);
+ *evt = kmem_cache_alloc(dazukofs_event_cachep, GFP_KERNEL);
  if (!*evt)
  return -1;
+ memset(*evt, 0, sizeof(**evt));
  init_waitqueue_head(&(*evt)->queue);
  mutex_init(&(*evt)->assigned_mutex);
 
  /* allocate containers now while we don't have a lock */
  for (i = 0; i < grp_count; i++) {
- ec_array[i] = kmem_cache_zalloc(
- dazukofs_event_container_cachep, GFP_KERNEL);
- if (!ec_array[i])
+ struct dazukofs_event_container *ec;
+
+ ec = kmem_cache_alloc(dazukofs_event_container_cachep,
+      GFP_KERNEL);
+ if (!ec)
  goto error_out;
+ memset(ec, 0, sizeof(*ec));
+
+ ec_array[i] = ec;
  }
 
  return 0;
@@ -701,11 +715,10 @@ int dazukofs_check_access(struct dentry
 {
  struct dazukofs_event_container *ec_array[GROUP_COUNT];
  struct dazukofs_event *evt;
- int grp_count = get_group_count();
- int err;
+ int grp_count;
+ int err = 0;
 
- if (grp_count < 0)
- return grp_count;
+ grp_count = get_group_count();
 
  if (check_access_precheck(grp_count)) {
  put_group_count();
@@ -713,32 +726,29 @@ int dazukofs_check_access(struct dentry
  }
 
  /* at this point, the access should be handled */
-
  if (allocate_event_and_containers(&evt, ec_array, grp_count)) {
  put_group_count();
- err = -ENOMEM;
- goto out;
+ return -ENOMEM;
  }
-
  evt->dentry = dget(dentry);
  evt->mnt = mntget(mnt);
  evt->pid = current->pid;
-
  assign_event_to_groups(evt, ec_array);
 
  put_group_count();
 
- /* wait until event completely processed or signal */
- err = wait_event_freezable(evt->queue, event_assigned(evt) == 0);
+ /* wait until event completely processed */
+ wait_event(evt->queue, event_assigned(evt) == 0);
 
  if (evt->deny)
  err = -EPERM;
 
  release_event(evt, 0, 0);
-out:
+
  return err;
 }
 
+
 int dazukofs_group_open_tracking(unsigned long group_id)
 {
  struct dazukofs_group *grp;
@@ -874,7 +884,8 @@ static struct dazukofs_event_container *
  /* move first todo-item to working list */
  mutex_lock(&work_mutex);
  if (!list_empty(&grp->todo_list.list)) {
- ec = list_first_entry(&grp->todo_list.list,
+ struct list_head *head = &grp->todo_list.list;
+ ec = list_entry(head->next,
       struct dazukofs_event_container, list);
  list_del(&ec->list);
  list_add(&ec->list, &grp->working_list.list);
@@ -928,7 +939,8 @@ static int open_file(struct dazukofs_eve
  /* add myself to be ignored on file open (to avoid recursion) */
  mask_proc(&proc);
 
- ec->file = dentry_open(dget(evt->dentry), mntget(evt->mnt), O_RDONLY);
+ ec->file = dentry_open(dget(evt->dentry), mntget(evt->mnt),
+       O_RDONLY | O_LARGEFILE);
  if (IS_ERR(ec->file)) {
  check_recursion();  /* remove myself from proc_list */
  ret = PTR_ERR(ec->file);
@@ -1004,9 +1016,9 @@ int dazukofs_get_event(unsigned long gro
  }
 
  while (1) {
- ret = wait_event_freezable(grp->queue,
-   is_event_available(grp) ||
-   grp->deprecated);
+ ret = wait_event_interruptible(grp->queue,
+   is_event_available(grp) ||
+   grp->deprecated);
  if (ret != 0)
  break;
 
diff -x CVS -rup dazukofs-3.0.0/file.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/file.c
--- dazukofs-3.0.0/file.c 2009-02-22 17:43:11.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/file.c 2009-07-03 18:50:52.000000000 +0200
@@ -25,7 +25,7 @@
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/file.h>
-#include <linux/fs_stack.h>
+
 
 #include "dazukofs_fs.h"
 #include "event.h"
@@ -37,7 +37,7 @@ static loff_t dazukofs_llseek(struct fil
 {
  loff_t retval = -EINVAL;
  struct file *lower_file = GET_LOWER_FILE(file);
-
+
  lower_file->f_pos = file->f_pos;
 
  memcpy(&(lower_file->f_ra), &(file->f_ra),
@@ -174,19 +174,23 @@ static int dazukofs_open(struct inode *i
  struct dentry *dentry = file->f_dentry;
  struct dentry *lower_dentry = dget(GET_LOWER_DENTRY(dentry));
  struct vfsmount *lower_mnt = mntget(GET_LOWER_MNT(dentry));
+ struct dazukofs_file_info *fi;
  struct file *lower_file;
  int err;
 
- err = dazukofs_check_access(file->f_dentry, file->f_vfsmnt);
- if (err)
- goto error_out1;
-
- SET_FILE_INFO(file, kmem_cache_zalloc(dazukofs_file_info_cachep,
-      GFP_KERNEL));
- if (!GET_FILE_INFO(file)) {
+ if (S_ISREG(inode->i_mode)) {
+ err = dazukofs_check_access(file->f_dentry, file->f_vfsmnt);
+ if (err)
+ goto error_out1;
+ }
+ fi = kmem_cache_alloc(dazukofs_file_info_cachep, GFP_KERNEL);
+ if (!fi) {
  err = -ENOMEM;
  goto error_out1;
  }
+ memset(fi, 0, sizeof(*fi));
+
+ SET_FILE_INFO(file, fi);
 
  lower_file = dentry_open(lower_dentry, lower_mnt, file->f_flags);
  if (IS_ERR(lower_file)) {
@@ -272,6 +276,20 @@ out:
  return err;
 }
 
+static int dazukofs_mmap (struct file *file, struct vm_area_struct *vm)
+{
+
+ struct file *lower_file = GET_LOWER_FILE(file);
+
+ /* if lower fs does not support mmap(), we dont call generic_file_readonly_mmap(),
+ * since this would result in calling lower readpage(), which might not be
+ * defined by lower fs if mmap() is not supported*/
+ if (!lower_file->f_op || !lower_file->f_op->mmap)
+ return -ENODEV;
+
+
+ return generic_file_readonly_mmap(file, vm);
+}
 /**
  * Unused operations:
  *   - owner
@@ -295,18 +313,15 @@ out:
 struct file_operations dazukofs_main_fops = {
  .llseek = dazukofs_llseek,
  .read = dazukofs_read,
- .aio_read = generic_file_aio_read,
  .write = dazukofs_write,
- .aio_write = generic_file_aio_write,
  .readdir = dazukofs_readdir,
  .ioctl = dazukofs_ioctl,
- .mmap = generic_file_mmap,
+ .mmap = dazukofs_mmap,
  .open = dazukofs_open,
  .flush = dazukofs_flush,
  .release = dazukofs_release,
  .fsync = dazukofs_fsync,
  .fasync = dazukofs_fasync,
- .splice_read = generic_file_splice_read,
 };
 
 /**
@@ -332,14 +347,13 @@ struct file_operations dazukofs_main_fop
  *   - splice_read (generic)
  *   - setlease
  */
-const struct file_operations dazukofs_dir_fops = {
+struct file_operations dazukofs_dir_fops = {
  .readdir = dazukofs_readdir,
  .ioctl = dazukofs_ioctl,
- .mmap = generic_file_mmap,
+ .mmap = dazukofs_mmap,
  .open = dazukofs_open,
  .flush = dazukofs_flush,
  .release = dazukofs_release,
  .fsync = dazukofs_fsync,
  .fasync = dazukofs_fasync,
- .splice_read = generic_file_splice_read,
 };
diff -x CVS -rup dazukofs-3.0.0/group_dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/group_dev.c
--- dazukofs-3.0.0/group_dev.c 2009-02-22 17:45:20.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/group_dev.c 2009-02-06 19:04:28.000000000 +0100
@@ -21,31 +21,55 @@
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
-#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
 
 #include "dazukofs_fs.h"
 #include "event.h"
 #include "dev.h"
 
-static int dazukofs_group_open(int group_id, struct inode *inode,
+
+
+
+struct group_device {
+ struct cdev cdev;
+ struct device dev;
+ struct class_device cls_dev;
+ int id;
+ int track;
+};
+
+static struct group_device *grp_devs;
+static int minor_start;  /* initial minor number */
+
+static int dazukofs_group_open(struct inode *inode,
        struct file *file)
 {
- if (dazukofs_group_open_tracking(group_id))
- file->private_data = file;
- else
- file->private_data = NULL;
+ int id;
+ struct group_device *gdev;
+
+ id = MINOR(inode->i_rdev) - minor_start;
+ gdev = &grp_devs[id];
+
+ gdev->track = dazukofs_group_open_tracking(id);
+ gdev->id = id;
+ file->private_data = gdev;
  return 0;
 }
 
-static int dazukofs_group_release(int group_id, struct inode *inode,
+static int dazukofs_group_release(struct inode *inode,
   struct file *file)
 {
- if (file->private_data)
- dazukofs_group_release_tracking(group_id);
+ struct group_device *gdev;
+
+ gdev = (struct group_device *) file->private_data;
+
+ if (gdev->track)
+ dazukofs_group_release_tracking(gdev->id);
  return 0;
 }
 
-static ssize_t dazukofs_group_read(int group_id, struct file *file,
+static ssize_t dazukofs_group_read(struct file *file,
    char __user *buffer, size_t length,
    loff_t *pos)
 {
@@ -56,6 +80,9 @@ static ssize_t dazukofs_group_read(int g
  int fd;
  int err;
  unsigned long event_id;
+ struct group_device *gdev;
+  
+ gdev = (struct group_device *) file->private_data;
 
  if (*pos > 0)
  return 0;
@@ -63,7 +90,7 @@ static ssize_t dazukofs_group_read(int g
  if (length < DAZUKOFS_MIN_READ_BUFFER)
  return -EINVAL;
 
- err = dazukofs_get_event(group_id, &event_id, &fd, &pid);
+ err = dazukofs_get_event(gdev->id, &event_id, &fd, &pid);
  if (err) {
  if (err == -ERESTARTSYS)
  return -EINTR;
@@ -83,7 +110,7 @@ static ssize_t dazukofs_group_read(int g
  return tmp_used;
 }
 
-static ssize_t dazukofs_group_write(int group_id, struct file *file,
+static ssize_t dazukofs_group_write(struct file *file,
     const char __user *buffer, size_t length,
     loff_t *pos)
 {
@@ -94,6 +121,9 @@ static ssize_t dazukofs_group_write(int
  char *p;
  char *p2;
  int ret;
+ struct group_device *gdev;
+
+ gdev = (struct group_device *) file->private_data;
 
  if (length >= DAZUKOFS_MAX_WRITE_BUFFER)
  length = DAZUKOFS_MAX_WRITE_BUFFER - 1;
@@ -118,7 +148,7 @@ static ssize_t dazukofs_group_write(int
  return -EINVAL;
  response = (*(p + 2)) - '0';
 
- ret = dazukofs_return_event(group_id, event_id, response);
+ ret = dazukofs_return_event(gdev->id, event_id, response);
  if (ret == 0) {
  *pos += length;
  ret = length;
@@ -129,104 +159,105 @@ static ssize_t dazukofs_group_write(int
  return ret;
 }
 
-#define DECLARE_GROUP_FOPS(group_id) \
-static int \
-dazukofs_group_open_##group_id(struct inode *inode, struct file *file) \
-{ \
- return dazukofs_group_open(group_id, inode, file); \
-} \
-static int \
-dazukofs_group_release_##group_id(struct inode *inode, struct file *file) \
-{ \
- return dazukofs_group_release(group_id, inode, file); \
-} \
-static ssize_t \
-dazukofs_group_read_##group_id(struct file *file, char __user *buffer, \
-       size_t length, loff_t *pos) \
-{ \
- return dazukofs_group_read(group_id, file, buffer, length, pos); \
-} \
-static ssize_t \
-dazukofs_group_write_##group_id(struct file *file, \
- const char __user *buffer, size_t length, \
- loff_t *pos) \
-{ \
- return dazukofs_group_write(group_id, file, buffer, length, pos); \
-} \
-static struct file_operations group_fops_##group_id = { \
- .owner = THIS_MODULE, \
- .open = dazukofs_group_open_##group_id, \
- .release = dazukofs_group_release_##group_id, \
- .read = dazukofs_group_read_##group_id, \
- .write = dazukofs_group_write_##group_id, \
+struct file_operations grp_fops = {
+ .owner   = THIS_MODULE,
+ .open   = dazukofs_group_open,
+ .release   = dazukofs_group_release,
+ .read   = dazukofs_group_read,
+ .write   = dazukofs_group_write,
 };
 
-DECLARE_GROUP_FOPS(0)
-DECLARE_GROUP_FOPS(1)
-DECLARE_GROUP_FOPS(2)
-DECLARE_GROUP_FOPS(3)
-DECLARE_GROUP_FOPS(4)
-DECLARE_GROUP_FOPS(5)
-DECLARE_GROUP_FOPS(6)
-DECLARE_GROUP_FOPS(7)
-DECLARE_GROUP_FOPS(8)
-DECLARE_GROUP_FOPS(9)
-
-static struct cdev groups_cdev[GROUP_COUNT];
-
-static struct file_operations *group_fops[GROUP_COUNT] = {
- &group_fops_0,
- &group_fops_1,
- &group_fops_2,
- &group_fops_3,
- &group_fops_4,
- &group_fops_5,
- &group_fops_6,
- &group_fops_7,
- &group_fops_8,
- &group_fops_9,
-};
+
+static void dazukofs_group_class_dev_release(struct class_device *cls_dev)
+{
+ // nothing
+}
+
+static void dazukofs_group_dev_release(struct device *dev)
+{
+ // Nothing
+}
+
+static int __dazukofs_group_dev_init(dev_t devt, struct class *cls,
+     struct group_device *gdev, char *name)
+{
+ int err;
+
+ cdev_init(&gdev->cdev, &grp_fops);
+ gdev->cdev.owner = THIS_MODULE;
+
+ err = cdev_add(&gdev->cdev, devt, GROUP_COUNT);
+
+ if (err)
+ return -1;
+
+ gdev->dev.parent = &platform_bus;
+ gdev->dev.release = dazukofs_group_dev_release;
+ strncpy(gdev->dev.bus_id, name, BUS_ID_SIZE);
+
+ err = device_register(&gdev->dev);
+
+ if (err)
+ goto err_out;
+
+ gdev->cls_dev.release = dazukofs_group_class_dev_release;
+ gdev->cls_dev.class = cls;
+ gdev->cls_dev.dev = &gdev->dev;
+ strncpy(gdev->cls_dev.class_id, name, BUS_ID_SIZE);
+ gdev->cls_dev.devt = devt;
+
+ err = class_device_register(&gdev->cls_dev);
+
+ if (err)
+ goto err_out2;
+
+ return 0;
+
+err_out2:
+ device_unregister(&gdev->dev);
+err_out:
+ cdev_del(&gdev->cdev);
+
+ return err;
+}
 
 int dazukofs_group_dev_init(int dev_major, int dev_minor_start,
     struct class *dazukofs_class)
 {
- int err = 0;
- struct device *dev;
+ int err;
  int i;
- int cdev_count;
- int dev_minor_end = dev_minor_start;
+ dev_t devt;
+ struct group_device *gdev;
+ char name[BUS_ID_SIZE];
 
- /* setup cdevs for groups */
- for (cdev_count = 0; cdev_count < GROUP_COUNT; cdev_count++) {
- cdev_init(&groups_cdev[cdev_count], group_fops[cdev_count]);
- groups_cdev[cdev_count].owner = THIS_MODULE;
- err = cdev_add(&groups_cdev[cdev_count],
-       MKDEV(dev_major, dev_minor_start + cdev_count),
-       GROUP_COUNT);
- if (err)
- goto error_out1;
- }
+ grp_devs = kzalloc(sizeof(struct group_device) * GROUP_COUNT,
+   GFP_KERNEL);
+
+ if (!grp_devs)
+ return -ENOMEM;
 
  /* create group devices */
  for (i = 0; i < GROUP_COUNT; i++) {
- dev = device_create(dazukofs_class, NULL,
-    MKDEV(dev_major, dev_minor_end), NULL,
-    "%s.%d", DEVICE_NAME, i);
- if (IS_ERR(dev)) {
- err = PTR_ERR(dev);
- goto error_out2;
- }
- dev_minor_end++;
+ gdev = &grp_devs[i];
+ devt = MKDEV(dev_major, dev_minor_start + i);
+ snprintf(name, sizeof(name), "%s.%i", DEVICE_NAME, i);
+ err = __dazukofs_group_dev_init(devt, dazukofs_class,
+                                                gdev, name);
+ if (err)
+ goto undo;
  }
 
- return dev_minor_end;
+ minor_start = dev_minor_start;
+ return i;
 
-error_out2:
- for (i = dev_minor_start; i < dev_minor_end; i++)
- device_destroy(dazukofs_class, MKDEV(dev_major, i));
-error_out1:
- for (i = 0; i < cdev_count; i++)
- cdev_del(&groups_cdev[i]);
+undo:
+ while(i) {
+ i--;
+ gdev = &grp_devs[i];
+ class_device_unregister(&gdev->cls_dev);
+ device_unregister(&gdev->dev);
+ cdev_del(&gdev->cdev);
+ }
  return err;
 }
 
@@ -236,9 +267,14 @@ void dazukofs_group_dev_destroy(int dev_
 {
  int i;
 
- for (i = dev_minor_start; i < dev_minor_end; i++)
- device_destroy(dazukofs_class, MKDEV(dev_major, i));
+ for (i = 0; i < GROUP_COUNT; i++) {
+ struct group_device *gdev;
+
+ gdev = &grp_devs[i];
 
- for (i = 0; i < GROUP_COUNT; i++)
- cdev_del(&groups_cdev[i]);
+ class_device_unregister(&gdev->cls_dev);
+ device_unregister(&gdev->dev);
+ cdev_del(&gdev->cdev);
+ }
+ kfree(grp_devs);
 }
diff -x CVS -rup dazukofs-3.0.0/ign_dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ign_dev.c
--- dazukofs-3.0.0/ign_dev.c 2009-02-22 17:45:20.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ign_dev.c 2009-02-06 18:29:19.000000000 +0100
@@ -21,7 +21,8 @@
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
-#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
 
 #include "dazukofs_fs.h"
 #include "dev.h"
@@ -56,12 +57,14 @@ int dazukofs_check_ignore_process(void)
 
 static int dazukofs_add_ign(struct file *file)
 {
- struct dazukofs_proc *proc =
- kmem_cache_zalloc(dazukofs_ign_cachep, GFP_KERNEL);
+ struct dazukofs_proc *proc;
+
+ proc = kmem_cache_alloc(dazukofs_ign_cachep, GFP_KERNEL);
  if (!proc) {
  file->private_data = NULL;
  return -ENOMEM;
  }
+ memset(proc, 0, sizeof(*proc));
 
  file->private_data = proc;
  proc->curr = current;
@@ -124,7 +127,11 @@ static void dazukofs_destroy_ignlist(voi
  }
 }
 
-static struct cdev ign_cdev;
+static struct {
+ struct cdev cdev;
+ struct device dev;
+ struct class_device cls_dev;
+} ign_dev;
 
 static struct file_operations ign_fops = {
  .owner = THIS_MODULE,
@@ -132,11 +139,23 @@ static struct file_operations ign_fops =
  .release = dazukofs_ign_release,
 };
 
+
+static void dazukofs_ign_class_dev_release(struct class_device *dev)
+{
+ // nothing
+}
+
+static void dazukofs_ign_dev_release(struct device *dev)
+{
+ // nothing
+}
+
+
 int dazukofs_ign_dev_init(int dev_major, int dev_minor,
   struct class *dazukofs_class)
 {
- int err = 0;
- struct device *dev;
+ dev_t devt;
+ int err;
 
  INIT_LIST_HEAD(&ign_list.list);
  mutex_init(&ign_list_mutex);
@@ -144,43 +163,57 @@ int dazukofs_ign_dev_init(int dev_major,
  dazukofs_ign_cachep =
  kmem_cache_create("dazukofs_ign_cache",
   sizeof(struct dazukofs_proc), 0,
-  SLAB_HWCACHE_ALIGN, NULL);
- if (!dazukofs_ign_cachep) {
- err = -ENOMEM;
- goto error_out1;
- }
+  SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (!dazukofs_ign_cachep)
+ return -ENOMEM;
+
+ devt = MKDEV(dev_major, dev_minor);
 
  /* setup cdev for ignore */
- cdev_init(&ign_cdev, &ign_fops);
- ign_cdev.owner = THIS_MODULE;
- err = cdev_add(&ign_cdev, MKDEV(dev_major, dev_minor), 1);
+ cdev_init(&ign_dev.cdev, &ign_fops);
+ ign_dev.cdev.owner = THIS_MODULE;
+ err = cdev_add(&ign_dev.cdev, devt, 1);
  if (err)
+ goto error_out;
+
+ ign_dev.dev.parent = &platform_bus;
+ ign_dev.dev.release = dazukofs_ign_dev_release;
+ snprintf(ign_dev.dev.bus_id, BUS_ID_SIZE, "%s.ign", DEVICE_NAME);
+
+ err = device_register(&ign_dev.dev);
+
+ if (err)
  goto error_out2;
 
- /* create ignore device */
- dev = device_create(dazukofs_class, NULL, MKDEV(dev_major, dev_minor),
-    NULL, "%s.ign", DEVICE_NAME);
- if (IS_ERR(dev)) {
- err = PTR_ERR(dev);
+ ign_dev.cls_dev.release = dazukofs_ign_class_dev_release;
+ ign_dev.cls_dev.class = dazukofs_class;
+ ign_dev.cls_dev.dev = &ign_dev.dev;
+ snprintf(ign_dev.cls_dev.class_id, BUS_ID_SIZE, "%s.ign", DEVICE_NAME);
+ ign_dev.cls_dev.devt = devt;
+
+ err = class_device_register(&ign_dev.cls_dev);
+
+ if (err)
  goto error_out3;
- }
 
- return 0;
 
+ return 0;
 error_out3:
- cdev_del(&ign_cdev);
+ device_unregister(&ign_dev.dev);
 error_out2:
- dazukofs_destroy_ignlist();
+ cdev_del(&ign_dev.cdev);
+error_out:
  kmem_cache_destroy(dazukofs_ign_cachep);
-error_out1:
  return err;
 }
 
+
 void dazukofs_ign_dev_destroy(int dev_major, int dev_minor,
       struct class *dazukofs_class)
 {
- device_destroy(dazukofs_class, MKDEV(dev_major, dev_minor));
- cdev_del(&ign_cdev);
+ class_device_unregister(&ign_dev.cls_dev);
+ device_unregister(&ign_dev.dev);
+ cdev_del(&ign_dev.cdev);
  dazukofs_destroy_ignlist();
  kmem_cache_destroy(dazukofs_ign_cachep);
 }
diff -x CVS -rup dazukofs-3.0.0/inode.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/inode.c
--- dazukofs-3.0.0/inode.c 2009-02-22 17:46:02.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/inode.c 2009-07-06 10:26:13.000000000 +0200
@@ -25,15 +25,19 @@
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
-#include <linux/uaccess.h>
-#include <linux/fs_stack.h>
-
+#include <asm/uaccess.h>
 #include "dazukofs_fs.h"
 
 static struct inode_operations dazukofs_symlink_iops;
 static struct inode_operations dazukofs_dir_iops;
 static struct inode_operations dazukofs_main_iops;
 
+void fsstack_copy_inode_size(struct inode *dst, const struct inode *src)
+{
+ i_size_write(dst, i_size_read((struct inode *) src));
+ dst->i_blocks = src->i_blocks;
+}
+
 static int dazukofs_inode_test(struct inode *inode,
        void *candidate_lower_inode)
 {
@@ -47,14 +51,28 @@ static int dazukofs_inode_test(struct in
 
 static void dazukofs_init_inode(struct inode *inode, struct inode *lower_inode)
 {
- SET_LOWER_INODE(inode, lower_inode);
- inode->i_ino = lower_inode->i_ino;
- inode->i_version++;
- inode->i_op = &dazukofs_main_iops;
- inode->i_fop = &dazukofs_main_fops;
- inode->i_mapping->a_ops = &dazukofs_aops;
+        SET_LOWER_INODE(inode, lower_inode);
+        inode->i_ino = lower_inode->i_ino;
+        inode->i_version++;
+
+        if (S_ISDIR(lower_inode->i_mode)) {
+                inode->i_op = &dazukofs_dir_iops;
+                inode->i_fop = &dazukofs_dir_fops;
+        } else {
+                inode->i_op = &dazukofs_main_iops;
+                inode->i_fop = &dazukofs_main_fops;
+
+                if (S_ISLNK(lower_inode->i_mode))
+                        inode->i_op = &dazukofs_symlink_iops;
+                else  if (special_file(lower_inode->i_mode)) {
+                        init_special_inode(inode, lower_inode->i_mode,
+                                           lower_inode->i_rdev);
+                }
+        }
+        inode->i_mapping->a_ops = &dazukofs_aops;
 }
 
+
 static int dazukofs_inode_set(struct inode *inode, void *lower_inode)
 {
  dazukofs_init_inode(inode, (struct inode *)lower_inode);
@@ -62,72 +80,124 @@ static int dazukofs_inode_set(struct ino
 }
 
 int dazukofs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
-     struct super_block *sb, int flag)
+     struct super_block *sb, int hash)
 {
  struct inode *inode;
- struct inode *lower_inode = igrab(lower_dentry->d_inode);
- int err = 0;
+ struct inode *lower_inode;
+ int err;
 
- if (!lower_inode) {
- err = -ESTALE;
- goto out;
- }
+ lower_inode = igrab(lower_dentry->d_inode);
 
- if (lower_inode->i_sb != GET_LOWER_SB(sb)) {
- iput(lower_inode);
- err = -EXDEV;
- goto out;
- }
+ if (!lower_inode)
+ return -ESTALE;
 
  inode = iget5_locked(sb, (unsigned long)lower_inode,
      dazukofs_inode_test, dazukofs_inode_set,
      lower_inode);
-
  if (!inode) {
- iput(lower_inode);
  err = -EACCES;
- goto out;
+ goto err;
  }
 
- if (inode->i_state & I_NEW) {
+ if (inode->i_state & I_NEW)
  unlock_new_inode(inode);
  /*
  * This is a new node so we leave the lower_node "in use"
  * and do not call iput().
  */
- } else {
+ else
  /*
  * This is not a new node so we decrement the usage count.
  */
  iput(lower_inode);
- }
 
- if (S_ISLNK(lower_inode->i_mode))
- inode->i_op = &dazukofs_symlink_iops;
- else if (S_ISDIR(lower_inode->i_mode))
- inode->i_op = &dazukofs_dir_iops;
-
- if (S_ISDIR(lower_inode->i_mode))
- inode->i_fop = &dazukofs_dir_fops;
-
- if (special_file(lower_inode->i_mode)) {
- init_special_inode(inode, lower_inode->i_mode,
-   lower_inode->i_rdev);
- }
-
- dentry->d_op = &dazukofs_dops;
 
- if (flag)
+ if (hash)
  d_add(dentry, inode);
  else
  d_instantiate(dentry, inode);
 
- fsstack_copy_attr_all(inode, lower_inode, NULL);
+ fsstack_copy_attr_all(inode, lower_inode);
  fsstack_copy_inode_size(inode, lower_inode);
-out:
+
+ return 0;
+err:
+ iput(lower_inode);
  return err;
 }
 
+/* creates a new lower dentry */
+static struct dentry *dazukofs_new_lower_dentry(struct qstr *name,
+ struct dentry *lower_base,
+ struct nameidata *nd)
+{
+ struct dentry *new_dentry;
+ struct dentry *tmp;
+ struct inode *lower_inode;
+
+ lower_inode = lower_base->d_inode;
+ /* XXX: is this check still necessary? (see __lookup_hash())
+   This is (hopely) protected by locked upper inode */
+ if (IS_DEADDIR(lower_inode)) {
+ new_dentry = ERR_PTR(-ENOENT);
+ goto out;
+ }
+ tmp = d_alloc(lower_base, name);
+ if (!tmp) {
+ new_dentry = ERR_PTR(-ENOMEM);
+ goto out;
+ }
+ new_dentry = lower_inode->i_op->lookup(lower_inode, tmp, nd);
+ /* lookup() seemingly is allowed to return its own dentry (which
+ * may indeed be a dentry or only an error). If so
+ * we use it and discard ours. Otherwise we use ours */
+ if (!new_dentry)
+ new_dentry = tmp;
+ else
+ dput(tmp);
+
+out:
+ return new_dentry;
+}
+
+
+/* get lower dentry for given name */
+static struct dentry *dazukofs_lookup_one_lower(struct qstr *name,
+ struct dentry *lower_base,
+ struct vfsmount *lower_mnt)
+{
+ struct dentry *result;
+ struct nameidata nd;
+ int err;
+
+ /* see vfs_path_lookup in kernel versions >= 2.6.24 */
+ nd.last_type = LAST_ROOT;
+ nd.flags = 0;
+ nd.depth = 0;
+ nd.dentry = dget(lower_base);
+ nd.mnt = mntget(lower_mnt);
+
+ err = path_walk(name->name, &nd);
+
+ if (!err) {
+ /* inode already exists on disk */
+ result = nd.dentry;
+ /* we dont need the mount */
+ mntput(nd.mnt);
+ goto out;
+ }
+ if (err != -ENOENT) { /* this is a REAL error */
+ result = ERR_PTR(err);
+ goto out;
+ }
+ /* create a new (lower) dentry */
+ result = dazukofs_new_lower_dentry(name, lower_base, &nd);
+out:
+ return result;
+
+}
+
+
 /**
  * Description: Called when the VFS needs to look up an inode in a parent
  * directory. The name to look for is found in the dentry. This method
@@ -148,64 +218,52 @@ static struct dentry *dazukofs_lookup(st
  struct dentry *lower_dentry;
  struct dentry *lower_dentry_parent;
  struct vfsmount *lower_mnt;
- int err = 0;
-
- if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, "."))
-    || (dentry->d_name.len == 2 &&
- !strcmp(dentry->d_name.name, ".."))) {
- d_drop(dentry);
- goto out;
- }
-
- dentry->d_op = &dazukofs_dops;
+ struct dazukofs_dentry_info *di;
+ int err;
 
  lower_dentry_parent = GET_LOWER_DENTRY(dentry->d_parent);
- lower_dentry = lookup_one_len(dentry->d_name.name, lower_dentry_parent,
-      dentry->d_name.len);
+ /* should be released in d_release() */
+ lower_mnt = mntget(GET_LOWER_MNT(dentry->d_parent));
 
+ lower_dentry = dazukofs_lookup_one_lower(&dentry->d_name,
+ lower_dentry_parent,
+ lower_mnt);
  if (IS_ERR(lower_dentry)) {
- err = PTR_ERR(lower_dentry);
- d_drop(dentry);
- goto out;
+ mntput(lower_mnt);
+ return lower_dentry;
  }
-
  BUG_ON(!atomic_read(&lower_dentry->d_count));
 
- SET_DENTRY_INFO(dentry, kmem_cache_zalloc(dazukofs_dentry_info_cachep,
- GFP_KERNEL));
-
- if (!GET_DENTRY_INFO(dentry)) {
- err = -ENOMEM;
- goto out_dput;
+ dentry->d_op = &dazukofs_dops;
+ di = kmem_cache_alloc(dazukofs_dentry_info_cachep, GFP_KERNEL);
+ if (!di) {
+ mntput(lower_mnt);
+ dput(lower_dentry);
+ return ERR_PTR(-ENOMEM);
  }
-
- lower_mnt = mntget(GET_LOWER_MNT(dentry->d_parent));
-
- fsstack_copy_attr_atime(dir, lower_dentry_parent->d_inode);
-
+ memset(di, 0, sizeof(*di));
+ SET_DENTRY_INFO(dentry, di);
  SET_LOWER_DENTRY(dentry, lower_dentry, lower_mnt);
-
+ /* from now lower dentry and lower mount are released in
+  d_release of upper dentry */
+ fsstack_copy_attr_atime(dir, lower_dentry_parent->d_inode);
  if (!lower_dentry->d_inode) {
  /*
  * We want to add because we could not find in lower.
  */
  d_add(dentry, NULL);
- goto out;
+ goto ok;
  }
 
  err = dazukofs_interpose(lower_dentry, dentry, dir->i_sb, 1);
- if (err)
- goto out_dput;
- goto out;
+ if (err)
+ return ERR_PTR(err);
 
-out_dput:
- dput(lower_dentry);
- d_drop(dentry);
-
-out:
- return ERR_PTR(err);
+ok:
+ return NULL; /* tell caller to use its own, passed dentry, not ours */
 }
 
+
 /**
  * Description: Called by the mknod(2) system call to create a device
  * (char, block) inode or a named pipe (FIFO) or socket. Only required if
@@ -216,14 +274,15 @@ static int dazukofs_mknod(struct inode *
   dev_t dev)
 {
  struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
+ struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
  struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
  struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
  int err = -ENOENT;
 
- mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
-  I_MUTEX_PARENT);
+ mutex_lock(&(lower_dentry_parent_inode->i_mutex));
 
- err = vfs_mknod(lower_dentry_parent_inode, lower_dentry, mode, dev);
+ err = vfs_mknod(lower_dentry_parent_inode, lower_dentry, lower_mount,
+ mode, dev);
  if (err)
  goto out;
 
@@ -248,14 +307,15 @@ out:
 static int dazukofs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
  struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
+ struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
  struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
  struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
  int err = -ENOENT;
 
- mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
-  I_MUTEX_PARENT);
+ mutex_lock(&(lower_dentry_parent_inode->i_mutex));
 
- err = vfs_mkdir(lower_dentry_parent_inode, lower_dentry, mode);
+ err = vfs_mkdir(lower_dentry_parent_inode, lower_dentry, lower_mount,
+ mode);
  if (err)
  goto out;
 
@@ -291,22 +351,21 @@ static int dazukofs_create(struct inode
  struct dentry *dentry_save;
  int err = -ENOENT;
 
- mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
-  I_MUTEX_PARENT);
+ mutex_lock(&(lower_dentry_parent_inode->i_mutex));
 
- vfsmount_save = nd->path.mnt;
- dentry_save = nd->path.dentry;
+ vfsmount_save = nd->mnt;
+ dentry_save = nd->dentry;
 
- nd->path.mnt = mntget(lower_mnt);
- nd->path.dentry = dget(lower_dentry);
+ nd->mnt = mntget(lower_mnt);
+ nd->dentry = dget(lower_dentry);
 
  err = vfs_create(lower_dentry_parent_inode, lower_dentry, mode, nd);
 
  mntput(lower_mnt);
  dput(lower_dentry);
 
- nd->path.mnt = vfsmount_save;
- nd->path.dentry = dentry_save;
+ nd->mnt = vfsmount_save;
+ nd->dentry = dentry_save;
 
  if (err)
  goto out;
@@ -333,14 +392,15 @@ static int dazukofs_symlink(struct inode
     const char *symname)
 {
  struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
+ struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
  struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
  struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
  int err = -ENOENT;
 
- mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
-  I_MUTEX_PARENT);
+ mutex_lock(&(lower_dentry_parent_inode->i_mutex));
 
- err = vfs_symlink(lower_dentry_parent_inode, lower_dentry, symname);
+ err = vfs_symlink(lower_dentry_parent_inode, lower_dentry, lower_mount,
+  symname, S_IALLUGO);
  if (err)
  goto out;
 
@@ -452,9 +512,37 @@ static void dazukofs_put_link(struct den
  * Description: Called by the VFS to check for access rights on a
  * POSIX-like filesystem.
  */
-static int dazukofs_permission(struct inode *inode, int mask)
+static int dazukofs_permission(struct inode *inode, int mask,
+       struct nameidata *nd)
 {
- return inode_permission(GET_LOWER_INODE(inode), mask);
+ struct vfsmount *lower_mnt = NULL;
+ struct dentry *lower_dentry = NULL;
+ struct vfsmount *vfsmnt_save = NULL;
+ struct dentry *dentry_save = NULL;
+ int err;
+
+ if (nd) {
+ lower_mnt = GET_LOWER_MNT(nd->dentry);
+ lower_dentry = GET_LOWER_DENTRY(nd->dentry);
+
+ vfsmnt_save = nd->mnt;
+ dentry_save = nd->dentry;
+
+ nd->mnt = mntget(lower_mnt);
+ nd->dentry = dget(lower_dentry);
+ }
+
+ err = permission(GET_LOWER_INODE(inode), mask, nd);
+
+ if (nd) {
+ mntput(lower_mnt);
+ dput(lower_dentry);
+
+ nd->mnt = vfsmnt_save;
+ nd->dentry = dentry_save;
+ }
+
+        return err;
 }
 
 /**
@@ -464,18 +552,32 @@ static int dazukofs_permission(struct in
 static int dazukofs_setattr(struct dentry *dentry, struct iattr *ia)
 {
  struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
+ struct vfsmount *lower_mnt = GET_LOWER_MNT(dentry);
  struct inode *inode = dentry->d_inode;
  struct inode *lower_inode = GET_LOWER_INODE(inode);
  int err;
 
- err = notify_change(lower_dentry, ia);
 
- fsstack_copy_attr_all(inode, lower_inode, NULL);
- fsstack_copy_inode_size(inode, lower_inode);
+ if (!lower_inode->i_op || !lower_inode->i_op->setattr)
+ /* XXX: at this point it is too late to handle inodes properly that do NOT
+ specify setattr(). VFS would normally call inode_setattr() in
+ this case. So to force this we jump back to notify_change which will
+ handle this for us. But this is dangerous:
+ The attributes might be modified by notify_change() in a way
+ that results in invalid attributes. This seems to be the case
+ if the inode for which this function is called has the setuid
+ or setgid bit set */
+ err = notify_change(lower_dentry, lower_mnt, ia);
+ else
+ err = lower_inode->i_op->setattr(lower_dentry, ia);
+
+ if (!err) {
+ fsstack_copy_attr_all(inode, lower_inode);
+ fsstack_copy_inode_size(inode, lower_inode);
+ }
 
  return err;
 }
-
 /**
  * Description: Called by the VFS to set an extended attribute for a file.
  * Extended attribute is a name:value pair associated with an inode. This
@@ -496,14 +598,14 @@ static int dazukofs_setxattr(struct dent
 
  if (!lower_dentry_inode->i_op ||
     !lower_dentry_inode->i_op->setxattr) {
- err = -ENOSYS;
+ err = -EOPNOTSUPP;
  goto out;
  }
 
  err = lower_dentry_inode->i_op->setxattr(lower_dentry, name, value,
  size, flags);
 
- fsstack_copy_attr_all(dentry->d_inode, lower_dentry_inode, NULL);
+ fsstack_copy_attr_all(dentry->d_inode, lower_dentry_inode);
  fsstack_copy_inode_size(dentry->d_inode, lower_dentry_inode);
 out:
  return err;
@@ -528,7 +630,7 @@ static ssize_t dazukofs_getxattr(struct
 
  if (!lower_dentry_inode->i_op ||
     !lower_dentry_inode->i_op->getxattr) {
- err = -ENOSYS;
+ err = -EOPNOTSUPP;
  goto out;
  }
 
@@ -557,7 +659,7 @@ static ssize_t dazukofs_listxattr(struct
 
  if (!lower_dentry_inode->i_op ||
     !lower_dentry_inode->i_op->listxattr) {
- err = -ENOSYS;
+ err = -EOPNOTSUPP;
  goto out;
  }
 
@@ -584,7 +686,7 @@ static int dazukofs_removexattr(struct d
 
  if (!lower_dentry_inode->i_op ||
     !lower_dentry_inode->i_op->removexattr) {
- err = -ENOSYS;
+ err = -EOPNOTSUPP;
  goto out;
  }
 
@@ -602,16 +704,19 @@ static int dazukofs_link(struct dentry *
  struct dentry *new_dentry)
 {
  struct dentry *lower_old_dentry = GET_LOWER_DENTRY(old_dentry);
+ struct vfsmount *lower_old_mount = GET_LOWER_MNT(old_dentry);
  struct dentry *lower_new_dentry = GET_LOWER_DENTRY(new_dentry);
+ struct vfsmount *lower_new_mount = GET_LOWER_MNT(new_dentry);
+
  struct dentry *lower_dentry_parent = dget(lower_new_dentry->d_parent);
  struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
  int err = -ENOENT;
 
- mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
-  I_MUTEX_PARENT);
+ mutex_lock(&(lower_dentry_parent_inode->i_mutex));
 
- err = vfs_link(lower_old_dentry, lower_dentry_parent_inode,
-       lower_new_dentry);
+ err = vfs_link(lower_old_dentry, lower_old_mount,
+       lower_dentry_parent_inode, lower_new_dentry,
+       lower_new_mount);
  if (err)
  goto out;
 
@@ -635,14 +740,14 @@ out:
 static int dazukofs_unlink(struct inode *dir, struct dentry *dentry)
 {
  struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
+ struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
  struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
  struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
  int err;
 
- mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
-  I_MUTEX_PARENT);
+ mutex_lock(&(lower_dentry_parent_inode->i_mutex));
 
- err = vfs_unlink(lower_dentry_parent_inode, lower_dentry);
+ err = vfs_unlink(lower_dentry_parent_inode, lower_dentry, lower_mount);
  if (err)
  goto out;
 
@@ -664,14 +769,14 @@ out:
 static int dazukofs_rmdir(struct inode *dir, struct dentry *dentry)
 {
  struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
+ struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
  struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
  struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
  int err;
 
- mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
-  I_MUTEX_PARENT);
+ mutex_lock(&(lower_dentry_parent_inode->i_mutex));
 
- err = vfs_rmdir(lower_dentry_parent_inode, lower_dentry);
+ err = vfs_rmdir(lower_dentry_parent_inode, lower_dentry, lower_mount);
  if (err)
  goto out;
 
@@ -695,7 +800,9 @@ static int dazukofs_rename(struct inode
    struct inode *new_dir, struct dentry *new_dentry)
 {
  struct dentry *lower_old_dentry = GET_LOWER_DENTRY(old_dentry);
+ struct vfsmount *lower_old_mount = GET_LOWER_MNT(old_dentry);
  struct dentry *lower_new_dentry = GET_LOWER_DENTRY(new_dentry);
+ struct vfsmount *lower_new_mount = GET_LOWER_MNT(new_dentry);
  struct dentry *lower_old_dentry_parent =
  dget(lower_old_dentry->d_parent);
  struct dentry *lower_new_dentry_parent =
@@ -718,16 +825,17 @@ static int dazukofs_rename(struct inode
 
  lock_rename(lower_old_dentry_parent, lower_new_dentry_parent);
  err = vfs_rename(lower_old_dentry_parent_inode, lower_old_dentry,
- lower_new_dentry_parent_inode, lower_new_dentry);
+ lower_old_mount, lower_new_dentry_parent_inode,
+ lower_new_dentry, lower_new_mount);
  unlock_rename(lower_old_dentry_parent, lower_new_dentry_parent);
 
  if (err)
  goto out;
 
- fsstack_copy_attr_all(new_dir, lower_new_dentry_parent_inode, NULL);
+ fsstack_copy_attr_all(new_dir, lower_new_dentry_parent_inode);
  if (new_dir != old_dir)
- fsstack_copy_attr_all(old_dir, lower_old_dentry_parent_inode,
-      NULL);
+ fsstack_copy_attr_all(old_dir, lower_old_dentry_parent_inode);
+    
 out:
  dput(lower_old_dentry_parent);
  dput(lower_new_dentry_parent);
diff -x CVS -rup dazukofs-3.0.0/Makefile dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/Makefile
--- dazukofs-3.0.0/Makefile 2009-02-22 17:46:02.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/Makefile 2009-05-11 19:53:03.000000000 +0200
@@ -18,7 +18,8 @@ dazukofs_install: dazukofs_modules
  /sbin/depmod -ae
 
 clean:
- rm -f Module.symvers
+ rm -f Modules.symvers
+ rm -f modules.order
  make -C $(DAZUKOFS_KERNEL_SRC) SUBDIRS="`pwd`" clean
 
 .PHONY: dazukofs_modules dazukofs_install clean
diff -x CVS -rup dazukofs-3.0.0/README dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/README
--- dazukofs-3.0.0/README 2009-02-22 17:38:21.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/README 2009-02-06 17:48:21.000000000 +0100
@@ -21,10 +21,10 @@ NOTE: DazukoFS is completely separate fr
 =================
 
 Below are brief instructions to get DazukoFS compiled and running on a
-system with a Linux 2.6.28 kernel. You may need to manually adjust the
+system with a Linux 2.6.27 kernel. You may need to manually adjust the
 Makefile if you kernel sources are not in the default location.
-(Patches are provided for various other kernels. See the section below
-titled "PATCHING" for more information.)
+(A patch is provided to convert the DazukoFS code to support Linux
+2.6.26.)
 
 compile the kernel module
   # make
@@ -52,25 +52,6 @@ unmount DazukoFS
 
 
 
-==========
- PATCHING
-==========
-
-In the "patches" directory there are patches available to modify the
-DazukoFS code to fit various other kernels. For example, if you are
-running openSUSE 11.1 you can patch the code with the following
-command:
-
-$ patch -p1 < patches/patch-opensuse-11.1
-
-There should not be any errors. If there are errors, then the patch
-is broken and should be reported on the dazuko-devel mailing list.
-
-Once the code has been patched you can build the kernel module as
-described in the section "BUILD / INSTALL" above.
-
-
-
 =========
  TESTING
 =========
@@ -154,9 +135,6 @@ any problems.
  KNOWN ISSUES
 ==============
 
-- The kernel will crash if you attempt to mount DazukoFS to a file instead
-  of a directory. (The various kernel patches handle this error.)
-
 - DazukoFS does not support writing to memory mapped files. This should not
   cause the kernel to crash, but will instead result in the application
   failing to perform the writes (although mmap() will appear to be
diff -x CVS -rup dazukofs-3.0.0/super.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/super.c
--- dazukofs-3.0.0/super.c 2009-02-22 17:46:02.000000000 +0100
+++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/super.c 2009-07-03 17:59:02.000000000 +0200
@@ -35,6 +35,10 @@ static struct kmem_cache *dazukofs_sb_in
 struct kmem_cache *dazukofs_dentry_info_cachep;
 struct kmem_cache *dazukofs_file_info_cachep;
 
+
+#define DAZUKOFS_VERSION "3.0.0-rc4-avira-b2.6"
+
+
 static struct inode *dazukofs_alloc_inode(struct super_block *sb)
 {
  struct dazukofs_inode_info *inodei;
@@ -114,9 +118,10 @@ static int dazukofs_fill_super(struct su
  static const struct qstr name = { .name = "/", .len = 1 };
  struct dazukofs_dentry_info *di;
 
- sbi =  kmem_cache_zalloc(dazukofs_sb_info_cachep, GFP_KERNEL);
+ sbi =  kmem_cache_alloc(dazukofs_sb_info_cachep, GFP_KERNEL);
  if (!sbi)
  return -ENOMEM;
+ memset(sbi, 0, sizeof(*sbi));
 
  sb->s_op = &dazukofs_sops;
 
@@ -132,12 +137,13 @@ static int dazukofs_fill_super(struct su
  sb->s_root->d_sb = sb;
  sb->s_root->d_parent = sb->s_root;
 
- di = kmem_cache_zalloc(dazukofs_dentry_info_cachep, GFP_KERNEL);
+ di = kmem_cache_alloc(dazukofs_dentry_info_cachep, GFP_KERNEL);
  if (!di) {
  kmem_cache_free(dazukofs_sb_info_cachep, sbi);
  dput(sb->s_root);
  return -ENOMEM;
  }
+ memset(di, 0, sizeof(*di));
 
  SET_DENTRY_INFO(sb->s_root, di);
 
@@ -158,8 +164,8 @@ static int dazukofs_read_super(struct su
  if (err)
  return err;
 
- lower_root = dget(nd.path.dentry);
- lower_mnt = mntget(nd.path.mnt);
+ lower_root = dget(nd.dentry);
+ lower_mnt = mntget(nd.mnt);
 
  if (IS_ERR(lower_root)) {
  err = PTR_ERR(lower_root);
@@ -171,6 +177,11 @@ static int dazukofs_read_super(struct su
  goto out_put;
  }
 
+ if (!S_ISDIR(lower_root->d_inode->i_mode)) {
+ err = -ENOENT;
+ goto out_put;
+ }
+
  SET_LOWER_SB(sb, lower_root->d_sb);
  sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
  SET_LOWER_DENTRY(sb->s_root, lower_root, lower_mnt);
@@ -184,44 +195,42 @@ out_put:
  dput(lower_root);
  mntput(lower_mnt);
 out:
- path_put(&nd.path);
+ path_release(&nd);
  return err;
 }
 
-static int dazukofs_get_sb(struct file_system_type *fs_type, int flags,
-   const char *dev_name, void *data,
-   struct vfsmount *mnt)
+static struct super_block *
+dazukofs_get_sb(struct file_system_type *fs_type, int flags,  
+       const char *dev_name, void *data)
 {
  struct super_block *sb;
  int err;
 
- err = get_sb_nodev(fs_type, flags, data, dazukofs_fill_super, mnt);
- if (err)
- goto out;
-
- sb = mnt->mnt_sb;
+ sb = get_sb_nodev(fs_type, flags, data, dazukofs_fill_super);
+ if (IS_ERR(sb))
+ return sb;
 
  err = dazukofs_parse_mount_options(data, sb);
  if (err)
- goto out_abort;
+ goto out;
 
  err = dazukofs_read_super(sb, dev_name);
  if (err)
- goto out_abort;
+ goto out;
 
- goto out;
+ return sb;
 
-out_abort:
+out:
  up_write(&sb->s_umount);
+ dput(sb->s_root);
  deactivate_super(sb);
-out:
- return err;
+ return ERR_PTR(err);
 }
 
-static void init_once(void *data)
+static void init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags)
 {
  struct dazukofs_inode_info *inode_info =
- (struct dazukofs_inode_info *)data;
+ (struct dazukofs_inode_info *)vptr;
 
  memset(inode_info, 0, sizeof(struct dazukofs_inode_info));
  inode_init_once(&(inode_info->vfs_inode));
@@ -256,7 +265,7 @@ static int init_caches(void)
  kmem_cache_create("dazukofs_inode_info_cache",
   sizeof(struct dazukofs_inode_info), 0,
   SLAB_HWCACHE_ALIGN,
-  init_once);
+  init_once, NULL);
  if (!dazukofs_inode_info_cachep)
  goto out_nomem;
 
@@ -264,7 +273,7 @@ static int init_caches(void)
  kmem_cache_create("dazukofs_sb_info_cache",
   sizeof(struct dazukofs_sb_info), 0,
   SLAB_HWCACHE_ALIGN,
-  NULL);
+  NULL, NULL);
  if (!dazukofs_sb_info_cachep)
  goto out_nomem;
 
@@ -272,7 +281,7 @@ static int init_caches(void)
  kmem_cache_create("dazukofs_dentry_info_cache",
   sizeof(struct dazukofs_dentry_info), 0,
   SLAB_HWCACHE_ALIGN,
-  NULL);
+  NULL, NULL);
  if (!dazukofs_dentry_info_cachep)
  goto out_nomem;
 
@@ -280,7 +289,7 @@ static int init_caches(void)
  kmem_cache_create("dazukofs_file_info_cache",
   sizeof(struct dazukofs_file_info), 0,
   SLAB_HWCACHE_ALIGN,
-  NULL);
+  NULL, NULL);
  if (!dazukofs_file_info_cachep)
  goto out_nomem;
 
@@ -305,7 +314,7 @@ static struct file_system_type dazukofs_
 
 static int __init init_dazukofs_fs(void)
 {
- int err = 0;
+ int err;
 
  err = dazukofs_dev_init();
  if (err)
@@ -319,7 +328,7 @@ static int __init init_dazukofs_fs(void)
  if (err)
  goto error_out3;
 
- printk(KERN_INFO "dazukofs: loaded, version=%s\n", DAZUKOFS_VERSION);
+ printk(KERN_INFO "dazukofs: loaded, version=" DAZUKOFS_VERSION "\n");
  return 0;
 
 error_out3:
@@ -335,7 +344,7 @@ static void __exit exit_dazukofs_fs(void
  unregister_filesystem(&dazukofs_fs_type);
  destroy_caches();
  dazukofs_dev_destroy();
- printk(KERN_INFO "dazukofs: unloaded, version=%s\n", DAZUKOFS_VERSION);
+ printk(KERN_INFO "dazukofs: unloaded, version=" DAZUKOFS_VERSION "\n");
 }
 
 MODULE_AUTHOR("John Ogness");

_______________________________________________
Dazuko-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/dazuko-devel
Reply | Threaded
Open this post in threaded view
|

Re: patch for SLES 10 SP2

John Ogness-5
This patch involves significant changes to device logic. Although the
end result is the same, the changes are very different from the other
patches. Who is the author of this patch?


On 2009-07-07, Lino Sanfilippo <[hidden email]> wrote:

> diff -x CVS -rup dazukofs-3.0.0/CHANGELOG dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/CHANGELOG
> --- dazukofs-3.0.0/CHANGELOG 2009-02-22 17:51:22.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/CHANGELOG 2009-02-06 17:48:21.000000000 +0100
> @@ -2,11 +2,6 @@
>   DazukoFS CHANGELOG
>  ====================
>  
> -3.0.0 (2009-02-22)
> -- added define for version number output
> -- added patches for various other kernels
> -
> -
>  3.0.0-rc4 (2008-11-30)
>  - fix incorrect dentry/vfsmnt referencing when access denied
>  - fix improper cleanup in several error handling conditions
> diff -x CVS -rup dazukofs-3.0.0/ctrl_dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ctrl_dev.c
> --- dazukofs-3.0.0/ctrl_dev.c 2009-02-22 17:45:20.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ctrl_dev.c 2009-02-06 18:27:43.000000000 +0100
> @@ -21,7 +21,8 @@
>  #include <linux/device.h>
>  #include <linux/fs.h>
>  #include <linux/cdev.h>
> -#include <linux/uaccess.h>
> +#include <linux/platform_device.h>
> +#include <asm/uaccess.h>
>  
>  #include "event.h"
>  #include "dev.h"
> @@ -158,7 +159,11 @@ static ssize_t dazukofs_ctrl_write(struc
>   return ret;
>  }
>  
> -static struct cdev ctrl_cdev;
> +static struct {
> + struct cdev cdev;
> + struct device dev;
> + struct class_device cls_dev;
> +} ctrl_dev;
>  
>  static struct file_operations ctrl_fops = {
>   .owner = THIS_MODULE,
> @@ -168,38 +173,67 @@ static struct file_operations ctrl_fops
>   .write = dazukofs_ctrl_write,
>  };
>  
> +static void dazukofs_ctrl_class_dev_release(struct class_device *dev)
> +{
> + // nothing
> +}
> +
> +static void dazukofs_ctrl_dev_release(struct device *dev)
> +{
> + // nothing
> +}
> +
>  int dazukofs_ctrl_dev_init(int dev_major, int dev_minor,
>     struct class *dazukofs_class)
>  {
>   int err = 0;
> - struct device *dev;
> + dev_t devt;
> +
> + devt = MKDEV(dev_major, dev_minor);
>  
>   /* setup cdev for control */
> - cdev_init(&ctrl_cdev, &ctrl_fops);
> - ctrl_cdev.owner = THIS_MODULE;
> - err = cdev_add(&ctrl_cdev, MKDEV(dev_major, dev_minor), 1);
> + cdev_init(&ctrl_dev.cdev, &ctrl_fops);
> + ctrl_dev.cdev.owner = THIS_MODULE;
> + err = cdev_add(&ctrl_dev.cdev, devt, 1);
>   if (err)
> - goto error_out1;
> + return err;
>  
> - /* create control device */
> - dev = device_create(dazukofs_class, NULL, MKDEV(dev_major, dev_minor),
> -    NULL, "%s.ctrl", DEVICE_NAME);
> - if (IS_ERR(dev)) {
> - err = PTR_ERR(dev);
> - goto error_out2;
> - }
>  
> + ctrl_dev.dev.parent = &platform_bus;
> + ctrl_dev.dev.release = dazukofs_ctrl_dev_release;
> + snprintf(ctrl_dev.dev.bus_id, BUS_ID_SIZE, "%s.ctrl", DEVICE_NAME);
> +
> + err = device_register(&ctrl_dev.dev);
> +
> + if (err)
> + goto error_out;
> +
> + ctrl_dev.cls_dev.release = dazukofs_ctrl_class_dev_release;
> + ctrl_dev.cls_dev.class = dazukofs_class;
> + ctrl_dev.cls_dev.dev = &ctrl_dev.dev;
> +
> + snprintf(ctrl_dev.cls_dev.class_id, BUS_ID_SIZE, "%s.ctrl", DEVICE_NAME);
> + ctrl_dev.cls_dev.devt = devt;
> +
> + err = class_device_register(&ctrl_dev.cls_dev);
> +
> + if (err)
> + goto error_out2;
> +
>   return 0;
>  
>  error_out2:
> - cdev_del(&ctrl_cdev);
> -error_out1:
> + device_unregister(&ctrl_dev.dev);
> +error_out:
> + cdev_del(&ctrl_dev.cdev);
>   return err;
>  }
>  
> +
>  void dazukofs_ctrl_dev_destroy(int dev_major, int dev_minor,
>         struct class *dazukofs_class)
>  {
> - device_destroy(dazukofs_class, MKDEV(dev_major, dev_minor));
> - cdev_del(&ctrl_cdev);
> + class_device_unregister(&ctrl_dev.cls_dev);
> + device_unregister(&ctrl_dev.dev);
> + cdev_del(&ctrl_dev.cdev);
>  }
> diff -x CVS -rup dazukofs-3.0.0/dazukofs_fs.h dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dazukofs_fs.h
> --- dazukofs-3.0.0/dazukofs_fs.h 2009-02-22 17:43:11.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dazukofs_fs.h 2009-07-03 18:02:12.000000000 +0200
> @@ -3,7 +3,7 @@
>     Copyright (C) 1997-2004 Erez Zadok
>     Copyright (C) 2001-2004 Stony Brook University
>     Copyright (C) 2004-2007 International Business Machines Corp.
> -   Copyright (C) 2008-2009 John Ogness
> +   Copyright (C) 2008 John Ogness
>       Author: John Ogness <[hidden email]>
>  
>     This program is free software; you can redistribute it and/or
> @@ -24,12 +24,10 @@
>  #ifndef __DAZUKOFS_FS_H
>  #define __DAZUKOFS_FS_H
>  
> -#define DAZUKOFS_VERSION "3.0.0"
> -
>  extern struct kmem_cache *dazukofs_dentry_info_cachep;
>  extern struct kmem_cache *dazukofs_file_info_cachep;
>  extern struct file_operations dazukofs_main_fops;
> -extern const struct file_operations dazukofs_dir_fops;
> +extern struct file_operations dazukofs_dir_fops;
>  extern struct dentry_operations dazukofs_dops;
>  extern struct address_space_operations dazukofs_aops;
>  
> @@ -59,6 +57,37 @@ struct dazukofs_file_info {
>   struct file *lower_file;
>  };
>  
> +void fsstack_copy_inode_size(struct inode *dst, const struct inode *src);
> +
> +static inline
> +void fsstack_copy_attr_atime(struct inode *dst, const struct inode *src)
> +{
> + dst->i_atime = src->i_atime;
> +}
> +
> +static inline
> +void fsstack_copy_attr_times(struct inode *dst, const struct inode *src)
> +{
> + dst->i_atime = src->i_atime;
> + dst->i_mtime = src->i_mtime;
> + dst->i_ctime = src->i_ctime;
> +}
> +
> +static inline
> +void fsstack_copy_attr_all(struct inode *dst, const struct inode *src)
> +{
> + dst->i_mode = src->i_mode;
> + dst->i_uid = src->i_uid;
> + dst->i_gid = src->i_gid;
> + dst->i_rdev = src->i_rdev;
> + dst->i_atime = src->i_atime;
> + dst->i_mtime = src->i_mtime;
> + dst->i_ctime = src->i_ctime;
> + dst->i_blksize = src->i_blksize;
> + dst->i_blkbits = src->i_blkbits;
> + dst->i_flags = src->i_flags;
> +}
> +
>  static inline
>  struct dazukofs_sb_info *GET_SB_INFO(struct super_block *upper_sb)
>  {
> diff -x CVS -rup dazukofs-3.0.0/dentry.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dentry.c
> --- dazukofs-3.0.0/dentry.c 2009-02-22 17:44:22.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dentry.c 2009-02-06 17:48:21.000000000 +0100
> @@ -25,7 +25,7 @@
>  #include <linux/fs.h>
>  #include <linux/namei.h>
>  #include <linux/mount.h>
> -#include <linux/fs_stack.h>
> +
>  
>  #include "dazukofs_fs.h"
>  
> @@ -65,19 +65,19 @@ static int dazukofs_d_revalidate(struct
>  
>   lower_mnt = GET_LOWER_MNT(dentry);
>  
> - vfsmount_save = nd->path.mnt;
> - dentry_save = nd->path.dentry;
> + vfsmount_save = nd->mnt;
> + dentry_save = nd->dentry;
>  
> - nd->path.mnt = mntget(lower_mnt);
> - nd->path.dentry = dget(lower_dentry);
> + nd->mnt = mntget(lower_mnt);
> + nd->dentry = dget(lower_dentry);
>  
>   valid = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
>  
>   mntput(lower_mnt);
>   dput(lower_dentry);
>  
> - nd->path.mnt = vfsmount_save;
> - nd->path.dentry = dentry_save;
> + nd->mnt = vfsmount_save;
> + nd->dentry = dentry_save;
>  
>   /* update the inode, even if d_revalidate() != 1 */
>   if (dentry->d_inode) {
> @@ -85,7 +85,7 @@ static int dazukofs_d_revalidate(struct
>  
>   lower_inode = GET_LOWER_INODE(dentry->d_inode);
>  
> - fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL);
> + fsstack_copy_attr_all(dentry->d_inode, lower_inode);
>   }
>  out:
>   return valid;
> diff -x CVS -rup dazukofs-3.0.0/dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dev.c
> --- dazukofs-3.0.0/dev.c 2009-02-22 17:42:25.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/dev.c 2009-02-06 17:48:21.000000000 +0100
> @@ -21,18 +21,31 @@
>  #include <linux/device.h>
>  #include <linux/fs.h>
>  #include <linux/cdev.h>
> -#include <linux/uaccess.h>
>  
> +#include <asm/uaccess.h>
>  #include "dazukofs_fs.h"
>  #include "event.h"
>  #include "dev.h"
>  
> +
> +//static CLASS_DEVICE_ATTR(dev, S_IRUGO, read_devnum, NULL);
> +
>  static struct class *dazukofs_class;
>  
>  static int dev_major;
>  static int dev_minor_start;
>  static int dev_minor_end;
>  
> +#if 0
> +static ssize_t read_devnum(strut class_device *cls_dev, char *buf)
> +{
> + dev_t devnum;
> +
> + devnum = cls_dev->dev->
> +
> +}
> +#endif
> +
>  int dazukofs_dev_init(void)
>  {
>   int err = 0;
> diff -x CVS -rup dazukofs-3.0.0/event.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/event.c
> --- dazukofs-3.0.0/event.c 2009-02-22 17:44:03.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/event.c 2009-07-03 18:57:12.000000000 +0200
> @@ -23,7 +23,7 @@
>  #include <linux/file.h>
>  #include <linux/fs.h>
>  #include <linux/mount.h>
> -#include <linux/freezer.h>
> +
>  
>  #include "dev.h"
>  #include "dazukofs_fs.h"
> @@ -113,21 +113,21 @@ int dazukofs_init_events(void)
>   dazukofs_group_cachep =
>   kmem_cache_create("dazukofs_group_cache",
>    sizeof(struct dazukofs_group), 0,
> -  SLAB_HWCACHE_ALIGN, NULL);
> +  SLAB_HWCACHE_ALIGN, NULL, NULL);
>   if (!dazukofs_group_cachep)
>   goto error_out;
>  
>   dazukofs_event_container_cachep =
>   kmem_cache_create("dazukofs_event_container_cache",
>    sizeof(struct dazukofs_event_container), 0,
> -  SLAB_HWCACHE_ALIGN, NULL);
> +  SLAB_HWCACHE_ALIGN, NULL, NULL);
>   if (!dazukofs_event_container_cachep)
>   goto error_out;
>  
>   dazukofs_event_cachep =
>   kmem_cache_create("dazukofs_event_cache",
>    sizeof(struct dazukofs_event), 0,
> -  SLAB_HWCACHE_ALIGN, NULL);
> +  SLAB_HWCACHE_ALIGN, NULL, NULL);
>   if (!dazukofs_event_cachep)
>   goto error_out;
>  
> @@ -162,16 +162,23 @@ static int capture_group_count(int *cach
>   return err;
>  }
>  
> -static int get_group_count(void)
> +static int get_group_count_interruptible(void)
>  {
>   int cache = 0;
> - int ret = wait_event_freezable(__group_count_queue,
> -       capture_group_count(&cache) == 0);
> + int ret = wait_event_interruptible(__group_count_queue,
> + capture_group_count(&cache) == 0);
>   if (ret == 0)
>   ret = __group_count;
>   return ret;
>  }
>  
> +static int get_group_count(void)
> +{
> + int cache = 0;
> + wait_event(__group_count_queue, capture_group_count(&cache) == 0);
> + return __group_count;
> +}
> +
>  static void put_group_count(void)
>  {
>   mutex_lock(&group_count_mutex);
> @@ -373,9 +380,10 @@ static struct dazukofs_group *create_gro
>  {
>   struct dazukofs_group *grp;
>  
> - grp = kmem_cache_zalloc(dazukofs_group_cachep, GFP_KERNEL);
> + grp = kmem_cache_alloc(dazukofs_group_cachep, GFP_KERNEL);
>   if (!grp)
>   return NULL;
> + memset(grp, 0, sizeof(*grp));
>  
>   atomic_set(&grp->use_count, 0);
>   grp->group_id = id;
> @@ -399,7 +407,7 @@ int dazukofs_add_group(const char *name,
>   int already_exists;
>   int available_id = 0;
>   struct dazukofs_group *grp;
> - int grp_count = get_group_count();
> + int grp_count = get_group_count_interruptible();
>  
>   if (grp_count < 0) {
>   ret = grp_count;
> @@ -447,7 +455,7 @@ int dazukofs_remove_group(const char *na
>   int ret = 0;
>   struct dazukofs_group *grp;
>   struct list_head *pos;
> - int grp_count = get_group_count();
> + int grp_count = get_group_count_interruptible();
>  
>   if (grp_count < 0) {
>   ret = grp_count;
> @@ -661,18 +669,24 @@ allocate_event_and_containers(struct daz
>  {
>   int i;
>  
> - *evt = kmem_cache_zalloc(dazukofs_event_cachep, GFP_KERNEL);
> + *evt = kmem_cache_alloc(dazukofs_event_cachep, GFP_KERNEL);
>   if (!*evt)
>   return -1;
> + memset(*evt, 0, sizeof(**evt));
>   init_waitqueue_head(&(*evt)->queue);
>   mutex_init(&(*evt)->assigned_mutex);
>  
>   /* allocate containers now while we don't have a lock */
>   for (i = 0; i < grp_count; i++) {
> - ec_array[i] = kmem_cache_zalloc(
> - dazukofs_event_container_cachep, GFP_KERNEL);
> - if (!ec_array[i])
> + struct dazukofs_event_container *ec;
> +
> + ec = kmem_cache_alloc(dazukofs_event_container_cachep,
> +      GFP_KERNEL);
> + if (!ec)
>   goto error_out;
> + memset(ec, 0, sizeof(*ec));
> +
> + ec_array[i] = ec;
>   }
>  
>   return 0;
> @@ -701,11 +715,10 @@ int dazukofs_check_access(struct dentry
>  {
>   struct dazukofs_event_container *ec_array[GROUP_COUNT];
>   struct dazukofs_event *evt;
> - int grp_count = get_group_count();
> - int err;
> + int grp_count;
> + int err = 0;
>  
> - if (grp_count < 0)
> - return grp_count;
> + grp_count = get_group_count();
>  
>   if (check_access_precheck(grp_count)) {
>   put_group_count();
> @@ -713,32 +726,29 @@ int dazukofs_check_access(struct dentry
>   }
>  
>   /* at this point, the access should be handled */
> -
>   if (allocate_event_and_containers(&evt, ec_array, grp_count)) {
>   put_group_count();
> - err = -ENOMEM;
> - goto out;
> + return -ENOMEM;
>   }
> -
>   evt->dentry = dget(dentry);
>   evt->mnt = mntget(mnt);
>   evt->pid = current->pid;
> -
>   assign_event_to_groups(evt, ec_array);
>  
>   put_group_count();
>  
> - /* wait until event completely processed or signal */
> - err = wait_event_freezable(evt->queue, event_assigned(evt) == 0);
> + /* wait until event completely processed */
> + wait_event(evt->queue, event_assigned(evt) == 0);
>  
>   if (evt->deny)
>   err = -EPERM;
>  
>   release_event(evt, 0, 0);
> -out:
> +
>   return err;
>  }
>  
> +
>  int dazukofs_group_open_tracking(unsigned long group_id)
>  {
>   struct dazukofs_group *grp;
> @@ -874,7 +884,8 @@ static struct dazukofs_event_container *
>   /* move first todo-item to working list */
>   mutex_lock(&work_mutex);
>   if (!list_empty(&grp->todo_list.list)) {
> - ec = list_first_entry(&grp->todo_list.list,
> + struct list_head *head = &grp->todo_list.list;
> + ec = list_entry(head->next,
>        struct dazukofs_event_container, list);
>   list_del(&ec->list);
>   list_add(&ec->list, &grp->working_list.list);
> @@ -928,7 +939,8 @@ static int open_file(struct dazukofs_eve
>   /* add myself to be ignored on file open (to avoid recursion) */
>   mask_proc(&proc);
>  
> - ec->file = dentry_open(dget(evt->dentry), mntget(evt->mnt), O_RDONLY);
> + ec->file = dentry_open(dget(evt->dentry), mntget(evt->mnt),
> +       O_RDONLY | O_LARGEFILE);
>   if (IS_ERR(ec->file)) {
>   check_recursion();  /* remove myself from proc_list */
>   ret = PTR_ERR(ec->file);
> @@ -1004,9 +1016,9 @@ int dazukofs_get_event(unsigned long gro
>   }
>  
>   while (1) {
> - ret = wait_event_freezable(grp->queue,
> -   is_event_available(grp) ||
> -   grp->deprecated);
> + ret = wait_event_interruptible(grp->queue,
> +   is_event_available(grp) ||
> +   grp->deprecated);
>   if (ret != 0)
>   break;
>  
> diff -x CVS -rup dazukofs-3.0.0/file.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/file.c
> --- dazukofs-3.0.0/file.c 2009-02-22 17:43:11.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/file.c 2009-07-03 18:50:52.000000000 +0200
> @@ -25,7 +25,7 @@
>  #include <linux/fs.h>
>  #include <linux/mount.h>
>  #include <linux/file.h>
> -#include <linux/fs_stack.h>
> +
>  
>  #include "dazukofs_fs.h"
>  #include "event.h"
> @@ -37,7 +37,7 @@ static loff_t dazukofs_llseek(struct fil
>  {
>   loff_t retval = -EINVAL;
>   struct file *lower_file = GET_LOWER_FILE(file);
> -
> +
>   lower_file->f_pos = file->f_pos;
>  
>   memcpy(&(lower_file->f_ra), &(file->f_ra),
> @@ -174,19 +174,23 @@ static int dazukofs_open(struct inode *i
>   struct dentry *dentry = file->f_dentry;
>   struct dentry *lower_dentry = dget(GET_LOWER_DENTRY(dentry));
>   struct vfsmount *lower_mnt = mntget(GET_LOWER_MNT(dentry));
> + struct dazukofs_file_info *fi;
>   struct file *lower_file;
>   int err;
>  
> - err = dazukofs_check_access(file->f_dentry, file->f_vfsmnt);
> - if (err)
> - goto error_out1;
> -
> - SET_FILE_INFO(file, kmem_cache_zalloc(dazukofs_file_info_cachep,
> -      GFP_KERNEL));
> - if (!GET_FILE_INFO(file)) {
> + if (S_ISREG(inode->i_mode)) {
> + err = dazukofs_check_access(file->f_dentry, file->f_vfsmnt);
> + if (err)
> + goto error_out1;
> + }
> + fi = kmem_cache_alloc(dazukofs_file_info_cachep, GFP_KERNEL);
> + if (!fi) {
>   err = -ENOMEM;
>   goto error_out1;
>   }
> + memset(fi, 0, sizeof(*fi));
> +
> + SET_FILE_INFO(file, fi);
>  
>   lower_file = dentry_open(lower_dentry, lower_mnt, file->f_flags);
>   if (IS_ERR(lower_file)) {
> @@ -272,6 +276,20 @@ out:
>   return err;
>  }
>  
> +static int dazukofs_mmap (struct file *file, struct vm_area_struct *vm)
> +{
> +
> + struct file *lower_file = GET_LOWER_FILE(file);
> +
> + /* if lower fs does not support mmap(), we dont call generic_file_readonly_mmap(),
> + * since this would result in calling lower readpage(), which might not be
> + * defined by lower fs if mmap() is not supported*/
> + if (!lower_file->f_op || !lower_file->f_op->mmap)
> + return -ENODEV;
> +
> +
> + return generic_file_readonly_mmap(file, vm);
> +}
>  /**
>   * Unused operations:
>   *   - owner
> @@ -295,18 +313,15 @@ out:
>  struct file_operations dazukofs_main_fops = {
>   .llseek = dazukofs_llseek,
>   .read = dazukofs_read,
> - .aio_read = generic_file_aio_read,
>   .write = dazukofs_write,
> - .aio_write = generic_file_aio_write,
>   .readdir = dazukofs_readdir,
>   .ioctl = dazukofs_ioctl,
> - .mmap = generic_file_mmap,
> + .mmap = dazukofs_mmap,
>   .open = dazukofs_open,
>   .flush = dazukofs_flush,
>   .release = dazukofs_release,
>   .fsync = dazukofs_fsync,
>   .fasync = dazukofs_fasync,
> - .splice_read = generic_file_splice_read,
>  };
>  
>  /**
> @@ -332,14 +347,13 @@ struct file_operations dazukofs_main_fop
>   *   - splice_read (generic)
>   *   - setlease
>   */
> -const struct file_operations dazukofs_dir_fops = {
> +struct file_operations dazukofs_dir_fops = {
>   .readdir = dazukofs_readdir,
>   .ioctl = dazukofs_ioctl,
> - .mmap = generic_file_mmap,
> + .mmap = dazukofs_mmap,
>   .open = dazukofs_open,
>   .flush = dazukofs_flush,
>   .release = dazukofs_release,
>   .fsync = dazukofs_fsync,
>   .fasync = dazukofs_fasync,
> - .splice_read = generic_file_splice_read,
>  };
> diff -x CVS -rup dazukofs-3.0.0/group_dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/group_dev.c
> --- dazukofs-3.0.0/group_dev.c 2009-02-22 17:45:20.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/group_dev.c 2009-02-06 19:04:28.000000000 +0100
> @@ -21,31 +21,55 @@
>  #include <linux/device.h>
>  #include <linux/fs.h>
>  #include <linux/cdev.h>
> -#include <linux/uaccess.h>
> +#include <linux/platform_device.h>
> +#include <asm/uaccess.h>
>  
>  #include "dazukofs_fs.h"
>  #include "event.h"
>  #include "dev.h"
>  
> -static int dazukofs_group_open(int group_id, struct inode *inode,
> +
> +
> +
> +struct group_device {
> + struct cdev cdev;
> + struct device dev;
> + struct class_device cls_dev;
> + int id;
> + int track;
> +};
> +
> +static struct group_device *grp_devs;
> +static int minor_start;  /* initial minor number */
> +
> +static int dazukofs_group_open(struct inode *inode,
>         struct file *file)
>  {
> - if (dazukofs_group_open_tracking(group_id))
> - file->private_data = file;
> - else
> - file->private_data = NULL;
> + int id;
> + struct group_device *gdev;
> +
> + id = MINOR(inode->i_rdev) - minor_start;
> + gdev = &grp_devs[id];
> +
> + gdev->track = dazukofs_group_open_tracking(id);
> + gdev->id = id;
> + file->private_data = gdev;
>   return 0;
>  }
>  
> -static int dazukofs_group_release(int group_id, struct inode *inode,
> +static int dazukofs_group_release(struct inode *inode,
>    struct file *file)
>  {
> - if (file->private_data)
> - dazukofs_group_release_tracking(group_id);
> + struct group_device *gdev;
> +
> + gdev = (struct group_device *) file->private_data;
> +
> + if (gdev->track)
> + dazukofs_group_release_tracking(gdev->id);
>   return 0;
>  }
>  
> -static ssize_t dazukofs_group_read(int group_id, struct file *file,
> +static ssize_t dazukofs_group_read(struct file *file,
>     char __user *buffer, size_t length,
>     loff_t *pos)
>  {
> @@ -56,6 +80,9 @@ static ssize_t dazukofs_group_read(int g
>   int fd;
>   int err;
>   unsigned long event_id;
> + struct group_device *gdev;
> +  
> + gdev = (struct group_device *) file->private_data;
>  
>   if (*pos > 0)
>   return 0;
> @@ -63,7 +90,7 @@ static ssize_t dazukofs_group_read(int g
>   if (length < DAZUKOFS_MIN_READ_BUFFER)
>   return -EINVAL;
>  
> - err = dazukofs_get_event(group_id, &event_id, &fd, &pid);
> + err = dazukofs_get_event(gdev->id, &event_id, &fd, &pid);
>   if (err) {
>   if (err == -ERESTARTSYS)
>   return -EINTR;
> @@ -83,7 +110,7 @@ static ssize_t dazukofs_group_read(int g
>   return tmp_used;
>  }
>  
> -static ssize_t dazukofs_group_write(int group_id, struct file *file,
> +static ssize_t dazukofs_group_write(struct file *file,
>      const char __user *buffer, size_t length,
>      loff_t *pos)
>  {
> @@ -94,6 +121,9 @@ static ssize_t dazukofs_group_write(int
>   char *p;
>   char *p2;
>   int ret;
> + struct group_device *gdev;
> +
> + gdev = (struct group_device *) file->private_data;
>  
>   if (length >= DAZUKOFS_MAX_WRITE_BUFFER)
>   length = DAZUKOFS_MAX_WRITE_BUFFER - 1;
> @@ -118,7 +148,7 @@ static ssize_t dazukofs_group_write(int
>   return -EINVAL;
>   response = (*(p + 2)) - '0';
>  
> - ret = dazukofs_return_event(group_id, event_id, response);
> + ret = dazukofs_return_event(gdev->id, event_id, response);
>   if (ret == 0) {
>   *pos += length;
>   ret = length;
> @@ -129,104 +159,105 @@ static ssize_t dazukofs_group_write(int
>   return ret;
>  }
>  
> -#define DECLARE_GROUP_FOPS(group_id) \
> -static int \
> -dazukofs_group_open_##group_id(struct inode *inode, struct file *file) \
> -{ \
> - return dazukofs_group_open(group_id, inode, file); \
> -} \
> -static int \
> -dazukofs_group_release_##group_id(struct inode *inode, struct file *file) \
> -{ \
> - return dazukofs_group_release(group_id, inode, file); \
> -} \
> -static ssize_t \
> -dazukofs_group_read_##group_id(struct file *file, char __user *buffer, \
> -       size_t length, loff_t *pos) \
> -{ \
> - return dazukofs_group_read(group_id, file, buffer, length, pos); \
> -} \
> -static ssize_t \
> -dazukofs_group_write_##group_id(struct file *file, \
> - const char __user *buffer, size_t length, \
> - loff_t *pos) \
> -{ \
> - return dazukofs_group_write(group_id, file, buffer, length, pos); \
> -} \
> -static struct file_operations group_fops_##group_id = { \
> - .owner = THIS_MODULE, \
> - .open = dazukofs_group_open_##group_id, \
> - .release = dazukofs_group_release_##group_id, \
> - .read = dazukofs_group_read_##group_id, \
> - .write = dazukofs_group_write_##group_id, \
> +struct file_operations grp_fops = {
> + .owner   = THIS_MODULE,
> + .open   = dazukofs_group_open,
> + .release   = dazukofs_group_release,
> + .read   = dazukofs_group_read,
> + .write   = dazukofs_group_write,
>  };
>  
> -DECLARE_GROUP_FOPS(0)
> -DECLARE_GROUP_FOPS(1)
> -DECLARE_GROUP_FOPS(2)
> -DECLARE_GROUP_FOPS(3)
> -DECLARE_GROUP_FOPS(4)
> -DECLARE_GROUP_FOPS(5)
> -DECLARE_GROUP_FOPS(6)
> -DECLARE_GROUP_FOPS(7)
> -DECLARE_GROUP_FOPS(8)
> -DECLARE_GROUP_FOPS(9)
> -
> -static struct cdev groups_cdev[GROUP_COUNT];
> -
> -static struct file_operations *group_fops[GROUP_COUNT] = {
> - &group_fops_0,
> - &group_fops_1,
> - &group_fops_2,
> - &group_fops_3,
> - &group_fops_4,
> - &group_fops_5,
> - &group_fops_6,
> - &group_fops_7,
> - &group_fops_8,
> - &group_fops_9,
> -};
> +
> +static void dazukofs_group_class_dev_release(struct class_device *cls_dev)
> +{
> + // nothing
> +}
> +
> +static void dazukofs_group_dev_release(struct device *dev)
> +{
> + // Nothing
> +}
> +
> +static int __dazukofs_group_dev_init(dev_t devt, struct class *cls,
> +     struct group_device *gdev, char *name)
> +{
> + int err;
> +
> + cdev_init(&gdev->cdev, &grp_fops);
> + gdev->cdev.owner = THIS_MODULE;
> +
> + err = cdev_add(&gdev->cdev, devt, GROUP_COUNT);
> +
> + if (err)
> + return -1;
> +
> + gdev->dev.parent = &platform_bus;
> + gdev->dev.release = dazukofs_group_dev_release;
> + strncpy(gdev->dev.bus_id, name, BUS_ID_SIZE);
> +
> + err = device_register(&gdev->dev);
> +
> + if (err)
> + goto err_out;
> +
> + gdev->cls_dev.release = dazukofs_group_class_dev_release;
> + gdev->cls_dev.class = cls;
> + gdev->cls_dev.dev = &gdev->dev;
> + strncpy(gdev->cls_dev.class_id, name, BUS_ID_SIZE);
> + gdev->cls_dev.devt = devt;
> +
> + err = class_device_register(&gdev->cls_dev);
> +
> + if (err)
> + goto err_out2;
> +
> + return 0;
> +
> +err_out2:
> + device_unregister(&gdev->dev);
> +err_out:
> + cdev_del(&gdev->cdev);
> +
> + return err;
> +}
>  
>  int dazukofs_group_dev_init(int dev_major, int dev_minor_start,
>      struct class *dazukofs_class)
>  {
> - int err = 0;
> - struct device *dev;
> + int err;
>   int i;
> - int cdev_count;
> - int dev_minor_end = dev_minor_start;
> + dev_t devt;
> + struct group_device *gdev;
> + char name[BUS_ID_SIZE];
>  
> - /* setup cdevs for groups */
> - for (cdev_count = 0; cdev_count < GROUP_COUNT; cdev_count++) {
> - cdev_init(&groups_cdev[cdev_count], group_fops[cdev_count]);
> - groups_cdev[cdev_count].owner = THIS_MODULE;
> - err = cdev_add(&groups_cdev[cdev_count],
> -       MKDEV(dev_major, dev_minor_start + cdev_count),
> -       GROUP_COUNT);
> - if (err)
> - goto error_out1;
> - }
> + grp_devs = kzalloc(sizeof(struct group_device) * GROUP_COUNT,
> +   GFP_KERNEL);
> +
> + if (!grp_devs)
> + return -ENOMEM;
>  
>   /* create group devices */
>   for (i = 0; i < GROUP_COUNT; i++) {
> - dev = device_create(dazukofs_class, NULL,
> -    MKDEV(dev_major, dev_minor_end), NULL,
> -    "%s.%d", DEVICE_NAME, i);
> - if (IS_ERR(dev)) {
> - err = PTR_ERR(dev);
> - goto error_out2;
> - }
> - dev_minor_end++;
> + gdev = &grp_devs[i];
> + devt = MKDEV(dev_major, dev_minor_start + i);
> + snprintf(name, sizeof(name), "%s.%i", DEVICE_NAME, i);
> + err = __dazukofs_group_dev_init(devt, dazukofs_class,
> +                                                gdev, name);
> + if (err)
> + goto undo;
>   }
>  
> - return dev_minor_end;
> + minor_start = dev_minor_start;
> + return i;
>  
> -error_out2:
> - for (i = dev_minor_start; i < dev_minor_end; i++)
> - device_destroy(dazukofs_class, MKDEV(dev_major, i));
> -error_out1:
> - for (i = 0; i < cdev_count; i++)
> - cdev_del(&groups_cdev[i]);
> +undo:
> + while(i) {
> + i--;
> + gdev = &grp_devs[i];
> + class_device_unregister(&gdev->cls_dev);
> + device_unregister(&gdev->dev);
> + cdev_del(&gdev->cdev);
> + }
>   return err;
>  }
>  
> @@ -236,9 +267,14 @@ void dazukofs_group_dev_destroy(int dev_
>  {
>   int i;
>  
> - for (i = dev_minor_start; i < dev_minor_end; i++)
> - device_destroy(dazukofs_class, MKDEV(dev_major, i));
> + for (i = 0; i < GROUP_COUNT; i++) {
> + struct group_device *gdev;
> +
> + gdev = &grp_devs[i];
>  
> - for (i = 0; i < GROUP_COUNT; i++)
> - cdev_del(&groups_cdev[i]);
> + class_device_unregister(&gdev->cls_dev);
> + device_unregister(&gdev->dev);
> + cdev_del(&gdev->cdev);
> + }
> + kfree(grp_devs);
>  }
> diff -x CVS -rup dazukofs-3.0.0/ign_dev.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ign_dev.c
> --- dazukofs-3.0.0/ign_dev.c 2009-02-22 17:45:20.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/ign_dev.c 2009-02-06 18:29:19.000000000 +0100
> @@ -21,7 +21,8 @@
>  #include <linux/device.h>
>  #include <linux/fs.h>
>  #include <linux/cdev.h>
> -#include <linux/uaccess.h>
> +#include <linux/platform_device.h>
> +#include <asm/uaccess.h>
>  
>  #include "dazukofs_fs.h"
>  #include "dev.h"
> @@ -56,12 +57,14 @@ int dazukofs_check_ignore_process(void)
>  
>  static int dazukofs_add_ign(struct file *file)
>  {
> - struct dazukofs_proc *proc =
> - kmem_cache_zalloc(dazukofs_ign_cachep, GFP_KERNEL);
> + struct dazukofs_proc *proc;
> +
> + proc = kmem_cache_alloc(dazukofs_ign_cachep, GFP_KERNEL);
>   if (!proc) {
>   file->private_data = NULL;
>   return -ENOMEM;
>   }
> + memset(proc, 0, sizeof(*proc));
>  
>   file->private_data = proc;
>   proc->curr = current;
> @@ -124,7 +127,11 @@ static void dazukofs_destroy_ignlist(voi
>   }
>  }
>  
> -static struct cdev ign_cdev;
> +static struct {
> + struct cdev cdev;
> + struct device dev;
> + struct class_device cls_dev;
> +} ign_dev;
>  
>  static struct file_operations ign_fops = {
>   .owner = THIS_MODULE,
> @@ -132,11 +139,23 @@ static struct file_operations ign_fops =
>   .release = dazukofs_ign_release,
>  };
>  
> +
> +static void dazukofs_ign_class_dev_release(struct class_device *dev)
> +{
> + // nothing
> +}
> +
> +static void dazukofs_ign_dev_release(struct device *dev)
> +{
> + // nothing
> +}
> +
> +
>  int dazukofs_ign_dev_init(int dev_major, int dev_minor,
>    struct class *dazukofs_class)
>  {
> - int err = 0;
> - struct device *dev;
> + dev_t devt;
> + int err;
>  
>   INIT_LIST_HEAD(&ign_list.list);
>   mutex_init(&ign_list_mutex);
> @@ -144,43 +163,57 @@ int dazukofs_ign_dev_init(int dev_major,
>   dazukofs_ign_cachep =
>   kmem_cache_create("dazukofs_ign_cache",
>    sizeof(struct dazukofs_proc), 0,
> -  SLAB_HWCACHE_ALIGN, NULL);
> - if (!dazukofs_ign_cachep) {
> - err = -ENOMEM;
> - goto error_out1;
> - }
> +  SLAB_HWCACHE_ALIGN, NULL, NULL);
> + if (!dazukofs_ign_cachep)
> + return -ENOMEM;
> +
> + devt = MKDEV(dev_major, dev_minor);
>  
>   /* setup cdev for ignore */
> - cdev_init(&ign_cdev, &ign_fops);
> - ign_cdev.owner = THIS_MODULE;
> - err = cdev_add(&ign_cdev, MKDEV(dev_major, dev_minor), 1);
> + cdev_init(&ign_dev.cdev, &ign_fops);
> + ign_dev.cdev.owner = THIS_MODULE;
> + err = cdev_add(&ign_dev.cdev, devt, 1);
>   if (err)
> + goto error_out;
> +
> + ign_dev.dev.parent = &platform_bus;
> + ign_dev.dev.release = dazukofs_ign_dev_release;
> + snprintf(ign_dev.dev.bus_id, BUS_ID_SIZE, "%s.ign", DEVICE_NAME);
> +
> + err = device_register(&ign_dev.dev);
> +
> + if (err)
>   goto error_out2;
>  
> - /* create ignore device */
> - dev = device_create(dazukofs_class, NULL, MKDEV(dev_major, dev_minor),
> -    NULL, "%s.ign", DEVICE_NAME);
> - if (IS_ERR(dev)) {
> - err = PTR_ERR(dev);
> + ign_dev.cls_dev.release = dazukofs_ign_class_dev_release;
> + ign_dev.cls_dev.class = dazukofs_class;
> + ign_dev.cls_dev.dev = &ign_dev.dev;
> + snprintf(ign_dev.cls_dev.class_id, BUS_ID_SIZE, "%s.ign", DEVICE_NAME);
> + ign_dev.cls_dev.devt = devt;
> +
> + err = class_device_register(&ign_dev.cls_dev);
> +
> + if (err)
>   goto error_out3;
> - }
>  
> - return 0;
>  
> + return 0;
>  error_out3:
> - cdev_del(&ign_cdev);
> + device_unregister(&ign_dev.dev);
>  error_out2:
> - dazukofs_destroy_ignlist();
> + cdev_del(&ign_dev.cdev);
> +error_out:
>   kmem_cache_destroy(dazukofs_ign_cachep);
> -error_out1:
>   return err;
>  }
>  
> +
>  void dazukofs_ign_dev_destroy(int dev_major, int dev_minor,
>        struct class *dazukofs_class)
>  {
> - device_destroy(dazukofs_class, MKDEV(dev_major, dev_minor));
> - cdev_del(&ign_cdev);
> + class_device_unregister(&ign_dev.cls_dev);
> + device_unregister(&ign_dev.dev);
> + cdev_del(&ign_dev.cdev);
>   dazukofs_destroy_ignlist();
>   kmem_cache_destroy(dazukofs_ign_cachep);
>  }
> diff -x CVS -rup dazukofs-3.0.0/inode.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/inode.c
> --- dazukofs-3.0.0/inode.c 2009-02-22 17:46:02.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/inode.c 2009-07-06 10:26:13.000000000 +0200
> @@ -25,15 +25,19 @@
>  #include <linux/fs.h>
>  #include <linux/namei.h>
>  #include <linux/mount.h>
> -#include <linux/uaccess.h>
> -#include <linux/fs_stack.h>
> -
> +#include <asm/uaccess.h>
>  #include "dazukofs_fs.h"
>  
>  static struct inode_operations dazukofs_symlink_iops;
>  static struct inode_operations dazukofs_dir_iops;
>  static struct inode_operations dazukofs_main_iops;
>  
> +void fsstack_copy_inode_size(struct inode *dst, const struct inode *src)
> +{
> + i_size_write(dst, i_size_read((struct inode *) src));
> + dst->i_blocks = src->i_blocks;
> +}
> +
>  static int dazukofs_inode_test(struct inode *inode,
>         void *candidate_lower_inode)
>  {
> @@ -47,14 +51,28 @@ static int dazukofs_inode_test(struct in
>  
>  static void dazukofs_init_inode(struct inode *inode, struct inode *lower_inode)
>  {
> - SET_LOWER_INODE(inode, lower_inode);
> - inode->i_ino = lower_inode->i_ino;
> - inode->i_version++;
> - inode->i_op = &dazukofs_main_iops;
> - inode->i_fop = &dazukofs_main_fops;
> - inode->i_mapping->a_ops = &dazukofs_aops;
> +        SET_LOWER_INODE(inode, lower_inode);
> +        inode->i_ino = lower_inode->i_ino;
> +        inode->i_version++;
> +
> +        if (S_ISDIR(lower_inode->i_mode)) {
> +                inode->i_op = &dazukofs_dir_iops;
> +                inode->i_fop = &dazukofs_dir_fops;
> +        } else {
> +                inode->i_op = &dazukofs_main_iops;
> +                inode->i_fop = &dazukofs_main_fops;
> +
> +                if (S_ISLNK(lower_inode->i_mode))
> +                        inode->i_op = &dazukofs_symlink_iops;
> +                else  if (special_file(lower_inode->i_mode)) {
> +                        init_special_inode(inode, lower_inode->i_mode,
> +                                           lower_inode->i_rdev);
> +                }
> +        }
> +        inode->i_mapping->a_ops = &dazukofs_aops;
>  }
>  
> +
>  static int dazukofs_inode_set(struct inode *inode, void *lower_inode)
>  {
>   dazukofs_init_inode(inode, (struct inode *)lower_inode);
> @@ -62,72 +80,124 @@ static int dazukofs_inode_set(struct ino
>  }
>  
>  int dazukofs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
> -     struct super_block *sb, int flag)
> +     struct super_block *sb, int hash)
>  {
>   struct inode *inode;
> - struct inode *lower_inode = igrab(lower_dentry->d_inode);
> - int err = 0;
> + struct inode *lower_inode;
> + int err;
>  
> - if (!lower_inode) {
> - err = -ESTALE;
> - goto out;
> - }
> + lower_inode = igrab(lower_dentry->d_inode);
>  
> - if (lower_inode->i_sb != GET_LOWER_SB(sb)) {
> - iput(lower_inode);
> - err = -EXDEV;
> - goto out;
> - }
> + if (!lower_inode)
> + return -ESTALE;
>  
>   inode = iget5_locked(sb, (unsigned long)lower_inode,
>       dazukofs_inode_test, dazukofs_inode_set,
>       lower_inode);
> -
>   if (!inode) {
> - iput(lower_inode);
>   err = -EACCES;
> - goto out;
> + goto err;
>   }
>  
> - if (inode->i_state & I_NEW) {
> + if (inode->i_state & I_NEW)
>   unlock_new_inode(inode);
>   /*
>   * This is a new node so we leave the lower_node "in use"
>   * and do not call iput().
>   */
> - } else {
> + else
>   /*
>   * This is not a new node so we decrement the usage count.
>   */
>   iput(lower_inode);
> - }
>  
> - if (S_ISLNK(lower_inode->i_mode))
> - inode->i_op = &dazukofs_symlink_iops;
> - else if (S_ISDIR(lower_inode->i_mode))
> - inode->i_op = &dazukofs_dir_iops;
> -
> - if (S_ISDIR(lower_inode->i_mode))
> - inode->i_fop = &dazukofs_dir_fops;
> -
> - if (special_file(lower_inode->i_mode)) {
> - init_special_inode(inode, lower_inode->i_mode,
> -   lower_inode->i_rdev);
> - }
> -
> - dentry->d_op = &dazukofs_dops;
>  
> - if (flag)
> + if (hash)
>   d_add(dentry, inode);
>   else
>   d_instantiate(dentry, inode);
>  
> - fsstack_copy_attr_all(inode, lower_inode, NULL);
> + fsstack_copy_attr_all(inode, lower_inode);
>   fsstack_copy_inode_size(inode, lower_inode);
> -out:
> +
> + return 0;
> +err:
> + iput(lower_inode);
>   return err;
>  }
>  
> +/* creates a new lower dentry */
> +static struct dentry *dazukofs_new_lower_dentry(struct qstr *name,
> + struct dentry *lower_base,
> + struct nameidata *nd)
> +{
> + struct dentry *new_dentry;
> + struct dentry *tmp;
> + struct inode *lower_inode;
> +
> + lower_inode = lower_base->d_inode;
> + /* XXX: is this check still necessary? (see __lookup_hash())
> +   This is (hopely) protected by locked upper inode */
> + if (IS_DEADDIR(lower_inode)) {
> + new_dentry = ERR_PTR(-ENOENT);
> + goto out;
> + }
> + tmp = d_alloc(lower_base, name);
> + if (!tmp) {
> + new_dentry = ERR_PTR(-ENOMEM);
> + goto out;
> + }
> + new_dentry = lower_inode->i_op->lookup(lower_inode, tmp, nd);
> + /* lookup() seemingly is allowed to return its own dentry (which
> + * may indeed be a dentry or only an error). If so
> + * we use it and discard ours. Otherwise we use ours */
> + if (!new_dentry)
> + new_dentry = tmp;
> + else
> + dput(tmp);
> +
> +out:
> + return new_dentry;
> +}
> +
> +
> +/* get lower dentry for given name */
> +static struct dentry *dazukofs_lookup_one_lower(struct qstr *name,
> + struct dentry *lower_base,
> + struct vfsmount *lower_mnt)
> +{
> + struct dentry *result;
> + struct nameidata nd;
> + int err;
> +
> + /* see vfs_path_lookup in kernel versions >= 2.6.24 */
> + nd.last_type = LAST_ROOT;
> + nd.flags = 0;
> + nd.depth = 0;
> + nd.dentry = dget(lower_base);
> + nd.mnt = mntget(lower_mnt);
> +
> + err = path_walk(name->name, &nd);
> +
> + if (!err) {
> + /* inode already exists on disk */
> + result = nd.dentry;
> + /* we dont need the mount */
> + mntput(nd.mnt);
> + goto out;
> + }
> + if (err != -ENOENT) { /* this is a REAL error */
> + result = ERR_PTR(err);
> + goto out;
> + }
> + /* create a new (lower) dentry */
> + result = dazukofs_new_lower_dentry(name, lower_base, &nd);
> +out:
> + return result;
> +
> +}
> +
> +
>  /**
>   * Description: Called when the VFS needs to look up an inode in a parent
>   * directory. The name to look for is found in the dentry. This method
> @@ -148,64 +218,52 @@ static struct dentry *dazukofs_lookup(st
>   struct dentry *lower_dentry;
>   struct dentry *lower_dentry_parent;
>   struct vfsmount *lower_mnt;
> - int err = 0;
> -
> - if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, "."))
> -    || (dentry->d_name.len == 2 &&
> - !strcmp(dentry->d_name.name, ".."))) {
> - d_drop(dentry);
> - goto out;
> - }
> -
> - dentry->d_op = &dazukofs_dops;
> + struct dazukofs_dentry_info *di;
> + int err;
>  
>   lower_dentry_parent = GET_LOWER_DENTRY(dentry->d_parent);
> - lower_dentry = lookup_one_len(dentry->d_name.name, lower_dentry_parent,
> -      dentry->d_name.len);
> + /* should be released in d_release() */
> + lower_mnt = mntget(GET_LOWER_MNT(dentry->d_parent));
>  
> + lower_dentry = dazukofs_lookup_one_lower(&dentry->d_name,
> + lower_dentry_parent,
> + lower_mnt);
>   if (IS_ERR(lower_dentry)) {
> - err = PTR_ERR(lower_dentry);
> - d_drop(dentry);
> - goto out;
> + mntput(lower_mnt);
> + return lower_dentry;
>   }
> -
>   BUG_ON(!atomic_read(&lower_dentry->d_count));
>  
> - SET_DENTRY_INFO(dentry, kmem_cache_zalloc(dazukofs_dentry_info_cachep,
> - GFP_KERNEL));
> -
> - if (!GET_DENTRY_INFO(dentry)) {
> - err = -ENOMEM;
> - goto out_dput;
> + dentry->d_op = &dazukofs_dops;
> + di = kmem_cache_alloc(dazukofs_dentry_info_cachep, GFP_KERNEL);
> + if (!di) {
> + mntput(lower_mnt);
> + dput(lower_dentry);
> + return ERR_PTR(-ENOMEM);
>   }
> -
> - lower_mnt = mntget(GET_LOWER_MNT(dentry->d_parent));
> -
> - fsstack_copy_attr_atime(dir, lower_dentry_parent->d_inode);
> -
> + memset(di, 0, sizeof(*di));
> + SET_DENTRY_INFO(dentry, di);
>   SET_LOWER_DENTRY(dentry, lower_dentry, lower_mnt);
> -
> + /* from now lower dentry and lower mount are released in
> +  d_release of upper dentry */
> + fsstack_copy_attr_atime(dir, lower_dentry_parent->d_inode);
>   if (!lower_dentry->d_inode) {
>   /*
>   * We want to add because we could not find in lower.
>   */
>   d_add(dentry, NULL);
> - goto out;
> + goto ok;
>   }
>  
>   err = dazukofs_interpose(lower_dentry, dentry, dir->i_sb, 1);
> - if (err)
> - goto out_dput;
> - goto out;
> + if (err)
> + return ERR_PTR(err);
>  
> -out_dput:
> - dput(lower_dentry);
> - d_drop(dentry);
> -
> -out:
> - return ERR_PTR(err);
> +ok:
> + return NULL; /* tell caller to use its own, passed dentry, not ours */
>  }
>  
> +
>  /**
>   * Description: Called by the mknod(2) system call to create a device
>   * (char, block) inode or a named pipe (FIFO) or socket. Only required if
> @@ -216,14 +274,15 @@ static int dazukofs_mknod(struct inode *
>    dev_t dev)
>  {
>   struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
> + struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
>   struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
>   struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
>   int err = -ENOENT;
>  
> - mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
> -  I_MUTEX_PARENT);
> + mutex_lock(&(lower_dentry_parent_inode->i_mutex));
>  
> - err = vfs_mknod(lower_dentry_parent_inode, lower_dentry, mode, dev);
> + err = vfs_mknod(lower_dentry_parent_inode, lower_dentry, lower_mount,
> + mode, dev);
>   if (err)
>   goto out;
>  
> @@ -248,14 +307,15 @@ out:
>  static int dazukofs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
>  {
>   struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
> + struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
>   struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
>   struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
>   int err = -ENOENT;
>  
> - mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
> -  I_MUTEX_PARENT);
> + mutex_lock(&(lower_dentry_parent_inode->i_mutex));
>  
> - err = vfs_mkdir(lower_dentry_parent_inode, lower_dentry, mode);
> + err = vfs_mkdir(lower_dentry_parent_inode, lower_dentry, lower_mount,
> + mode);
>   if (err)
>   goto out;
>  
> @@ -291,22 +351,21 @@ static int dazukofs_create(struct inode
>   struct dentry *dentry_save;
>   int err = -ENOENT;
>  
> - mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
> -  I_MUTEX_PARENT);
> + mutex_lock(&(lower_dentry_parent_inode->i_mutex));
>  
> - vfsmount_save = nd->path.mnt;
> - dentry_save = nd->path.dentry;
> + vfsmount_save = nd->mnt;
> + dentry_save = nd->dentry;
>  
> - nd->path.mnt = mntget(lower_mnt);
> - nd->path.dentry = dget(lower_dentry);
> + nd->mnt = mntget(lower_mnt);
> + nd->dentry = dget(lower_dentry);
>  
>   err = vfs_create(lower_dentry_parent_inode, lower_dentry, mode, nd);
>  
>   mntput(lower_mnt);
>   dput(lower_dentry);
>  
> - nd->path.mnt = vfsmount_save;
> - nd->path.dentry = dentry_save;
> + nd->mnt = vfsmount_save;
> + nd->dentry = dentry_save;
>  
>   if (err)
>   goto out;
> @@ -333,14 +392,15 @@ static int dazukofs_symlink(struct inode
>      const char *symname)
>  {
>   struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
> + struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
>   struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
>   struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
>   int err = -ENOENT;
>  
> - mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
> -  I_MUTEX_PARENT);
> + mutex_lock(&(lower_dentry_parent_inode->i_mutex));
>  
> - err = vfs_symlink(lower_dentry_parent_inode, lower_dentry, symname);
> + err = vfs_symlink(lower_dentry_parent_inode, lower_dentry, lower_mount,
> +  symname, S_IALLUGO);
>   if (err)
>   goto out;
>  
> @@ -452,9 +512,37 @@ static void dazukofs_put_link(struct den
>   * Description: Called by the VFS to check for access rights on a
>   * POSIX-like filesystem.
>   */
> -static int dazukofs_permission(struct inode *inode, int mask)
> +static int dazukofs_permission(struct inode *inode, int mask,
> +       struct nameidata *nd)
>  {
> - return inode_permission(GET_LOWER_INODE(inode), mask);
> + struct vfsmount *lower_mnt = NULL;
> + struct dentry *lower_dentry = NULL;
> + struct vfsmount *vfsmnt_save = NULL;
> + struct dentry *dentry_save = NULL;
> + int err;
> +
> + if (nd) {
> + lower_mnt = GET_LOWER_MNT(nd->dentry);
> + lower_dentry = GET_LOWER_DENTRY(nd->dentry);
> +
> + vfsmnt_save = nd->mnt;
> + dentry_save = nd->dentry;
> +
> + nd->mnt = mntget(lower_mnt);
> + nd->dentry = dget(lower_dentry);
> + }
> +
> + err = permission(GET_LOWER_INODE(inode), mask, nd);
> +
> + if (nd) {
> + mntput(lower_mnt);
> + dput(lower_dentry);
> +
> + nd->mnt = vfsmnt_save;
> + nd->dentry = dentry_save;
> + }
> +
> +        return err;
>  }
>  
>  /**
> @@ -464,18 +552,32 @@ static int dazukofs_permission(struct in
>  static int dazukofs_setattr(struct dentry *dentry, struct iattr *ia)
>  {
>   struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
> + struct vfsmount *lower_mnt = GET_LOWER_MNT(dentry);
>   struct inode *inode = dentry->d_inode;
>   struct inode *lower_inode = GET_LOWER_INODE(inode);
>   int err;
>  
> - err = notify_change(lower_dentry, ia);
>  
> - fsstack_copy_attr_all(inode, lower_inode, NULL);
> - fsstack_copy_inode_size(inode, lower_inode);
> + if (!lower_inode->i_op || !lower_inode->i_op->setattr)
> + /* XXX: at this point it is too late to handle inodes properly that do NOT
> + specify setattr(). VFS would normally call inode_setattr() in
> + this case. So to force this we jump back to notify_change which will
> + handle this for us. But this is dangerous:
> + The attributes might be modified by notify_change() in a way
> + that results in invalid attributes. This seems to be the case
> + if the inode for which this function is called has the setuid
> + or setgid bit set */
> + err = notify_change(lower_dentry, lower_mnt, ia);
> + else
> + err = lower_inode->i_op->setattr(lower_dentry, ia);
> +
> + if (!err) {
> + fsstack_copy_attr_all(inode, lower_inode);
> + fsstack_copy_inode_size(inode, lower_inode);
> + }
>  
>   return err;
>  }
> -
>  /**
>   * Description: Called by the VFS to set an extended attribute for a file.
>   * Extended attribute is a name:value pair associated with an inode. This
> @@ -496,14 +598,14 @@ static int dazukofs_setxattr(struct dent
>  
>   if (!lower_dentry_inode->i_op ||
>      !lower_dentry_inode->i_op->setxattr) {
> - err = -ENOSYS;
> + err = -EOPNOTSUPP;
>   goto out;
>   }
>  
>   err = lower_dentry_inode->i_op->setxattr(lower_dentry, name, value,
>   size, flags);
>  
> - fsstack_copy_attr_all(dentry->d_inode, lower_dentry_inode, NULL);
> + fsstack_copy_attr_all(dentry->d_inode, lower_dentry_inode);
>   fsstack_copy_inode_size(dentry->d_inode, lower_dentry_inode);
>  out:
>   return err;
> @@ -528,7 +630,7 @@ static ssize_t dazukofs_getxattr(struct
>  
>   if (!lower_dentry_inode->i_op ||
>      !lower_dentry_inode->i_op->getxattr) {
> - err = -ENOSYS;
> + err = -EOPNOTSUPP;
>   goto out;
>   }
>  
> @@ -557,7 +659,7 @@ static ssize_t dazukofs_listxattr(struct
>  
>   if (!lower_dentry_inode->i_op ||
>      !lower_dentry_inode->i_op->listxattr) {
> - err = -ENOSYS;
> + err = -EOPNOTSUPP;
>   goto out;
>   }
>  
> @@ -584,7 +686,7 @@ static int dazukofs_removexattr(struct d
>  
>   if (!lower_dentry_inode->i_op ||
>      !lower_dentry_inode->i_op->removexattr) {
> - err = -ENOSYS;
> + err = -EOPNOTSUPP;
>   goto out;
>   }
>  
> @@ -602,16 +704,19 @@ static int dazukofs_link(struct dentry *
>   struct dentry *new_dentry)
>  {
>   struct dentry *lower_old_dentry = GET_LOWER_DENTRY(old_dentry);
> + struct vfsmount *lower_old_mount = GET_LOWER_MNT(old_dentry);
>   struct dentry *lower_new_dentry = GET_LOWER_DENTRY(new_dentry);
> + struct vfsmount *lower_new_mount = GET_LOWER_MNT(new_dentry);
> +
>   struct dentry *lower_dentry_parent = dget(lower_new_dentry->d_parent);
>   struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
>   int err = -ENOENT;
>  
> - mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
> -  I_MUTEX_PARENT);
> + mutex_lock(&(lower_dentry_parent_inode->i_mutex));
>  
> - err = vfs_link(lower_old_dentry, lower_dentry_parent_inode,
> -       lower_new_dentry);
> + err = vfs_link(lower_old_dentry, lower_old_mount,
> +       lower_dentry_parent_inode, lower_new_dentry,
> +       lower_new_mount);
>   if (err)
>   goto out;
>  
> @@ -635,14 +740,14 @@ out:
>  static int dazukofs_unlink(struct inode *dir, struct dentry *dentry)
>  {
>   struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
> + struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
>   struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
>   struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
>   int err;
>  
> - mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
> -  I_MUTEX_PARENT);
> + mutex_lock(&(lower_dentry_parent_inode->i_mutex));
>  
> - err = vfs_unlink(lower_dentry_parent_inode, lower_dentry);
> + err = vfs_unlink(lower_dentry_parent_inode, lower_dentry, lower_mount);
>   if (err)
>   goto out;
>  
> @@ -664,14 +769,14 @@ out:
>  static int dazukofs_rmdir(struct inode *dir, struct dentry *dentry)
>  {
>   struct dentry *lower_dentry = GET_LOWER_DENTRY(dentry);
> + struct vfsmount *lower_mount = GET_LOWER_MNT(dentry);
>   struct dentry *lower_dentry_parent = dget(lower_dentry->d_parent);
>   struct inode *lower_dentry_parent_inode = lower_dentry_parent->d_inode;
>   int err;
>  
> - mutex_lock_nested(&(lower_dentry_parent_inode->i_mutex),
> -  I_MUTEX_PARENT);
> + mutex_lock(&(lower_dentry_parent_inode->i_mutex));
>  
> - err = vfs_rmdir(lower_dentry_parent_inode, lower_dentry);
> + err = vfs_rmdir(lower_dentry_parent_inode, lower_dentry, lower_mount);
>   if (err)
>   goto out;
>  
> @@ -695,7 +800,9 @@ static int dazukofs_rename(struct inode
>     struct inode *new_dir, struct dentry *new_dentry)
>  {
>   struct dentry *lower_old_dentry = GET_LOWER_DENTRY(old_dentry);
> + struct vfsmount *lower_old_mount = GET_LOWER_MNT(old_dentry);
>   struct dentry *lower_new_dentry = GET_LOWER_DENTRY(new_dentry);
> + struct vfsmount *lower_new_mount = GET_LOWER_MNT(new_dentry);
>   struct dentry *lower_old_dentry_parent =
>   dget(lower_old_dentry->d_parent);
>   struct dentry *lower_new_dentry_parent =
> @@ -718,16 +825,17 @@ static int dazukofs_rename(struct inode
>  
>   lock_rename(lower_old_dentry_parent, lower_new_dentry_parent);
>   err = vfs_rename(lower_old_dentry_parent_inode, lower_old_dentry,
> - lower_new_dentry_parent_inode, lower_new_dentry);
> + lower_old_mount, lower_new_dentry_parent_inode,
> + lower_new_dentry, lower_new_mount);
>   unlock_rename(lower_old_dentry_parent, lower_new_dentry_parent);
>  
>   if (err)
>   goto out;
>  
> - fsstack_copy_attr_all(new_dir, lower_new_dentry_parent_inode, NULL);
> + fsstack_copy_attr_all(new_dir, lower_new_dentry_parent_inode);
>   if (new_dir != old_dir)
> - fsstack_copy_attr_all(old_dir, lower_old_dentry_parent_inode,
> -      NULL);
> + fsstack_copy_attr_all(old_dir, lower_old_dentry_parent_inode);
> +    
>  out:
>   dput(lower_old_dentry_parent);
>   dput(lower_new_dentry_parent);
> diff -x CVS -rup dazukofs-3.0.0/Makefile dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/Makefile
> --- dazukofs-3.0.0/Makefile 2009-02-22 17:46:02.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/Makefile 2009-05-11 19:53:03.000000000 +0200
> @@ -18,7 +18,8 @@ dazukofs_install: dazukofs_modules
>   /sbin/depmod -ae
>  
>  clean:
> - rm -f Module.symvers
> + rm -f Modules.symvers
> + rm -f modules.order
>   make -C $(DAZUKOFS_KERNEL_SRC) SUBDIRS="`pwd`" clean
>  
>  .PHONY: dazukofs_modules dazukofs_install clean
> diff -x CVS -rup dazukofs-3.0.0/README dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/README
> --- dazukofs-3.0.0/README 2009-02-22 17:38:21.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/README 2009-02-06 17:48:21.000000000 +0100
> @@ -21,10 +21,10 @@ NOTE: DazukoFS is completely separate fr
>  =================
>  
>  Below are brief instructions to get DazukoFS compiled and running on a
> -system with a Linux 2.6.28 kernel. You may need to manually adjust the
> +system with a Linux 2.6.27 kernel. You may need to manually adjust the
>  Makefile if you kernel sources are not in the default location.
> -(Patches are provided for various other kernels. See the section below
> -titled "PATCHING" for more information.)
> +(A patch is provided to convert the DazukoFS code to support Linux
> +2.6.26.)
>  
>  compile the kernel module
>    # make
> @@ -52,25 +52,6 @@ unmount DazukoFS
>  
>  
>  
> -==========
> - PATCHING
> -==========
> -
> -In the "patches" directory there are patches available to modify the
> -DazukoFS code to fit various other kernels. For example, if you are
> -running openSUSE 11.1 you can patch the code with the following
> -command:
> -
> -$ patch -p1 < patches/patch-opensuse-11.1
> -
> -There should not be any errors. If there are errors, then the patch
> -is broken and should be reported on the dazuko-devel mailing list.
> -
> -Once the code has been patched you can build the kernel module as
> -described in the section "BUILD / INSTALL" above.
> -
> -
> -
>  =========
>   TESTING
>  =========
> @@ -154,9 +135,6 @@ any problems.
>   KNOWN ISSUES
>  ==============
>  
> -- The kernel will crash if you attempt to mount DazukoFS to a file instead
> -  of a directory. (The various kernel patches handle this error.)
> -
>  - DazukoFS does not support writing to memory mapped files. This should not
>    cause the kernel to crash, but will instead result in the application
>    failing to perform the writes (although mmap() will appear to be
> diff -x CVS -rup dazukofs-3.0.0/super.c dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/super.c
> --- dazukofs-3.0.0/super.c 2009-02-22 17:46:02.000000000 +0100
> +++ dazukofs-3.0.0-rc4_2.6.16_SLES10SP2/super.c 2009-07-03 17:59:02.000000000 +0200
> @@ -35,6 +35,10 @@ static struct kmem_cache *dazukofs_sb_in
>  struct kmem_cache *dazukofs_dentry_info_cachep;
>  struct kmem_cache *dazukofs_file_info_cachep;
>  
> +
> +#define DAZUKOFS_VERSION "3.0.0-rc4-avira-b2.6"
> +
> +
>  static struct inode *dazukofs_alloc_inode(struct super_block *sb)
>  {
>   struct dazukofs_inode_info *inodei;
> @@ -114,9 +118,10 @@ static int dazukofs_fill_super(struct su
>   static const struct qstr name = { .name = "/", .len = 1 };
>   struct dazukofs_dentry_info *di;
>  
> - sbi =  kmem_cache_zalloc(dazukofs_sb_info_cachep, GFP_KERNEL);
> + sbi =  kmem_cache_alloc(dazukofs_sb_info_cachep, GFP_KERNEL);
>   if (!sbi)
>   return -ENOMEM;
> + memset(sbi, 0, sizeof(*sbi));
>  
>   sb->s_op = &dazukofs_sops;
>  
> @@ -132,12 +137,13 @@ static int dazukofs_fill_super(struct su
>   sb->s_root->d_sb = sb;
>   sb->s_root->d_parent = sb->s_root;
>  
> - di = kmem_cache_zalloc(dazukofs_dentry_info_cachep, GFP_KERNEL);
> + di = kmem_cache_alloc(dazukofs_dentry_info_cachep, GFP_KERNEL);
>   if (!di) {
>   kmem_cache_free(dazukofs_sb_info_cachep, sbi);
>   dput(sb->s_root);
>   return -ENOMEM;
>   }
> + memset(di, 0, sizeof(*di));
>  
>   SET_DENTRY_INFO(sb->s_root, di);
>  
> @@ -158,8 +164,8 @@ static int dazukofs_read_super(struct su
>   if (err)
>   return err;
>  
> - lower_root = dget(nd.path.dentry);
> - lower_mnt = mntget(nd.path.mnt);
> + lower_root = dget(nd.dentry);
> + lower_mnt = mntget(nd.mnt);
>  
>   if (IS_ERR(lower_root)) {
>   err = PTR_ERR(lower_root);
> @@ -171,6 +177,11 @@ static int dazukofs_read_super(struct su
>   goto out_put;
>   }
>  
> + if (!S_ISDIR(lower_root->d_inode->i_mode)) {
> + err = -ENOENT;
> + goto out_put;
> + }
> +
>   SET_LOWER_SB(sb, lower_root->d_sb);
>   sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
>   SET_LOWER_DENTRY(sb->s_root, lower_root, lower_mnt);
> @@ -184,44 +195,42 @@ out_put:
>   dput(lower_root);
>   mntput(lower_mnt);
>  out:
> - path_put(&nd.path);
> + path_release(&nd);
>   return err;
>  }
>  
> -static int dazukofs_get_sb(struct file_system_type *fs_type, int flags,
> -   const char *dev_name, void *data,
> -   struct vfsmount *mnt)
> +static struct super_block *
> +dazukofs_get_sb(struct file_system_type *fs_type, int flags,  
> +       const char *dev_name, void *data)
>  {
>   struct super_block *sb;
>   int err;
>  
> - err = get_sb_nodev(fs_type, flags, data, dazukofs_fill_super, mnt);
> - if (err)
> - goto out;
> -
> - sb = mnt->mnt_sb;
> + sb = get_sb_nodev(fs_type, flags, data, dazukofs_fill_super);
> + if (IS_ERR(sb))
> + return sb;
>  
>   err = dazukofs_parse_mount_options(data, sb);
>   if (err)
> - goto out_abort;
> + goto out;
>  
>   err = dazukofs_read_super(sb, dev_name);
>   if (err)
> - goto out_abort;
> + goto out;
>  
> - goto out;
> + return sb;
>  
> -out_abort:
> +out:
>   up_write(&sb->s_umount);
> + dput(sb->s_root);
>   deactivate_super(sb);
> -out:
> - return err;
> + return ERR_PTR(err);
>  }
>  
> -static void init_once(void *data)
> +static void init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags)
>  {
>   struct dazukofs_inode_info *inode_info =
> - (struct dazukofs_inode_info *)data;
> + (struct dazukofs_inode_info *)vptr;
>  
>   memset(inode_info, 0, sizeof(struct dazukofs_inode_info));
>   inode_init_once(&(inode_info->vfs_inode));
> @@ -256,7 +265,7 @@ static int init_caches(void)
>   kmem_cache_create("dazukofs_inode_info_cache",
>    sizeof(struct dazukofs_inode_info), 0,
>    SLAB_HWCACHE_ALIGN,
> -  init_once);
> +  init_once, NULL);
>   if (!dazukofs_inode_info_cachep)
>   goto out_nomem;
>  
> @@ -264,7 +273,7 @@ static int init_caches(void)
>   kmem_cache_create("dazukofs_sb_info_cache",
>    sizeof(struct dazukofs_sb_info), 0,
>    SLAB_HWCACHE_ALIGN,
> -  NULL);
> +  NULL, NULL);
>   if (!dazukofs_sb_info_cachep)
>   goto out_nomem;
>  
> @@ -272,7 +281,7 @@ static int init_caches(void)
>   kmem_cache_create("dazukofs_dentry_info_cache",
>    sizeof(struct dazukofs_dentry_info), 0,
>    SLAB_HWCACHE_ALIGN,
> -  NULL);
> +  NULL, NULL);
>   if (!dazukofs_dentry_info_cachep)
>   goto out_nomem;
>  
> @@ -280,7 +289,7 @@ static int init_caches(void)
>   kmem_cache_create("dazukofs_file_info_cache",
>    sizeof(struct dazukofs_file_info), 0,
>    SLAB_HWCACHE_ALIGN,
> -  NULL);
> +  NULL, NULL);
>   if (!dazukofs_file_info_cachep)
>   goto out_nomem;
>  
> @@ -305,7 +314,7 @@ static struct file_system_type dazukofs_
>  
>  static int __init init_dazukofs_fs(void)
>  {
> - int err = 0;
> + int err;
>  
>   err = dazukofs_dev_init();
>   if (err)
> @@ -319,7 +328,7 @@ static int __init init_dazukofs_fs(void)
>   if (err)
>   goto error_out3;
>  
> - printk(KERN_INFO "dazukofs: loaded, version=%s\n", DAZUKOFS_VERSION);
> + printk(KERN_INFO "dazukofs: loaded, version=" DAZUKOFS_VERSION "\n");
>   return 0;
>  
>  error_out3:
> @@ -335,7 +344,7 @@ static void __exit exit_dazukofs_fs(void
>   unregister_filesystem(&dazukofs_fs_type);
>   destroy_caches();
>   dazukofs_dev_destroy();
> - printk(KERN_INFO "dazukofs: unloaded, version=%s\n", DAZUKOFS_VERSION);
> + printk(KERN_INFO "dazukofs: unloaded, version=" DAZUKOFS_VERSION "\n");
>  }
>  
>  MODULE_AUTHOR("John Ogness");


_______________________________________________
Dazuko-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/dazuko-devel
Reply | Threaded
Open this post in threaded view
|

Re: patch for SLES 10 SP2

Lino Sanfilippo
John Ogness wrote:
> This patch involves significant changes to device logic. Although the
> end result is the same, the changes are very different from the other
> patches. Who is the author of this patch?
>  

These patches have been implemented by me.
For the 2.6.16 kernel there unfortunately does not exist a
device_create() function yet,
so this had to be done "by hand".
Beside this only the group device implementation has slightly been
changed. The idea was
not to use static arrays of group devices and file operations, but to
allocate them at runtime.

Regards,
Lino

Geschäftsführender Gesellschafter: Tjark Auerbach
Sitz der Gesellschaft: Tettnang
Handelsregister: Amtsgericht Ulm, HRB 630992
ALLGEMEINE GESCHÄFTSBEDINGUNGEN
Es gelten unsere Allgemeinen Geschäftsbedingungen
(AGB). Sie finden sie in der jeweils gültigen Fassung
im Internet unter http://www.avira.de/agb
***************************************************


_______________________________________________
Dazuko-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/dazuko-devel