Whamcloud - gitweb
things are starting to work for Linux 2.4.2!!
authorbraam <braam>
Thu, 8 Mar 2001 23:51:32 +0000 (23:51 +0000)
committerbraam <braam>
Thu, 8 Mar 2001 23:51:32 +0000 (23:51 +0000)
ext2obd works (except _write and _read which aren't that important).

lustre/include/linux/obd.h
lustre/include/linux/obd_class.h
lustre/include/linux/obd_ext2.h
lustre/include/linux/obd_raid1.h
lustre/include/linux/obd_rpc.h
lustre/include/linux/obd_support.h
lustre/obdclass/class_obd.c
lustre/obdclass/genops.c
lustre/obdclass/sysctl.c
lustre/obdfs/flushd.c

index b3b9e7f..a73c64f 100644 (file)
@@ -3,18 +3,18 @@
 
 
 struct obd_conn_info {
-       unsigned int conn_id;     /* handle */
+        unsigned int conn_id;     /* handle */
 };
 
 struct obd_type {
-       struct list_head typ_chain;
-       struct obd_ops *typ_ops;
-       char *typ_name;
-       int  typ_refcnt;
+        struct list_head typ_chain;
+        struct obd_ops *typ_ops;
+        char *typ_name;
+        int  typ_refcnt;
 };
 
-#define OBD_MAGIC      0xffff0000
-#define OBD_MAGIC_MASK 0xffff0000
+#define OBD_MAGIC       0xffff0000
+#define OBD_MAGIC_MASK  0xffff0000
 
 
 
index 114095d..6758bc6 100644 (file)
  *  ======== OBD type Declarations ===========
  */
 
-typedef uint64_t       obd_id;
-typedef uint64_t       obd_gr;
-typedef uint64_t       obd_time;
-typedef uint64_t       obd_size;
-typedef uint64_t       obd_off;
-typedef uint64_t       obd_blocks;
-typedef uint32_t       obd_blksize;
-typedef uint32_t       obd_mode;
-typedef uint32_t       obd_uid;
-typedef uint32_t       obd_gid;
-typedef uint32_t       obd_flag;
-typedef uint32_t       obd_count;
-
-#define OBD_FL_INLINEDATA      (0x00000001UL)  
-#define OBD_FL_OBDMDEXISTS     (0x00000002UL)
-
-#define OBD_INLINESZ   60
-#define OBD_OBDMDSZ    60
+typedef uint64_t        obd_id;
+typedef uint64_t        obd_gr;
+typedef uint64_t        obd_time;
+typedef uint64_t        obd_size;
+typedef uint64_t        obd_off;
+typedef uint64_t        obd_blocks;
+typedef uint32_t        obd_blksize;
+typedef uint32_t        obd_mode;
+typedef uint32_t        obd_uid;
+typedef uint32_t        obd_gid;
+typedef uint32_t        obd_flag;
+typedef uint32_t        obd_count;
+
+#define OBD_FL_INLINEDATA       (0x00000001UL)  
+#define OBD_FL_OBDMDEXISTS      (0x00000002UL)
+
+#define OBD_INLINESZ    60
+#define OBD_OBDMDSZ     60
 /* Note: 64-bit types are 64-bit aligned in structure */
 struct obdo {
-       obd_id                  o_id;
-       obd_gr                  o_gr;
-       obd_time                o_atime;
-       obd_time                o_mtime;
-       obd_time                o_ctime;
-       obd_size                o_size;
-       obd_blocks              o_blocks;
-       obd_blksize             o_blksize;
-       obd_mode                o_mode;
-       obd_uid                 o_uid;
-       obd_gid                 o_gid;
-       obd_flag                o_flags;
-       obd_flag                o_obdflags;
-       obd_count               o_nlink;
-       obd_count               o_generation;
-       obd_flag                o_valid;        /* hot fields in this obdo */
-       char                    o_inline[OBD_INLINESZ];
-       char                    o_obdmd[OBD_OBDMDSZ];
-       struct list_head        o_list;
-       struct obd_ops          *o_op;
+        obd_id                  o_id;
+        obd_gr                  o_gr;
+        obd_time                o_atime;
+        obd_time                o_mtime;
+        obd_time                o_ctime;
+        obd_size                o_size;
+        obd_blocks              o_blocks;
+        obd_blksize             o_blksize;
+        obd_mode                o_mode;
+        obd_uid                 o_uid;
+        obd_gid                 o_gid;
+        obd_flag                o_flags;
+        obd_flag                o_obdflags;
+        obd_count               o_nlink;
+        obd_count               o_generation;
+        obd_flag                o_valid;        /* hot fields in this obdo */
+        char                    o_inline[OBD_INLINESZ];
+        char                    o_obdmd[OBD_OBDMDSZ];
+        struct list_head        o_list;
+        struct obd_ops          *o_op;
 };
 
-#define OBD_MD_FLALL   (~0UL)
-#define OBD_MD_FLID    (0x00000001UL)
-#define OBD_MD_FLATIME (0x00000002UL)
-#define OBD_MD_FLMTIME (0x00000004UL)
-#define OBD_MD_FLCTIME (0x00000008UL)
-#define OBD_MD_FLSIZE  (0x00000010UL)
-#define OBD_MD_FLBLOCKS        (0x00000020UL)
-#define OBD_MD_FLBLKSZ (0x00000040UL)
-#define OBD_MD_FLMODE  (0x00000080UL)
-#define OBD_MD_FLUID   (0x00000100UL)
-#define OBD_MD_FLGID   (0x00000200UL)
-#define OBD_MD_FLFLAGS (0x00000400UL)
-#define OBD_MD_FLOBDFLG        (0x00000800UL)
-#define OBD_MD_FLNLINK (0x00001000UL)
-#define OBD_MD_FLGENER (0x00002000UL)
-#define OBD_MD_FLINLINE        (0x00004000UL)
-#define OBD_MD_FLOBDMD (0x00008000UL)
-#define OBD_MD_FLNOTOBD        (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS))
+#define OBD_MD_FLALL    (~0UL)
+#define OBD_MD_FLID     (0x00000001UL)
+#define OBD_MD_FLATIME  (0x00000002UL)
+#define OBD_MD_FLMTIME  (0x00000004UL)
+#define OBD_MD_FLCTIME  (0x00000008UL)
+#define OBD_MD_FLSIZE   (0x00000010UL)
+#define OBD_MD_FLBLOCKS (0x00000020UL)
+#define OBD_MD_FLBLKSZ  (0x00000040UL)
+#define OBD_MD_FLMODE   (0x00000080UL)
+#define OBD_MD_FLUID    (0x00000100UL)
+#define OBD_MD_FLGID    (0x00000200UL)
+#define OBD_MD_FLFLAGS  (0x00000400UL)
+#define OBD_MD_FLOBDFLG (0x00000800UL)
+#define OBD_MD_FLNLINK  (0x00001000UL)
+#define OBD_MD_FLGENER  (0x00002000UL)
+#define OBD_MD_FLINLINE (0x00004000UL)
+#define OBD_MD_FLOBDMD  (0x00008000UL)
+#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS))
 
 /*
  *  ======== OBD Device Declarations ===========
  */
 
 
-#define OBD_PSDEV_MAJOR        186
-#define MAX_OBD_DEVICES        8
-#define MAX_MULTI      16
+#define OBD_PSDEV_MAJOR 186
+#define MAX_OBD_DEVICES 8
+#define MAX_MULTI       16
 
 
 extern struct obd_device obd_dev[MAX_OBD_DEVICES];
@@ -95,83 +95,83 @@ extern struct obd_device obd_dev[MAX_OBD_DEVICES];
 #define OBD_SET_UP   0x2
 
 struct obd_conn {
-       struct obd_device *oc_dev;
-       uint32_t oc_id;
+        struct obd_device *oc_dev;
+        uint32_t oc_id;
 };
 
 /* corresponds to one of the obdx */
 struct obd_device {
-       struct obd_type *obd_type;
-       int obd_minor;
-       int obd_flags;
-       int obd_refcnt; 
-       int obd_multi_count;
-       struct obd_conn obd_multi_conn[MAX_MULTI];
-       unsigned int obd_gen_last_id;
-       unsigned long obd_gen_prealloc_quota;
-       struct list_head obd_gen_clients;
-       union {
-               struct ext2_obd ext2;
-               struct raid1_obd raid1;
-               struct snap_obd snap;
-               struct rpc_obd rpc;
-               /* struct fc_obd fc; */
-       } u;
+        struct obd_type *obd_type;
+        int obd_minor;
+        int obd_flags;
+        int obd_refcnt; 
+        int obd_multi_count;
+        struct obd_conn obd_multi_conn[MAX_MULTI];
+        unsigned int obd_gen_last_id;
+        unsigned long obd_gen_prealloc_quota;
+        struct list_head obd_gen_clients;
+        union {
+                struct ext2_obd ext2;
+                struct raid1_obd raid1;
+                struct snap_obd snap;
+                struct rpc_obd rpc;
+                /* struct fc_obd fc; */
+        } u;
 };
 
 /*
  *  ======== OBD Operations Declarations ===========
  */
 
-#define OBD_BRW_READ   (READ)
-#define OBD_BRW_WRITE  (WRITE)
-#define OBD_BRW_RWMASK (READ | WRITE)
-#define OBD_BRW_CREATE (0x00000010UL)
+#define OBD_BRW_READ    (READ)
+#define OBD_BRW_WRITE   (WRITE)
+#define OBD_BRW_RWMASK  (READ | WRITE)
+#define OBD_BRW_CREATE  (0x00000010UL)
 
 struct obd_ops {
-       int (*o_iocontrol)(int cmd, struct obd_conn *, int len, void *karg,
-                          void *uarg);
-       int (*o_get_info)(struct obd_conn *, obd_count keylen, void *key,
-                         obd_count *vallen, void **val);
-       int (*o_set_info)(struct obd_conn *, obd_count keylen, void *key,
-                         obd_count vallen, void *val);
-       int (*o_attach)(struct obd_device *dev, obd_count len, void *data);
-       int (*o_detach)(struct obd_device *dev);
-       int (*o_setup) (struct obd_device *dev, obd_count len, void *data);
-       int (*o_cleanup)(struct obd_device *dev);
-       int (*o_connect)(struct obd_conn *conn);
-       int (*o_disconnect)(struct obd_conn *conn);
-       int (*o_statfs)(struct obd_conn *conn, struct statfs *statfs);
-       int (*o_preallocate)(struct obd_conn *, obd_count *req, obd_id *ids);
-       int (*o_create)(struct obd_conn *conn,  struct obdo *oa);
-       int (*o_destroy)(struct obd_conn *conn, struct obdo *oa);
-       int (*o_setattr)(struct obd_conn *conn, struct obdo *oa);
-       int (*o_getattr)(struct obd_conn *conn, struct obdo *oa);
-       int (*o_read)(struct obd_conn *conn, struct obdo *oa, char *buf,
-                     obd_size *count, obd_off offset);
-       int (*o_write)(struct obd_conn *conn, struct obdo *oa, char *buf,
-                      obd_size *count, obd_off offset);
-       int (*o_brw)(int rw, struct obd_conn *conn, obd_count num_oa,
-                    struct obdo **oa, obd_count *oa_bufs, char **buf,
-                    obd_size *count, obd_off *offset, obd_flag *flags);
-       int (*o_punch)(struct obd_conn *conn, struct obdo *tgt, obd_size count,
-                      obd_off offset);
-       int (*o_sync)(struct obd_conn *conn, struct obdo *tgt, obd_size count,
-                     obd_off offset);
-       int (*o_migrate)(struct obd_conn *conn, struct obdo *dst,
-                        struct obdo *src, obd_size count, obd_off offset);
-       int (*o_copy)(struct obd_conn *dstconn, struct obdo *dst,
-                     struct obd_conn *srconn, struct obdo *src,
-                     obd_size count, obd_off offset);
-       int (*o_iterate)(struct obd_conn *conn, int (*)(obd_id, obd_gr, void *),
-                        obd_id *startid, obd_gr group, void *data);
+        int (*o_iocontrol)(int cmd, struct obd_conn *, int len, void *karg,
+                           void *uarg);
+        int (*o_get_info)(struct obd_conn *, obd_count keylen, void *key,
+                          obd_count *vallen, void **val);
+        int (*o_set_info)(struct obd_conn *, obd_count keylen, void *key,
+                          obd_count vallen, void *val);
+        int (*o_attach)(struct obd_device *dev, obd_count len, void *data);
+        int (*o_detach)(struct obd_device *dev);
+        int (*o_setup) (struct obd_device *dev, obd_count len, void *data);
+        int (*o_cleanup)(struct obd_device *dev);
+        int (*o_connect)(struct obd_conn *conn);
+        int (*o_disconnect)(struct obd_conn *conn);
+        int (*o_statfs)(struct obd_conn *conn, struct statfs *statfs);
+        int (*o_preallocate)(struct obd_conn *, obd_count *req, obd_id *ids);
+        int (*o_create)(struct obd_conn *conn,  struct obdo *oa);
+        int (*o_destroy)(struct obd_conn *conn, struct obdo *oa);
+        int (*o_setattr)(struct obd_conn *conn, struct obdo *oa);
+        int (*o_getattr)(struct obd_conn *conn, struct obdo *oa);
+        int (*o_read)(struct obd_conn *conn, struct obdo *oa, char *buf,
+                      obd_size *count, obd_off offset);
+        int (*o_write)(struct obd_conn *conn, struct obdo *oa, char *buf,
+                       obd_size *count, obd_off offset);
+        int (*o_brw)(int rw, struct obd_conn *conn, obd_count num_oa,
+                     struct obdo **oa, obd_count *oa_bufs, char **buf,
+                     obd_size *count, obd_off *offset, obd_flag *flags);
+        int (*o_punch)(struct obd_conn *conn, struct obdo *tgt, obd_size count,
+                       obd_off offset);
+        int (*o_sync)(struct obd_conn *conn, struct obdo *tgt, obd_size count,
+                      obd_off offset);
+        int (*o_migrate)(struct obd_conn *conn, struct obdo *dst,
+                         struct obdo *src, obd_size count, obd_off offset);
+        int (*o_copy)(struct obd_conn *dstconn, struct obdo *dst,
+                      struct obd_conn *srconn, struct obdo *src,
+                      obd_size count, obd_off offset);
+        int (*o_iterate)(struct obd_conn *conn, int (*)(obd_id, obd_gr, void *),
+                         obd_id *startid, obd_gr group, void *data);
 };
 
-#define OBT(dev)       dev->obd_type->typ_ops
-#define OBP(dev,op)    dev->obd_type->typ_ops->o_ ## op
+#define OBT(dev)        dev->obd_type->typ_ops
+#define OBP(dev,op)     dev->obd_type->typ_ops->o_ ## op
 
 /* This value is not arbitrarily chosen.  KIO_STATIC_PAGES from linux/iobuf.h */
-#define MAX_IOVEC      (KIO_STATIC_PAGES - 1)
+#define MAX_IOVEC       (KIO_STATIC_PAGES - 1)
 
 
 /*
@@ -184,14 +184,14 @@ extern void obd_cleanup_obdo_cache(void);
 
 static inline int obdo_has_inline(struct obdo *obdo)
 {
-       return (obdo->o_valid & OBD_MD_FLINLINE &&
-               obdo->o_obdflags & OBD_FL_INLINEDATA);
+        return (obdo->o_valid & OBD_MD_FLINLINE &&
+                obdo->o_obdflags & OBD_FL_INLINEDATA);
 };
 
 static inline int obdo_has_obdmd(struct obdo *obdo)
 {
-       return (obdo->o_valid & OBD_MD_FLOBDMD &&
-               obdo->o_obdflags & OBD_FL_OBDMDEXISTS);
+        return (obdo->o_valid & OBD_MD_FLOBDMD &&
+                obdo->o_obdflags & OBD_FL_OBDMDEXISTS);
 };
 
 /* support routines */
@@ -199,229 +199,229 @@ extern kmem_cache_t *obdo_cachep;
 
 static __inline__ struct obdo *obdo_alloc(void)
 {
-       struct obdo *oa = NULL;
+        struct obdo *oa = NULL;
 
-       oa = kmem_cache_alloc(obdo_cachep, SLAB_KERNEL);
-       memset(oa, 0, sizeof (*oa));
+        oa = kmem_cache_alloc(obdo_cachep, SLAB_KERNEL);
+        memset(oa, 0, sizeof (*oa));
 
-       return oa;
+        return oa;
 }
 
 static __inline__ void obdo_free(struct obdo *oa)
 {
-       if ( !oa ) 
-               return;
-       kmem_cache_free(obdo_cachep, oa);
+        if ( !oa ) 
+                return;
+        kmem_cache_free(obdo_cachep, oa);
 }
 
 
 
 static __inline__ struct obdo *obdo_fromid(struct obd_conn *conn, obd_id id,
-                                          obd_flag valid)
+                                           obd_flag valid)
 {
-       struct obdo *oa;
-       int err;
-
-       ENTRY;
-       oa = obdo_alloc();
-       if ( !oa ) {
-               EXIT;
-               return ERR_PTR(-ENOMEM);
-       }
-       memset(oa, 0, sizeof(*oa));
-       oa->o_id = id;
-       oa->o_valid = valid;
-       if ((err = OBP(conn->oc_dev, getattr)(conn, oa))) {
-               obdo_free(oa);
-               EXIT;
-               return ERR_PTR(err);
-       }
-       EXIT;
-       return oa;
+        struct obdo *oa;
+        int err;
+
+        ENTRY;
+        oa = obdo_alloc();
+        if ( !oa ) {
+                EXIT;
+                return ERR_PTR(-ENOMEM);
+        }
+        memset(oa, 0, sizeof(*oa));
+        oa->o_id = id;
+        oa->o_valid = valid;
+        if ((err = OBP(conn->oc_dev, getattr)(conn, oa))) {
+                obdo_free(oa);
+                EXIT;
+                return ERR_PTR(err);
+        }
+        EXIT;
+        return oa;
 }
 
 static inline void obdo_from_iattr(struct obdo *oa, struct iattr *attr)
 {
-       unsigned int ia_valid = attr->ia_valid;
-
-       if (ia_valid & ATTR_ATIME) {
-               oa->o_atime = attr->ia_atime;
-               oa->o_valid |= OBD_MD_FLATIME;
-       }
-       if (ia_valid & ATTR_MTIME) {
-               oa->o_mtime = attr->ia_mtime;
-               oa->o_valid |= OBD_MD_FLMTIME;
-       }
-       if (ia_valid & ATTR_CTIME) {
-               oa->o_ctime = attr->ia_ctime;
-               oa->o_valid |= OBD_MD_FLCTIME;
-       }
-       if (ia_valid & ATTR_SIZE) {
-               oa->o_size = attr->ia_size;
-               oa->o_valid |= OBD_MD_FLSIZE;
-       }
-       if (ia_valid & ATTR_MODE) {
-               oa->o_mode = attr->ia_mode;
-               oa->o_valid |= OBD_MD_FLMODE;
-               if (!in_group_p(oa->o_gid) && !capable(CAP_FSETID))
-                       oa->o_mode &= ~S_ISGID;
-       }
-       if (ia_valid & ATTR_UID)
-       {
-               oa->o_uid = attr->ia_uid;
-               oa->o_valid |= OBD_MD_FLUID;
-       }
-       if (ia_valid & ATTR_GID) {
-               oa->o_gid = attr->ia_gid;
-               oa->o_valid |= OBD_MD_FLGID;
-       }
+        unsigned int ia_valid = attr->ia_valid;
+
+        if (ia_valid & ATTR_ATIME) {
+                oa->o_atime = attr->ia_atime;
+                oa->o_valid |= OBD_MD_FLATIME;
+        }
+        if (ia_valid & ATTR_MTIME) {
+                oa->o_mtime = attr->ia_mtime;
+                oa->o_valid |= OBD_MD_FLMTIME;
+        }
+        if (ia_valid & ATTR_CTIME) {
+                oa->o_ctime = attr->ia_ctime;
+                oa->o_valid |= OBD_MD_FLCTIME;
+        }
+        if (ia_valid & ATTR_SIZE) {
+                oa->o_size = attr->ia_size;
+                oa->o_valid |= OBD_MD_FLSIZE;
+        }
+        if (ia_valid & ATTR_MODE) {
+                oa->o_mode = attr->ia_mode;
+                oa->o_valid |= OBD_MD_FLMODE;
+                if (!in_group_p(oa->o_gid) && !capable(CAP_FSETID))
+                        oa->o_mode &= ~S_ISGID;
+        }
+        if (ia_valid & ATTR_UID)
+        {
+                oa->o_uid = attr->ia_uid;
+                oa->o_valid |= OBD_MD_FLUID;
+        }
+        if (ia_valid & ATTR_GID) {
+                oa->o_gid = attr->ia_gid;
+                oa->o_valid |= OBD_MD_FLGID;
+        }
 }
 
 
 static __inline__ void obdo_cpy_md(struct obdo *dst, struct obdo *src)
 {
-       CDEBUG(D_INFO, "src obdo %Ld valid 0x%x, dst obdo %Ld\n",
-              src->o_id, src->o_valid, dst->o_id);
-       if ( src->o_valid & OBD_MD_FLATIME ) 
-               dst->o_atime = src->o_atime;
-       if ( src->o_valid & OBD_MD_FLMTIME ) 
-               dst->o_mtime = src->o_mtime;
-       if ( src->o_valid & OBD_MD_FLCTIME ) 
-               dst->o_ctime = src->o_ctime;
-       if ( src->o_valid & OBD_MD_FLSIZE ) 
-               dst->o_size = src->o_size;
-       if ( src->o_valid & OBD_MD_FLBLOCKS ) /* allocation of space */
-               dst->o_blocks = src->o_blocks;
-       if ( src->o_valid & OBD_MD_FLBLKSZ )
-               dst->o_blksize = src->o_blksize;
-       if ( src->o_valid & OBD_MD_FLMODE ) 
-               dst->o_mode = src->o_mode;
-       if ( src->o_valid & OBD_MD_FLUID ) 
-               dst->o_uid = src->o_uid;
-       if ( src->o_valid & OBD_MD_FLGID ) 
-               dst->o_gid = src->o_gid;
-       if ( src->o_valid & OBD_MD_FLFLAGS ) 
-               dst->o_flags = src->o_flags;
-       /*
-       if ( src->o_valid & OBD_MD_FLOBDFLG ) 
-               dst->o_obdflags = src->o_obdflags;
-       */
-       if ( src->o_valid & OBD_MD_FLNLINK ) 
-               dst->o_nlink = src->o_nlink;
-       if ( src->o_valid & OBD_MD_FLGENER ) 
-               dst->o_generation = src->o_generation;
-       if ( src->o_valid & OBD_MD_FLINLINE &&
-            src->o_obdflags & OBD_FL_INLINEDATA) {
-               memcpy(dst->o_inline, src->o_inline, sizeof(src->o_inline));
-               dst->o_obdflags |= OBD_FL_INLINEDATA;
-       }
-       if ( src->o_valid & OBD_MD_FLOBDMD &&
-            src->o_obdflags & OBD_FL_OBDMDEXISTS) {
-               memcpy(dst->o_obdmd, src->o_obdmd, sizeof(src->o_obdmd));
-               dst->o_obdflags |= OBD_FL_OBDMDEXISTS;
-       }
-
-       dst->o_valid |= src->o_valid;
+        CDEBUG(D_INODE, "src obdo %Ld valid 0x%x, dst obdo %Ld\n",
+               src->o_id, src->o_valid, dst->o_id);
+        if ( src->o_valid & OBD_MD_FLATIME ) 
+                dst->o_atime = src->o_atime;
+        if ( src->o_valid & OBD_MD_FLMTIME ) 
+                dst->o_mtime = src->o_mtime;
+        if ( src->o_valid & OBD_MD_FLCTIME ) 
+                dst->o_ctime = src->o_ctime;
+        if ( src->o_valid & OBD_MD_FLSIZE ) 
+                dst->o_size = src->o_size;
+        if ( src->o_valid & OBD_MD_FLBLOCKS ) /* allocation of space */
+                dst->o_blocks = src->o_blocks;
+        if ( src->o_valid & OBD_MD_FLBLKSZ )
+                dst->o_blksize = src->o_blksize;
+        if ( src->o_valid & OBD_MD_FLMODE ) 
+                dst->o_mode = src->o_mode;
+        if ( src->o_valid & OBD_MD_FLUID ) 
+                dst->o_uid = src->o_uid;
+        if ( src->o_valid & OBD_MD_FLGID ) 
+                dst->o_gid = src->o_gid;
+        if ( src->o_valid & OBD_MD_FLFLAGS ) 
+                dst->o_flags = src->o_flags;
+        /*
+        if ( src->o_valid & OBD_MD_FLOBDFLG ) 
+                dst->o_obdflags = src->o_obdflags;
+        */
+        if ( src->o_valid & OBD_MD_FLNLINK ) 
+                dst->o_nlink = src->o_nlink;
+        if ( src->o_valid & OBD_MD_FLGENER ) 
+                dst->o_generation = src->o_generation;
+        if ( src->o_valid & OBD_MD_FLINLINE &&
+             src->o_obdflags & OBD_FL_INLINEDATA) {
+                memcpy(dst->o_inline, src->o_inline, sizeof(src->o_inline));
+                dst->o_obdflags |= OBD_FL_INLINEDATA;
+        }
+        if ( src->o_valid & OBD_MD_FLOBDMD &&
+             src->o_obdflags & OBD_FL_OBDMDEXISTS) {
+                memcpy(dst->o_obdmd, src->o_obdmd, sizeof(src->o_obdmd));
+                dst->o_obdflags |= OBD_FL_OBDMDEXISTS;
+        }
+
+        dst->o_valid |= src->o_valid;
 }
 
 static __inline__ void obdo_from_inode(struct obdo *dst, struct inode *src)
 {
-       if ( dst->o_valid & OBD_MD_FLID )
-               dst->o_id = src->i_ino;
-       if ( dst->o_valid & OBD_MD_FLATIME )
-               dst->o_atime = src->i_atime;
-       if ( dst->o_valid & OBD_MD_FLMTIME )
-               dst->o_mtime = src->i_mtime;
-       if ( dst->o_valid & OBD_MD_FLCTIME )
-               dst->o_ctime = src->i_ctime;
-       if ( dst->o_valid & OBD_MD_FLSIZE )
-               dst->o_size = src->i_size;
-       if ( dst->o_valid & OBD_MD_FLBLOCKS )   /* allocation of space */
-               dst->o_blocks = src->i_blocks;
-       if ( dst->o_valid & OBD_MD_FLBLKSZ )
-               dst->o_blksize = src->i_blksize;
-       if ( dst->o_valid & OBD_MD_FLMODE )
-               dst->o_mode = src->i_mode;
-       if ( dst->o_valid & OBD_MD_FLUID )
-               dst->o_uid = src->i_uid;
-       if ( dst->o_valid & OBD_MD_FLGID )
-               dst->o_gid = src->i_gid;
-       if ( dst->o_valid & OBD_MD_FLFLAGS )
-               dst->o_flags = src->i_flags;
-       if ( dst->o_valid & OBD_MD_FLNLINK )
-               dst->o_nlink = src->i_nlink;
-       if ( dst->o_valid & OBD_MD_FLGENER ) 
-               dst->o_generation = src->i_generation;
+        if ( dst->o_valid & OBD_MD_FLID )
+                dst->o_id = src->i_ino;
+        if ( dst->o_valid & OBD_MD_FLATIME )
+                dst->o_atime = src->i_atime;
+        if ( dst->o_valid & OBD_MD_FLMTIME )
+                dst->o_mtime = src->i_mtime;
+        if ( dst->o_valid & OBD_MD_FLCTIME )
+                dst->o_ctime = src->i_ctime;
+        if ( dst->o_valid & OBD_MD_FLSIZE )
+                dst->o_size = src->i_size;
+        if ( dst->o_valid & OBD_MD_FLBLOCKS )   /* allocation of space */
+                dst->o_blocks = src->i_blocks;
+        if ( dst->o_valid & OBD_MD_FLBLKSZ )
+                dst->o_blksize = src->i_blksize;
+        if ( dst->o_valid & OBD_MD_FLMODE )
+                dst->o_mode = src->i_mode;
+        if ( dst->o_valid & OBD_MD_FLUID )
+                dst->o_uid = src->i_uid;
+        if ( dst->o_valid & OBD_MD_FLGID )
+                dst->o_gid = src->i_gid;
+        if ( dst->o_valid & OBD_MD_FLFLAGS )
+                dst->o_flags = src->i_flags;
+        if ( dst->o_valid & OBD_MD_FLNLINK )
+                dst->o_nlink = src->i_nlink;
+        if ( dst->o_valid & OBD_MD_FLGENER ) 
+                dst->o_generation = src->i_generation;
 }
 
 static __inline__ void obdo_to_inode(struct inode *dst, struct obdo *src)
 {
 
-       if ( src->o_valid & OBD_MD_FLID )
-               dst->i_ino = src->o_id;
-       if ( src->o_valid & OBD_MD_FLATIME ) 
-               dst->i_atime = src->o_atime;
-       if ( src->o_valid & OBD_MD_FLMTIME ) 
-               dst->i_mtime = src->o_mtime;
-       if ( src->o_valid & OBD_MD_FLCTIME ) 
-               dst->i_ctime = src->o_ctime;
-       if ( src->o_valid & OBD_MD_FLSIZE ) 
-               dst->i_size = src->o_size;
-       if ( src->o_valid & OBD_MD_FLBLOCKS ) /* allocation of space */
-               dst->i_blocks = src->o_blocks;
-       if ( src->o_valid & OBD_MD_FLBLKSZ )
-               dst->i_blksize = src->o_blksize;
-       if ( src->o_valid & OBD_MD_FLMODE ) 
-               dst->i_mode = src->o_mode;
-       if ( src->o_valid & OBD_MD_FLUID ) 
-               dst->i_uid = src->o_uid;
-       if ( src->o_valid & OBD_MD_FLGID ) 
-               dst->i_gid = src->o_gid;
-       if ( src->o_valid & OBD_MD_FLFLAGS ) 
-               dst->i_flags = src->o_flags;
-       if ( src->o_valid & OBD_MD_FLNLINK )
-               dst->i_nlink = src->o_nlink;
-       if ( src->o_valid & OBD_MD_FLGENER )
-               dst->i_generation = src->o_generation;
+        if ( src->o_valid & OBD_MD_FLID )
+                dst->i_ino = src->o_id;
+        if ( src->o_valid & OBD_MD_FLATIME ) 
+                dst->i_atime = src->o_atime;
+        if ( src->o_valid & OBD_MD_FLMTIME ) 
+                dst->i_mtime = src->o_mtime;
+        if ( src->o_valid & OBD_MD_FLCTIME ) 
+                dst->i_ctime = src->o_ctime;
+        if ( src->o_valid & OBD_MD_FLSIZE ) 
+                dst->i_size = src->o_size;
+        if ( src->o_valid & OBD_MD_FLBLOCKS ) /* allocation of space */
+                dst->i_blocks = src->o_blocks;
+        if ( src->o_valid & OBD_MD_FLBLKSZ )
+                dst->i_blksize = src->o_blksize;
+        if ( src->o_valid & OBD_MD_FLMODE ) 
+                dst->i_mode = src->o_mode;
+        if ( src->o_valid & OBD_MD_FLUID ) 
+                dst->i_uid = src->o_uid;
+        if ( src->o_valid & OBD_MD_FLGID ) 
+                dst->i_gid = src->o_gid;
+        if ( src->o_valid & OBD_MD_FLFLAGS ) 
+                dst->i_flags = src->o_flags;
+        if ( src->o_valid & OBD_MD_FLNLINK )
+                dst->i_nlink = src->o_nlink;
+        if ( src->o_valid & OBD_MD_FLGENER )
+                dst->i_generation = src->o_generation;
 }
 
 /* returns FALSE if comparison (by flags) is same, TRUE if changed */
 static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src,
-                                 obd_flag compare)
+                                  obd_flag compare)
 {
-       int res = 0;
-
-       if ( compare & OBD_MD_FLATIME )
-               res = (res || (dst->o_atime != src->o_atime));
-       if ( compare & OBD_MD_FLMTIME )
-               res = (res || (dst->o_mtime != src->o_mtime));
-       if ( compare & OBD_MD_FLCTIME )
-               res = (res || (dst->o_ctime != src->o_ctime));
-       if ( compare & OBD_MD_FLSIZE )
-               res = (res || (dst->o_size != src->o_size));
-       if ( compare & OBD_MD_FLBLOCKS ) /* allocation of space */
-               res = (res || (dst->o_blocks != src->o_blocks));
-       if ( compare & OBD_MD_FLBLKSZ )
-               res = (res || (dst->o_blksize != src->o_blksize));
-       if ( compare & OBD_MD_FLMODE )
-               res = (res || (dst->o_mode != src->o_mode));
-       if ( compare & OBD_MD_FLUID )
-               res = (res || (dst->o_uid != src->o_uid));
-       if ( compare & OBD_MD_FLGID )
-               res = (res || (dst->o_gid != src->o_gid));
-       if ( compare & OBD_MD_FLFLAGS ) 
-               res = (res || (dst->o_flags != src->o_flags));
-       if ( compare & OBD_MD_FLNLINK )
-               res = (res || (dst->o_nlink != src->o_nlink));
-       if ( compare & OBD_MD_FLGENER )
-               res = (res || (dst->o_generation != src->o_generation));
-       /* XXX Don't know if thses should be included here - wasn't previously
-       if ( compare & OBD_MD_FLINLINE )
-               res = (res || memcmp(dst->o_inline, src->o_inline));
-       if ( compare & OBD_MD_FLOBDMD )
-               res = (res || memcmp(dst->o_obdmd, src->o_obdmd));
-       */
-       return res;
+        int res = 0;
+
+        if ( compare & OBD_MD_FLATIME )
+                res = (res || (dst->o_atime != src->o_atime));
+        if ( compare & OBD_MD_FLMTIME )
+                res = (res || (dst->o_mtime != src->o_mtime));
+        if ( compare & OBD_MD_FLCTIME )
+                res = (res || (dst->o_ctime != src->o_ctime));
+        if ( compare & OBD_MD_FLSIZE )
+                res = (res || (dst->o_size != src->o_size));
+        if ( compare & OBD_MD_FLBLOCKS ) /* allocation of space */
+                res = (res || (dst->o_blocks != src->o_blocks));
+        if ( compare & OBD_MD_FLBLKSZ )
+                res = (res || (dst->o_blksize != src->o_blksize));
+        if ( compare & OBD_MD_FLMODE )
+                res = (res || (dst->o_mode != src->o_mode));
+        if ( compare & OBD_MD_FLUID )
+                res = (res || (dst->o_uid != src->o_uid));
+        if ( compare & OBD_MD_FLGID )
+                res = (res || (dst->o_gid != src->o_gid));
+        if ( compare & OBD_MD_FLFLAGS ) 
+                res = (res || (dst->o_flags != src->o_flags));
+        if ( compare & OBD_MD_FLNLINK )
+                res = (res || (dst->o_nlink != src->o_nlink));
+        if ( compare & OBD_MD_FLGENER )
+                res = (res || (dst->o_generation != src->o_generation));
+        /* XXX Don't know if thses should be included here - wasn't previously
+        if ( compare & OBD_MD_FLINLINE )
+                res = (res || memcmp(dst->o_inline, src->o_inline));
+        if ( compare & OBD_MD_FLOBDMD )
+                res = (res || memcmp(dst->o_obdmd, src->o_obdmd));
+        */
+        return res;
 }
 
 
@@ -430,17 +430,17 @@ int obd_register_type(struct obd_ops *ops, char *nm);
 int obd_unregister_type(char *nm);
 
 struct obd_client {
-       struct list_head cli_chain;
-       struct obd_device *cli_obd;
-       unsigned int cli_id;
-       unsigned long cli_prealloc_quota;
-       struct list_head cli_prealloc_inodes;
+        struct list_head cli_chain;
+        struct obd_device *cli_obd;
+        unsigned int cli_id;
+        unsigned long cli_prealloc_quota;
+        struct list_head cli_prealloc_inodes;
 };
 
 
 struct obd_prealloc_inode {
-       struct list_head obd_prealloc_chain;
-       unsigned long inode;
+        struct list_head obd_prealloc_chain;
+        unsigned long inode;
 };
 
 /* generic operations shared by various OBD types */
@@ -453,8 +453,8 @@ int gen_disconnect(struct obd_conn *conn);
 struct obd_client *gen_client(struct obd_conn *);
 int gen_cleanup(struct obd_device *obddev);
 int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
-                 struct obd_conn *src_conn, struct obdo *src,
-                 obd_size count, obd_off offset);
+                  struct obd_conn *src_conn, struct obdo *src,
+                  obd_size count, obd_off offset);
 
 
 
@@ -462,53 +462,53 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
  *  ======== OBD IOCL Declarations ===========
  */
 struct oic_generic {
-       uint32_t att_connid;
-       int      att_typelen;
-       void    *att_type;
-       int      att_datalen;
-       void    *att_data;
+        uint32_t att_connid;
+        int      att_typelen;
+        void    *att_type;
+        int      att_datalen;
+        void    *att_data;
 };
 
 
 /* for preallocation */
 struct oic_prealloc_s {
-       uint32_t         conn_id;
-       uint32_t         alloc; /* user sets it to the number of inodes
-                                * requesting to be preallocated.  kernel
-                                * sets it to the actual number of
-                                * succesfully preallocated inodes */
-       obd_id           ids[32]; /* actual inode numbers */
+        uint32_t         conn_id;
+        uint32_t         alloc; /* user sets it to the number of inodes
+                                 * requesting to be preallocated.  kernel
+                                 * sets it to the actual number of
+                                 * succesfully preallocated inodes */
+        obd_id           ids[32]; /* actual inode numbers */
 };
 
 /* for getattr, setattr, create, destroy */
 struct oic_attr_s {
-       uint32_t         conn_id;
-       struct obdo      obdo;
+        uint32_t         conn_id;
+        struct obdo      obdo;
 };
 
 /* for copy, migrate */
 struct ioc_mv_s {
-       uint32_t         src_conn_id;
-       struct obdo      src;
-       uint32_t         dst_conn_id;
-       struct obdo      dst;
+        uint32_t         src_conn_id;
+        struct obdo      src;
+        uint32_t         dst_conn_id;
+        struct obdo      dst;
 };
 
 /* for read/write */
 struct oic_rw_s {
-       uint32_t         conn_id;
-       struct obdo      obdo;
-       char            *buf;
-       obd_size         count;
-       obd_off          offset;
+        uint32_t         conn_id;
+        struct obdo      obdo;
+        char            *buf;
+        obd_size         count;
+        obd_off          offset;
 };
 
 /* for punch, sync */
 struct oic_range_s {
-       uint32_t         conn_id;
-       struct obdo      obdo;
-       obd_size         count;
-       obd_off          offset;
+        uint32_t         conn_id;
+        struct obdo      obdo;
+        obd_size         count;
+        obd_off          offset;
 };
 
 
@@ -542,10 +542,10 @@ struct oic_range_s {
 extern void obd_sysctl_init (void);
 extern void obd_sysctl_clean (void);
 
-#define CHKCONN(conn)  do { if (!gen_client(conn)) {\
-               printk("%s %d invalid client %u\n", __FILE__, __LINE__, \
-                      conn->oc_id);\
-               return -EINVAL; }} while (0) 
+#define CHKCONN(conn)   do { if (!gen_client(conn)) {\
+                printk("%s %d invalid client %u\n", __FILE__, __LINE__, \
+                       conn->oc_id);\
+                return -EINVAL; }} while (0) 
 
 
 
index bc58ca0..1059e58 100644 (file)
@@ -10,7 +10,7 @@
 #endif
 
 struct ext2_obd {
-       struct super_block * ext2_sb;
+        struct super_block * ext2_sb;
 };
 
 
@@ -29,8 +29,8 @@ void ext2_free_blocks (const struct inode * inode, unsigned long block,
 unsigned long ext2_count_free_blocks (struct super_block * sb);
 int ext2_group_sparse(int group);
 struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
-                                            unsigned int block_group,
-                                            struct buffer_head ** bh);
+                                             unsigned int block_group,
+                                             struct buffer_head ** bh);
 
 /* bitmap.c */
 unsigned long ext2_count_free(struct buffer_head * map, unsigned int numchars);
@@ -43,19 +43,19 @@ extern struct file_operations ext2_file_operations;
 extern struct inode_operations ext2_file_inode_operations;
 
 /* fsync.c */
-int ext2_sync_file(struct file * file, struct dentry *dentry);
+int ext2_sync_file(struct file * file, struct dentry *dentry, int);
 
 /* ialloc.c */
 void ext2_free_inode (struct inode * inode);
-struct inode * ext2_new_inode (const struct inode * dir, int mode,
-                                    int * err);
+struct inode * ext2_new_inode (const struct inode * dir, int );
 unsigned long ext2_count_free_inodes (struct super_block * sb);
 void ext2_check_inodes_bitmap (struct super_block * sb);
 int load_inode_bitmap (struct super_block * sb,
-                             unsigned int block_group);
+                              unsigned int block_group);
 
 /* inode.c */
-inline long ext2_block_map (struct inode * inode, long block);
+int ext2_bmap(struct address_space *mapping, long block);
+int ext2_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create);
 
 
 /* super.c */
@@ -76,25 +76,10 @@ inline long ext2_block_map (struct inode * inode, long block);
 extern struct super_operations ext2_sops;
 int obd_remount (struct super_block * sb, int * flags, char * data);
 struct super_block * ext2_read_super (struct super_block * sb, void * data,
-                                     int silent);
+                                      int silent);
 
 /* punch.c */
 void ext2_truncate (struct inode * inode);
 int ext2_punch (struct inode * inode, loff_t start, size_t count);
 
-static inline struct page *addr_to_page(char *buf)
-{
-       unsigned long addr = (unsigned long)buf;
-        unsigned long map_nr;
-
-#ifdef CONFIG_DISCONTIGMEM
-        if (addr == 0) return;
-#endif
-        map_nr = MAP_NR(addr);
-        if (map_nr < max_mapnr)
-               return mem_map + map_nr;
-       else 
-               return 0;
-}
-
 #endif
index d668fca..a1ecc41 100644 (file)
 #endif
 
 struct raid1_obd {
-       unsigned int raid1_count; /* how many replicas */
-       /* devices to replicate on */
-       struct obd_device *raid1_devlist[MAX_RAID1];
-       /* connections we make */
-       struct obd_conn_info raid1_connections[MAX_RAID1];
-       struct list_head raid1_clients;  /* clients we have */
+        unsigned int raid1_count; /* how many replicas */
+        /* devices to replicate on */
+        struct obd_device *raid1_devlist[MAX_RAID1];
+        /* connections we make */
+        struct obd_conn_info raid1_connections[MAX_RAID1];
+        struct list_head raid1_clients;  /* clients we have */
 };
 
 
@@ -35,8 +35,8 @@ void ext2_free_blocks (const struct inode * inode, unsigned long block,
 unsigned long ext2_count_free_blocks (struct super_block * sb);
 int ext2_group_sparse(int group);
 struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
-                                            unsigned int block_group,
-                                            struct buffer_head ** bh);
+                                             unsigned int block_group,
+                                             struct buffer_head ** bh);
 
 /* bitmap.c */
 unsigned long ext2_count_free(struct buffer_head * map, unsigned int numchars);
@@ -46,12 +46,11 @@ extern int obd_sync_file(struct file * file, struct dentry *dentry);
 
 /* ialloc.c */
 extern void ext2_free_inode (struct inode * inode);
-extern struct inode * ext2_new_inode (const struct inode * dir, int mode,
-                                    int * err);
+extern struct inode * ext2_new_inode (const struct inode * dir, int mode);
 extern unsigned long ext2_count_free_inodes (struct super_block * sb);
 extern void ext2_check_inodes_bitmap (struct super_block * sb);
 extern int load_inode_bitmap (struct super_block * sb,
-                             unsigned int block_group);
+                              unsigned int block_group);
 
 /* inode.c */
 void obd_read_inode (struct inode * inode);
@@ -68,7 +67,7 @@ struct buffer_head * obd_getblk (struct inode * inode, long block,
 
 int obd_remount (struct super_block * sb, int * flags, char * data);
 struct super_block * ext2_read_super (struct super_block * sb, void * data,
-                                     int silent);
+                                      int silent);
 
 /* truncate.c */
 void obd_truncate (struct inode * inode);
index b103bd1..64372c1 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __OBD_RPC_H
 #define __OBD_RPC_H
 
+#include <linux/sunrpc/svc.h>
 #define OBD_TGT_VERSION  001
 
 #define OBD_TGT_TCP  0x1
@@ -35,42 +36,42 @@ extern struct rpc_program obd_program;
 
 
 struct obd_target {
-       struct sockaddr_in tgt_addr;
-       int tgt_flags;
-       int tgt_timeo;
-       int tgt_retrans;
-       int tgt_hostnamelen;
-       char tgt_hostname[0];
-       
+        struct sockaddr_in tgt_addr;
+        int tgt_flags;
+        int tgt_timeo;
+        int tgt_retrans;
+        int tgt_hostnamelen;
+        char tgt_hostname[0];
+        
 };
 
 
 struct rpc_obd {
-       struct rpc_clnt *       handle;         /* RPC client handle */
-       struct sockaddr_in      addr;
-       int                     flags;          /* various flags */
-       int                     timeo;
-       int                     retrans;
-       int                     rsize;          /* read size */
-       int                     wsize;          /* write size */
-       unsigned int            bsize;          /* server block size */
-       char *                  hostname;       /* remote hostname */
+        struct rpc_clnt *       handle;         /* RPC client handle */
+        struct sockaddr_in      addr;
+        int                     flags;          /* various flags */
+        int                     timeo;
+        int                     retrans;
+        int                     rsize;          /* read size */
+        int                     wsize;          /* write size */
+        unsigned int            bsize;          /* server block size */
+        char *                  hostname;       /* remote hostname */
 };
 
 
-#define OBD_PROGRAM            300001
-#define OBD_VERSION            1
-#define OBDPROC_NULL           0
-#define OBDPROC_ECHOINT                1
+#define OBD_PROGRAM             300001
+#define OBD_VERSION             1
+#define OBDPROC_NULL            0
+#define OBDPROC_ECHOINT         1
 
 #ifdef  OBD_NEED_XDR_TYPES
 
 struct obd_echoint_in {
-       __u32                   in;
+        __u32                   in;
 };
 
 struct obd_echoint_out {
-       __u32                   out;
+        __u32                   out;
 };
 
 
index 2be72f9..9320f5c 100644 (file)
@@ -22,90 +22,90 @@ extern long obd_memory;
 #define CMD(cmd) (( cmd == READ ) ? "read" : "write")
 
 /* debugging masks */
-#define D_PSDEV   0x001        /* debug information from psdev.c */
+#define D_PSDEV   0x001 /* debug information from psdev.c */
 #define D_INODE   0x002
 #define D_SUPER   0x004
 #define D_SNAP    0x008
 #define D_UNUSED4 0x010
-#define D_WARNING 0x020        /* misc warnings */
-#define D_EXT2    0x040        /* anything from ext2_debug */
-#define D_MALLOC  0x080        /* print malloc, free information */
-#define D_CACHE   0x100        /* cache-related items */
-#define D_INFO    0x200        /* general information, especially from interface.c */
-#define D_IOCTL   0x400        /* ioctl related information */
-#define D_BLOCKS  0x800        /* ext2 block allocation */
-#define D_RPC    0x1000        /* rpc communications */
+#define D_WARNING 0x020 /* misc warnings */
+#define D_EXT2    0x040 /* anything from ext2_debug */
+#define D_MALLOC  0x080 /* print malloc, free information */
+#define D_CACHE   0x100 /* cache-related items */
+#define D_INFO    0x200 /* general information, especially from interface.c */
+#define D_IOCTL   0x400 /* ioctl related information */
+#define D_BLOCKS  0x800 /* ext2 block allocation */
+#define D_RPC    0x1000 /* rpc communications */
 #define D_PUNCH  0x2000
  
 #define CDEBUG(mask, format, a...)                                      \
-       do {                                                            \
-       if (obd_debug_level & mask) {                                   \
-               printk("(%s:%d):", __FUNCTION__, __LINE__);             \
-               printk(format, ## a); }                                 \
-       } while (0)
+        do {                                                            \
+        if (obd_debug_level & mask) {                                   \
+                printk("(%s:%d):", __FUNCTION__, __LINE__);             \
+                printk(format, ## a); }                                 \
+        } while (0)
 
-#define ENTRY if (obd_print_entry)                                     \
-       printk(KERN_INFO "Process %d entered %s\n", current->pid, __FUNCTION__)
+#define ENTRY if (obd_print_entry)                                      \
+        printk(KERN_INFO "Process %d entered %s\n", current->pid, __FUNCTION__)
 
-#define EXIT if (obd_print_entry)                                      \
-       printk(KERN_INFO "Process %d leaving %s [%d]\n", current->pid,  \
-              __FUNCTION__, __LINE__)
+#define EXIT if (obd_print_entry)                                       \
+        printk(KERN_INFO "Process %d leaving %s [%d]\n", current->pid,  \
+               __FUNCTION__, __LINE__)
 
 /* Inode common information printed out (used by obdfs and ext2obd inodes) */
-#define ICDEBUG(inode) {                                               \
-       CDEBUG(D_INFO,                                                  \
-              "ino %ld, atm %ld, mtm %ld, ctm %ld, size %Ld, blocks %ld\n",\
-              inode->i_ino, inode->i_atime, inode->i_mtime, inode->i_ctime,\
-              inode->i_size, inode->i_blocks);                         \
-       CDEBUG(D_INFO, "mode %o, uid %d, gid %d, nlnk %d, count %d\n",  \
-              inode->i_mode, inode->i_uid, inode->i_gid, inode->i_nlink,\
-              inode->i_count);                                         \
+#define ICDEBUG(inode) {                                                \
+        CDEBUG(D_INFO,                                                  \
+               "ino %ld, atm %ld, mtm %ld, ctm %ld, size %Ld, blocks %ld\n",\
+               inode->i_ino, inode->i_atime, inode->i_mtime, inode->i_ctime,\
+               inode->i_size, inode->i_blocks);                         \
+        CDEBUG(D_INFO, "mode %o, uid %d, gid %d, nlnk %d, count %d\n",  \
+               inode->i_mode, inode->i_uid, inode->i_gid, inode->i_nlink,\
+               atomic_read(&inode->i_count));                                         \
 }
 
 /* Ext2 inode information */
-#define EXDEBUG(inode) {                                               \
-       ICDEBUG(inode);                                                 \
-       CDEBUG(D_INFO, "ext2 blocks: %d %d %d %d %d %d %d %d\n",        \
-              inode->u.ext2_i.i_data[0], inode->u.ext2_i.i_data[1],    \
-              inode->u.ext2_i.i_data[2], inode->u.ext2_i.i_data[3],    \
-              inode->u.ext2_i.i_data[4], inode->u.ext2_i.i_data[5],    \
-              inode->u.ext2_i.i_data[6], inode->u.ext2_i.i_data[7]);   \
+#define EXDEBUG(inode) {                                                \
+        ICDEBUG(inode);                                                 \
+        CDEBUG(D_INFO, "ext2 blocks: %d %d %d %d %d %d %d %d\n",        \
+               inode->u.ext2_i.i_data[0], inode->u.ext2_i.i_data[1],    \
+               inode->u.ext2_i.i_data[2], inode->u.ext2_i.i_data[3],    \
+               inode->u.ext2_i.i_data[4], inode->u.ext2_i.i_data[5],    \
+               inode->u.ext2_i.i_data[6], inode->u.ext2_i.i_data[7]);   \
 }
 
 /* OBDFS inode information */
-#define OIDEBUG(inode) {                                               \
-       ICDEBUG(inode);                                                 \
-       CDEBUG(D_INFO,"oinfo: flags 0x%08x\n", obdfs_i2info(inode)->oi_flags);\
-       /* obdfs_print_plist(inode); */                                 \
+#define OIDEBUG(inode) {                                                \
+        ICDEBUG(inode);                                                 \
+        CDEBUG(D_INFO,"oinfo: flags 0x%08x\n", obdfs_i2info(inode)->oi_flags);\
+        /* obdfs_print_plist(inode); */                                 \
 }
 
-#define ODEBUG(obdo) {                                                 \
-       CDEBUG(D_INFO, "id %ld, atm %ld, mtm %ld, ctm %ld, "            \
-              "size %ld, blocks %ld\n",                                \
-              (long)(obdo)->o_id, (long)(obdo)->o_atime,               \
-              (long)(obdo)->o_mtime, (long)(obdo)->o_ctime,            \
-              (long)(obdo)->o_size, (long)(obdo)->o_blocks);           \
-       CDEBUG(D_INFO, " mode %o, uid %d, gid %d, flg 0x%0x, "          \
-              "obdflg 0x%0x, nlnk %d, valid 0x%0x\n",                  \
-              (obdo)->o_mode, (obdo)->o_uid, (obdo)->o_gid, (obdo)->o_flags,\
-              (obdo)->o_obdflags, (obdo)->o_nlink, (obdo)->o_valid);   \
+#define ODEBUG(obdo) {                                                  \
+        CDEBUG(D_INFO, "id %ld, atm %ld, mtm %ld, ctm %ld, "            \
+               "size %ld, blocks %ld\n",                                \
+               (long)(obdo)->o_id, (long)(obdo)->o_atime,               \
+               (long)(obdo)->o_mtime, (long)(obdo)->o_ctime,            \
+               (long)(obdo)->o_size, (long)(obdo)->o_blocks);           \
+        CDEBUG(D_INFO, " mode %o, uid %d, gid %d, flg 0x%0x, "          \
+               "obdflg 0x%0x, nlnk %d, valid 0x%0x\n",                  \
+               (obdo)->o_mode, (obdo)->o_uid, (obdo)->o_gid, (obdo)->o_flags,\
+               (obdo)->o_obdflags, (obdo)->o_nlink, (obdo)->o_valid);   \
 }
 
 
-#define PDEBUG(page,msg) {                                             \
-       if (page){                                                      \
-               char *uptodate = (Page_Uptodate(page)) ? "upto" : "outof";\
-               char *locked = (PageLocked(page)) ? "" : "un";          \
-               char *buffer = page->buffers ? "buffer" : "";           \
-               int count = page_count(page);                           \
-               long index = page->index;                               \
-               CDEBUG(D_CACHE, "%s: ** off %ld, %sdate, %slocked, flag %ld,"\
-                      " cnt %d page 0x%p pages %ld virt %lx %s**\n",   \
-                      msg, index, uptodate, locked, page->flags, count,\
-                      page, page->mapping ? page->mapping->nrpages : -1,\
-                      page->virtual, buffer);                          \
-       } else                                                          \
-               CDEBUG(D_CACHE, "** %s: no page\n", msg);               \
+#define PDEBUG(page,msg) {                                              \
+        if (page){                                                      \
+                char *uptodate = (Page_Uptodate(page)) ? "upto" : "outof";\
+                char *locked = (PageLocked(page)) ? "" : "un";          \
+                char *buffer = page->buffers ? "buffer" : "";           \
+                int count = page_count(page);                           \
+                long index = page->index;                               \
+                CDEBUG(D_CACHE, "%s: ** off %ld, %sdate, %slocked, flag %ld,"\
+                       " cnt %d page 0x%p pages %ld virt %lx %s**\n",   \
+                       msg, index, uptodate, locked, page->flags, count,\
+                       page, page->mapping ? page->mapping->nrpages : -1,\
+                       page->virtual, buffer);                          \
+        } else                                                          \
+                CDEBUG(D_CACHE, "** %s: no page\n", msg);               \
 }
 
 #if 0
@@ -114,21 +114,21 @@ extern long obd_memory;
 
 static inline struct inode *obd_iget(struct super_block *sb, unsigned long ino)
 {
-       struct inode *inode;
-       
-       if ((inode = iget(sb, ino)) == NULL)
-               CDEBUG(D_INODE, "NULL in iget for %ld\n", ino);
-       else
-               obd_inodes++;
-       return inode;
+        struct inode *inode;
+        
+        if ((inode = iget(sb, ino)) == NULL)
+                CDEBUG(D_INODE, "NULL in iget for %ld\n", ino);
+        else
+                obd_inodes++;
+        return inode;
 }
 
 static inline void obd_iput(struct inode *inode)
 {
-       if (inode == NULL)
-               CDEBUG(D_INODE, "NULL in iput\n");
-       else
-               obd_inodes--;
+        if (inode == NULL)
+                CDEBUG(D_INODE, "NULL in iput\n");
+        else
+                obd_inodes--;
 }
 #endif
 
@@ -146,38 +146,38 @@ static inline void obd_iput(struct inode *inode)
 
 
 
-#define OBD_ALLOC(ptr, cast, size)                                     \
-do {                                                                   \
-       if (size <= 4096) {                                             \
-               ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL);  \
-                CDEBUG(D_MALLOC, "kmalloced: %d at %x.\n",             \
-                      (int) size, (int) ptr);                          \
-       } else {                                                        \
-               ptr = (cast)vmalloc((unsigned long) size);              \
-               CDEBUG(D_MALLOC, "vmalloced: %d at %x.\n",              \
-                      (int) size, (int) ptr);                          \
-       }                                                               \
-       if (ptr == 0) {                                                 \
-               printk("kernel malloc returns 0 at %s:%d\n",            \
-                      __FILE__, __LINE__);                             \
-       } else {                                                        \
-               memset(ptr, 0, size);                                   \
-               obd_memory += size;                                     \
-       }                                                               \
+#define OBD_ALLOC(ptr, cast, size)                                      \
+do {                                                                    \
+        if (size <= 4096) {                                             \
+                ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL);  \
+                CDEBUG(D_MALLOC, "kmalloced: %d at %x.\n",              \
+                       (int) size, (int) ptr);                          \
+        } else {                                                        \
+                ptr = (cast)vmalloc((unsigned long) size);              \
+                CDEBUG(D_MALLOC, "vmalloced: %d at %x.\n",              \
+                       (int) size, (int) ptr);                          \
+        }                                                               \
+        if (ptr == 0) {                                                 \
+                printk("kernel malloc returns 0 at %s:%d\n",            \
+                       __FILE__, __LINE__);                             \
+        } else {                                                        \
+                memset(ptr, 0, size);                                   \
+                obd_memory += size;                                     \
+        }                                                               \
 } while (0)
 
-#define OBD_FREE(ptr,size)                             \
-do {                                                   \
-       if (size <= 4096) {                             \
-               kfree_s((ptr), (size));                 \
-               CDEBUG(D_MALLOC, "kfreed: %d at %x.\n", \
-                      (int) size, (int) ptr);          \
-       } else {                                        \
-               vfree((ptr));                           \
-               CDEBUG(D_MALLOC, "vfreed: %d at %x.\n", \
-                      (int) size, (int) ptr);          \
-       }                                               \
-       obd_memory -= size;                             \
+#define OBD_FREE(ptr,size)                              \
+do {                                                    \
+        if (size <= 4096) {                             \
+                kfree((ptr));                   \
+                CDEBUG(D_MALLOC, "kfreed: %d at %x.\n", \
+                       (int) size, (int) ptr);          \
+        } else {                                        \
+                vfree((ptr));                           \
+                CDEBUG(D_MALLOC, "vfreed: %d at %x.\n", \
+                       (int) size, (int) ptr);          \
+        }                                               \
+        obd_memory -= size;                             \
 } while (0)
 
 
index 6d42ddd..6940caa 100644 (file)
@@ -1,13 +1,13 @@
 /*
- *             An implementation of a loadable kernel mode driver providing
- *             multiple kernel/user space bidirectional communications links.
+ *              An implementation of a loadable kernel mode driver providing
+ *              multiple kernel/user space bidirectional communications links.
  *
- *             Author:         Alan Cox <alan@cymru.net>
+ *              Author:         Alan Cox <alan@cymru.net>
  *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
  * 
  *              Adapted to become the Linux 2.0 Coda pseudo device
  *              Peter  Braam  <braam@maths.ox.ac.uk> 
@@ -58,8 +58,8 @@
 #include <linux/obd_class.h>
 
 static int obd_init_magic;
-int obd_print_entry = 0;
-int obd_debug_level = ~D_INFO;
+int obd_print_entry = 1;
+int obd_debug_level = ~0;
 long obd_memory = 0;
 struct obd_device obd_dev[MAX_OBD_DEVICES];
 struct list_head obd_types;
@@ -67,17 +67,17 @@ struct list_head obd_types;
 /* called when opening /dev/obdNNN */
 static int obd_class_open(struct inode * inode, struct file * file)
 {
-       int dev;
+        int dev;
         ENTRY;
 
-       if (!inode)
-               return -EINVAL;
-       dev = MINOR(inode->i_rdev);
-       if (dev >= MAX_OBD_DEVICES)
-               return -ENODEV;
-       obd_dev[dev].obd_refcnt++;
-       CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
-              obd_dev[dev].obd_refcnt);
+        if (!inode)
+                return -EINVAL;
+        dev = MINOR(inode->i_rdev);
+        if (dev >= MAX_OBD_DEVICES)
+                return -ENODEV;
+        obd_dev[dev].obd_refcnt++;
+        CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
+               obd_dev[dev].obd_refcnt);
 
         MOD_INC_USE_COUNT;
         EXIT;
@@ -87,22 +87,22 @@ static int obd_class_open(struct inode * inode, struct file * file)
 /* called when closing /dev/obdNNN */
 static int obd_class_release(struct inode * inode, struct file * file)
 {
-       int dev;
+        int dev;
         ENTRY;
 
-       if (!inode)
-               return -EINVAL;
-       dev = MINOR(inode->i_rdev);
-       if (dev >= MAX_OBD_DEVICES)
-               return -ENODEV;
-       fsync_dev(inode->i_rdev);
-       if (obd_dev[dev].obd_refcnt <= 0)
-               printk(KERN_ALERT __FUNCTION__ ": refcount(%d) <= 0\n",
-                      obd_dev[dev].obd_refcnt);
-       obd_dev[dev].obd_refcnt--;
-
-       CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
-              obd_dev[dev].obd_refcnt);
+        if (!inode)
+                return -EINVAL;
+        dev = MINOR(inode->i_rdev);
+        if (dev >= MAX_OBD_DEVICES)
+                return -ENODEV;
+        fsync_dev(inode->i_rdev);
+        if (obd_dev[dev].obd_refcnt <= 0)
+                printk(KERN_ALERT __FUNCTION__ ": refcount(%d) <= 0\n",
+                       obd_dev[dev].obd_refcnt);
+        obd_dev[dev].obd_refcnt--;
+
+        CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
+               obd_dev[dev].obd_refcnt);
         MOD_DEC_USE_COUNT;
 
         EXIT;
@@ -112,823 +112,814 @@ static int obd_class_release(struct inode * inode, struct file * file)
 /* support function */
 static struct obd_type *obd_nm_to_type(char *nm) 
 {
-       struct list_head *tmp;
-       struct obd_type *type;
-       CDEBUG(D_INFO, "SEARCH %s\n", nm);
-       
-       tmp = &obd_types;
-       while ( (tmp = tmp->next) != &obd_types ) {
-               type = list_entry(tmp, struct obd_type, typ_chain);
-               CDEBUG(D_INFO, "TYP %s\n", type->typ_name);
-               if (strlen(type->typ_name) == strlen(nm) &&
-                   strcmp(type->typ_name, nm) == 0 ) {
-                       return type;
-               }
-       }
-       return NULL;
+        struct list_head *tmp;
+        struct obd_type *type;
+        CDEBUG(D_INFO, "SEARCH %s\n", nm);
+        
+        tmp = &obd_types;
+        while ( (tmp = tmp->next) != &obd_types ) {
+                type = list_entry(tmp, struct obd_type, typ_chain);
+                CDEBUG(D_INFO, "TYP %s\n", type->typ_name);
+                if (strlen(type->typ_name) == strlen(nm) &&
+                    strcmp(type->typ_name, nm) == 0 ) {
+                        return type;
+                }
+        }
+        return NULL;
 }
 
 
 static int getdata(int len, void **data)
 {
-       void *tmp = NULL;
-
-       if (!len) {
-               *data = NULL;
-               return 0;
-       }
-
-       CDEBUG(D_MALLOC, "len %d, add %p\n", len, *data);
-
-       OBD_ALLOC(tmp, void *, len);
-       if ( !tmp )
-               return -ENOMEM;
-       
-       memset(tmp, 0, len);
-       if ( copy_from_user(tmp, *data, len)) {
-               OBD_FREE(tmp, len);
-               return -EFAULT;
-       }
-       *data = tmp;
-
-       return 0;
+        void *tmp = NULL;
+
+        if (!len) {
+                *data = NULL;
+                return 0;
+        }
+
+        CDEBUG(D_MALLOC, "len %d, add %p\n", len, *data);
+
+        OBD_ALLOC(tmp, void *, len);
+        if ( !tmp )
+                return -ENOMEM;
+        
+        memset(tmp, 0, len);
+        if ( copy_from_user(tmp, *data, len)) {
+                OBD_FREE(tmp, len);
+                return -EFAULT;
+        }
+        *data = tmp;
+
+        return 0;
 }
 
 /* to control /dev/obdNNN */
 static int obd_class_ioctl (struct inode * inode, struct file * filp, 
-                           unsigned int cmd, unsigned long arg)
+                            unsigned int cmd, unsigned long arg)
 {
-       struct obd_device *obddev;
-       /* NOTE this must be larger than any of the ioctl data structs */
-       char buf[1024];
-       void *tmp_buf = buf;
-       struct obd_conn conn;
-       int err, dev;
-       long int cli_id; /* connect, disconnect */
-
-       if (!inode) {
-               CDEBUG(D_IOCTL, "invalid inode\n");
-               return -EINVAL;
-       }
-
-       dev = MINOR(inode->i_rdev);
-       if (dev > MAX_OBD_DEVICES)
-               return -ENODEV;
-       obddev = &obd_dev[dev];
-       conn.oc_dev = obddev;
-
-       switch (cmd) {
-       case TCGETS:
-               return -EINVAL;
-       case OBD_IOC_ATTACH: {
-               struct obd_type *type;
-               struct oic_generic *input = tmp_buf;
-               char *nm;
-
-               ENTRY;
-               /* have we attached a type to this device */
-               if ( obddev->obd_type || 
-                    (obddev->obd_flags & OBD_ATTACHED) ){
-                       CDEBUG(D_IOCTL,
-                              "OBD Device %d already attached to type %s.\n",
-                              dev, obddev->obd_type->typ_name);
-                       EXIT;
-                       return -EBUSY;
-               }
-
-               /* get data structures */
-               err = copy_from_user(input, (void *)arg, sizeof(*input));
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               err = getdata(input->att_typelen + 1, &input->att_type);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               /* find the type */
-               nm = input->att_type;
-               type = obd_nm_to_type(nm);
+        struct obd_device *obddev;
+        /* NOTE this must be larger than any of the ioctl data structs */
+        char buf[1024];
+        void *tmp_buf = buf;
+        struct obd_conn conn;
+        int err, dev;
+        long int cli_id; /* connect, disconnect */
+
+        if (!inode) {
+                CDEBUG(D_IOCTL, "invalid inode\n");
+                return -EINVAL;
+        }
+
+        dev = MINOR(inode->i_rdev);
+        if (dev > MAX_OBD_DEVICES)
+                return -ENODEV;
+        obddev = &obd_dev[dev];
+        conn.oc_dev = obddev;
+
+        switch (cmd) {
+        case TCGETS:
+                return -EINVAL;
+        case OBD_IOC_ATTACH: {
+                struct obd_type *type;
+                struct oic_generic *input = tmp_buf;
+                char *nm;
+
+                ENTRY;
+                /* have we attached a type to this device */
+                if ( obddev->obd_type || 
+                     (obddev->obd_flags & OBD_ATTACHED) ){
+                        CDEBUG(D_IOCTL,
+                               "OBD Device %d already attached to type %s.\n",
+                               dev, obddev->obd_type->typ_name);
+                        EXIT;
+                        return -EBUSY;
+                }
+
+                /* get data structures */
+                err = copy_from_user(input, (void *)arg, sizeof(*input));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                err = getdata(input->att_typelen + 1, &input->att_type);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                /* find the type */
+                nm = input->att_type;
+                type = obd_nm_to_type(nm);
 #ifdef CONFIG_KMOD
-               if ( !type ) {
-                       if ( !request_module(nm) ) {
-                               CDEBUG(D_PSDEV, "Loaded module '%s'\n", nm);
-                               type = obd_nm_to_type(nm);
-                       } else {
-                               CDEBUG(D_PSDEV, "Can't load module '%s'\n", nm);
-                       }
-               }
+                if ( !type ) {
+                        if ( !request_module(nm) ) {
+                                CDEBUG(D_PSDEV, "Loaded module '%s'\n", nm);
+                                type = obd_nm_to_type(nm);
+                        } else {
+                                CDEBUG(D_PSDEV, "Can't load module '%s'\n", nm);
+                        }
+                }
 #endif
 
-               OBD_FREE(input->att_type, input->att_typelen + 1);
-               if ( !type ) {
-                       printk(__FUNCTION__ ": unknown obd type dev %d\n",
-                              dev);
-                       EXIT;
-                       return -EINVAL;
-               }
-               obddev->obd_type = type;
-               
-               /* get the attach data */
-               err = getdata(input->att_datalen, &input->att_data);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               INIT_LIST_HEAD(&obddev->obd_gen_clients);
-               obddev->obd_multi_count = 0;
-
-               CDEBUG(D_IOCTL, "Attach %d, datalen %d, type %s\n", 
-                      dev, input->att_datalen, obddev->obd_type->typ_name);
-               /* maybe we are done */
-               if ( !OBT(obddev) || !OBP(obddev, attach) ) {
-                       obddev->obd_flags |= OBD_ATTACHED;
-                       type->typ_refcnt++;
-                       CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
-                              type->typ_refcnt);
-                       if (input->att_data)
-                               OBD_FREE(input->att_data, input->att_datalen);
-                       MOD_INC_USE_COUNT;
-                       EXIT;
-                       return 0;
-               }
-
-               /* do the attach */
-               err = OBP(obddev, attach)(obddev, input->att_datalen,
-                                         input->att_data);
-               if (input->att_data)
-                       OBD_FREE(input->att_data, input->att_datalen);
-
-               if ( err ) {
-                       obddev->obd_flags &= ~OBD_ATTACHED;
-                       obddev->obd_type = NULL;
-                       EXIT;
-               } else {
-                       obddev->obd_flags |=  OBD_ATTACHED;
-                       type->typ_refcnt++;
-                       CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
-                              type->typ_refcnt);
-                       MOD_INC_USE_COUNT;
-                       EXIT;
-               }
-               return err;
-       }
-
-       case OBD_IOC_DETACH: {
-
-               ENTRY;
-               if (obddev->obd_flags & OBD_SET_UP) {
-                       EXIT;
-                       return -EBUSY;
-               }
-               if (! (obddev->obd_flags & OBD_ATTACHED) ) {
-                       CDEBUG(D_IOCTL, "Device not attached\n");
-                       EXIT;
-                       return -ENODEV;
-               }
-               if ( !list_empty(&obddev->obd_gen_clients) ) {
-                       CDEBUG(D_IOCTL, "Device has connected clients\n");
-                       EXIT;
-                       return -EBUSY;
-               }
-
-               CDEBUG(D_PSDEV, "Detach %d, type %s\n", dev,
-                      obddev->obd_type->typ_name);
-               obddev->obd_flags &= ~OBD_ATTACHED;
-               obddev->obd_type->typ_refcnt--;
-               CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
-                      obddev->obd_type->typ_refcnt);
-               obddev->obd_type = NULL;
-               MOD_DEC_USE_COUNT;
-               EXIT;
-               return 0;
-       }
-
-       case OBD_IOC_SETUP: {
-               struct ioc_setup {
-                       int setup_datalen;
-                       void *setup_data;
-               } *setup;
-               setup = tmp_buf;
-
-               ENTRY;
-               /* have we attached a type to this device */
-               if (!(obddev->obd_flags & OBD_ATTACHED)) {
-                       CDEBUG(D_IOCTL, "Device not attached\n");
-                       EXIT;
-                       return -ENODEV;
-               }
-
-               /* has this been done already? */
-               if ( obddev->obd_flags & OBD_SET_UP ) {
-                       CDEBUG(D_IOCTL, "Device %d already setup (type %s)\n",
-                              dev, obddev->obd_type->typ_name);
-                       EXIT;
-                       return -EBUSY;
-               }
-
-               /* get main structure */
-               err = copy_from_user(setup, (void *) arg, sizeof(*setup));
-               if (err) {
-                       EXIT;
-                       return err;
-               }
-
-               err = getdata(setup->setup_datalen, &setup->setup_data);
-               if (err) {
-                       EXIT;
-                       return err;
-               }
-
-               /* do the setup */
-               CDEBUG(D_PSDEV, "Setup %d, type %s\n", dev, 
-                      obddev->obd_type->typ_name);
-               if ( !OBT(obddev) || !OBP(obddev, setup) ) {
-                       obddev->obd_type->typ_refcnt++;
-                       CDEBUG(D_PSDEV, "Dev %d refcount now %d\n",
-                              dev, obddev->obd_type->typ_refcnt);
-                       if (setup->setup_data)
-                               OBD_FREE(setup->setup_data,
-                                        setup->setup_datalen);
-                       obddev->obd_flags |= OBD_SET_UP;
-                       EXIT;
-                       return 0;
-               }
-
-               err = OBP(obddev, setup)(obddev, setup->setup_datalen,
-                                        setup->setup_data);
-
-               if ( err )  {
-                       obddev->obd_flags &= ~OBD_SET_UP;
-                       EXIT;
-               } else {
-                       obddev->obd_type->typ_refcnt++;
-                       CDEBUG(D_PSDEV, "Dev %d refcount now %d\n",
-                              dev, obddev->obd_type->typ_refcnt);
-                       obddev->obd_flags |= OBD_SET_UP;
-                       EXIT;
-               }
-               if (setup->setup_data)
-                       OBD_FREE(setup->setup_data, setup->setup_datalen);
-               return err;
-       }
-       case OBD_IOC_CLEANUP: {
-               ENTRY;
-               /* has this minor been registered? */
-               if (!obddev->obd_type) {
-                       CDEBUG(D_IOCTL, "OBD Device %d has no type.\n", dev);
-                       EXIT;
-                       return -ENODEV;
-               }
-
-               if ( !obddev->obd_type->typ_refcnt ) {
-                       CDEBUG(D_IOCTL, "dev %d has refcount (%d)!\n",
-                              dev, obddev->obd_type->typ_refcnt);
-                       EXIT;
-                       return -EBUSY;
-               }
-
-               if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
-                    (!(obddev->obd_flags & OBD_ATTACHED))) {
-                       CDEBUG(D_IOCTL, "device not attached or set up\n");
-                       EXIT;
-                       return -ENODEV;
-               }
-
-               if ( !OBT(obddev) || !OBP(obddev, cleanup) )
-                       goto cleanup_out;
-
-               /* cleanup has no argument */
-               err = OBP(obddev, cleanup)(obddev);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-       cleanup_out: 
-               obddev->obd_flags &= ~OBD_SET_UP;
-               obddev->obd_type->typ_refcnt--;
-               CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
-                      obddev->obd_type->typ_refcnt);
-               EXIT;
-               return 0;
-       }
-       case OBD_IOC_CONNECT:
-       {
-               if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
-                    (!(obddev->obd_flags & OBD_ATTACHED))) {
-                       CDEBUG(D_IOCTL, "Device not attached or set up\n");
-                       return -ENODEV;
-               }
-
-               if ( !OBT(obddev) || !OBP(obddev, connect) )
-                       return -EOPNOTSUPP;
-               
-               err = OBP(obddev, connect)(&conn);
-               if ( err )
-                       return err;
-
-               return copy_to_user((int *)arg, &conn.oc_id,
-                                   sizeof(uint32_t));
-       }
-       case OBD_IOC_DISCONNECT:
-               /* frees data structures */
-               /* has this minor been registered? */
-               if (!obddev->obd_type)
-                       return -ENODEV;
-
-               get_user(cli_id, (int *) arg);
-               conn.oc_id = cli_id;
-
-               if ( !OBT(obddev) || !OBP(obddev, disconnect))
-                       return -EOPNOTSUPP;
-               
-               OBP(obddev, disconnect)(&conn);
-               return 0;
-
-       case OBD_IOC_SYNC: {
-               struct oic_range_s *range = tmp_buf;
-
-               if (!obddev->obd_type)
-                       return -ENODEV;
-
-               err = copy_from_user(range, (const void *)arg,  sizeof(*range));
-
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-                       
-               if ( !OBT(obddev) || !OBP(obddev, sync) ) {
-                       err = -EOPNOTSUPP;
-                       EXIT;
-                       return err;
-               }
-
-               /* XXX sync needs to be tested/verified */
-               err = OBP(obddev, sync)(&conn, &range->obdo, range->count,
-                                       range->offset);
-
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-                       
-               return put_user(err, (int *) arg);
-       }
-       case OBD_IOC_CREATE: {
-               struct oic_attr_s *attr = tmp_buf;
-
-               err = copy_from_user(attr, (const void *)arg,  sizeof(*attr));
-               if (err) {
-                       EXIT;
-                       return err;
-               }
-
-               /* has this minor been registered? */
-               if ( !(obddev->obd_flags & OBD_ATTACHED) ||
-                    !(obddev->obd_flags & OBD_SET_UP)) {
-                       CDEBUG(D_IOCTL, "Device not attached or set up\n");
-                       return -ENODEV;
-               }
-               conn.oc_id = attr->conn_id;
-
-               if ( !OBT(obddev) || !OBP(obddev, create) )
-                       return -EOPNOTSUPP;
-
-               err = OBP(obddev, create)(&conn, &attr->obdo);
-               if (err) {
-                       EXIT;
-                       return err;
-               }
-
-               err = copy_to_user((int *)arg, attr, sizeof(*attr));
-               EXIT;
-               return err;
-       }
-
-       case OBD_IOC_DESTROY: {
-               struct oic_attr_s *attr = tmp_buf;
-               
-               /* has this minor been registered? */
-               if (!obddev->obd_type)
-                       return -ENODEV;
-
-               err = copy_from_user(attr, (int *)arg, sizeof(*attr));
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               if ( !OBT(obddev) || !OBP(obddev, destroy) )
-                       return -EOPNOTSUPP;
-
-               conn.oc_id = attr->conn_id;
-               err = OBP(obddev, destroy)(&conn, &attr->obdo);
-               EXIT;
-               return err;
-       }
-
-       case OBD_IOC_SETATTR: {
-               struct oic_attr_s *attr = tmp_buf;
-
-               /* has this minor been registered? */
-               if (!obddev->obd_type)
-                       return -ENODEV;
-
-               err = copy_from_user(attr, (int *)arg, sizeof(*attr));
-               if (err)
-                       return err;
-
-               if ( !OBT(obddev) || !OBP(obddev, setattr) )
-                       return -EOPNOTSUPP;
-               
-               conn.oc_id = attr->conn_id;
-               err = OBP(obddev, setattr)(&conn, &attr->obdo);
-               EXIT;
-               return err;
-       }
-
-       case OBD_IOC_GETATTR: {
-               struct oic_attr_s *attr = tmp_buf;
-
-               err = copy_from_user(attr, (int *)arg, sizeof(*attr));
-               if (err)
-                       return err;
-
-               conn.oc_id = attr->conn_id;
-               ODEBUG(&attr->obdo);
-               err = OBP(obddev, getattr)(&conn, &attr->obdo);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               err = copy_to_user((int *)arg, attr, sizeof(*attr));
-               EXIT;
-               return err;
-       }
-
-       case OBD_IOC_READ: {
-               int err;
-               struct oic_rw_s *rw_s = tmp_buf;  /* read, write ioctl str */
-
-               err = copy_from_user(rw_s, (int *)arg, sizeof(*rw_s));
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               conn.oc_id = rw_s->conn_id;
-
-               if ( !OBT(obddev) || !OBP(obddev, read) ) {
-                       err = -EOPNOTSUPP;
-                       EXIT;
-                       return err;
-               }
-
-
-               err = OBP(obddev, read)(&conn, &rw_s->obdo, rw_s->buf, 
-                                       &rw_s->count, rw_s->offset);
-               
-               ODEBUG(&rw_s->obdo);
-               CDEBUG(D_INFO, "READ: conn %d, count %Ld, offset %Ld, '%s'\n",
-                      rw_s->conn_id, rw_s->count, rw_s->offset, rw_s->buf);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-                       
-               err = copy_to_user((int*)arg, &rw_s->count, sizeof(rw_s->count));
-               EXIT;
-               return err;
-       }
-
-       case OBD_IOC_WRITE: {
-               struct oic_rw_s *rw_s = tmp_buf;  /* read, write ioctl str */
-
-               err = copy_from_user(rw_s, (int *)arg, sizeof(*rw_s));
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               conn.oc_id = rw_s->conn_id;
-
-               if ( !OBT(obddev) || !OBP(obddev, write) ) {
-                       err = -EOPNOTSUPP;
-                       return err;
-               }
-
-               CDEBUG(D_INFO, "WRITE: conn %d, count %Ld, offset %Ld, '%s'\n",
-                      rw_s->conn_id, rw_s->count, rw_s->offset, rw_s->buf);
-               err = OBP(obddev, write)(&conn, &rw_s->obdo, rw_s->buf, 
-                                        &rw_s->count, rw_s->offset);
-               ODEBUG(&rw_s->obdo);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               err = copy_to_user((int *)arg, &rw_s->count,
-                                  sizeof(rw_s->count));
-               EXIT;
-               return err;
-       }
-       case OBD_IOC_PREALLOCATE: {
-               struct oic_prealloc_s *prealloc = tmp_buf;
-
-               /* has this minor been registered? */
-               if (!obddev->obd_type)
-                       return -ENODEV;
-
-               err = copy_from_user(prealloc, (int *)arg, sizeof(*prealloc));
-               if (err) 
-                       return -EFAULT;
-
-               if ( !(obddev->obd_flags & OBD_ATTACHED) ||
-                    !(obddev->obd_flags & OBD_SET_UP)) {
-                       CDEBUG(D_IOCTL, "Device not attached or set up\n");
-                       return -ENODEV;
-               }
-
-               if ( !OBT(obddev) || !OBP(obddev, preallocate) )
-                       return -EOPNOTSUPP;
-
-               conn.oc_id = prealloc->conn_id;
-               err = OBP(obddev, preallocate)(&conn, &prealloc->alloc,
-                                              prealloc->ids);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               err =copy_to_user((int *)arg, prealloc, sizeof(*prealloc));
-               EXIT;
-               return err;
-       }
-       case OBD_IOC_STATFS: {
-               struct statfs *tmp;
-               unsigned int conn_id;
-               struct statfs buf;
-
-               /* has this minor been registered? */
-               if (!obddev->obd_type)
-                       return -ENODEV;
-
-               tmp = (void *)arg + sizeof(unsigned int);
-               get_user(conn_id, (int *) arg);
-
-               if ( !OBT(obddev) || !OBP(obddev, statfs) )
-                       return -EOPNOTSUPP;
-
-               conn.oc_id = conn_id;
-               err = OBP(obddev, statfs)(&conn, &buf);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-               err = copy_to_user(tmp, &buf, sizeof(buf));
-               EXIT;
-               return err;
-               
-       }
-       case OBD_IOC_COPY: {
-               struct ioc_mv_s *mvdata = tmp_buf;
-
-               if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
-                    (!(obddev->obd_flags & OBD_ATTACHED))) {
-                       CDEBUG(D_IOCTL, "Device not attached or set up\n");
-                       return -ENODEV;
-               }
-
-               /* get main structure */
-               err = copy_from_user(mvdata, (void *) arg, sizeof(*mvdata));
-               if (err) {
-                       EXIT;
-                       return err;
-               }
-
-               if ( !OBT(obddev) || !OBP(obddev, copy) )
-                       return -EOPNOTSUPP;
-
-               /* do the partition */
-               CDEBUG(D_INFO, "Copy %d, type %s dst %Ld src %Ld\n", dev, 
-                      obddev->obd_type->typ_name, mvdata->dst.o_id, 
-                      mvdata->src.o_id);
-
-               conn.oc_id = mvdata->src_conn_id;
-
-               err = OBP(obddev, copy)(&conn, &mvdata->dst, 
-                                       &conn, &mvdata->src, 
-                                       mvdata->src.o_size, 0);
-               return err;
-       }
-
-       case OBD_IOC_MIGR: {
-               struct ioc_mv_s *mvdata = tmp_buf;
-
-               if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
-                    (!(obddev->obd_flags & OBD_ATTACHED))) {
-                       CDEBUG(D_IOCTL, "Device not attached or set up\n");
-                       return -ENODEV;
-               }
-
-               err = copy_from_user(mvdata, (void *) arg, sizeof(*mvdata));
-               if (err) {
-                       EXIT;
-                       return err;
-               }
-
-               CDEBUG(D_INFO, "Migrate copying %d bytes\n", sizeof(*mvdata));
-
-               if ( !OBT(obddev) || !OBP(obddev, migrate) )
-                       return -EOPNOTSUPP;
-
-               /* do the partition */
-               CDEBUG(D_INFO, "Migrate %d, type %s conn %d src %Ld dst %Ld\n",
-                      dev, obddev->obd_type->typ_name, mvdata->src_conn_id,
-                      mvdata->src.o_id, mvdata->dst.o_id);
-
-               conn.oc_id = mvdata->src_conn_id;
-               err = OBP(obddev, migrate)(&conn, &mvdata->dst, &mvdata->src, 
-                                          mvdata->src.o_size, 0);
-
-               return err;
-       }
-       case OBD_IOC_PUNCH: {
-               struct oic_rw_s *rw_s = tmp_buf;  /* read, write ioctl str */
-
-               err = copy_from_user(rw_s, (int *)arg, sizeof(*rw_s));
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               conn.oc_id = rw_s->conn_id;
-
-               if ( !OBT(obddev) || !OBP(obddev, punch) ) {
-                       err = -EOPNOTSUPP;
-                       return err;
-               }
-
-               CDEBUG(D_INFO, "PUNCH: conn %d, count %Ld, offset %Ld\n",
-                      rw_s->conn_id, rw_s->count, rw_s->offset);
-               err = OBP(obddev, punch)(&conn, &rw_s->obdo, rw_s->count,
-                                        rw_s->offset);
-               ODEBUG(&rw_s->obdo);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-               EXIT;
-               return err;
-       }
-
-       default: {
-               struct obd_type *type;
-               struct oic_generic input;
-               char *nm;
-               void *karg;
-
-               /* get data structures */
-               err = copy_from_user(&input, (void *)arg, sizeof(input));
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               err = getdata(input.att_typelen + 1, &input.att_type);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               /* find the type */
-               nm = input.att_type;
-               type = obd_nm_to_type(nm);
+                OBD_FREE(input->att_type, input->att_typelen + 1);
+                if ( !type ) {
+                        printk(__FUNCTION__ ": unknown obd type dev %d\n",
+                               dev);
+                        EXIT;
+                        return -EINVAL;
+                }
+                obddev->obd_type = type;
+                
+                /* get the attach data */
+                err = getdata(input->att_datalen, &input->att_data);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                INIT_LIST_HEAD(&obddev->obd_gen_clients);
+                obddev->obd_multi_count = 0;
+
+                CDEBUG(D_IOCTL, "Attach %d, datalen %d, type %s\n", 
+                       dev, input->att_datalen, obddev->obd_type->typ_name);
+                /* maybe we are done */
+                if ( !OBT(obddev) || !OBP(obddev, attach) ) {
+                        obddev->obd_flags |= OBD_ATTACHED;
+                        type->typ_refcnt++;
+                        CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
+                               type->typ_refcnt);
+                        if (input->att_data)
+                                OBD_FREE(input->att_data, input->att_datalen);
+                        MOD_INC_USE_COUNT;
+                        EXIT;
+                        return 0;
+                }
+
+                /* do the attach */
+                err = OBP(obddev, attach)(obddev, input->att_datalen,
+                                          input->att_data);
+                if (input->att_data)
+                        OBD_FREE(input->att_data, input->att_datalen);
+
+                if ( err ) {
+                        obddev->obd_flags &= ~OBD_ATTACHED;
+                        obddev->obd_type = NULL;
+                        EXIT;
+                } else {
+                        obddev->obd_flags |=  OBD_ATTACHED;
+                        type->typ_refcnt++;
+                        CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
+                               type->typ_refcnt);
+                        MOD_INC_USE_COUNT;
+                        EXIT;
+                }
+                return err;
+        }
+
+        case OBD_IOC_DETACH: {
+
+                ENTRY;
+                if (obddev->obd_flags & OBD_SET_UP) {
+                        EXIT;
+                        return -EBUSY;
+                }
+                if (! (obddev->obd_flags & OBD_ATTACHED) ) {
+                        CDEBUG(D_IOCTL, "Device not attached\n");
+                        EXIT;
+                        return -ENODEV;
+                }
+                if ( !list_empty(&obddev->obd_gen_clients) ) {
+                        CDEBUG(D_IOCTL, "Device has connected clients\n");
+                        EXIT;
+                        return -EBUSY;
+                }
+
+                CDEBUG(D_PSDEV, "Detach %d, type %s\n", dev,
+                       obddev->obd_type->typ_name);
+                obddev->obd_flags &= ~OBD_ATTACHED;
+                obddev->obd_type->typ_refcnt--;
+                CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
+                       obddev->obd_type->typ_refcnt);
+                obddev->obd_type = NULL;
+                MOD_DEC_USE_COUNT;
+                EXIT;
+                return 0;
+        }
+
+        case OBD_IOC_SETUP: {
+                struct ioc_setup {
+                        int setup_datalen;
+                        void *setup_data;
+                } *setup;
+                setup = tmp_buf;
+
+                ENTRY;
+                /* have we attached a type to this device */
+                if (!(obddev->obd_flags & OBD_ATTACHED)) {
+                        CDEBUG(D_IOCTL, "Device not attached\n");
+                        EXIT;
+                        return -ENODEV;
+                }
+
+                /* has this been done already? */
+                if ( obddev->obd_flags & OBD_SET_UP ) {
+                        CDEBUG(D_IOCTL, "Device %d already setup (type %s)\n",
+                               dev, obddev->obd_type->typ_name);
+                        EXIT;
+                        return -EBUSY;
+                }
+
+                /* get main structure */
+                err = copy_from_user(setup, (void *) arg, sizeof(*setup));
+                if (err) {
+                        EXIT;
+                        return err;
+                }
+
+                err = getdata(setup->setup_datalen, &setup->setup_data);
+                if (err) {
+                        EXIT;
+                        return err;
+                }
+
+                /* do the setup */
+                CDEBUG(D_PSDEV, "Setup %d, type %s\n", dev, 
+                       obddev->obd_type->typ_name);
+                if ( !OBT(obddev) || !OBP(obddev, setup) ) {
+                        obddev->obd_type->typ_refcnt++;
+                        CDEBUG(D_PSDEV, "Dev %d refcount now %d\n",
+                               dev, obddev->obd_type->typ_refcnt);
+                        if (setup->setup_data)
+                                OBD_FREE(setup->setup_data,
+                                         setup->setup_datalen);
+                        obddev->obd_flags |= OBD_SET_UP;
+                        EXIT;
+                        return 0;
+                }
+
+                err = OBP(obddev, setup)(obddev, setup->setup_datalen,
+                                         setup->setup_data);
+
+                if ( err )  {
+                        obddev->obd_flags &= ~OBD_SET_UP;
+                        EXIT;
+                } else {
+                        obddev->obd_type->typ_refcnt++;
+                        CDEBUG(D_PSDEV, "Dev %d refcount now %d\n",
+                               dev, obddev->obd_type->typ_refcnt);
+                        obddev->obd_flags |= OBD_SET_UP;
+                        EXIT;
+                }
+                if (setup->setup_data)
+                        OBD_FREE(setup->setup_data, setup->setup_datalen);
+                return err;
+        }
+        case OBD_IOC_CLEANUP: {
+                ENTRY;
+                /* has this minor been registered? */
+                if (!obddev->obd_type) {
+                        CDEBUG(D_IOCTL, "OBD Device %d has no type.\n", dev);
+                        EXIT;
+                        return -ENODEV;
+                }
+
+                if ( !obddev->obd_type->typ_refcnt ) {
+                        CDEBUG(D_IOCTL, "dev %d has refcount (%d)!\n",
+                               dev, obddev->obd_type->typ_refcnt);
+                        EXIT;
+                        return -EBUSY;
+                }
+
+                if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
+                     (!(obddev->obd_flags & OBD_ATTACHED))) {
+                        CDEBUG(D_IOCTL, "device not attached or set up\n");
+                        EXIT;
+                        return -ENODEV;
+                }
+
+                if ( !OBT(obddev) || !OBP(obddev, cleanup) )
+                        goto cleanup_out;
+
+                /* cleanup has no argument */
+                err = OBP(obddev, cleanup)(obddev);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+        cleanup_out: 
+                obddev->obd_flags &= ~OBD_SET_UP;
+                obddev->obd_type->typ_refcnt--;
+                CDEBUG(D_PSDEV, "Dev %d refcount now %d\n", dev,
+                       obddev->obd_type->typ_refcnt);
+                EXIT;
+                return 0;
+        }
+        case OBD_IOC_CONNECT:
+        {
+                if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
+                     (!(obddev->obd_flags & OBD_ATTACHED))) {
+                        CDEBUG(D_IOCTL, "Device not attached or set up\n");
+                        return -ENODEV;
+                }
+
+                if ( !OBT(obddev) || !OBP(obddev, connect) )
+                        return -EOPNOTSUPP;
+                
+                err = OBP(obddev, connect)(&conn);
+                if ( err )
+                        return err;
+
+                return copy_to_user((int *)arg, &conn.oc_id,
+                                    sizeof(uint32_t));
+        }
+        case OBD_IOC_DISCONNECT:
+                /* frees data structures */
+                /* has this minor been registered? */
+                if (!obddev->obd_type)
+                        return -ENODEV;
+
+                get_user(cli_id, (int *) arg);
+                conn.oc_id = cli_id;
+
+                if ( !OBT(obddev) || !OBP(obddev, disconnect))
+                        return -EOPNOTSUPP;
+                
+                OBP(obddev, disconnect)(&conn);
+                return 0;
+
+        case OBD_IOC_SYNC: {
+                struct oic_range_s *range = tmp_buf;
+
+                if (!obddev->obd_type)
+                        return -ENODEV;
+
+                err = copy_from_user(range, (const void *)arg,  sizeof(*range));
+
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+                        
+                if ( !OBT(obddev) || !OBP(obddev, sync) ) {
+                        err = -EOPNOTSUPP;
+                        EXIT;
+                        return err;
+                }
+
+                /* XXX sync needs to be tested/verified */
+                err = OBP(obddev, sync)(&conn, &range->obdo, range->count,
+                                        range->offset);
+
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+                        
+                return put_user(err, (int *) arg);
+        }
+        case OBD_IOC_CREATE: {
+                struct oic_attr_s *attr = tmp_buf;
+
+                err = copy_from_user(attr, (const void *)arg,  sizeof(*attr));
+                if (err) {
+                        EXIT;
+                        return err;
+                }
+
+                /* has this minor been registered? */
+                if ( !(obddev->obd_flags & OBD_ATTACHED) ||
+                     !(obddev->obd_flags & OBD_SET_UP)) {
+                        CDEBUG(D_IOCTL, "Device not attached or set up\n");
+                        return -ENODEV;
+                }
+                conn.oc_id = attr->conn_id;
+
+                if ( !OBT(obddev) || !OBP(obddev, create) )
+                        return -EOPNOTSUPP;
+
+                err = OBP(obddev, create)(&conn, &attr->obdo);
+                if (err) {
+                        EXIT;
+                        return err;
+                }
+
+                err = copy_to_user((int *)arg, attr, sizeof(*attr));
+                EXIT;
+                return err;
+        }
+
+        case OBD_IOC_DESTROY: {
+                struct oic_attr_s *attr = tmp_buf;
+                
+                /* has this minor been registered? */
+                if (!obddev->obd_type)
+                        return -ENODEV;
+
+                err = copy_from_user(attr, (int *)arg, sizeof(*attr));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                if ( !OBT(obddev) || !OBP(obddev, destroy) )
+                        return -EOPNOTSUPP;
+
+                conn.oc_id = attr->conn_id;
+                err = OBP(obddev, destroy)(&conn, &attr->obdo);
+                EXIT;
+                return err;
+        }
+
+        case OBD_IOC_SETATTR: {
+                struct oic_attr_s *attr = tmp_buf;
+
+                /* has this minor been registered? */
+                if (!obddev->obd_type)
+                        return -ENODEV;
+
+                err = copy_from_user(attr, (int *)arg, sizeof(*attr));
+                if (err)
+                        return err;
+
+                if ( !OBT(obddev) || !OBP(obddev, setattr) )
+                        return -EOPNOTSUPP;
+                
+                conn.oc_id = attr->conn_id;
+                err = OBP(obddev, setattr)(&conn, &attr->obdo);
+                EXIT;
+                return err;
+        }
+
+        case OBD_IOC_GETATTR: {
+                struct oic_attr_s *attr = tmp_buf;
+
+                err = copy_from_user(attr, (int *)arg, sizeof(*attr));
+                if (err)
+                        return err;
+
+                conn.oc_id = attr->conn_id;
+                ODEBUG(&attr->obdo);
+                err = OBP(obddev, getattr)(&conn, &attr->obdo);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                err = copy_to_user((int *)arg, attr, sizeof(*attr));
+                EXIT;
+                return err;
+        }
+
+        case OBD_IOC_READ: {
+                int err;
+                struct oic_rw_s *rw_s = tmp_buf;  /* read, write ioctl str */
+
+                err = copy_from_user(rw_s, (int *)arg, sizeof(*rw_s));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                conn.oc_id = rw_s->conn_id;
+
+                if ( !OBT(obddev) || !OBP(obddev, read) ) {
+                        err = -EOPNOTSUPP;
+                        EXIT;
+                        return err;
+                }
+
+
+                err = OBP(obddev, read)(&conn, &rw_s->obdo, rw_s->buf, 
+                                        &rw_s->count, rw_s->offset);
+                
+                ODEBUG(&rw_s->obdo);
+                CDEBUG(D_INFO, "READ: conn %d, count %Ld, offset %Ld, '%s'\n",
+                       rw_s->conn_id, rw_s->count, rw_s->offset, rw_s->buf);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+                        
+                err = copy_to_user((int*)arg, &rw_s->count, sizeof(rw_s->count));
+                EXIT;
+                return err;
+        }
+
+        case OBD_IOC_WRITE: {
+                struct oic_rw_s *rw_s = tmp_buf;  /* read, write ioctl str */
+
+                err = copy_from_user(rw_s, (int *)arg, sizeof(*rw_s));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                conn.oc_id = rw_s->conn_id;
+
+                if ( !OBT(obddev) || !OBP(obddev, write) ) {
+                        err = -EOPNOTSUPP;
+                        return err;
+                }
+
+                CDEBUG(D_INFO, "WRITE: conn %d, count %Ld, offset %Ld, '%s'\n",
+                       rw_s->conn_id, rw_s->count, rw_s->offset, rw_s->buf);
+
+                err = OBP(obddev, write)(&conn, &rw_s->obdo, rw_s->buf, 
+                                         &rw_s->count, rw_s->offset);
+                ODEBUG(&rw_s->obdo);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                err = copy_to_user((int *)arg, &rw_s->count,
+                                   sizeof(rw_s->count));
+                EXIT;
+                return err;
+        }
+        case OBD_IOC_PREALLOCATE: {
+                struct oic_prealloc_s *prealloc = tmp_buf;
+
+                /* has this minor been registered? */
+                if (!obddev->obd_type)
+                        return -ENODEV;
+
+                err = copy_from_user(prealloc, (int *)arg, sizeof(*prealloc));
+                if (err) 
+                        return -EFAULT;
+
+                if ( !(obddev->obd_flags & OBD_ATTACHED) ||
+                     !(obddev->obd_flags & OBD_SET_UP)) {
+                        CDEBUG(D_IOCTL, "Device not attached or set up\n");
+                        return -ENODEV;
+                }
+
+                if ( !OBT(obddev) || !OBP(obddev, preallocate) )
+                        return -EOPNOTSUPP;
+
+                conn.oc_id = prealloc->conn_id;
+                err = OBP(obddev, preallocate)(&conn, &prealloc->alloc,
+                                               prealloc->ids);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                err =copy_to_user((int *)arg, prealloc, sizeof(*prealloc));
+                EXIT;
+                return err;
+        }
+        case OBD_IOC_STATFS: {
+                struct statfs *tmp;
+                unsigned int conn_id;
+                struct statfs buf;
+
+                /* has this minor been registered? */
+                if (!obddev->obd_type)
+                        return -ENODEV;
+
+                tmp = (void *)arg + sizeof(unsigned int);
+                get_user(conn_id, (int *) arg);
+
+                if ( !OBT(obddev) || !OBP(obddev, statfs) )
+                        return -EOPNOTSUPP;
+
+                conn.oc_id = conn_id;
+                err = OBP(obddev, statfs)(&conn, &buf);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+                err = copy_to_user(tmp, &buf, sizeof(buf));
+                EXIT;
+                return err;
+                
+        }
+        case OBD_IOC_COPY: {
+                struct ioc_mv_s *mvdata = tmp_buf;
+
+                if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
+                     (!(obddev->obd_flags & OBD_ATTACHED))) {
+                        CDEBUG(D_IOCTL, "Device not attached or set up\n");
+                        return -ENODEV;
+                }
+
+                /* get main structure */
+                err = copy_from_user(mvdata, (void *) arg, sizeof(*mvdata));
+                if (err) {
+                        EXIT;
+                        return err;
+                }
+
+                if ( !OBT(obddev) || !OBP(obddev, copy) )
+                        return -EOPNOTSUPP;
+
+                /* do the partition */
+                CDEBUG(D_INFO, "Copy %d, type %s dst %Ld src %Ld\n", dev, 
+                       obddev->obd_type->typ_name, mvdata->dst.o_id, 
+                       mvdata->src.o_id);
+
+                conn.oc_id = mvdata->src_conn_id;
+
+                err = OBP(obddev, copy)(&conn, &mvdata->dst, 
+                                        &conn, &mvdata->src, 
+                                        mvdata->src.o_size, 0);
+                return err;
+        }
+
+        case OBD_IOC_MIGR: {
+                struct ioc_mv_s *mvdata = tmp_buf;
+
+                if ( (!(obddev->obd_flags & OBD_SET_UP)) ||
+                     (!(obddev->obd_flags & OBD_ATTACHED))) {
+                        CDEBUG(D_IOCTL, "Device not attached or set up\n");
+                        return -ENODEV;
+                }
+
+                err = copy_from_user(mvdata, (void *) arg, sizeof(*mvdata));
+                if (err) {
+                        EXIT;
+                        return err;
+                }
+
+                CDEBUG(D_INFO, "Migrate copying %d bytes\n", sizeof(*mvdata));
+
+                if ( !OBT(obddev) || !OBP(obddev, migrate) )
+                        return -EOPNOTSUPP;
+
+                /* do the partition */
+                CDEBUG(D_INFO, "Migrate %d, type %s conn %d src %Ld dst %Ld\n",
+                       dev, obddev->obd_type->typ_name, mvdata->src_conn_id,
+                       mvdata->src.o_id, mvdata->dst.o_id);
+
+                conn.oc_id = mvdata->src_conn_id;
+                err = OBP(obddev, migrate)(&conn, &mvdata->dst, &mvdata->src, 
+                                           mvdata->src.o_size, 0);
+
+                return err;
+        }
+        case OBD_IOC_PUNCH: {
+                struct oic_rw_s *rw_s = tmp_buf;  /* read, write ioctl str */
+
+                err = copy_from_user(rw_s, (int *)arg, sizeof(*rw_s));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                conn.oc_id = rw_s->conn_id;
+
+                if ( !OBT(obddev) || !OBP(obddev, punch) ) {
+                        err = -EOPNOTSUPP;
+                        return err;
+                }
+
+                CDEBUG(D_INFO, "PUNCH: conn %d, count %Ld, offset %Ld\n",
+                       rw_s->conn_id, rw_s->count, rw_s->offset);
+                err = OBP(obddev, punch)(&conn, &rw_s->obdo, rw_s->count,
+                                         rw_s->offset);
+                ODEBUG(&rw_s->obdo);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+                EXIT;
+                return err;
+        }
+
+        default: {
+                struct obd_type *type;
+                struct oic_generic input;
+                char *nm;
+                void *karg;
+
+                /* get data structures */
+                err = copy_from_user(&input, (void *)arg, sizeof(input));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                err = getdata(input.att_typelen + 1, &input.att_type);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                /* find the type */
+                nm = input.att_type;
+                type = obd_nm_to_type(nm);
 #ifdef CONFIG_KMOD
-               if ( !type ) {
-                       if ( !request_module(nm) ) {
-                               CDEBUG(D_PSDEV, "Loaded module '%s'\n", nm);
-                               type = obd_nm_to_type(nm);
-                       } else {
-                               CDEBUG(D_PSDEV, "Can't load module '%s'\n", nm);
-                       }
-               }
+                if ( !type ) {
+                        if ( !request_module(nm) ) {
+                                CDEBUG(D_PSDEV, "Loaded module '%s'\n", nm);
+                                type = obd_nm_to_type(nm);
+                        } else {
+                                CDEBUG(D_PSDEV, "Can't load module '%s'\n", nm);
+                        }
+                }
 #endif
-               OBD_FREE(input.att_type, input.att_typelen + 1);
-               if ( !type ) {
-                       printk(__FUNCTION__ ": unknown obd type dev %d\n", dev);
-                       EXIT;
-                       return -EINVAL;
-               }
-               
-               if ( !type->typ_ops || !type->typ_ops->o_iocontrol ) {
-                       EXIT;
-                       return -EOPNOTSUPP;
-               }
-               conn.oc_id = input.att_connid;
-               
-               CDEBUG(D_INFO, "Calling ioctl %x for type %s, len %d\n",
-                      cmd, type->typ_name, input.att_datalen);
-
-               /* get the generic data */
-               karg = input.att_data;
-               err = getdata(input.att_datalen, &karg);
-               if ( err ) {
-                       EXIT;
-                       return err;
-               }
-
-               err = type->typ_ops->o_iocontrol(cmd, &conn, input.att_datalen, 
-                                                karg, input.att_data);
-               OBD_FREE(karg, input.att_datalen);
-
-               EXIT;
-               return err;
-       }
-       }
+                OBD_FREE(input.att_type, input.att_typelen + 1);
+                if ( !type ) {
+                        printk(__FUNCTION__ ": unknown obd type dev %d\n", dev);
+                        EXIT;
+                        return -EINVAL;
+                }
+                
+                if ( !type->typ_ops || !type->typ_ops->o_iocontrol ) {
+                        EXIT;
+                        return -EOPNOTSUPP;
+                }
+                conn.oc_id = input.att_connid;
+                
+                CDEBUG(D_INFO, "Calling ioctl %x for type %s, len %d\n",
+                       cmd, type->typ_name, input.att_datalen);
+
+                /* get the generic data */
+                karg = input.att_data;
+                err = getdata(input.att_datalen, &karg);
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                err = type->typ_ops->o_iocontrol(cmd, &conn, input.att_datalen, 
+                                                 karg, input.att_data);
+                OBD_FREE(karg, input.att_datalen);
+
+                EXIT;
+                return err;
+        }
+        }
 } /* obd_class_ioctl */
 
 /* Driver interface done, utility functions follow */
 
 int obd_register_type(struct obd_ops *ops, char *nm)
 {
-       struct obd_type *type;
-
-
-       if (obd_init_magic != 0x11223344) {
-               printk(__FUNCTION__ ": bad magic for type\n");
-               EXIT;
-               return -EINVAL;
-       }
-
-       if  ( obd_nm_to_type(nm) ) {
-               CDEBUG(D_IOCTL, "Type %s already registered\n", nm);
-               EXIT;
-               return -EEXIST;
-       }
-       
-       OBD_ALLOC(type, struct obd_type * , sizeof(*type));
-       if ( !type ) {
-               EXIT;
-               return -ENOMEM;
-       }
-       memset(type, 0, sizeof(*type));
-       INIT_LIST_HEAD(&type->typ_chain);
-       MOD_INC_USE_COUNT;
-       list_add(&type->typ_chain, obd_types.next);
-       type->typ_ops = ops;
-       type->typ_name = nm;
-       EXIT;
-       return 0;
+        struct obd_type *type;
+
+
+        if (obd_init_magic != 0x11223344) {
+                printk(__FUNCTION__ ": bad magic for type\n");
+                EXIT;
+                return -EINVAL;
+        }
+
+        if  ( obd_nm_to_type(nm) ) {
+                CDEBUG(D_IOCTL, "Type %s already registered\n", nm);
+                EXIT;
+                return -EEXIST;
+        }
+        
+        OBD_ALLOC(type, struct obd_type * , sizeof(*type));
+        if ( !type ) {
+                EXIT;
+                return -ENOMEM;
+        }
+        memset(type, 0, sizeof(*type));
+        INIT_LIST_HEAD(&type->typ_chain);
+        MOD_INC_USE_COUNT;
+        list_add(&type->typ_chain, obd_types.next);
+        type->typ_ops = ops;
+        type->typ_name = nm;
+        EXIT;
+        return 0;
 }
-       
+        
 int obd_unregister_type(char *nm)
 {
-       struct obd_type *type = obd_nm_to_type(nm);
-
-       if ( !type ) {
-               MOD_DEC_USE_COUNT;
-               printk(KERN_INFO __FUNCTION__ ": unknown obd type\n");
-               EXIT;
-               return -EINVAL;
-       }
-
-       if ( type->typ_refcnt ) {
-               MOD_DEC_USE_COUNT;
-               printk(KERN_ALERT __FUNCTION__ ":type %s has refcount "
-                      "(%d)\n", nm, type->typ_refcnt);
-               EXIT;
-               return -EBUSY;
-       }
-
-       list_del(&type->typ_chain);
-       OBD_FREE(type, sizeof(*type));
-       MOD_DEC_USE_COUNT;
-       return 0;
+        struct obd_type *type = obd_nm_to_type(nm);
+
+        if ( !type ) {
+                MOD_DEC_USE_COUNT;
+                printk(KERN_INFO __FUNCTION__ ": unknown obd type\n");
+                EXIT;
+                return -EINVAL;
+        }
+
+        if ( type->typ_refcnt ) {
+                MOD_DEC_USE_COUNT;
+                printk(KERN_ALERT __FUNCTION__ ":type %s has refcount "
+                       "(%d)\n", nm, type->typ_refcnt);
+                EXIT;
+                return -EBUSY;
+        }
+
+        list_del(&type->typ_chain);
+        OBD_FREE(type, sizeof(*type));
+        MOD_DEC_USE_COUNT;
+        return 0;
 } /* obd_unregister_type */
 
 /* declare character device */
 static struct file_operations obd_psdev_fops = {
-       NULL,                  /* llseek */
-       NULL,                  /* read */
-       NULL,                  /* write */
-       NULL,                  /* presto_psdev_readdir */
-        NULL,                  /* poll */
-       obd_class_ioctl,       /* ioctl */
-       NULL,                  /* presto_psdev_mmap */
-       obd_class_open,        /* open */
-       NULL,
-       obd_class_release,     /* release */
-       NULL,                  /* fsync */
-       NULL,                  /* fasync */
-       NULL                   /* lock */
+        ioctl: obd_class_ioctl,       /* ioctl */
+        open: obd_class_open,        /* open */
+        release: obd_class_release,     /* release */
 };
 
 
@@ -936,32 +927,32 @@ static struct file_operations obd_psdev_fops = {
 
 int init_obd(void)
 {
-       int err;
-       int i;
-
-       printk(KERN_INFO "OBD class driver  v0.01, braam@stelias.com\n");
-       
-       INIT_LIST_HEAD(&obd_types);
-       
-       if (register_chrdev(OBD_PSDEV_MAJOR,"obd_psdev", 
-                           &obd_psdev_fops)) {
-               printk(KERN_ERR __FUNCTION__ ": unable to get major %d\n", 
-                      OBD_PSDEV_MAJOR);
-               return -EIO;
-       }
-
-       for (i = 0; i < MAX_OBD_DEVICES; i++) {
-               memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
-               obd_dev[i].obd_minor = i;
-               INIT_LIST_HEAD(&obd_dev[i].obd_gen_clients);
-       }
-
-       err = obd_init_obdo_cache();
-       if (err)
-               return err;
-       obd_sysctl_init();
-       obd_init_magic = 0x11223344;
-       return 0;
+        int err;
+        int i;
+
+        printk(KERN_INFO "OBD class driver  v0.01, braam@stelias.com\n");
+        
+        INIT_LIST_HEAD(&obd_types);
+        
+        if (register_chrdev(OBD_PSDEV_MAJOR,"obd_psdev", 
+                            &obd_psdev_fops)) {
+                printk(KERN_ERR __FUNCTION__ ": unable to get major %d\n", 
+                       OBD_PSDEV_MAJOR);
+                return -EIO;
+        }
+
+        for (i = 0; i < MAX_OBD_DEVICES; i++) {
+                memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
+                obd_dev[i].obd_minor = i;
+                INIT_LIST_HEAD(&obd_dev[i].obd_gen_clients);
+        }
+
+        err = obd_init_obdo_cache();
+        if (err)
+                return err;
+        obd_sysctl_init();
+        obd_init_magic = 0x11223344;
+        return 0;
 }
 
 EXPORT_SYMBOL(obd_register_type);
@@ -986,29 +977,29 @@ EXPORT_SYMBOL(gen_multi_cleanup);
 #ifdef MODULE
 int init_module(void)
 {
-       return init_obd();
+        return init_obd();
 }
 
 void cleanup_module(void)
 {
-       int i;
+        int i;
         ENTRY;
 
         unregister_chrdev(OBD_PSDEV_MAJOR, "obd_psdev");
-       for (i = 0; i < MAX_OBD_DEVICES; i++) {
-               struct obd_device *obddev = &obd_dev[i];
-               if ( obddev->obd_type && 
-                    (obddev->obd_flags & OBD_SET_UP) &&
-                    OBT(obddev) && OBP(obddev, detach) ) {
-                       /* XXX should this call generic detach otherwise? */
-                       OBP(obddev, detach)(obddev);
-               } 
-       }
-
-       obd_cleanup_obdo_cache();
-       obd_sysctl_clean();
-       CDEBUG(D_MALLOC, "CLASS mem used %ld\n", obd_memory);
-       obd_init_magic = 0;
-       EXIT;
+        for (i = 0; i < MAX_OBD_DEVICES; i++) {
+                struct obd_device *obddev = &obd_dev[i];
+                if ( obddev->obd_type && 
+                     (obddev->obd_flags & OBD_SET_UP) &&
+                     OBT(obddev) && OBP(obddev, detach) ) {
+                        /* XXX should this call generic detach otherwise? */
+                        OBP(obddev, detach)(obddev);
+                
+        }
+
+        obd_cleanup_obdo_cache();
+        obd_sysctl_clean();
+        CDEBUG(D_MALLOC, "CLASS mem used %ld\n", obd_memory);
+        obd_init_magic = 0;
+        EXIT;
 }
 #endif
index c4f1533..f73dc27 100644 (file)
@@ -6,26 +6,11 @@
  *
  */
 
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
-#include <linux/locks.h>
-#include <linux/unistd.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
 
+#include <linux/mm.h>
 #include <linux/fs.h>
-#include <linux/stat.h>
+#include <linux/sched.h>
 #include <asm/uaccess.h>
-#include <linux/vmalloc.h>
-#include <asm/segment.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
@@ -36,106 +21,106 @@ kmem_cache_t *obdo_cachep = NULL;
 
 int obd_init_obdo_cache(void)
 {
-       ENTRY;
-       if (obdo_cachep == NULL) {
-               CDEBUG(D_CACHE, "allocating obdo_cache\n");
-               obdo_cachep = kmem_cache_create("obdo_cache",
-                                               sizeof(struct obdo),
-                                               0, SLAB_HWCACHE_ALIGN,
-                                               NULL, NULL);
-               if (obdo_cachep == NULL) {
-                       EXIT;
-                       return -ENOMEM;
-               } else {
-                       CDEBUG(D_CACHE, "allocated cache at %p\n", obdo_cachep);
-               }
-       } else {
-               CDEBUG(D_CACHE, "using existing cache at %p\n", obdo_cachep);
-       }
-       EXIT;
-       return 0;
+        ENTRY;
+        if (obdo_cachep == NULL) {
+                CDEBUG(D_CACHE, "allocating obdo_cache\n");
+                obdo_cachep = kmem_cache_create("obdo_cache",
+                                                sizeof(struct obdo),
+                                                0, SLAB_HWCACHE_ALIGN,
+                                                NULL, NULL);
+                if (obdo_cachep == NULL) {
+                        EXIT;
+                        return -ENOMEM;
+                } else {
+                        CDEBUG(D_CACHE, "allocated cache at %p\n", obdo_cachep);
+                }
+        } else {
+                CDEBUG(D_CACHE, "using existing cache at %p\n", obdo_cachep);
+        }
+        EXIT;
+        return 0;
 }
 
 void obd_cleanup_obdo_cache(void)
 {
-       ENTRY;
-       if (obdo_cachep != NULL) {
-               CDEBUG(D_CACHE, "destroying obdo_cache at %p\n", obdo_cachep);
-               if (kmem_cache_destroy(obdo_cachep))
-                       printk(KERN_WARNING __FUNCTION__
-                              ": unable to free cache\n");
-       } else
-               printk(KERN_INFO __FUNCTION__
-                      ": called with NULL cache pointer\n");
-
-       obdo_cachep = NULL;
-       EXIT;
+        ENTRY;
+        if (obdo_cachep != NULL) {
+                CDEBUG(D_CACHE, "destroying obdo_cache at %p\n", obdo_cachep);
+                if (kmem_cache_destroy(obdo_cachep))
+                        printk(KERN_WARNING __FUNCTION__
+                               ": unable to free cache\n");
+        } else
+                printk(KERN_INFO __FUNCTION__
+                       ": called with NULL cache pointer\n");
+
+        obdo_cachep = NULL;
+        EXIT;
 }
 
 
 /* map connection to client */
 struct obd_client *gen_client(struct obd_conn *conn)
 {
-       struct obd_device * obddev = conn->oc_dev;
-       struct list_head * lh, * next;
-       struct obd_client * cli;
-
-       lh = next = &obddev->obd_gen_clients;
-       while ((lh = lh->next) != &obddev->obd_gen_clients) {
-               cli = list_entry(lh, struct obd_client, cli_chain);
-               
-               if (cli->cli_id == conn->oc_id)
-                       return cli;
-       }
-
-       return NULL;
+        struct obd_device * obddev = conn->oc_dev;
+        struct list_head * lh, * next;
+        struct obd_client * cli;
+
+        lh = next = &obddev->obd_gen_clients;
+        while ((lh = lh->next) != &obddev->obd_gen_clients) {
+                cli = list_entry(lh, struct obd_client, cli_chain);
+                
+                if (cli->cli_id == conn->oc_id)
+                        return cli;
+        }
+
+        return NULL;
 } /* obd_client */
 
 
 /* a connection defines a context in which preallocation can be managed. */ 
 int gen_connect (struct obd_conn *conn)
 {
-       struct obd_client * cli;
-
-       OBD_ALLOC(cli, struct obd_client *, sizeof(struct obd_client));
-       if ( !cli ) {
-               printk(__FUNCTION__ ": no memory! (minor %d)\n", 
-                      conn->oc_dev->obd_minor);
-               return -ENOMEM;
-       }
-
-       INIT_LIST_HEAD(&cli->cli_prealloc_inodes);
-       /* XXX this should probably spinlocked? */
-       cli->cli_id = ++conn->oc_dev->obd_gen_last_id;
-       cli->cli_prealloc_quota = 0;
-       cli->cli_obd = conn->oc_dev;
-       list_add(&(cli->cli_chain), conn->oc_dev->obd_gen_clients.prev);
-
-       CDEBUG(D_INFO, "connect: new ID %u\n", cli->cli_id);
-       conn->oc_id = cli->cli_id;
-       return 0;
+        struct obd_client * cli;
+
+        OBD_ALLOC(cli, struct obd_client *, sizeof(struct obd_client));
+        if ( !cli ) {
+                printk(__FUNCTION__ ": no memory! (minor %d)\n", 
+                       conn->oc_dev->obd_minor);
+                return -ENOMEM;
+        }
+
+        INIT_LIST_HEAD(&cli->cli_prealloc_inodes);
+        /* XXX this should probably spinlocked? */
+        cli->cli_id = ++conn->oc_dev->obd_gen_last_id;
+        cli->cli_prealloc_quota = 0;
+        cli->cli_obd = conn->oc_dev;
+        list_add(&(cli->cli_chain), conn->oc_dev->obd_gen_clients.prev);
+
+        CDEBUG(D_INFO, "connect: new ID %u\n", cli->cli_id);
+        conn->oc_id = cli->cli_id;
+        return 0;
 } /* gen_obd_connect */
 
 
 int gen_disconnect(struct obd_conn *conn)
 {
-       struct obd_client * cli;
-       ENTRY;
+        struct obd_client * cli;
+        ENTRY;
 
-       if (!(cli = gen_client(conn))) {
-               CDEBUG(D_IOCTL, "disconnect: attempting to free "
-                      "nonexistent client %u\n", conn->oc_id);
-               return -EINVAL;
-       }
+        if (!(cli = gen_client(conn))) {
+                CDEBUG(D_IOCTL, "disconnect: attempting to free "
+                       "nonexistent client %u\n", conn->oc_id);
+                return -EINVAL;
+        }
 
 
-       list_del(&(cli->cli_chain));
-       OBD_FREE(cli, sizeof(struct obd_client));
+        list_del(&(cli->cli_chain));
+        OBD_FREE(cli, sizeof(struct obd_client));
 
-       CDEBUG(D_INFO, "disconnect: ID %u\n", conn->oc_id);
+        CDEBUG(D_INFO, "disconnect: ID %u\n", conn->oc_id);
 
-       EXIT;
-       return 0;
+        EXIT;
+        return 0;
 } /* gen_obd_disconnect */
 
 
@@ -146,43 +131,43 @@ int gen_disconnect(struct obd_conn *conn)
  */ 
 int gen_multi_setup(struct obd_device *obddev, uint32_t len, void *data)
 {
-       int i;
-
-       for (i = 0 ; i < obddev->obd_multi_count ; i++ ) {
-               int rc;
-               struct obd_conn *ch_conn = &obddev->obd_multi_conn[i];
-               rc  = OBP(ch_conn->oc_dev, connect)(ch_conn);
-
-               if ( rc != 0 ) {
-                       int j;
-
-                       for (j = --i; j >= 0; --j) {
-                               ch_conn = &obddev->obd_multi_conn[i];
-                               OBP(ch_conn->oc_dev, disconnect)(ch_conn);
-                       }
-                       return -EINVAL;
-               }
-       }               
-       return 0;
+        int i;
+
+        for (i = 0 ; i < obddev->obd_multi_count ; i++ ) {
+                int rc;
+                struct obd_conn *ch_conn = &obddev->obd_multi_conn[i];
+                rc  = OBP(ch_conn->oc_dev, connect)(ch_conn);
+
+                if ( rc != 0 ) {
+                        int j;
+
+                        for (j = --i; j >= 0; --j) {
+                                ch_conn = &obddev->obd_multi_conn[i];
+                                OBP(ch_conn->oc_dev, disconnect)(ch_conn);
+                        }
+                        return -EINVAL;
+                }
+        }               
+        return 0;
 }
 
 
 #if 0
 int gen_multi_attach(struct obd_device *obddev, int len, void *data)
 {
-       int i;
-       int count;
-       struct obd_device *rdev = obddev->obd_multi_dev[0];
-
-       count = len/sizeof(int);
-       obddev->obd_multi_count = count;
-       for (i=0 ; i<count ; i++) {
-               rdev = &obd_dev[*((int *)data + i)];
-               rdev = rdev + 1;
-               CDEBUG(D_INFO, "OBD RAID1: replicator %d is of type %s\n", i,
-                      (rdev + i)->obd_type->typ_name);
-       }
-       return 0;
+        int i;
+        int count;
+        struct obd_device *rdev = obddev->obd_multi_dev[0];
+
+        count = len/sizeof(int);
+        obddev->obd_multi_count = count;
+        for (i=0 ; i<count ; i++) {
+                rdev = &obd_dev[*((int *)data + i)];
+                rdev = rdev + 1;
+                CDEBUG(D_INFO, "OBD RAID1: replicator %d is of type %s\n", i,
+                       (rdev + i)->obd_type->typ_name);
+        }
+        return 0;
 }
 #endif
 
@@ -194,20 +179,20 @@ int gen_multi_attach(struct obd_device *obddev, int len, void *data)
  */
 int gen_multi_cleanup(struct obd_device *obddev)
 {
-       int i;
-
-       for (i = 0 ; i < obddev->obd_multi_count ; i++ ) {
-               struct obd_conn *ch_conn = &obddev->obd_multi_conn[i];
-               int rc;
-               rc  = OBP(ch_conn->oc_dev, disconnect)(ch_conn);
-
-               if ( rc != 0 ) {
-                       printk(KERN_WARNING __FUNCTION__
-                              ": disconnect failure %d\n",
-                              ch_conn->oc_dev->obd_minor);
-               }
-       }               
-       return 0;
+        int i;
+
+        for (i = 0 ; i < obddev->obd_multi_count ; i++ ) {
+                struct obd_conn *ch_conn = &obddev->obd_multi_conn[i];
+                int rc;
+                rc  = OBP(ch_conn->oc_dev, disconnect)(ch_conn);
+
+                if ( rc != 0 ) {
+                        printk(KERN_WARNING __FUNCTION__
+                               ": disconnect failure %d\n",
+                               ch_conn->oc_dev->obd_minor);
+                }
+        }               
+        return 0;
 } /* gen_multi_cleanup_device */
 
 
@@ -218,18 +203,18 @@ int gen_multi_cleanup(struct obd_device *obddev)
  */
 int gen_cleanup(struct obd_device * obddev)
 {
-       struct list_head * lh, * tmp;
-       struct obd_client * cli;
-
-       ENTRY;
-
-       lh = tmp = &obddev->obd_gen_clients;
-       while ((tmp = tmp->next) != lh) {
-               cli = list_entry(tmp, struct obd_client, cli_chain);
-               CDEBUG(D_INFO, "Disconnecting obd_connection %d, at %p\n",
-                      cli->cli_id, cli);
-       }
-       return 0;
+        struct list_head * lh, * tmp;
+        struct obd_client * cli;
+
+        ENTRY;
+
+        lh = tmp = &obddev->obd_gen_clients;
+        while ((tmp = tmp->next) != lh) {
+                cli = list_entry(tmp, struct obd_client, cli_chain);
+                CDEBUG(D_INFO, "Disconnecting obd_connection %d, at %p\n",
+                       cli->cli_id, cli);
+        }
+        return 0;
 } /* sim_cleanup_device */
 
 void ___wait_on_page(struct page *page)
@@ -256,69 +241,69 @@ void lck_page(struct page *page)
 }
 
 int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
-                 struct obd_conn *src_conn, struct obdo *src,
-                 obd_size count, obd_off offset)
+                  struct obd_conn *src_conn, struct obdo *src,
+                  obd_size count, obd_off offset)
 {
-       struct page *page;
-       unsigned long index = 0;
-       int err = 0;
-
-       ENTRY;
-       CDEBUG(D_INFO, "src: ino %Ld blocks %Ld, size %Ld, dst: ino %Ld\n", 
-              src->o_id, src->o_blocks, src->o_size, dst->o_id);
-       page = alloc_page(GFP_USER);
-       if ( !page ) {
-               EXIT;
-               return -ENOMEM;
-       }
-       
-       lck_page(page);
-       
-       /* XXX with brw vector I/O, we could batch up reads and writes here,
-        *     all we need to do is allocate multiple pages to handle the I/Os
-        *     and arrays to handle the request parameters.
-        */
-       while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
-               obd_count        num_oa = 1;
-               obd_count        num_buf = 1;
-               char            *buf;
-               obd_size         brw_count = PAGE_SIZE;
-               obd_off          brw_offset = (page->index) << PAGE_SHIFT;
-               obd_flag         flagr = 0;
-               obd_flag         flagw = OBD_BRW_CREATE;
-               
-               page->index = index;
-               buf = (char *)page_address(page); 
-               err = OBP(src_conn->oc_dev, brw)(READ, src_conn, num_oa, &src,
-                                                &num_buf, &buf, &brw_count,
-                                                &brw_offset, &flagr);
-
-               if ( err ) {
-                       EXIT;
-                       break;
-               }
-               CDEBUG(D_INFO, "Read page %ld ...\n", page->index);
-
-               err = OBP(dst_conn->oc_dev, brw)(WRITE, dst_conn, num_oa, &dst,
-                                                &num_buf, &buf, &brw_count,
-                                                &brw_offset, &flagw);
-
-               /* XXX should handle dst->o_size, dst->o_blocks here */
-               if ( err ) {
-                       EXIT;
-                       break;
-               }
-
-               CDEBUG(D_INFO, "Wrote page %ld ...\n", page->index);
-               
-               index++;
-       }
-       dst->o_size = src->o_size;
-       dst->o_blocks = src->o_blocks;
-       dst->o_valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS);
-       UnlockPage(page);
-       __free_page(page);
-
-       EXIT;
-       return err;
+        struct page *page;
+        unsigned long index = 0;
+        int err = 0;
+
+        ENTRY;
+        CDEBUG(D_INFO, "src: ino %Ld blocks %Ld, size %Ld, dst: ino %Ld\n", 
+               src->o_id, src->o_blocks, src->o_size, dst->o_id);
+        page = alloc_page(GFP_USER);
+        if ( !page ) {
+                EXIT;
+                return -ENOMEM;
+        }
+        
+        lck_page(page);
+        
+        /* XXX with brw vector I/O, we could batch up reads and writes here,
+         *     all we need to do is allocate multiple pages to handle the I/Os
+         *     and arrays to handle the request parameters.
+         */
+        while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
+                obd_count        num_oa = 1;
+                obd_count        num_buf = 1;
+                char            *buf;
+                obd_size         brw_count = PAGE_SIZE;
+                obd_off          brw_offset = (page->index) << PAGE_SHIFT;
+                obd_flag         flagr = 0;
+                obd_flag         flagw = OBD_BRW_CREATE;
+                
+                page->index = index;
+                buf = (char *)page_address(page); 
+                err = OBP(src_conn->oc_dev, brw)(READ, src_conn, num_oa, &src,
+                                                 &num_buf, &buf, &brw_count,
+                                                 &brw_offset, &flagr);
+
+                if ( err ) {
+                        EXIT;
+                        break;
+                }
+                CDEBUG(D_INFO, "Read page %ld ...\n", page->index);
+
+                err = OBP(dst_conn->oc_dev, brw)(WRITE, dst_conn, num_oa, &dst,
+                                                 &num_buf, &buf, &brw_count,
+                                                 &brw_offset, &flagw);
+
+                /* XXX should handle dst->o_size, dst->o_blocks here */
+                if ( err ) {
+                        EXIT;
+                        break;
+                }
+
+                CDEBUG(D_INFO, "Wrote page %ld ...\n", page->index);
+                
+                index++;
+        }
+        dst->o_size = src->o_size;
+        dst->o_blocks = src->o_blocks;
+        dst->o_valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS);
+        UnlockPage(page);
+        __free_page(page);
+
+        EXIT;
+        return err;
 }
index 080dc1b..5feaccf 100644 (file)
@@ -1,3 +1,5 @@
+#include <linux/autoconf.h>
+#include <linux/sysctl.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
@@ -19,16 +21,16 @@ static int vars[2];
 static int index = 0;
 
 static int obd_sctl_vars( ctl_table * table, int write, struct file *
-                         filp, void * buffer, size_t * lenp );
+                          filp, void * buffer, size_t * lenp );
 static int obd_sctl_reset( ctl_table * table, int write, struct file
-                          * filp, void * buffer, size_t * lenp );
+                           * filp, void * buffer, size_t * lenp );
 
 
 
-#define OBD_SYSCTL 1
+#define OBD_SYSCTL 300
 
-#define OBD_DEBUG          1       /* control debugging */
-#define OBD_ENTRY          2       /* control enter/leave pattern */
+#define OBD_DEBUG           1       /* control debugging */
+#define OBD_ENTRY           2       /* control enter/leave pattern */
 #define OBD_TIMEOUT         3       /* timeout on upcalls to become intrble */
 #define OBD_HARD            4       /* mount type "hard" or "soft" */
 #define OBD_VARS            5       
@@ -38,69 +40,67 @@ static int obd_sctl_reset( ctl_table * table, int write, struct file
 #define OBD_VARS_SLOT       2
 
 static ctl_table obd_table[] = {
-       {OBD_DEBUG, "debug", &obd_debug_level, sizeof(int), 0644, NULL, &proc_dointvec},
-       {OBD_ENTRY, "trace", &obd_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
-       {OBD_VARS, "vars", &vars[0], sizeof(int), 0644, NULL, &proc_dointvec},
-       {OBD_INDEX, "index", &index, sizeof(int), 0644, NULL, &obd_sctl_vars},
-       {OBD_RESET, "reset", NULL, 0, 0644, NULL, &obd_sctl_reset},
-       { 0 }
+        {OBD_DEBUG, "debug", &obd_debug_level, sizeof(int), 0644, NULL, &proc_dointvec},
+        {OBD_ENTRY, "trace", &obd_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
+        {OBD_VARS, "vars", &vars[0], sizeof(int), 0644, NULL, &proc_dointvec},
+        {OBD_INDEX, "index", &index, sizeof(int), 0644, NULL, &obd_sctl_vars},
+        {OBD_RESET, "reset", NULL, 0, 0644, NULL, &obd_sctl_reset},
+        { 0 }
 };
 
-#if 0
-static ctl_table jukebox_table[] = {
+static ctl_table parent_table[] = {
        {OBD_SYSCTL, "obd",    NULL, 0, 0555, obd_table},
        {0}
 };
 
-#endif
 void obd_sysctl_init (void)
 {
 #ifdef CONFIG_SYSCTL
-       if ( !obd_table_header )
-               obd_table_header = register_sysctl_table(jukebox_table, 0); 
+        if ( !obd_table_header )
+                obd_table_header = register_sysctl_table(parent_table, 0); 
 #endif
 }
 
 void obd_sysctl_clean (void)
 {
 #ifdef CONFIG_SYSCTL
-       if ( obd_table_header )
-               unregister_sysctl_table(obd_table_header);
-       obd_table_header = NULL;
+        if ( obd_table_header )
+                unregister_sysctl_table(obd_table_header);
+        obd_table_header = NULL;
 #endif
 }
 
 int obd_sctl_reset (ctl_table * table, int write, 
-                   struct file * filp, void * buffer, 
-                   size_t * lenp)
+                    struct file * filp, void * buffer, 
+                    size_t * lenp)
 {
-       if ( write ) {
-               /* do something here */
-               vars[0]=0;
-               vars[1]=0;
-       }
-
-       *lenp = 0;
-       return 0;
+        if ( write ) {
+                /* do something here */
+                vars[0]=0;
+                vars[1]=0;
+        }
+
+        *lenp = 0;
+        return 0;
 }
 
 int obd_sctl_vars (ctl_table * table, int write, 
-                  struct file * filp, void * buffer, 
-                  size_t * lenp)
+                   struct file * filp, void * buffer, 
+                   size_t * lenp)
 {
-       int rc;
+        int rc;
 
-       rc = proc_dointvec(table, write, filp, buffer, lenp);
+        rc = proc_dointvec(table, write, filp, buffer, lenp);
 
-       if ( rc ) 
-               return rc;
+        if ( rc ) 
+                return rc;
 
-       if ( index < 0 || index > 1 ) {
-               printk(KERN_WARNING __FUNCTION__ "Illegal index %d!\n", index);
-               index = 0;
-       } else {
-               obd_table[OBD_VARS_SLOT].data = &vars[index];
-       }
+        if ( index < 0 || index > 1 ) {
+                printk(KERN_WARNING __FUNCTION__ "Illegal index %d!\n", index);
+                index = 0;
+        } else {
+                obd_table[OBD_VARS_SLOT].data = &vars[index];
+        }
 
-       return rc; 
+        return rc; 
 }
index 588c7f8..b56cc8a 100644 (file)
 #define nr_free_buffer_pages() 32768
 
 struct {
-       int nfract;  /* Percentage of buffer cache dirty to 
-                       activate bdflush */
-       int ndirty;  /* Maximum number of dirty blocks to write out per
-                       wake-cycle */
-       int nrefill; /* Number of clean buffers to try to obtain
-                               each time we call refill */
-       int nref_dirt; /* Dirty buffer threshold for activating bdflush
-                         when trying to refill buffers. */
-       int interval; /* jiffies delay between pupdate flushes */
-       int age_buffer;  /* Time for normal buffer to age before we flush it */
-       int age_super;  /* Time for superblock to age before we flush it */
+        int nfract;  /* Percentage of buffer cache dirty to 
+                        activate bdflush */
+        int ndirty;  /* Maximum number of dirty blocks to write out per
+                        wake-cycle */
+        int nrefill; /* Number of clean buffers to try to obtain
+                                each time we call refill */
+        int nref_dirt; /* Dirty buffer threshold for activating bdflush
+                          when trying to refill buffers. */
+        int interval; /* jiffies delay between pupdate flushes */
+        int age_buffer;  /* Time for normal buffer to age before we flush it */
+        int age_super;  /* Time for superblock to age before we flush it */
 } pupd_prm = {40, 1024, 64, 256, 1*HZ, 30*HZ, 5*HZ };
 
 /* Called with the superblock list lock held */
 static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
-                              int nr_slots, struct page **pages, char **bufs,
-                              obd_size *counts, obd_off *offsets,
-                              obd_flag *flag, unsigned long check_time)
+                               int nr_slots, struct page **pages, char **bufs,
+                               obd_size *counts, obd_off *offsets,
+                               obd_flag *flag, unsigned long check_time)
 {
-       struct list_head *page_list = obdfs_iplist(inode);
-       struct list_head *tmp;
-       int num = 0;
-
-       ENTRY;
-
-       tmp = page_list;
-       /* Traverse list in reverse order, so we do FIFO, not LIFO order */
-       while ( (tmp = tmp->prev) != page_list && num < nr_slots ) {
-               struct obdfs_pgrq *req;
-               struct page *page;
-               
-               req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
-               page = req->rq_page;
-
-               
-               if (req->rq_jiffies > check_time)
-                       break;          /* pages are in chronological order */
-
-               /* Only allocate the obdo if we will actually do I/O here */
-               if ( !*obdo ) {
-                       OIDEBUG(inode);
-                       *obdo = obdo_fromid(IID(inode), inode->i_ino,
-                                           OBD_MD_FLNOTOBD);
-                       if ( IS_ERR(*obdo) ) {
-                               int err = PTR_ERR(*obdo);
-                               *obdo = NULL;
-
-                               EXIT;
-                               return err;
-                       }
-
-                       /* FIXME revisit fromid & from_inode */
-                       obdfs_from_inode(*obdo, inode);
-                       *flag = OBD_BRW_CREATE;
-               }
-
-               /* Remove request from list before write to avoid conflict.
-                * Note that obdfs_pgrq_del() also deletes the request.
-                */
-               obdfs_pgrq_del(req);
-               if ( !page ) {
-                       CDEBUG(D_CACHE, "no page \n");
-                       continue;
-               }
-
-               bufs[num] = (char *)page_address(page);
-               pages[num] = page;
-               counts[num] = PAGE_SIZE;
-               offsets[num] = ((obd_off)page->index) << PAGE_SHIFT;
-               CDEBUG(D_INFO, "ENQ inode %ld, page %p addr %p to vector\n", 
-                      inode->i_ino, page, (char *)page_address(page));
-               num++;
-       }
-
-       if (!list_empty(page_list))
-               CDEBUG(D_INFO, "inode %ld list not empty\n", inode->i_ino);
-       CDEBUG(D_INFO, "added %d page(s) to vector\n", num);
-
-       EXIT;
-       return num;  
+        struct list_head *page_list = obdfs_iplist(inode);
+        struct list_head *tmp;
+        int num = 0;
+
+        ENTRY;
+
+        tmp = page_list;
+        /* Traverse list in reverse order, so we do FIFO, not LIFO order */
+        while ( (tmp = tmp->prev) != page_list && num < nr_slots ) {
+                struct obdfs_pgrq *req;
+                struct page *page;
+                
+                req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
+                page = req->rq_page;
+
+                
+                if (req->rq_jiffies > check_time)
+                        break;          /* pages are in chronological order */
+
+                /* Only allocate the obdo if we will actually do I/O here */
+                if ( !*obdo ) {
+                        OIDEBUG(inode);
+                        *obdo = obdo_fromid(IID(inode), inode->i_ino,
+                                            OBD_MD_FLNOTOBD);
+                        if ( IS_ERR(*obdo) ) {
+                                int err = PTR_ERR(*obdo);
+                                *obdo = NULL;
+
+                                EXIT;
+                                return err;
+                        }
+
+                        /* FIXME revisit fromid & from_inode */
+                        obdfs_from_inode(*obdo, inode);
+                        *flag = OBD_BRW_CREATE;
+                }
+
+                /* Remove request from list before write to avoid conflict.
+                 * Note that obdfs_pgrq_del() also deletes the request.
+                 */
+                obdfs_pgrq_del(req);
+                if ( !page ) {
+                        CDEBUG(D_CACHE, "no page \n");
+                        continue;
+                }
+
+                bufs[num] = (char *)page_address(page);
+                pages[num] = page;
+                counts[num] = PAGE_SIZE;
+                offsets[num] = ((obd_off)page->index) << PAGE_SHIFT;
+                CDEBUG(D_INFO, "ENQ inode %ld, page %p addr %p to vector\n", 
+                       inode->i_ino, page, (char *)page_address(page));
+                num++;
+        }
+
+        if (!list_empty(page_list))
+                CDEBUG(D_INFO, "inode %ld list not empty\n", inode->i_ino);
+        CDEBUG(D_INFO, "added %d page(s) to vector\n", num);
+
+        EXIT;
+        return num;  
 } /* obdfs_enqueue_pages */
 
 /* Dequeue cached pages for a dying inode without writing them to disk. */
 void obdfs_dequeue_pages(struct inode *inode)
 {
-       struct list_head *tmp;
-
-       ENTRY;
-       obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
-       tmp = obdfs_islist(inode);
-       if ( list_empty(tmp) ) {
-               CDEBUG(D_INFO, "no dirty pages for inode %ld\n", inode->i_ino);
-               obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
-               EXIT;
-               return;
-       }
-
-       /* take it out of the super list */
-       list_del(tmp);
-       INIT_LIST_HEAD(obdfs_islist(inode));
-
-       tmp = obdfs_iplist(inode);
-       while ( (tmp = tmp->prev) != obdfs_iplist(inode) ) {
-               struct obdfs_pgrq *req;
-               struct page *page;
-               
-               req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
-               page = req->rq_page;
-               /* take it out of the list and free */
-               obdfs_pgrq_del(req);
-               /* now put the page away */
-               put_page(page);
-       }
-
-       obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
-
-       /* decrement inode reference for page cache */
-       inode->i_count--;
-       EXIT;
+        struct list_head *tmp;
+
+        ENTRY;
+        obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
+        tmp = obdfs_islist(inode);
+        if ( list_empty(tmp) ) {
+                CDEBUG(D_INFO, "no dirty pages for inode %ld\n", inode->i_ino);
+                obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
+                EXIT;
+                return;
+        }
+
+        /* take it out of the super list */
+        list_del(tmp);
+        INIT_LIST_HEAD(obdfs_islist(inode));
+
+        tmp = obdfs_iplist(inode);
+        while ( (tmp = tmp->prev) != obdfs_iplist(inode) ) {
+                struct obdfs_pgrq *req;
+                struct page *page;
+                
+                req = list_entry(tmp, struct obdfs_pgrq, rq_plist);
+                page = req->rq_page;
+                /* take it out of the list and free */
+                obdfs_pgrq_del(req);
+                /* now put the page away */
+                put_page(page);
+        }
+
+        obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
+
+        /* decrement inode reference for page cache */
+        atomic_dec(&inode->i_count);
+        EXIT;
 }
 
 /* Remove writeback requests for the superblock */
 int obdfs_flush_reqs(struct list_head *inode_list, unsigned long check_time)
 {
-       struct list_head *tmp;
-       unsigned long     max_io, total_io = 0;
-       obd_count         num_io;
-       obd_count         num_obdos;
-       struct inode     *inodes[MAX_IOVEC];    /* write data back to these */
-       struct page      *pages[MAX_IOVEC];     /* call put_page on these */
-       struct obdo      *obdos[MAX_IOVEC];
-       char             *bufs[MAX_IOVEC];
-       obd_size          counts[MAX_IOVEC];
-       obd_off           offsets[MAX_IOVEC];
-       obd_flag          flags[MAX_IOVEC];
-       obd_count         bufs_per_obdo[MAX_IOVEC];
-       int               err = 0;
-       struct obdfs_sb_info *sbi;
-
-       ENTRY;
-       if (!inode_list) {
-               CDEBUG(D_INODE, "no list\n");
-               EXIT;
-               return 0;
-       }
-
-       sbi = list_entry(inode_list, struct obdfs_sb_info, osi_inodes);
-
-       obd_down(&sbi->osi_list_mutex);
-       if ( list_empty(inode_list) ) {
-               CDEBUG(D_INFO, "list empty\n");
-               obd_up(&sbi->osi_list_mutex);
-               EXIT;
-               return 0;
-       }
-
-       /* If we are forcing a write, write out all dirty pages */
-       max_io = check_time == ~0UL ? 1<<31 : pupd_prm.ndirty;
-       CDEBUG(D_INFO, "max_io = %lu\n", max_io);
-
-       /* Add each inode's dirty pages to a write vector, and write it.
-        * Traverse list in reverse order, so we do FIFO, not LIFO order
-        */
+        struct list_head *tmp;
+        unsigned long     max_io, total_io = 0;
+        obd_count         num_io;
+        obd_count         num_obdos;
+        struct inode     *inodes[MAX_IOVEC];    /* write data back to these */
+        struct page      *pages[MAX_IOVEC];     /* call put_page on these */
+        struct obdo      *obdos[MAX_IOVEC];
+        char             *bufs[MAX_IOVEC];
+        obd_size          counts[MAX_IOVEC];
+        obd_off           offsets[MAX_IOVEC];
+        obd_flag          flags[MAX_IOVEC];
+        obd_count         bufs_per_obdo[MAX_IOVEC];
+        int               err = 0;
+        struct obdfs_sb_info *sbi;
+
+        ENTRY;
+        if (!inode_list) {
+                CDEBUG(D_INODE, "no list\n");
+                EXIT;
+                return 0;
+        }
+
+        sbi = list_entry(inode_list, struct obdfs_sb_info, osi_inodes);
+
+        obd_down(&sbi->osi_list_mutex);
+        if ( list_empty(inode_list) ) {
+                CDEBUG(D_INFO, "list empty\n");
+                obd_up(&sbi->osi_list_mutex);
+                EXIT;
+                return 0;
+        }
+
+        /* If we are forcing a write, write out all dirty pages */
+        max_io = check_time == ~0UL ? 1<<31 : pupd_prm.ndirty;
+        CDEBUG(D_INFO, "max_io = %lu\n", max_io);
+
+        /* Add each inode's dirty pages to a write vector, and write it.
+         * Traverse list in reverse order, so we do FIFO, not LIFO order
+         */
  again:
-       tmp = inode_list;
-       num_io = 0;
-       num_obdos = 0;
-       while ( (tmp = tmp->prev) != inode_list && total_io < max_io) {
-               struct obdfs_inode_info *ii;
-               struct inode *inode;
-               int res;
-
-               ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes);
-               inode = list_entry(ii, struct inode, u);
-               inodes[num_obdos] = inode;
-               obdos[num_obdos] = NULL;
-               CDEBUG(D_INFO, "checking inode %ld pages\n", inode->i_ino);
-
-               /* Make sure we reference "inode" and not "inodes[num_obdos]",
-                * as num_obdos will change after the loop is run.
-                */
-               if (!list_empty(obdfs_iplist(inode))) {
-                       res = obdfs_enqueue_pages(inode, &obdos[num_obdos],
-                                                 MAX_IOVEC - num_io,
-                                                 &pages[num_io], &bufs[num_io],
-                                                 &counts[num_io],
-                                                 &offsets[num_io],
-                                                 &flags[num_obdos],
-                                                 check_time);
-                       CDEBUG(D_INFO, "FLUSH inode %ld, pages flushed: %d\n",
-                              inode->i_ino, res);
-                       if ( res < 0 ) {
-                               CDEBUG(D_INODE,
-                                      "fatal: unable to enqueue inode %ld (err %d)\n",
-                                      inode->i_ino, res);
-                               /* XXX Move bad inode to end of list so we can
-                                * continue with flushing list.  This is a
-                                * temporary measure to avoid machine lockups.
-                                * Maybe if we have -ENOENT, simply discard.
-                                */
-                               list_del(tmp);
-                               list_add(tmp, inode_list);
-                               err = res;
-                               EXIT;
-                               goto BREAK;
-                       }
-                       if (res == 0)
-                               continue;
-
-                       num_io += res;
-                       total_io += res;
-                       bufs_per_obdo[num_obdos] = res;
-                       num_obdos++;
-
-                       if ( num_io == MAX_IOVEC ) {
-                               obd_up(&sbi->osi_list_mutex);
-                               err = obdfs_do_vec_wr(inodes, num_io, num_obdos,
-                                                     obdos, bufs_per_obdo,
-                                                     pages, bufs, counts,
-                                                     offsets, flags);
-                               if ( err ) {
-                                       CDEBUG(D_INODE,
-                                              "fatal: do_vec_wr err=%d\n",
-                                              err);
-                                       EXIT;
-                                       goto ERR;
-                               }
-                               obd_down(&sbi->osi_list_mutex);
-                               goto again;
-                       }
-               }
-       }
+        tmp = inode_list;
+        num_io = 0;
+        num_obdos = 0;
+        while ( (tmp = tmp->prev) != inode_list && total_io < max_io) {
+                struct obdfs_inode_info *ii;
+                struct inode *inode;
+                int res;
+
+                ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes);
+                inode = list_entry(ii, struct inode, u);
+                inodes[num_obdos] = inode;
+                obdos[num_obdos] = NULL;
+                CDEBUG(D_INFO, "checking inode %ld pages\n", inode->i_ino);
+
+                /* Make sure we reference "inode" and not "inodes[num_obdos]",
+                 * as num_obdos will change after the loop is run.
+                 */
+                if (!list_empty(obdfs_iplist(inode))) {
+                        res = obdfs_enqueue_pages(inode, &obdos[num_obdos],
+                                                  MAX_IOVEC - num_io,
+                                                  &pages[num_io], &bufs[num_io],
+                                                  &counts[num_io],
+                                                  &offsets[num_io],
+                                                  &flags[num_obdos],
+                                                  check_time);
+                        CDEBUG(D_INFO, "FLUSH inode %ld, pages flushed: %d\n",
+                               inode->i_ino, res);
+                        if ( res < 0 ) {
+                                CDEBUG(D_INODE,
+                                       "fatal: unable to enqueue inode %ld (err %d)\n",
+                                       inode->i_ino, res);
+                                /* XXX Move bad inode to end of list so we can
+                                 * continue with flushing list.  This is a
+                                 * temporary measure to avoid machine lockups.
+                                 * Maybe if we have -ENOENT, simply discard.
+                                 */
+                                list_del(tmp);
+                                list_add(tmp, inode_list);
+                                err = res;
+                                EXIT;
+                                goto BREAK;
+                        }
+                        if (res == 0)
+                                continue;
+
+                        num_io += res;
+                        total_io += res;
+                        bufs_per_obdo[num_obdos] = res;
+                        num_obdos++;
+
+                        if ( num_io == MAX_IOVEC ) {
+                                obd_up(&sbi->osi_list_mutex);
+                                err = obdfs_do_vec_wr(inodes, num_io, num_obdos,
+                                                      obdos, bufs_per_obdo,
+                                                      pages, bufs, counts,
+                                                      offsets, flags);
+                                if ( err ) {
+                                        CDEBUG(D_INODE,
+                                               "fatal: do_vec_wr err=%d\n",
+                                               err);
+                                        EXIT;
+                                        goto ERR;
+                                }
+                                obd_down(&sbi->osi_list_mutex);
+                                goto again;
+                        }
+                }
+        }
 
 BREAK:
-       obd_up(&sbi->osi_list_mutex);
-
-       /* flush any remaining I/Os */
-       if ( num_io ) {
-               err = obdfs_do_vec_wr(inodes, num_io, num_obdos, obdos,
-                                     bufs_per_obdo, pages, bufs, counts,
-                                     offsets, flags);
-               if (err)
-                       CDEBUG(D_INODE, "fatal: unable to do vec_wr (err %d)\n", err);
-               num_io = 0;
-               num_obdos = 0;
-       }
-
-       /* Remove inode from superblock dirty list when no more pages.
-        * Make sure we don't point at the current inode with tmp
-        * when we re-init the list on the inode, or we will loop.
-        */
-       obd_down(&sbi->osi_list_mutex);
-       tmp = inode_list;
-       while ( (tmp = tmp->prev) != inode_list ) {
-               struct obdfs_inode_info *ii;
-               struct inode *inode;
-
-               ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes);
-               inode = list_entry(ii, struct inode, u);
-               CDEBUG(D_INFO, "checking inode %ld empty\n", inode->i_ino);
-               if (list_empty(obdfs_iplist(inode))) {
-                       CDEBUG(D_INFO, "remove inode %ld from dirty list\n",
-                              inode->i_ino);
-                       tmp = tmp->next;
-                       list_del(obdfs_islist(inode));
-                       /* decrement inode reference for page cache */
-                       inode->i_count--;
-                       INIT_LIST_HEAD(obdfs_islist(inode));
-               }
-       }
-       obd_up(&sbi->osi_list_mutex);
-
-       CDEBUG(D_INFO, "flushed %d pages in total\n", total_io);
-       EXIT;
+        obd_up(&sbi->osi_list_mutex);
+
+        /* flush any remaining I/Os */
+        if ( num_io ) {
+                err = obdfs_do_vec_wr(inodes, num_io, num_obdos, obdos,
+                                      bufs_per_obdo, pages, bufs, counts,
+                                      offsets, flags);
+                if (err)
+                        CDEBUG(D_INODE, "fatal: unable to do vec_wr (err %d)\n", err);
+                num_io = 0;
+                num_obdos = 0;
+        }
+
+        /* Remove inode from superblock dirty list when no more pages.
+         * Make sure we don't point at the current inode with tmp
+         * when we re-init the list on the inode, or we will loop.
+         */
+        obd_down(&sbi->osi_list_mutex);
+        tmp = inode_list;
+        while ( (tmp = tmp->prev) != inode_list ) {
+                struct obdfs_inode_info *ii;
+                struct inode *inode;
+
+                ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes);
+                inode = list_entry(ii, struct inode, u);
+                CDEBUG(D_INFO, "checking inode %ld empty\n", inode->i_ino);
+                if (list_empty(obdfs_iplist(inode))) {
+                        CDEBUG(D_INFO, "remove inode %ld from dirty list\n",
+                               inode->i_ino);
+                        tmp = tmp->next;
+                        list_del(obdfs_islist(inode));
+                        /* decrement inode reference for page cache */
+                        atomic_dec(&inode->i_count);
+                        INIT_LIST_HEAD(obdfs_islist(inode));
+                }
+        }
+        obd_up(&sbi->osi_list_mutex);
+
+        CDEBUG(D_INFO, "flushed %ld pages in total\n", total_io);
+        EXIT;
 ERR:
-       return err ? err : total_io;
+        return err ? err : total_io;
 } /* obdfs_flush_reqs */
 
 
@@ -307,24 +307,24 @@ ERR:
  */
 int obdfs_flush_dirty_pages(unsigned long check_time)
 {
-       struct list_head *sl;
-       int max = 0;
-
-       ENTRY;
-       sl = &obdfs_super_list;
-       while ( (sl = sl->prev) != &obdfs_super_list ) {
-               struct obdfs_sb_info *sbi = 
-                       list_entry(sl, struct obdfs_sb_info, osi_list);
-               int ret;
-
-               /* walk write requests here, use the sb, check the time */
-               ret = obdfs_flush_reqs(&sbi->osi_inodes, check_time);
-               /* XXX handle error?  What to do with it? */
-
-               max = ret > max ? ret : max;
-       }
-       EXIT;
-       return max;
+        struct list_head *sl;
+        int max = 0;
+
+        ENTRY;
+        sl = &obdfs_super_list;
+        while ( (sl = sl->prev) != &obdfs_super_list ) {
+                struct obdfs_sb_info *sbi = 
+                        list_entry(sl, struct obdfs_sb_info, osi_list);
+                int ret;
+
+                /* walk write requests here, use the sb, check the time */
+                ret = obdfs_flush_reqs(&sbi->osi_inodes, check_time);
+                /* XXX handle error?  What to do with it? */
+
+                max = ret > max ? ret : max;
+        }
+        EXIT;
+        return max;
 } /* obdfs_flush_dirty_pages */
 
 
@@ -332,124 +332,124 @@ static struct task_struct *pupdated;
 
 static int pupdate(void *unused) 
 {
-       int interval = pupd_prm.interval;
-       long age = pupd_prm.age_buffer;
-       int wrote = 0;
-       
-       exit_files(current);
-       exit_mm(current);
-
-       pupdated = current;
-       pupdated->session = 1;
-       pupdated->pgrp = 1;
-       strcpy(pupdated->comm, "pupdated");
-
-       printk("pupdated activated...\n");
-
-       spin_lock_irq(&pupdated->sigmask_lock);
-       sigfillset(&pupdated->blocked);
-       siginitsetinv(&pupdated->blocked, sigmask(SIGTERM));
-       recalc_sigpending(pupdated);
-       spin_unlock_irq(&pupdated->sigmask_lock);
-
-       for (;;) {
-               long dirty_limit;
-
-               /* update interval */
-               if (interval) {
-                       set_task_state(pupdated, TASK_INTERRUPTIBLE);
-                       schedule_timeout(interval);
-               }
-               if (signal_pending(pupdated))
-               {
-                       int stopped = 0;
-                       spin_lock_irq(&pupdated->sigmask_lock);
-                       if (sigismember(&pupdated->signal, SIGTERM))
-                       {
-                               sigdelset(&pupdated->signal, SIGTERM);
-                               stopped = 1;
-                       }
-                       recalc_sigpending(pupdated);
-                       spin_unlock_irq(&pupdated->sigmask_lock);
-                       if (stopped) {
-                               printk("pupdated stopped...\n");
-                               set_task_state(pupdated, TASK_STOPPED);
-                               pupdated = NULL;
-                               return 0;
-                       }
-               }
-               /* asynchronous setattr etc for the future ...
-               obdfs_flush_dirty_inodes(jiffies - pupd_prm.age_super);
-                */
-               dirty_limit = nr_free_buffer_pages() * pupd_prm.nfract / 100;
-
-               if (obdfs_cache_count > dirty_limit) {
-                       interval = 0;
-                       if ( wrote < pupd_prm.ndirty )
-                               age >>= 1;
-                       CDEBUG(D_CACHE, "wrote %d, age %ld, interval %d\n",
-                               wrote, age, interval);
-               } else {
-                       if ( wrote < pupd_prm.ndirty >> 1 &&
-                            obdfs_cache_count < dirty_limit / 2) {
-                               interval = pupd_prm.interval;
-                               age = pupd_prm.age_buffer;
-                               CDEBUG(D_INFO,
-                                      "wrote %d, age %ld, interval %d\n",
-                                      wrote, age, interval);
-                       } else if (obdfs_cache_count > dirty_limit / 2) {
-                               interval >>= 1;
-                               if ( wrote < pupd_prm.ndirty )
-                                       age >>= 1;
-                               CDEBUG(D_CACHE,
-                                      "wrote %d, age %ld, interval %d\n",
-                                      wrote, age, interval);
-                       }
-               }
-
-               wrote = obdfs_flush_dirty_pages(jiffies - age);
-               if (wrote)
-                       CDEBUG(D_CACHE,
-                              "dirty_limit %ld, cache_count %ld, wrote %d\n",
-                              dirty_limit, obdfs_cache_count, wrote);
-       }
+        int interval = pupd_prm.interval;
+        long age = pupd_prm.age_buffer;
+        int wrote = 0;
+        
+        exit_files(current);
+        exit_mm(current);
+
+        pupdated = current;
+        pupdated->session = 1;
+        pupdated->pgrp = 1;
+        strcpy(pupdated->comm, "pupdated");
+
+        printk("pupdated activated...\n");
+
+        spin_lock_irq(&pupdated->sigmask_lock);
+        sigfillset(&pupdated->blocked);
+        siginitsetinv(&pupdated->blocked, sigmask(SIGTERM));
+        recalc_sigpending(pupdated);
+        spin_unlock_irq(&pupdated->sigmask_lock);
+
+        for (;;) {
+                long dirty_limit;
+
+                /* update interval */
+                if (interval) {
+                        set_task_state(pupdated, TASK_INTERRUPTIBLE);
+                        schedule_timeout(interval);
+                }
+                if (signal_pending(pupdated))
+                {
+                        int stopped = 0;
+                        spin_lock_irq(&pupdated->sigmask_lock);
+                        if (sigismember(&pupdated->pending.signal, SIGTERM))
+                        {
+                                sigdelset(&pupdated->pending.signal, SIGTERM);
+                                stopped = 1;
+                        }
+                        recalc_sigpending(pupdated);
+                        spin_unlock_irq(&pupdated->sigmask_lock);
+                        if (stopped) {
+                                printk("pupdated stopped...\n");
+                                set_task_state(pupdated, TASK_STOPPED);
+                                pupdated = NULL;
+                                return 0;
+                        }
+                }
+                /* asynchronous setattr etc for the future ...
+                obdfs_flush_dirty_inodes(jiffies - pupd_prm.age_super);
+                 */
+                dirty_limit = nr_free_buffer_pages() * pupd_prm.nfract / 100;
+
+                if (obdfs_cache_count > dirty_limit) {
+                        interval = 0;
+                        if ( wrote < pupd_prm.ndirty )
+                                age >>= 1;
+                        CDEBUG(D_CACHE, "wrote %d, age %ld, interval %d\n",
+                                wrote, age, interval);
+                } else {
+                        if ( wrote < pupd_prm.ndirty >> 1 &&
+                             obdfs_cache_count < dirty_limit / 2) {
+                                interval = pupd_prm.interval;
+                                age = pupd_prm.age_buffer;
+                                CDEBUG(D_INFO,
+                                       "wrote %d, age %ld, interval %d\n",
+                                       wrote, age, interval);
+                        } else if (obdfs_cache_count > dirty_limit / 2) {
+                                interval >>= 1;
+                                if ( wrote < pupd_prm.ndirty )
+                                        age >>= 1;
+                                CDEBUG(D_CACHE,
+                                       "wrote %d, age %ld, interval %d\n",
+                                       wrote, age, interval);
+                        }
+                }
+
+                wrote = obdfs_flush_dirty_pages(jiffies - age);
+                if (wrote)
+                        CDEBUG(D_CACHE,
+                               "dirty_limit %ld, cache_count %ld, wrote %d\n",
+                               dirty_limit, obdfs_cache_count, wrote);
+        }
 }
 
 
 int obdfs_flushd_init(void)
 {
-       /*
-       kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-        */
-       kernel_thread(pupdate, NULL, 0);
-       CDEBUG(D_PSDEV, __FUNCTION__ ": flushd inited\n");
-       return 0;
+        /*
+        kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+         */
+        kernel_thread(pupdate, NULL, 0);
+        CDEBUG(D_PSDEV, __FUNCTION__ ": flushd inited\n");
+        return 0;
 }
 
 int obdfs_flushd_cleanup(void)
 {
-       ENTRY;
-
-       if (pupdated) /* for debugging purposes only */
-               CDEBUG(D_CACHE, "pupdated->state = %lx\n", pupdated->state);
-
-       /* deliver a signal to pupdated to shut it down */
-       if (pupdated && (pupdated->state == TASK_RUNNING ||
-                        pupdated->state == TASK_INTERRUPTIBLE )) {
-               unsigned long timeout = HZ/20;
-               unsigned long count = 0;
-               send_sig_info(SIGTERM, (struct siginfo *)1, pupdated);
-               while (pupdated) {
-                       if ((count % 2*HZ) == timeout)
-                               printk(KERN_INFO "wait for pupdated to stop\n");
-                       count += timeout;
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(timeout);
-               }
-       }
-
-       EXIT;
-       /* not reached */
-       return 0;
+        ENTRY;
+
+        if (pupdated) /* for debugging purposes only */
+                CDEBUG(D_CACHE, "pupdated->state = %lx\n", pupdated->state);
+
+        /* deliver a signal to pupdated to shut it down */
+        if (pupdated && (pupdated->state == TASK_RUNNING ||
+                         pupdated->state == TASK_INTERRUPTIBLE )) {
+                unsigned long timeout = HZ/20;
+                unsigned long count = 0;
+                send_sig_info(SIGTERM, (struct siginfo *)1, pupdated);
+                while (pupdated) {
+                        if ((count % 2*HZ) == timeout)
+                                printk(KERN_INFO "wait for pupdated to stop\n");
+                        count += timeout;
+                        set_current_state(TASK_INTERRUPTIBLE);
+                        schedule_timeout(timeout);
+                }
+        }
+
+        EXIT;
+        /* not reached */
+        return 0;
 
 }