Whamcloud - gitweb
a working file system!
authorbraam <braam>
Sun, 11 Mar 2001 00:53:49 +0000 (00:53 +0000)
committerbraam <braam>
Sun, 11 Mar 2001 00:53:49 +0000 (00:53 +0000)
lustre/include/linux/obd_class.h
lustre/include/linux/obdfs.h
lustre/obdclass/genops.c
lustre/obdclass/obdcontrol
lustre/obdfs/dir.c
lustre/obdfs/file.c
lustre/obdfs/namei.c
lustre/obdfs/rw.c
lustre/obdfs/super.c
lustre/obdfs/symlink.c

index 6758bc6..93a5338 100644 (file)
@@ -2,7 +2,6 @@
 #define __LINUX_CLASS_OBD_H
 
 #include <linux/fs.h>
 #define __LINUX_CLASS_OBD_H
 
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/time.h>
 #include <linux/obd.h>
 
 #include <linux/time.h>
 #include <linux/obd.h>
 
index 3787608..6f60217 100644 (file)
 #include <linux/obd_class.h>
 #include <linux/list.h>
 
 #include <linux/obd_class.h>
 #include <linux/list.h>
 
+
+#define obd_unlock_page(page)   do {    if (PageLocked(page)) { \
+                        UnlockPage(page);\
+                } else {\
+                        printk("file %s, line %d: expecting locked page\n",\
+                               __FILE__, __LINE__); \
+                }                       \
+} while(0)
+
 struct obdfs_pgrq {
 struct obdfs_pgrq {
-       struct list_head         rq_plist;      /* linked list of req's */
-       unsigned long            rq_jiffies;
-       struct page             *rq_page;       /* page to be written */
+        struct list_head         rq_plist;      /* linked list of req's */
+        unsigned long            rq_jiffies;
+        struct page             *rq_page;       /* page to be written */
 };
 
 };
 
-struct list_head obdfs_super_list;      /* list of all OBDFS superblocks */
+struct list_head obdfs_super_list;       /* list of all OBDFS superblocks */
 
 struct obdfs_sb_info {
 
 struct obdfs_sb_info {
-       struct list_head         osi_list;      /* list of supers */
-       struct obd_conn          osi_conn;
-       struct super_block      *osi_super;
-       struct obd_device       *osi_obd;
-       struct obd_ops          *osi_ops;
-       ino_t                    osi_rootino;   /* number of root inode */
-       int                      osi_minor;     /* minor of /dev/obdX */
-       struct list_head         osi_inodes;    /* list of dirty inodes */
-       unsigned long            osi_cache_count;
-       struct semaphore         osi_list_mutex;
+        struct list_head         osi_list;      /* list of supers */
+        struct obd_conn          osi_conn;
+        struct super_block      *osi_super;
+        struct obd_device       *osi_obd;
+        struct obd_ops          *osi_ops;
+        ino_t                    osi_rootino;   /* number of root inode */
+        int                      osi_minor;     /* minor of /dev/obdX */
+        struct list_head         osi_inodes;    /* list of dirty inodes */
+        unsigned long            osi_cache_count;
+        struct semaphore         osi_list_mutex;
 };
 
 struct obdfs_inode_info {
 };
 
 struct obdfs_inode_info {
-       int              oi_flags;
-       struct list_head oi_inodes;
-       struct list_head oi_pages;
-       char             oi_inline[OBD_INLINESZ];
+        int              oi_flags;
+        struct list_head oi_inodes;
+        struct list_head oi_pages;
+        char             oi_inline[OBD_INLINESZ];
 };
 
 /* dir.c */
 };
 
 /* dir.c */
+#define EXT2_DIR_PAD                    4
+#define EXT2_DIR_ROUND                  (EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len)      (((name_len) + 8 + EXT2_DIR_ROUND) & \
+                                         ~EXT2_DIR_ROUND)
+#define EXT2_NAME_LEN 255
+struct ext2_dir_entry_2 {
+        __u32   inode;                  /* Inode number */
+        __u16   rec_len;                /* Directory entry length */
+        __u8    name_len;               /* Name length */
+        __u8    file_type;
+        char    name[EXT2_NAME_LEN];    /* File name */
+};
 int obdfs_check_dir_entry (const char * function, struct inode * dir,
 int obdfs_check_dir_entry (const char * function, struct inode * dir,
-                         struct ext2_dir_entry_2 * de, struct page * page,
-                         unsigned long offset);
+                          struct ext2_dir_entry_2 * de, struct page * page,
+                          unsigned long offset);
 extern struct file_operations obdfs_dir_operations;
 extern struct inode_operations obdfs_dir_inode_operations;
 
 extern struct file_operations obdfs_dir_operations;
 extern struct inode_operations obdfs_dir_inode_operations;
 
@@ -61,6 +82,97 @@ int obdfs_flush_reqs(struct list_head *inode_list, unsigned long check_time);
 int obdfs_flush_dirty_pages(unsigned long check_time);
 
 /* namei.c */
 int obdfs_flush_dirty_pages(unsigned long check_time);
 
 /* namei.c */
+/*
+ * Structure of the super block
+ */
+struct ext2_super_block {
+        __u32   s_inodes_count;         /* Inodes count */
+        __u32   s_blocks_count;         /* Blocks count */
+        __u32   s_r_blocks_count;       /* Reserved blocks count */
+        __u32   s_free_blocks_count;    /* Free blocks count */
+        __u32   s_free_inodes_count;    /* Free inodes count */
+        __u32   s_first_data_block;     /* First Data Block */
+        __u32   s_log_block_size;       /* Block size */
+        __s32   s_log_frag_size;        /* Fragment size */
+        __u32   s_blocks_per_group;     /* # Blocks per group */
+        __u32   s_frags_per_group;      /* # Fragments per group */
+        __u32   s_inodes_per_group;     /* # Inodes per group */
+        __u32   s_mtime;                /* Mount time */
+        __u32   s_wtime;                /* Write time */
+        __u16   s_mnt_count;            /* Mount count */
+        __s16   s_max_mnt_count;        /* Maximal mount count */
+        __u16   s_magic;                /* Magic signature */
+        __u16   s_state;                /* File system state */
+        __u16   s_errors;               /* Behaviour when detecting errors */
+        __u16   s_minor_rev_level;      /* minor revision level */
+        __u32   s_lastcheck;            /* time of last check */
+        __u32   s_checkinterval;        /* max. time between checks */
+        __u32   s_creator_os;           /* OS */
+        __u32   s_rev_level;            /* Revision level */
+        __u16   s_def_resuid;           /* Default uid for reserved blocks */
+        __u16   s_def_resgid;           /* Default gid for reserved blocks */
+        /*
+         * These fields are for EXT2_DYNAMIC_REV superblocks only.
+         *
+         * Note: the difference between the compatible feature set and
+         * the incompatible feature set is that if there is a bit set
+         * in the incompatible feature set that the kernel doesn't
+         * know about, it should refuse to mount the filesystem.
+         * 
+         * e2fsck's requirements are more strict; if it doesn't know
+         * about a feature in either the compatible or incompatible
+         * feature set, it must abort and not try to meddle with
+         * things it doesn't understand...
+         */
+        __u32   s_first_ino;            /* First non-reserved inode */
+        __u16   s_inode_size;           /* size of inode structure */
+        __u16   s_block_group_nr;       /* block group # of this superblock */
+        __u32   s_feature_compat;       /* compatible feature set */
+        __u32   s_feature_incompat;     /* incompatible feature set */
+        __u32   s_feature_ro_compat;    /* readonly-compatible feature set */
+        __u8    s_uuid[16];             /* 128-bit uuid for volume */
+        char    s_volume_name[16];      /* volume name */
+        char    s_last_mounted[64];     /* directory where last mounted */
+        __u32   s_algorithm_usage_bitmap; /* For compression */
+        /*
+         * Performance hints.  Directory preallocation should only
+         * happen if the EXT2_COMPAT_PREALLOC flag is on.
+         */
+        __u8    s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
+        __u8    s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
+        __u16   s_padding1;
+        __u32   s_reserved[204];        /* Padding to the end of the block */
+};
+
+#define EXT2_SB(sb)     (&((sb)->u.ext2_sb))
+/*
+ * Maximal count of links to a file
+ */
+#define EXT2_LINK_MAX           32000
+/*
+ * Ext2 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define EXT2_FT_UNKNOWN         0
+#define EXT2_FT_REG_FILE        1
+#define EXT2_FT_DIR             2
+#define EXT2_FT_CHRDEV          3
+#define EXT2_FT_BLKDEV          4
+#define EXT2_FT_FIFO            5
+#define EXT2_FT_SOCK            6
+#define EXT2_FT_SYMLINK         7
+
+#define EXT2_FT_MAX             8
+
+#define EXT2_BTREE_FL                   0x00001000 /* btree format dir */
+#define EXT2_RESERVED_FL                0x80000000 /* reserved for ext2 lib */
+#define EXT2_FEATURE_INCOMPAT_FILETYPE          0x0002
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)                        \
+        ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)                      \
+        ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
+
+
 struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry);
 int obdfs_create (struct inode * dir, struct dentry * dentry, int mode);
 int obdfs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
 struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry);
 int obdfs_create (struct inode * dir, struct dentry * dentry, int mode);
 int obdfs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
@@ -68,28 +180,28 @@ int obdfs_rmdir(struct inode *dir, struct dentry *dentry);
 int obdfs_unlink(struct inode *dir, struct dentry *dentry);
 int obdfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev);
 int obdfs_symlink(struct inode *dir, struct dentry *dentry,
 int obdfs_unlink(struct inode *dir, struct dentry *dentry);
 int obdfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev);
 int obdfs_symlink(struct inode *dir, struct dentry *dentry,
-                 const char *symname);
+                  const char *symname);
 int obdfs_link(struct dentry *old_dentry, struct inode *dir,
 int obdfs_link(struct dentry *old_dentry, struct inode *dir,
-              struct dentry *dentry);
+               struct dentry *dentry);
 int obdfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 int obdfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-                struct inode *new_dir, struct dentry *new_dentry);
+                 struct inode *new_dir, struct dentry *new_dentry);
 
 /* rw.c */
 
 /* rw.c */
-int obdfs_do_writepage(struct inode *, struct page *, int sync);
+int obdfs_do_writepage(struct page *, int sync);
 int obdfs_init_pgrqcache(void);
 void obdfs_cleanup_pgrqcache(void);
 inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq);
 int obdfs_init_pgrqcache(void);
 void obdfs_cleanup_pgrqcache(void);
 inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq);
-int obdfs_readpage(struct dentry *dentry, struct page *page);
-int obdfs_writepage(struct dentry *dentry, struct page *page);
+int obdfs_readpage(struct file *file, struct page *page);
+int obdfs_writepage(struct page *page);
 struct page *obdfs_getpage(struct inode *inode, unsigned long offset,
 struct page *obdfs_getpage(struct inode *inode, unsigned long offset,
-                          int create, int locked);
+                           int create, int locked);
 int obdfs_write_one_page(struct file *file, struct page *page,
 int obdfs_write_one_page(struct file *file, struct page *page,
-                        unsigned long offset, unsigned long bytes,
-                        const char * buf);
+                         unsigned long offset, unsigned long bytes,
+                         const char * buf);
 int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io, obd_count num_oa,
 int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io, obd_count num_oa,
-                   struct obdo **obdos, obd_count *oa_bufs,
-                   struct page **pages, char **bufs, obd_size *counts,
-                   obd_off *offsets, obd_flag *flags);
+                    struct obdo **obdos, obd_count *oa_bufs,
+                    struct page **pages, char **bufs, obd_size *counts,
+                    obd_off *offsets, obd_flag *flags);
 void obdfs_truncate(struct inode *inode);
 
 /* super.c */
 void obdfs_truncate(struct inode *inode);
 
 /* super.c */
@@ -107,50 +219,50 @@ void obdfs_sysctl_clean(void);
 
 static inline struct obdfs_inode_info *obdfs_i2info(struct inode *inode)
 {
 
 static inline struct obdfs_inode_info *obdfs_i2info(struct inode *inode)
 {
-       return (struct obdfs_inode_info *)&(inode->u.generic_ip);
+        return (struct obdfs_inode_info *)&(inode->u.generic_ip);
 }
 
 static inline struct obdfs_sb_info *obdfs_i2sbi(struct inode *inode)
 {
 }
 
 static inline struct obdfs_sb_info *obdfs_i2sbi(struct inode *inode)
 {
-       return (struct obdfs_sb_info *) &(inode->i_sb->u.generic_sbp);
+        return (struct obdfs_sb_info *) &(inode->i_sb->u.generic_sbp);
 }
 
 static inline struct list_head *obdfs_iplist(struct inode *inode) 
 {
 }
 
 static inline struct list_head *obdfs_iplist(struct inode *inode) 
 {
-       struct obdfs_inode_info *info = obdfs_i2info(inode);
+        struct obdfs_inode_info *info = obdfs_i2info(inode);
 
 
-       return &info->oi_pages;
+        return &info->oi_pages;
 }
 
 static inline struct list_head *obdfs_islist(struct inode *inode) 
 {
 }
 
 static inline struct list_head *obdfs_islist(struct inode *inode) 
 {
-       struct obdfs_inode_info *info = obdfs_i2info(inode);
+        struct obdfs_inode_info *info = obdfs_i2info(inode);
 
 
-       return &info->oi_inodes;
+        return &info->oi_inodes;
 }
 
 static inline struct list_head *obdfs_slist(struct inode *inode) 
 {
 }
 
 static inline struct list_head *obdfs_slist(struct inode *inode) 
 {
-       struct obdfs_sb_info *sbi = obdfs_i2sbi(inode);
+        struct obdfs_sb_info *sbi = obdfs_i2sbi(inode);
 
 
-       return &sbi->osi_inodes;
+        return &sbi->osi_inodes;
 }
 
 }
 
-#define obd_down(mutex) {                                              \
-       /* CDEBUG(D_INFO, "get lock\n"); */                             \
-       obdfs_mutex_start = jiffies;                                    \
-       down(mutex);                                                    \
-       if (jiffies - obdfs_mutex_start)                                \
-               CDEBUG(D_CACHE, "waited on mutex %ld jiffies\n",        \
-                      jiffies - obdfs_mutex_start);                    \
+#define obd_down(mutex) {                                               \
+        /* CDEBUG(D_INFO, "get lock\n"); */                             \
+        obdfs_mutex_start = jiffies;                                    \
+        down(mutex);                                                    \
+        if (jiffies - obdfs_mutex_start)                                \
+                CDEBUG(D_CACHE, "waited on mutex %ld jiffies\n",        \
+                       jiffies - obdfs_mutex_start);                    \
 }
 
 }
 
-#define obd_up(mutex) {                                                        \
-       up(mutex);                                                      \
-       if (jiffies - obdfs_mutex_start > 1)                            \
-               CDEBUG(D_CACHE, "held mutex for %ld jiffies\n",         \
-                      jiffies - obdfs_mutex_start);                    \
-       /* CDEBUG(D_INFO, "free lock\n"); */                            \
+#define obd_up(mutex) {                                                 \
+        up(mutex);                                                      \
+        if (jiffies - obdfs_mutex_start > 1)                            \
+                CDEBUG(D_CACHE, "held mutex for %ld jiffies\n",         \
+                       jiffies - obdfs_mutex_start);                    \
+        /* CDEBUG(D_INFO, "free lock\n"); */                            \
 }
 
 /* We track if a page has been added to the OBD page cache by stting a
 }
 
 /* We track if a page has been added to the OBD page cache by stting a
@@ -158,66 +270,66 @@ static inline struct list_head *obdfs_slist(struct inode *inode)
  * used for a while.
  */
 #define PG_obdcache 29
  * used for a while.
  */
 #define PG_obdcache 29
-#define OBDAddCachePage(page)  test_and_set_bit(PG_obdcache, &(page)->flags)
-#define OBDClearCachePage(page)        clear_bit(PG_obdcache, &(page)->flags)
+#define OBDAddCachePage(page)   test_and_set_bit(PG_obdcache, &(page)->flags)
+#define OBDClearCachePage(page) clear_bit(PG_obdcache, &(page)->flags)
 
 static inline void obdfs_print_plist(struct inode *inode) 
 {
 
 static inline void obdfs_print_plist(struct inode *inode) 
 {
-       struct list_head *page_list = obdfs_iplist(inode);
-       struct list_head *tmp;
-
-       CDEBUG(D_INFO, "inode %ld: page", inode->i_ino);
-       /* obd_down(&obdfs_i2sbi(inode)->osi_list_mutex); */
-       if (list_empty(page_list)) {
-               CDEBUG(D_INFO, " list empty\n");
-               obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
-               return;
-       }
-
-       tmp = page_list;
-       while ( (tmp = tmp->next) != page_list) {
-               struct obdfs_pgrq *pgrq;
-               pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
-               CDEBUG(D_INFO, " %p", pgrq->rq_page);
-       }
-       CDEBUG(D_INFO, "\n");
-       /* obd_up(&obdfs_i2sbi(inode)->osi_list_mutex); */
+        struct list_head *page_list = obdfs_iplist(inode);
+        struct list_head *tmp;
+
+        CDEBUG(D_INFO, "inode %ld: page", inode->i_ino);
+        /* obd_down(&obdfs_i2sbi(inode)->osi_list_mutex); */
+        if (list_empty(page_list)) {
+                CDEBUG(D_INFO, " list empty\n");
+                obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
+                return;
+        }
+
+        tmp = page_list;
+        while ( (tmp = tmp->next) != page_list) {
+                struct obdfs_pgrq *pgrq;
+                pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
+                CDEBUG(D_INFO, " %p", pgrq->rq_page);
+        }
+        CDEBUG(D_INFO, "\n");
+        /* obd_up(&obdfs_i2sbi(inode)->osi_list_mutex); */
 }
 
 static inline int obdfs_has_inline(struct inode *inode)
 {
 }
 
 static inline int obdfs_has_inline(struct inode *inode)
 {
-       return (obdfs_i2info(inode)->oi_flags & OBD_FL_INLINEDATA);
+        return (obdfs_i2info(inode)->oi_flags & OBD_FL_INLINEDATA);
 }
 
 static void inline obdfs_from_inode(struct obdo *oa, struct inode *inode)
 {
 }
 
 static void inline obdfs_from_inode(struct obdo *oa, struct inode *inode)
 {
-       struct obdfs_inode_info *oinfo = obdfs_i2info(inode);
-
-       CDEBUG(D_INFO, "src inode %ld, dst obdo %ld valid 0x%08x\n",
-              inode->i_ino, (long)oa->o_id, oa->o_valid);
-       obdo_from_inode(oa, inode);
-       if (obdfs_has_inline(inode)) {
-               CDEBUG(D_INODE, "copying inline data from inode to obdo\n");
-               memcpy(oa->o_inline, oinfo->oi_inline, OBD_INLINESZ);
-               oa->o_obdflags |= OBD_FL_INLINEDATA;
-               oa->o_valid |= OBD_MD_FLINLINE;
-       }
+        struct obdfs_inode_info *oinfo = obdfs_i2info(inode);
+
+        CDEBUG(D_INFO, "src inode %ld, dst obdo %ld valid 0x%08x\n",
+               inode->i_ino, (long)oa->o_id, oa->o_valid);
+        obdo_from_inode(oa, inode);
+        if (obdfs_has_inline(inode)) {
+                CDEBUG(D_INODE, "copying inline data from inode to obdo\n");
+                memcpy(oa->o_inline, oinfo->oi_inline, OBD_INLINESZ);
+                oa->o_obdflags |= OBD_FL_INLINEDATA;
+                oa->o_valid |= OBD_MD_FLINLINE;
+        }
 } /* obdfs_from_inode */
 
 static void inline obdfs_to_inode(struct inode *inode, struct obdo *oa)
 {
 } /* obdfs_from_inode */
 
 static void inline obdfs_to_inode(struct inode *inode, struct obdo *oa)
 {
-       struct obdfs_inode_info *oinfo = obdfs_i2info(inode);
+        struct obdfs_inode_info *oinfo = obdfs_i2info(inode);
 
 
-       CDEBUG(D_INFO, "src obdo %ld valid 0x%08x, dst inode %ld\n",
-              (long)oa->o_id, oa->o_valid, inode->i_ino);
+        CDEBUG(D_INFO, "src obdo %ld valid 0x%08x, dst inode %ld\n",
+               (long)oa->o_id, oa->o_valid, inode->i_ino);
 
 
-       obdo_to_inode(inode, oa);
+        obdo_to_inode(inode, oa);
 
 
-       if (obdo_has_inline(oa)) {
-               CDEBUG(D_INODE, "copying inline data from obdo to inode\n");
-               memcpy(oinfo->oi_inline, oa->o_inline, OBD_INLINESZ);
-               oinfo->oi_flags |= OBD_FL_INLINEDATA;
-       }
+        if (obdo_has_inline(oa)) {
+                CDEBUG(D_INODE, "copying inline data from obdo to inode\n");
+                memcpy(oinfo->oi_inline, oa->o_inline, OBD_INLINESZ);
+                oinfo->oi_flags |= OBD_FL_INLINEDATA;
+        }
 } /* obdfs_to_inode */
 
 #define NOLOCK 0
 } /* obdfs_to_inode */
 
 #define NOLOCK 0
index f73dc27..445b410 100644 (file)
@@ -301,7 +301,7 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
         dst->o_size = src->o_size;
         dst->o_blocks = src->o_blocks;
         dst->o_valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS);
         dst->o_size = src->o_size;
         dst->o_blocks = src->o_blocks;
         dst->o_valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS);
-        UnlockPage(page);
+        obd_unlock_page(page);
         __free_page(page);
 
         EXIT;
         __free_page(page);
 
         EXIT;
index 59dda5a..94aea02 100755 (executable)
@@ -97,30 +97,30 @@ use IO::Handle;
 # this may be different on other architectures
 
 # we use 32-bit integers for all 64-bit quantities in this program
 # this may be different on other architectures
 
 # we use 32-bit integers for all 64-bit quantities in this program
-# #define OBD_INLINESZ 60
-# #define OBD_OBDMDSZ  60
+# #define OBD_INLINESZ  60
+# #define OBD_OBDMDSZ   60
 # /* Note: 64-bit types are 64-bit aligned in structure */
 # struct obdo {
 # /* 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[60];
-#      char                    o_obdmd[60];
-#      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[60];
+#       char                    o_obdmd[60];
+#       struct list_head        o_list;
+#       struct obd_ops          *o_op;
 # };
 
 sub obdo_pack {
 # };
 
 sub obdo_pack {
@@ -139,9 +139,9 @@ sub obdo_pack {
     $obdo->{gid},
     $obdo->{flags},
     $obdo->{obdflags},
     $obdo->{gid},
     $obdo->{flags},
     $obdo->{obdflags},
-    $obdo->{nlink},    
-    $obdo->{generation},       
-    $obdo->{valid},    
+    $obdo->{nlink},     
+    $obdo->{generation},        
+    $obdo->{valid},     
     $obdo->{inline},
     $obdo->{obdmd},
     0, 0, # struct list_head 
     $obdo->{inline},
     $obdo->{obdmd},
     0, 0, # struct list_head 
@@ -245,7 +245,7 @@ my %commands =
     );
 
 #
     );
 
 #
-#      setup completion function
+#       setup completion function
 #
 my @jcm_cmd_list = keys %commands;
 
 #
 my @jcm_cmd_list = keys %commands;
 
@@ -258,9 +258,9 @@ Device($::device);
 
 sub readl {
     if ( $file ) {
 
 sub readl {
     if ( $file ) {
-       my $str = <STDIN>;
-       chop($str);
-       return $str;
+        my $str = <STDIN>;
+        chop($str);
+        return $str;
     } else {
         return $term->readline(@_);
     }
     } else {
         return $term->readline(@_);
     }
@@ -278,7 +278,7 @@ if ( $file ) {
     $term = new Term::ReadLine 'obdcontrol ';
     $attribs = $term->Attribs;
     $attribs->{attempted_completion_function} = \&completeme;
     $term = new Term::ReadLine 'obdcontrol ';
     $attribs = $term->Attribs;
     $attribs->{attempted_completion_function} = \&completeme;
-    $term->ornaments('md,me,,');       # bold face prompt
+    $term->ornaments('md,me,,');        # bold face prompt
     
     # make sure stdout is not buffered
     STDOUT->autoflush(1);
     
     # make sure stdout is not buffered
     STDOUT->autoflush(1);
@@ -292,9 +292,9 @@ if ( $file ) {
 sub completeme {
     my ($text, $line, $start, $end) = @_;
     if (substr($line, 0, $start) =~ /^\s*$/) {
 sub completeme {
     my ($text, $line, $start, $end) = @_;
     if (substr($line, 0, $start) =~ /^\s*$/) {
-       $attribs->{completion_word} = \@jcm_cmd_list;
-       return $term->completion_matches($text,
-                                        $attribs->{'list_completion_function'});
+        $attribs->{completion_word} = \@jcm_cmd_list;
+        return $term->completion_matches($text,
+                                         $attribs->{'list_completion_function'});
     }
 }
 
     }
 }
 
@@ -303,7 +303,7 @@ sub find_command {
     my $name;
     my @completions = completeme($given, $given, 0, length($given));
     if ($#completions == 0) {
     my $name;
     my @completions = completeme($given, $given, 0, length($given));
     if ($#completions == 0) {
-       $name = shift @completions;
+        $name = shift @completions;
     }
 
     return $name;
     }
 
     return $name;
@@ -325,17 +325,17 @@ sub execute_line {
 
     my $cmd;
     if ( $file ) {
 
     my $cmd;
     if ( $file ) {
-       $cmd = $word;
+        $cmd = $word;
     } else {
     } else {
-       $cmd = find_command($word);
+        $cmd = find_command($word);
     }
     unless ($cmd) {
     }
     unless ($cmd) {
-       printf STDERR "$word: No such command, or not unique.\n";
-       return (-1);
+        printf STDERR "$word: No such command, or not unique.\n";
+        return (-1);
     }
 
     if ($cmd eq "help" || $cmd eq "exit" || $cmd eq "quit") {
     }
 
     if ($cmd eq "help" || $cmd eq "exit" || $cmd eq "quit") {
-       return (&{$commands{$cmd}->{func}}(@cmdline));
+        return (&{$commands{$cmd}->{func}}(@cmdline));
     }
 
     # Call the function.
     }
 
     # Call the function.
@@ -348,11 +348,11 @@ sub Device {
     my $device = shift;
 
     if ($::client_id) {
     my $device = shift;
 
     if ($::client_id) {
-       print "Disconnecting active session ($::client_id)...";
-       Disconnect($::client_id);
+        print "Disconnecting active session ($::client_id)...";
+        Disconnect($::client_id);
     }
     if (! $device ) {
     }
     if (! $device ) {
-       $device = "/dev/obd0";
+        $device = "/dev/obd0";
     }
     $::device = $device;
     # Open the device, as we need an FD for the ioctl
     }
     $::device = $device;
     # Open the device, as we need an FD for the ioctl
@@ -368,33 +368,33 @@ sub Attach {
     my $datalen = 0;
 
     if ( ! $type ) {
     my $datalen = 0;
 
     if ( ! $type ) {
-       print "error: missing type\n";
+        print "error: missing type\n";
 usage:
 usage:
-       print "usage: attach {obdext2 | obdsnap | obdscsi}\n";
-       return;
+        print "usage: attach {obdext2 | obdsnap | obdscsi}\n";
+        return;
     }
 
     if ($type eq "obdscsi" ) {
     }
 
     if ($type eq "obdscsi" ) {
-       my $adapter = shift;
-       my $bus = shift;
-       my $tid = shift;
-       my $lun = shift;
+        my $adapter = shift;
+        my $bus = shift;
+        my $tid = shift;
+        my $lun = shift;
 
 
-       $data = pack("iiii", $adapter, $bus, $tid, $lun);
-       $datalen = 4 * 4;
+        $data = pack("iiii", $adapter, $bus, $tid, $lun);
+        $datalen = 4 * 4;
     } elsif ($type eq "obdsnap" ) {
     } elsif ($type eq "obdsnap" ) {
-       my $snapdev = shift;
-       my $snapidx = shift;
-       my $tableno = shift;
+        my $snapdev = shift;
+        my $snapidx = shift;
+        my $tableno = shift;
 
 
-       $data = pack("iii", $snapdev, $snapidx, $tableno);
-       $datalen = 3 * 4;
+        $data = pack("iii", $snapdev, $snapidx, $tableno);
+        $datalen = 3 * 4;
     } elsif ($type eq "obdext2") {
     } elsif ($type eq "obdext2") {
-       $data = pack("i", 4711);   # bogus data
-       $datalen = 0;
+        $data = pack("i", 4711);   # bogus data
+        $datalen = 0;
     } else {
     } else {
-       print "error: unknown attach type $type\n";
-       goto usage;
+        print "error: unknown attach type $type\n";
+        goto usage;
     }
 
     my $len = length($type);
     }
 
     my $len = length($type);
@@ -406,11 +406,11 @@ usage:
     my $rc = ioctl(DEV_OBD, &OBD_IOC_ATTACH, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_ATTACH, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -421,19 +421,19 @@ sub Detach {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DETACH, $data);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DETACH, $data);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 
 sub TestExt2Iterator { 
     if (!defined($::client_id)) {
     }
 }
 
 
 sub TestExt2Iterator { 
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $err = 0;
     }
 
     my $err = 0;
@@ -450,19 +450,19 @@ sub TestExt2Iterator {
     my $rc = ioctl(DEV_OBD, &OBD_EXT2_RUNIT, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_EXT2_RUNIT, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 
 sub SnapDelete { 
     if (!defined($::client_id)) {
     }
 }
 
 
 sub SnapDelete { 
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $err = 0;
     }
 
     my $err = 0;
@@ -481,11 +481,11 @@ sub SnapDelete {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_DELETE, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_DELETE, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -499,32 +499,32 @@ sub SnapRestore {
 
     # don't do anything until connected
     if (!defined($::client_id)) {
 
     # don't do anything until connected
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     if ( ! $snaptable || ! defined $restoreto ) {
     }
 
     if ( ! $snaptable || ! defined $restoreto ) {
-       print "Usage: snaprestore \"restore to slot\" \"snaptable\" \"tableno\"\n";
-       return;
+        print "Usage: snaprestore \"restore to slot\" \"snaptable\" \"tableno\"\n";
+        return;
     }
 
     if ( ! -f $snaptable ) {
     }
 
     if ( ! -f $snaptable ) {
-       print "Table $snaptable doesn't exist\n";
-       return;
+        print "Table $snaptable doesn't exist\n";
+        return;
     }
    
     my $table = ReadSnapShotTable($snaptable);
     $restoretime = FindSnapInTable($table, $restoreto);
     if ( ! defined $table->{0} || ! defined $restoretime ) {
     }
    
     my $table = ReadSnapShotTable($snaptable);
     $restoretime = FindSnapInTable($table, $restoreto);
     if ( ! defined $table->{0} || ! defined $restoretime ) {
-       PrintSnapShotTable($table);
-       print "No current or $restoreto slot in this table\n";
-       return;
+        PrintSnapShotTable($table);
+        print "No current or $restoreto slot in this table\n";
+        return;
     }
 
     my $currentindex = $table->{0};
     if (  $table->{$restoretime} == $currentindex ) {
     }
 
     my $currentindex = $table->{0};
     if (  $table->{$restoretime} == $currentindex ) {
-       print "You should not restore to the current snapshot\n";
-       return;
+        print "You should not restore to the current snapshot\n";
+        return;
     }
     
     # swap the entries for 0 and $restoreto
     }
     
     # swap the entries for 0 and $restoreto
@@ -552,19 +552,19 @@ sub SnapRestore {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_RESTORE, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_RESTORE, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Snaprestore finished (success)\n";
-       delete $table->{$restoretime} if defined $restoretime;
-       # write it back
-       WriteSnapShotTable($snaptable, $table);
-       
-       # set it in the kernel
-       SnapSetTable($tableno, $snaptable);
-       # PrintSnapShotTable($table);
+        print "Snaprestore finished (success)\n";
+        delete $table->{$restoretime} if defined $restoretime;
+        # write it back
+        WriteSnapShotTable($snaptable, $table);
+        
+        # set it in the kernel
+        SnapSetTable($tableno, $snaptable);
+        # PrintSnapShotTable($table);
 
     } else {
 
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -573,14 +573,14 @@ sub FindSnapInTable {
     my $snapno =shift;
 
     foreach my $restoretime ( keys %{$table} ) {
     my $snapno =shift;
 
     foreach my $restoretime ( keys %{$table} ) {
-       if ( $table->{$restoretime} == $snapno) { 
-           print "Found key $restoretime for snapno $snapno\n";
-           return $restoretime;
-       }
+        if ( $table->{$restoretime} == $snapno) { 
+            print "Found key $restoretime for snapno $snapno\n";
+            return $restoretime;
+        }
     }
     undef;
 }
     }
     undef;
 }
-           
+            
 
 sub SnapPrint { 
     my $err = 0;
 
 sub SnapPrint { 
     my $err = 0;
@@ -598,11 +598,11 @@ sub SnapPrint {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_PRINTTABLE, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_PRINTTABLE, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -617,7 +617,7 @@ sub SnapSetTable {
     my $datalen = 0;
 
     if ( ! -f $file ) {
     my $datalen = 0;
 
     if ( ! -f $file ) {
-       print "No such file $file\n";
+        print "No such file $file\n";
     }
 
     $table = ReadSnapShotTable($file);
     }
 
     $table = ReadSnapShotTable($file);
@@ -626,15 +626,15 @@ sub SnapSetTable {
     print "Snapcount $snapcount\n";
 
     if ( ! defined $table->{0} ) {
     print "Snapcount $snapcount\n";
 
     if ( ! defined $table->{0} ) {
-       print "No current snapshot in table! First make one\n";
-       return ;
+        print "No current snapshot in table! First make one\n";
+        return ;
     }
     $data = pack("ii", $snaptableno, $snapcount);
     $datalen = 2 * 4;
     foreach my $time (sort keys %{$table}) {
     }
     $data = pack("ii", $snaptableno, $snapcount);
     $datalen = 2 * 4;
     foreach my $time (sort keys %{$table}) {
-       # XXX we should change to pack LL instead of I for times
-       $data .= pack("Ii", $time, $table->{$time});
-       $datalen += 8;
+        # XXX we should change to pack LL instead of I for times
+        $data .= pack("Ii", $time, $table->{$time});
+        $datalen += 8;
     }
 
     my $len = length($type);
     }
 
     my $len = length($type);
@@ -645,11 +645,11 @@ sub SnapSetTable {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_SETTABLE, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_SNAP_SETTABLE, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -658,7 +658,7 @@ sub SnapShotTable  {
 
     my $file = &readl("enter file name: ");
     if ( ! -f $file ) {
 
     my $file = &readl("enter file name: ");
     if ( ! -f $file ) {
-       `touch $file`;
+        `touch $file`;
     }
     my $table = ReadSnapShotTable($file);
   
     }
     my $table = ReadSnapShotTable($file);
   
@@ -675,14 +675,14 @@ sub SnapShotTable  {
     my $time = &readl("enter time or 'now' or 'current': ");
     my $oldtime = SnapFindTimeFromIdx($idx, $table);
     if (defined $oldtime) {
     my $time = &readl("enter time or 'now' or 'current': ");
     my $oldtime = SnapFindTimeFromIdx($idx, $table);
     if (defined $oldtime) {
-       print "This already exists, first clean up\n";
-       goto again;
+        print "This already exists, first clean up\n";
+        goto again;
     }
 
     if ( $time  eq 'now' ) {
     }
 
     if ( $time  eq 'now' ) {
-       $time = time;
+        $time = time;
     } elsif ( $time eq 'current' ) { 
     } elsif ( $time eq 'current' ) { 
-       $time = 0;
+        $time = 0;
     }
     $table->{$time} = $idx;
     goto again;
     }
     $table->{$time} = $idx;
     goto again;
@@ -696,7 +696,7 @@ sub SnapShotTable  {
   done:
     my $ok = &readl("OK with new table? [Yn]: ");
     unless ( $ok eq "n" )  {
   done:
     my $ok = &readl("OK with new table? [Yn]: ");
     unless ( $ok eq "n" )  {
-       WriteSnapShotTable($file, $table);
+        WriteSnapShotTable($file, $table);
     }
 }
 
     }
 }
 
@@ -705,9 +705,9 @@ sub SnapFindTimeFromIdx {
     my $table = shift;
 
     foreach my $time ( keys %{$table} ) {
     my $table = shift;
 
     foreach my $time ( keys %{$table} ) {
-       if ( $table->{$time} == $idx ) {
-           return $time;
-       }
+        if ( $table->{$time} == $idx ) {
+            return $time;
+        }
     }
     undef;
 }
     }
     undef;
 }
@@ -717,11 +717,11 @@ sub PrintSnapShotTable {
     my $time;
     
     foreach  $time ( sort keys %{$table} ) {
     my $time;
     
     foreach  $time ( sort keys %{$table} ) {
-       my $stime = localtime($time);
-       if ( ! $time ) { 
-           $stime = "current";
-       }
-       printf "Time: %s -- Index %d\n", $stime, $table->{$time};
+        my $stime = localtime($time);
+        if ( ! $time ) { 
+            $stime = "current";
+        }
+        printf "Time: %s -- Index %d\n", $stime, $table->{$time};
     }
 }
 
     }
 }
 
@@ -732,8 +732,8 @@ sub ReadSnapShotTable {
 
     open FH, "<$file";
     while ( <FH> ) {
 
     open FH, "<$file";
     while ( <FH> ) {
-       my ($time, $index) = split ;
-       $table->{$time} = $index;
+        my ($time, $index) = split ;
+        $table->{$time} = $index;
     }
     close FH;
 
     }
     close FH;
 
@@ -748,7 +748,7 @@ sub WriteSnapShotTable {
 
     open FH, ">$file";
     foreach my $time ( sort keys %{$table}  ) {
 
     open FH, ">$file";
     foreach my $time ( sort keys %{$table}  ) {
-       print FH "$time $table->{$time}\n";
+        print FH "$time $table->{$time}\n";
     }
     close FH;
 }
     }
     close FH;
 }
@@ -770,11 +770,11 @@ sub Copy {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_COPY, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_COPY, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -793,11 +793,11 @@ sub Migrate {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_MIGR, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_MIGR, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -812,11 +812,11 @@ sub Format {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_FORMATOBD, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_FORMATOBD, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -831,11 +831,11 @@ sub Partition {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_PARTITION, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_PARTITION, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -849,25 +849,25 @@ sub Setup {
     # by type here
 
     if ($arg && !defined($::st = stat($arg))) {
     # by type here
 
     if ($arg && !defined($::st = stat($arg))) {
-           print "$dev is not a valid device\n";
-           return;
+            print "$dev is not a valid device\n";
+            return;
     }
     
     if ( $arg ) {
     }
     
     if ( $arg ) {
-       $dev = $::st->rdev() unless $dev;
-       $data = pack("i", $dev);
-       $datalen = 4;
+        $dev = $::st->rdev() unless $dev;
+        $data = pack("i", $dev);
+        $datalen = 4;
     }
 
     my $packed = pack("ip", $datalen, $data);
     my $rc = ioctl(DEV_OBD, &OBD_IOC_SETUP, $packed);
 
     if (!defined $rc) {
     }
 
     my $packed = pack("ip", $datalen, $data);
     my $rc = ioctl(DEV_OBD, &OBD_IOC_SETUP, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -876,12 +876,12 @@ sub Cleanup {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_CLEANUP, $err);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_CLEANUP, $err);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
-       $::client_id = 0;
+        print "Finished (success)\n";
+        $::client_id = 0;
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -894,13 +894,13 @@ sub Connect {
     $id = unpack("I", $packed);
 
     if (!defined $rc) {
     $id = unpack("I", $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       $::client_id = $id;
-       print "Client ID     : $id\n";
-       print "Finished (success)\n";
+        $::client_id = $id;
+        print "Client ID     : $id\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -908,33 +908,33 @@ sub Disconnect {
     my $id = shift;
 
     if (!defined($id)) {
     my $id = shift;
 
     if (!defined($id)) {
-       $id = $::client_id;
+        $id = $::client_id;
     }
 
     if (!defined($id)) {
     }
 
     if (!defined($id)) {
-       print "syntax: disconnect [client ID]\n";
-       print "When client ID is not given, the last valid client ID to be returned by a\n";
-       print "connect command this session is used; there is no such ID.\n";
-       return;
+        print "syntax: disconnect [client ID]\n";
+        print "When client ID is not given, the last valid client ID to be returned by a\n";
+        print "connect command this session is used; there is no such ID.\n";
+        return;
     }
 
     my $packed = pack("L", $id);
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DISCONNECT, $packed);
 
     if (!defined $rc) {
     }
 
     my $packed = pack("L", $id);
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DISCONNECT, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       $::client_id = undef;
-       print "Finished (success)\n";
+        $::client_id = undef;
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Create {
     if (!defined($::client_id)) {
     }
 }
 
 sub Create {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $num = shift;
     }
 
     my $num = shift;
@@ -948,45 +948,45 @@ sub Create {
     }
 
     if (!defined($mode)) {
     }
 
     if (!defined($mode)) {
-        $mode = 0100644;        # create a file (rw-r--r--) if not specified
+        $mode = 0100644;         # create a file (rw-r--r--) if not specified
     }
 
     if (scalar($num) < 1 || defined($quiet) && $quiet ne "quiet") {
     }
 
     if (scalar($num) < 1 || defined($quiet) && $quiet ne "quiet") {
-       print "usage: create [<number of objects> [<mode> [quiet]]]\n";
-       return;
+        print "usage: create [<number of objects> [<mode> [quiet]]]\n";
+        return;
     }
 
     my $i;
     }
 
     my $i;
-    my $id = 0;                        # can't currently request IDs
+    my $id = 0;                 # can't currently request IDs
 
     print "Creating " . scalar($num) . " object";
     if (scalar($num) > 1) {
 
     print "Creating " . scalar($num) . " object";
     if (scalar($num) > 1) {
-       print "s";
+        print "s";
     }
     print "\n";
 
     for ($i = 0; $i < scalar($num); $i++) {
     }
     print "\n";
 
     for ($i = 0; $i < scalar($num); $i++) {
-       my $obdo;
-       $obdo->{id} = $id;
-       $obdo->{mode} = scalar($mode);
-       $obdo->{valid} = &OBD_MD_FLMODE;
+        my $obdo;
+        $obdo->{id} = $id;
+        $obdo->{mode} = scalar($mode);
+        $obdo->{valid} = &OBD_MD_FLMODE;
 
 
-       my $packed = pack("I", $::client_id) . obdo_pack($obdo);
-       $rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $packed);
-       if ($rc ne "0 but true") {
-           last;
-       } elsif (!defined($quiet)) {
-           $obdo = obdo_unpack($packed, 4);
-           print "Created object #$obdo->{id}.\n";
-       }
+        my $packed = pack("I", $::client_id) . obdo_pack($obdo);
+        $rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $packed);
+        if ($rc ne "0 but true") {
+            last;
+        } elsif (!defined($quiet)) {
+            $obdo = obdo_unpack($packed, 4);
+            print "Created object #$obdo->{id}.\n";
+        }
     }
 
     if (!defined $rc) {
     }
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -995,25 +995,25 @@ sub Sync {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_SYNC, $err);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_SYNC, $err);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Destroy {
     if (!defined($::client_id)) {
     }
 }
 
 sub Destroy {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $id = shift;
 
     if (!defined($id) || scalar($id) < 1) {
     }
 
     my $id = shift;
 
     if (!defined($id) || scalar($id) < 1) {
-       print "usage: destroy <object number>\n";
-       return;
+        print "usage: destroy <object number>\n";
+        return;
     }
 
     print "Destroying object $id...\n";
     }
 
     print "Destroying object $id...\n";
@@ -1021,25 +1021,25 @@ sub Destroy {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DESTROY, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DESTROY, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Getattr {
     if (!defined($::client_id)) {
     }
 }
 
 sub Getattr {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $id = shift;
 
     if (!defined($id) || scalar($id) < 1) {
     }
 
     my $id = shift;
 
     if (!defined($id) || scalar($id) < 1) {
-       print "invalid arguments; type \"help getattr\" for a synopsis\n";
-       return;
+        print "invalid arguments; type \"help getattr\" for a synopsis\n";
+        return;
     }
 
     # see Setattr
     }
 
     # see Setattr
@@ -1050,26 +1050,26 @@ sub Getattr {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_GETATTR, $packed);
     
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_GETATTR, $packed);
     
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       $obdo = obdo_unpack($packed,  4); 
-       obdo_print($obdo);
+        $obdo = obdo_unpack($packed,  4); 
+        obdo_print($obdo);
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Setattr {
     if (!defined($::client_id)) {
     }
 }
 
 sub Setattr {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $id = shift;
 
     if (!defined($id) || scalar($id) < 1) {
     }
 
     my $id = shift;
 
     if (!defined($id) || scalar($id) < 1) {
-       print "invalid arguments; type \"help setattr\" for a synopsis\n";
-       return;
+        print "invalid arguments; type \"help setattr\" for a synopsis\n";
+        return;
     }
 
     # XXX we do not currently set all of the fields in the obdo
     }
 
     # XXX we do not currently set all of the fields in the obdo
@@ -1085,25 +1085,25 @@ sub Setattr {
     $obdo->{valid} = 0;
 
     if (defined($obdo->{atime})) {
     $obdo->{valid} = 0;
 
     if (defined($obdo->{atime})) {
-       $obdo->{valid} |= &OBD_MD_FLATIME;
+        $obdo->{valid} |= &OBD_MD_FLATIME;
     }
     if (defined($obdo->{mtime})) {
     }
     if (defined($obdo->{mtime})) {
-       $obdo->{valid} |= &OBD_MD_FLMTIME;
+        $obdo->{valid} |= &OBD_MD_FLMTIME;
     }
     if (defined($obdo->{ctime})) {
     }
     if (defined($obdo->{ctime})) {
-       $obdo->{valid} |= &OBD_MD_FLCTIME;
+        $obdo->{valid} |= &OBD_MD_FLCTIME;
     }
     if (defined($obdo->{size})) {
     }
     if (defined($obdo->{size})) {
-       $obdo->{valid} |= &OBD_MD_FLSIZE;
+        $obdo->{valid} |= &OBD_MD_FLSIZE;
     }
     if (defined($obdo->{mode})) {
     }
     if (defined($obdo->{mode})) {
-       $obdo->{valid} |= &OBD_MD_FLMODE;
+        $obdo->{valid} |= &OBD_MD_FLMODE;
     }
     if (defined($obdo->{uid})) {
     }
     if (defined($obdo->{uid})) {
-       $obdo->{valid} |= &OBD_MD_FLUID;
+        $obdo->{valid} |= &OBD_MD_FLUID;
     }
     if (defined($obdo->{gid})) {
     }
     if (defined($obdo->{gid})) {
-       $obdo->{valid} |= &OBD_MD_FLGID;
+        $obdo->{valid} |= &OBD_MD_FLGID;
     }
 
     printf "valid is %x, mode is %o\n", $obdo->{valid}, $obdo->{mode};
     }
 
     printf "valid is %x, mode is %o\n", $obdo->{valid}, $obdo->{mode};
@@ -1111,18 +1111,18 @@ sub Setattr {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_SETATTR, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_SETATTR, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Read {
     if (!defined($::client_id)) {
     }
 }
 
 sub Read {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $id = shift;
     }
 
     my $id = shift;
@@ -1130,17 +1130,17 @@ sub Read {
     my $offset = shift;
   
     if (!defined($id) || scalar($id) < 1 || !defined($count) ||
     my $offset = shift;
   
     if (!defined($id) || scalar($id) < 1 || !defined($count) ||
-       $count < 1 || (defined($offset) && $offset < 0)) {
-       print "invalid arguments; type \"help read\" for a synopsis\n";
-       return;
+        $count < 1 || (defined($offset) && $offset < 0)) {
+        print "invalid arguments; type \"help read\" for a synopsis\n";
+        return;
     }
 
     if (!defined($offset)) {
     }
 
     if (!defined($offset)) {
-       $offset = 0;
+        $offset = 0;
     }
 
     print("Reading $count bytes starting at byte $offset from object " .
     }
 
     print("Reading $count bytes starting at byte $offset from object " .
-         "$id...\n");
+          "$id...\n");
 
     # "allocate" a large enough buffer
     my $buf = sprintf("%${count}s", " ");
 
     # "allocate" a large enough buffer
     my $buf = sprintf("%${count}s", " ");
@@ -1151,31 +1151,31 @@ sub Read {
 
     # the perl we're using doesn't support pack type Q, and offset is 64 bits
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
 
     # the perl we're using doesn't support pack type Q, and offset is 64 bits
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
-                pack("p LL LL", $buf, $count, $offset);
+                 pack("p LL LL", $buf, $count, $offset);
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_READ, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_READ, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       if ($retval >= 0) {
-               print substr($buf, 0, $retval);
-               print "\nRead $retval of an attempted $count bytes.\n";
-               print "Finished (success)\n";
-       } else {
-               print "Finished (error $retval)\n";
-       }
+        if ($retval >= 0) {
+                print substr($buf, 0, $retval);
+                print "\nRead $retval of an attempted $count bytes.\n";
+                print "Finished (success)\n";
+        } else {
+                print "Finished (error $retval)\n";
+        }
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Read2 {
     if (!defined($::client_id)) {
     }
 }
 
 sub Read2 {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $id = shift;
     }
 
     my $id = shift;
@@ -1183,17 +1183,17 @@ sub Read2 {
     my $offset = shift;
   
     if (!defined($id) || scalar($id) < 1 || !defined($count) ||
     my $offset = shift;
   
     if (!defined($id) || scalar($id) < 1 || !defined($count) ||
-       $count < 1 || (defined($offset) && $offset < 0)) {
-       print "invalid arguments; type \"help read\" for a synopsis\n";
-       return;
+        $count < 1 || (defined($offset) && $offset < 0)) {
+        print "invalid arguments; type \"help read\" for a synopsis\n";
+        return;
     }
 
     if (!defined($offset)) {
     }
 
     if (!defined($offset)) {
-       $offset = 0;
+        $offset = 0;
     }
 
     print("Reading $count bytes starting at byte $offset from object " .
     }
 
     print("Reading $count bytes starting at byte $offset from object " .
-         "$id...\n");
+          "$id...\n");
 
     # "allocate" a large enough buffer
     my $buf = sprintf("%${count}s", " ");
 
     # "allocate" a large enough buffer
     my $buf = sprintf("%${count}s", " ");
@@ -1204,31 +1204,31 @@ sub Read2 {
 
     # the perl we're using doesn't support pack type Q, and offset is 64 bits
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
 
     # the perl we're using doesn't support pack type Q, and offset is 64 bits
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
-                pack("p LL LL", $buf, $count, $offset);
+                 pack("p LL LL", $buf, $count, $offset);
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_READ2, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_READ2, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       if ($retval >= 0) {
-               print substr($buf, 0, $retval);
-               print "\nRead $retval of an attempted $count bytes.\n";
-               print "Finished (success)\n";
-       } else {
-               print "Finished (error $retval)\n";
-       }
+        if ($retval >= 0) {
+                print substr($buf, 0, $retval);
+                print "\nRead $retval of an attempted $count bytes.\n";
+                print "Finished (success)\n";
+        } else {
+                print "Finished (error $retval)\n";
+        }
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Write {
     if (!defined($::client_id)) {
     }
 }
 
 sub Write {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $id = shift;
     }
 
     my $id = shift;
@@ -1237,14 +1237,14 @@ sub Write {
     my $count = length($text);
 
     if (!defined($id) || scalar($id) < 1 || !defined($offset) ||
     my $count = length($text);
 
     if (!defined($id) || scalar($id) < 1 || !defined($offset) ||
-       scalar($offset) < 0) {
-       print "invalid arguments; type \"help write\" for a synopsis\n";
-       return;
+        scalar($offset) < 0) {
+        print "invalid arguments; type \"help write\" for a synopsis\n";
+        return;
     }
 
     if (!defined($text)) {
     }
 
     if (!defined($text)) {
-       $text = "";
-       $count = 0;
+        $text = "";
+        $count = 0;
     }
 
     print("Writing $count bytes starting at byte $offset to object $id...\n");
     }
 
     print("Writing $count bytes starting at byte $offset to object $id...\n");
@@ -1254,30 +1254,30 @@ sub Write {
 
     # the perl we're using doesn't support pack type Q
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
 
     # the perl we're using doesn't support pack type Q
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
-                pack("p LL LL", $buf, $count, $offset);
+                 pack("p LL LL", $text, $count, $offset);
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_WRITE, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_WRITE, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       if ($retval >= 0) {
-               print "\nWrote $retval of an attempted $count bytes.\n";
-               print "Finished (success)\n";
-       } else {
-               print "Finished (error $retval)\n";
-       }
+        if ($retval >= 0) {
+                print "\nWrote $retval of an attempted $count bytes.\n";
+                print "Finished (success)\n";
+        } else {
+                print "Finished (error $retval)\n";
+        }
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Punch {
     if (!defined($::client_id)) {
     }
 }
 
 sub Punch {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     my $id = shift;
     }
 
     my $id = shift;
@@ -1285,9 +1285,9 @@ sub Punch {
     my $count = shift;
 
     if (!defined($id) || scalar($id) < 1 || !defined($start) ||
     my $count = shift;
 
     if (!defined($id) || scalar($id) < 1 || !defined($start) ||
-       scalar($start) < 0 || !defined($count) || scalar($count) < 0) {
-       print "invalid arguments; type \"help punch\" for a synopsis\n";
-       return;
+        scalar($start) < 0 || !defined($count) || scalar($count) < 0) {
+        print "invalid arguments; type \"help punch\" for a synopsis\n";
+        return;
     }
 
     print("Punching $count bytes starting at byte $start from object $id...\n");
     }
 
     print("Punching $count bytes starting at byte $start from object $id...\n");
@@ -1297,23 +1297,23 @@ sub Punch {
 
     # the perl we're using doesn't support pack type Q
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
 
     # the perl we're using doesn't support pack type Q
     my $packed = pack("L", $::client_id) . obdo_pack($obdo) .
-                pack("p LL LL", $buf, $start, $count);
+                 pack("p LL LL", $buf, $start, $count);
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_PUNCH, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_PUNCH, $packed);
 
     $retval = unpack("l", $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       if ($retval >= 0) {
-               print "\nPunched $retval of an attempted $count bytes.\n";
-               print "Finished (success)\n";
-       } else {
-               print "Finished (error $retval)\n";
-       }
+        if ($retval >= 0) {
+                print "\nPunched $retval of an attempted $count bytes.\n";
+                print "Finished (success)\n";
+        } else {
+                print "Finished (error $retval)\n";
+        }
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -1321,12 +1321,12 @@ sub Preallocate {
     my $num = shift;
 
     if (!defined($::client_id)) {
     my $num = shift;
 
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     if (!defined($num) || scalar($num) < 1 || scalar($num) > 32) {
     }
 
     if (!defined($num) || scalar($num) < 1 || scalar($num) > 32) {
-       $num = 32;
+        $num = 32;
     }
 
     print "Preallocating $num objects...\n";
     }
 
     print "Preallocating $num objects...\n";
@@ -1336,19 +1336,19 @@ sub Preallocate {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_PREALLOCATE, $packed);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_PREALLOCATE, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       my $alloc = unpack("x4L", $packed);
-       my @ids = unpack("x8L32", $packed);
-       my $i;
-
-       print "Got $alloc objects: ";
-       foreach $i (@ids) {
-           print $i . " ";
-       }
-       print "\nFinished (success)\n";
+        my $alloc = unpack("x4L", $packed);
+        my @ids = unpack("x8L32", $packed);
+        my $i;
+
+        print "Got $alloc objects: ";
+        foreach $i (@ids) {
+            print $i . " ";
+        }
+        print "\nFinished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -1356,18 +1356,18 @@ sub Decusecount {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DEC_USE_COUNT, 0);
 
     if (!defined $rc) {
     my $rc = ioctl(DEV_OBD, &OBD_IOC_DEC_USE_COUNT, 0);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       print "Finished (success)\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
 sub Statfs {
     if (!defined($::client_id)) {
     }
 }
 
 sub Statfs {
     if (!defined($::client_id)) {
-       print "You must first ``connect''.\n";
-       return;
+        print "You must first ``connect''.\n";
+        return;
     }
 
     # struct statfs {
     }
 
     # struct statfs {
@@ -1384,22 +1384,22 @@ sub Statfs {
     # };
 
     my $packed = pack("LLLLLLLIILL6", $::client_id, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     # };
 
     my $packed = pack("LLLLLLLIILL6", $::client_id, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                     0, 0, 0, 0, 0, 0);
+                      0, 0, 0, 0, 0, 0);
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_STATFS, $packed);
 
     if (!defined $rc) {
 
     my $rc = ioctl(DEV_OBD, &OBD_IOC_STATFS, $packed);
 
     if (!defined $rc) {
-       print STDERR "ioctl failed: $!\n";
+        print STDERR "ioctl failed: $!\n";
     } elsif ($rc eq "0 but true") {
     } elsif ($rc eq "0 but true") {
-       # skip both the conn_id and the fs_type in the buffer
-       my ($bsize, $blocks, $bfree, $bavail, $files, $ffree) =
-           unpack("x4x4LLLLLL", $packed);
-       print("$bsize byte blocks: $blocks, " . ($blocks - $bfree) . " used, " .
-             "$bfree free ($bavail available).\n");
-       print "$files files, " . ($files - $ffree) . " used, $ffree free.\n";
-       print "Finished (success)\n";
+        # skip both the conn_id and the fs_type in the buffer
+        my ($bsize, $blocks, $bfree, $bavail, $files, $ffree) =
+            unpack("x4x4LLLLLL", $packed);
+        print("$bsize byte blocks: $blocks, " . ($blocks - $bfree) . " used, " .
+              "$bfree free ($bavail available).\n");
+        print "$files files, " . ($files - $ffree) . " used, $ffree free.\n";
+        print "Finished (success)\n";
     } else {
     } else {
-       print "ioctl returned error code $rc.\n";
+        print "ioctl returned error code $rc.\n";
     }
 }
 
     }
 }
 
@@ -1407,16 +1407,16 @@ sub Help {
     my $cmd = shift;
 
     if ( !$cmd || !$commands{$cmd} ) {
     my $cmd = shift;
 
     if ( !$cmd || !$commands{$cmd} ) {
-       print "Comands: ", join( ' ', @jcm_cmd_list), "\n";
+        print "Comands: ", join( ' ', @jcm_cmd_list), "\n";
     } else {
     } else {
-       print "Usage: " .  $commands{$cmd}->{doc} . "\n";
+        print "Usage: " .  $commands{$cmd}->{doc} . "\n";
     }
 }
 
 sub Quit {
     if ($::client_id) {
     }
 }
 
 sub Quit {
     if ($::client_id) {
-       print "Disconnecting active session ($::client_id)...";
-       Disconnect($::client_id);
+        print "Disconnecting active session ($::client_id)...";
+        Disconnect($::client_id);
     }
     exit;
 }
     }
     exit;
 }
index 56db69a..59e6fb0 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/errno.h>
 #include <linux/fs.h>
 
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
 #include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
 #include <linux/obdfs.h>
 
 static ssize_t obdfs_dir_read (struct file * filp, char * buf,
 #include <linux/obdfs.h>
 
 static ssize_t obdfs_dir_read (struct file * filp, char * buf,
-                             size_t count, loff_t *ppos)
+                              size_t count, loff_t *ppos)
 {
 {
-       return -EISDIR;
+        return -EISDIR;
 }
 
 static int obdfs_readdir(struct file *, void *, filldir_t);
 
 struct file_operations obdfs_dir_operations = {
 }
 
 static int obdfs_readdir(struct file *, void *, filldir_t);
 
 struct file_operations obdfs_dir_operations = {
-       NULL,                   /* lseek - default */
-       obdfs_dir_read,         /* read */
-       NULL,                   /* write - bad */
-       obdfs_readdir,          /* readdir */
-       NULL,                   /* poll - default */
-       NULL,                   /* ioctl */
-       NULL,                   /* mmap */
-       NULL,                   /* no special open code */
-       NULL,                   /* flush */
-       NULL,                   /* no special release code */
-       NULL,                   /* fsync */
-       NULL,                   /* fasync */
-       NULL                    /* lock */
+        read: obdfs_dir_read,
+        readdir: obdfs_readdir
 };
 
 struct inode_operations obdfs_dir_inode_operations = {
 };
 
 struct inode_operations obdfs_dir_inode_operations = {
-       &obdfs_dir_operations,  /* default directory file-ops */
-       obdfs_create,           /* create */
-       obdfs_lookup,           /* lookup */
-       obdfs_link,             /* link */
-       obdfs_unlink,           /* unlink */
-       obdfs_symlink,          /* symlink */
-       obdfs_mkdir,            /* mkdir */
-       obdfs_rmdir,            /* rmdir */
-       obdfs_mknod,            /* mknod */
-       obdfs_rename,           /* rename */
-       NULL,                   /* readlink */
-       NULL,                   /* follow_link */
-       NULL,                   /* get_block */
-       obdfs_readpage,         /* readpage */
-       obdfs_writepage,        /* writepage */
-       obdfs_truncate,         /* truncate */
-       NULL,                   /* permission */
-       NULL                    /* revalidate */
+        create: obdfs_create,
+        lookup: obdfs_lookup,
+        link: obdfs_link,
+        unlink: obdfs_unlink,
+        symlink: obdfs_symlink,
+        mkdir: obdfs_mkdir,
+        rmdir: obdfs_rmdir,
+        mknod: obdfs_mknod,
+        rename: obdfs_rename,
+        truncate: obdfs_truncate
 };
 
 int obdfs_check_dir_entry (const char * function, struct inode * dir,
 };
 
 int obdfs_check_dir_entry (const char * function, struct inode * dir,
-                         struct ext2_dir_entry_2 * de,
-                         struct page * page,
-                         unsigned long offset)
+                          struct ext2_dir_entry_2 * de,
+                          struct page * page,
+                          unsigned long offset)
 {
 {
-       const char * error_msg = NULL;
-       return 1;
-
-       ENTRY;
-       if ( !de ) {
-               error_msg = "null de passed";
-               return 1;
-       }
-
-       if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
-               error_msg = "rec_len is smaller than minimal";
-       else if (le16_to_cpu(de->rec_len) % 4 != 0)
-               error_msg = "rec_len % 4 != 0";
-       else if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(de->name_len))
-               error_msg = "rec_len is too small for name_len";
-       else if (dir && ((char *) de - (char *)page_address(page)) + le16_to_cpu(de->rec_len) >
-                dir->i_sb->s_blocksize)
-               error_msg = "directory entry across blocks";
+        const char * error_msg = NULL;
+        return 1;
+
+        ENTRY;
+        if ( !de ) {
+                error_msg = "null de passed";
+                return 1;
+        }
+
+        if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
+                error_msg = "rec_len is smaller than minimal";
+        else if (le16_to_cpu(de->rec_len) % 4 != 0)
+                error_msg = "rec_len % 4 != 0";
+        else if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(de->name_len))
+                error_msg = "rec_len is too small for name_len";
+        else if (dir && ((char *) de - (char *)page_address(page)) + le16_to_cpu(de->rec_len) >
+                 dir->i_sb->s_blocksize)
+                error_msg = "directory entry across blocks";
 #if 0 /* this one doesn't yet work for OBDFS */
 #if 0 /* this one doesn't yet work for OBDFS */
-       else 
+        else 
 
 if (dir && le32_to_cpu(de->inode) > le32_to_cpu(dir->i_sb->u.ext2_sb.s_es->s_inodes_count))
 
 if (dir && le32_to_cpu(de->inode) > le32_to_cpu(dir->i_sb->u.ext2_sb.s_es->s_inodes_count))
-               error_msg = "inode out of bounds";
+                error_msg = "inode out of bounds";
 #endif
 #endif
-       if (error_msg != NULL)
-               ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
-                           "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
-                           dir->i_ino, error_msg, offset,
-                           (unsigned long) le32_to_cpu(de->inode),
-                           le16_to_cpu(de->rec_len), de->name_len);
-       EXIT;
-       return error_msg == NULL ? 1 : 0;
+        if (error_msg != NULL)
+                ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
+                            "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+                            dir->i_ino, error_msg, offset,
+                            (unsigned long) le32_to_cpu(de->inode),
+                            le16_to_cpu(de->rec_len), de->name_len);
+        EXIT;
+        return error_msg == NULL ? 1 : 0;
 }
 
 
 static int obdfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
 }
 
 
 static int obdfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-       int error = 0;
-       unsigned long offset;
-       int stored;
-       struct ext2_dir_entry_2 * de;
-       struct super_block * sb;
-       struct page *page;
-       struct inode *inode = filp->f_dentry->d_inode;
-
-       ENTRY;
-
-       sb = inode->i_sb;
-
-       stored = 0;
-       offset = filp->f_pos & (PAGE_SIZE - 1);
-
-       OIDEBUG(inode);
-       while (!error && !stored && filp->f_pos < inode->i_size) {
-               page = obdfs_getpage(inode, filp->f_pos, 0, LOCKED);
-               /* PDEBUG(page, "readdir"); */
-               if (!page) {
-                       ext2_error (sb, "ext2_readdir",
-                                   "directory #%lu contains a hole at offset %lu",
-                                   inode->i_ino, (unsigned long)filp->f_pos);
-                       filp->f_pos += PAGE_SIZE - offset;
-                       continue;
-               }
+        int error = 0;
+        unsigned long offset;
+        int stored;
+        struct ext2_dir_entry_2 * de;
+        struct super_block * sb;
+        struct page *page;
+        struct inode *inode = filp->f_dentry->d_inode;
+
+        ENTRY;
+
+        sb = inode->i_sb;
+
+        stored = 0;
+        offset = filp->f_pos & (PAGE_SIZE - 1);
+
+        OIDEBUG(inode);
+        while (!error && !stored && filp->f_pos < inode->i_size) {
+                page = obdfs_getpage(inode, filp->f_pos, 0, LOCKED);
+                /* PDEBUG(page, "readdir"); */
+                if (!page) {
+                        ext2_error (sb, "ext2_readdir",
+                                    "directory #%lu contains a hole at offset %lu",
+                                    inode->i_ino, (unsigned long)filp->f_pos);
+                        filp->f_pos += PAGE_SIZE - offset;
+                        continue;
+                }
 
 #if 0
 
 #if 0
-               /* XXX need to do read ahead and support stuff below */
+                /* XXX need to do read ahead and support stuff below */
 revalidate:
 revalidate:
-               /* If the dir block has changed since the last call to
-                * readdir(2), then we might be pointing to an invalid
-                * dirent right now.  Scan from the start of the block
-                * to make sure. */
-               if (filp->f_version != inode->i_version) {
-                       for (i = 0; i < sb->s_blocksize && i < offset; ) {
-                               de = (struct ext2_dir_entry_2 *) 
-                                       (bh->b_data + i);
-                               /* It's too expensive to do a full
-                                * dirent test each time round this
-                                * loop, but we do have to test at
-                                * least that it is non-zero.  A
-                                * failure will be detected in the
-                                * dirent test below. */
-                               if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
-                                       break;
-                               i += le16_to_cpu(de->rec_len);
-                       }
-                       offset = i;
-                       filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
-                               | offset;
-                       filp->f_version = inode->i_version;
-               }
-#endif         
-               while (!error && filp->f_pos < inode->i_size 
-                      && offset < PAGE_SIZE) {
-                       de = (struct ext2_dir_entry_2 *) ((char *)page_address(page) + offset);
+                /* If the dir block has changed since the last call to
+                 * readdir(2), then we might be pointing to an invalid
+                 * dirent right now.  Scan from the start of the block
+                 * to make sure. */
+                if (filp->f_version != inode->i_version) {
+                        for (i = 0; i < sb->s_blocksize && i < offset; ) {
+                                de = (struct ext2_dir_entry_2 *) 
+                                        (bh->b_data + i);
+                                /* It's too expensive to do a full
+                                 * dirent test each time round this
+                                 * loop, but we do have to test at
+                                 * least that it is non-zero.  A
+                                 * failure will be detected in the
+                                 * dirent test below. */
+                                if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
+                                        break;
+                                i += le16_to_cpu(de->rec_len);
+                        }
+                        offset = i;
+                        filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
+                                | offset;
+                        filp->f_version = inode->i_version;
+                }
+#endif          
+                while (!error && filp->f_pos < inode->i_size 
+                       && offset < PAGE_SIZE) {
+                        de = (struct ext2_dir_entry_2 *) ((char *)page_address(page) + offset);
 #if 0
 #if 0
-                       if (!obdfs_check_dir_entry ("ext2_readdir", inode, de,
-                                                  bh, offset)) {
-                               /* On error, skip the f_pos to the
+                        if (!obdfs_check_dir_entry ("ext2_readdir", inode, de,
+                                                   bh, offset)) {
+                                /* On error, skip the f_pos to the
                                    next block. */
                                    next block. */
-                               filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
-                                             + sb->s_blocksize;
-                               brelse (bh);
-                               return stored;
-                       }
+                                filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
+                                              + sb->s_blocksize;
+                                brelse (bh);
+                                return stored;
+                        }
 #endif
 #endif
-                       offset += le16_to_cpu(de->rec_len);
-                       if (le32_to_cpu(de->inode)) {
-                               /* We might block in the next section
-                                * if the data destination is
-                                * currently swapped out.  So, use a
-                                * version stamp to detect whether or
-                                * not the directory has been modified
-                                * during the copy operation.
-                                */
-                               /* XXX
-                               unsigned long version = inode->i_version;
-                                */
-                               error = filldir(dirent, de->name,
-                                               de->name_len,
-                                               filp->f_pos, le32_to_cpu(de->inode));
-                               if (error)
-                                       break;
+                        offset += le16_to_cpu(de->rec_len);
+                        if (le32_to_cpu(de->inode)) {
+                                unsigned char d_type = DT_UNKNOWN;
+                                /* We might block in the next section
+                                 * if the data destination is
+                                 * currently swapped out.  So, use a
+                                 * version stamp to detect whether or
+                                 * not the directory has been modified
+                                 * during the copy operation.
+                                 */
+                                /* XXX
+                                unsigned long version = inode->i_version;
+                                 */
+                                error = filldir
+                                        (dirent, de->name, de->name_len,
+                                         filp->f_pos, le32_to_cpu(de->inode),
+                                         d_type);
+                                if (error)
+                                        break;
 #if 0
 #if 0
-                               if (version != inode->i_version)
-                                       goto revalidate;
+                                if (version != inode->i_version)
+                                        goto revalidate;
 #endif
 #endif
-                               stored ++;
-                       }
-                       filp->f_pos += le16_to_cpu(de->rec_len);
-               }
-               offset = 0;
-               UnlockPage(page);
-               page_cache_release(page);
-       }
-       UPDATE_ATIME(inode);
-       EXIT;
-       return 0;
+                                stored ++;
+                        }
+                        filp->f_pos += le16_to_cpu(de->rec_len);
+                }
+                offset = 0;
+                obd_unlock_page(page);
+                page_cache_release(page);
+        }
+        UPDATE_ATIME(inode);
+        EXIT;
+        return 0;
 }
 }
index 4416161..7623a9a 100644 (file)
@@ -15,7 +15,7 @@
  *  ext2 fs regular file handling primitives
  *
  *  64-bit file support on 64-bit platforms by Jakub Jelinek
  *  ext2 fs regular file handling primitives
  *
  *  64-bit file support on 64-bit platforms by Jakub Jelinek
- *     (jj@sunsite.ms.mff.cuni.cz)
+ *      (jj@sunsite.ms.mff.cuni.cz)
  */
 
 #include <asm/uaccess.h>
  */
 
 #include <asm/uaccess.h>
@@ -23,7 +23,6 @@
 
 #include <linux/errno.h>
 #include <linux/fs.h>
 
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
 #include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
 
 static inline void remove_suid(struct inode *inode)
 {
 
 static inline void remove_suid(struct inode *inode)
 {
-       unsigned int mode;
+        unsigned int mode;
 
 
-       /* set S_IGID if S_IXGRP is set, and always set S_ISUID */
-       mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
+        /* set S_IGID if S_IXGRP is set, and always set S_ISUID */
+        mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
 
 
-       /* was any of the uid bits set? */
-       mode &= inode->i_mode;
-       if (mode && !capable(CAP_FSETID)) {
-               inode->i_mode &= ~mode;
-               mark_inode_dirty(inode);
-       }
+        /* was any of the uid bits set? */
+        mode &= inode->i_mode;
+        if (mode && !capable(CAP_FSETID)) {
+                inode->i_mode &= ~mode;
+                mark_inode_dirty(inode);
+        }
 }
 
 /*
 }
 
 /*
@@ -56,57 +55,40 @@ static inline void remove_suid(struct inode *inode)
 static ssize_t
 obdfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
 static ssize_t
 obdfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-       ssize_t retval;
-       CDEBUG(D_INFO, "Writing inode %ld, %d bytes, offset %ld\n",
-              file->f_dentry->d_inode->i_ino, count, (long)*ppos);
+        ssize_t retval;
+        CDEBUG(D_INFO, "Writing inode %ld, %d bytes, offset %ld\n",
+               file->f_dentry->d_inode->i_ino, count, (long)*ppos);
 
 
-       retval = generic_file_write(file, buf, count,
-                                   ppos, obdfs_write_one_page);
-       CDEBUG(D_INFO, "Wrote %d\n", retval);
-       if (retval > 0) {
-               struct inode *inode = file->f_dentry->d_inode;
-               remove_suid(inode);
-               inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-               mark_inode_dirty(inode);
-       }
-       EXIT;
-       return retval;
+        retval = generic_file_write(file, buf, count, ppos);
+        CDEBUG(D_INFO, "Wrote %d\n", retval);
+        if (retval > 0) {
+                struct inode *inode = file->f_dentry->d_inode;
+                remove_suid(inode);
+                inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+                mark_inode_dirty(inode);
+        }
+        EXIT;
+        return retval;
 }
 
 struct file_operations obdfs_file_operations = {
 }
 
 struct file_operations obdfs_file_operations = {
-       NULL,                   /* lseek - default */
-       generic_file_read,      /* read */
-       obdfs_file_write,       /* write  */
-       NULL,                   /* readdir - bad */
-       NULL,                   /* poll */
-       NULL,                   /* ioctl */
-       generic_file_mmap,      /* mmap */
-       NULL,                   /* open */
-       NULL,                   /* flush */
-       NULL,                   /* release */
-       NULL /* XXX add XXX */, /* fsync */
-       NULL,                   /* fasync */
-       NULL                    /* lock */
+        read: generic_file_read,      /* read */
+        write: obdfs_file_write,       /* write  */
+        mmap: generic_file_mmap,      /* mmap */
 };
 
 };
 
+extern int obdfs_notify_change(struct dentry *de, struct iattr *attr);
 struct inode_operations obdfs_file_inode_operations = {
 struct inode_operations obdfs_file_inode_operations = {
-       &obdfs_file_operations, /* default directory file-ops */
-       obdfs_create,           /* create */
-       obdfs_lookup,           /* lookup */
-       obdfs_link,             /* link */
-       obdfs_unlink,           /* unlink */
-       obdfs_symlink,          /* symlink */
-       obdfs_mkdir,            /* mkdir */
-       obdfs_rmdir,            /* rmdir */
-       obdfs_mknod,            /* mknod */
-       obdfs_rename,           /* rename */
-       NULL,                   /* readlink */
-       NULL,                   /* follow_link */
-       NULL,                   /* get_block */
-       obdfs_readpage,         /* readpage */
-       obdfs_writepage,        /* writepage */
-       obdfs_truncate,         /* truncate */
-       NULL,                   /* permission */
-       NULL                    /* revalidate */
+        create: obdfs_create,
+        lookup: obdfs_lookup,
+        link: obdfs_link,
+        unlink: obdfs_unlink,
+        symlink: obdfs_symlink,
+        mkdir: obdfs_mkdir,
+        rmdir: obdfs_rmdir,
+        mknod: obdfs_mknod,
+        rename: obdfs_rename,
+        truncate: obdfs_truncate,
+        setattr: obdfs_notify_change
 };
 
 };
 
index c474514..66bba9e 100644 (file)
@@ -15,7 +15,7 @@
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  *  Directory entry file type support and forward compatibility hooks
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  *  Directory entry file type support and forward compatibility hooks
- *     for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
+ *      for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
  * 
  *  Changes for use in OBDFS
  *  Copyright (c) 1999, Seagate Technology Inc.
  * 
  *  Changes for use in OBDFS
  *  Copyright (c) 1999, Seagate Technology Inc.
@@ -37,6 +37,8 @@
 #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
 #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
 #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
 #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
+
+
 /*
  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
  *
 /*
  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
  *
  * `de != NULL' is guaranteed by caller.
  */
 static inline int ext2_match (int len, const char * const name,
  * `de != NULL' is guaranteed by caller.
  */
 static inline int ext2_match (int len, const char * const name,
-                      struct ext2_dir_entry_2 * de)
+                       struct ext2_dir_entry_2 * de)
 {
 {
-       if (len != de->name_len)
-               return 0;
-       if (!de->inode)
-               return 0;
-       return !memcmp(name, de->name, len);
+        if (len != de->name_len)
+                return 0;
+        if (!de->inode)
+                return 0;
+        return !memcmp(name, de->name, len);
 }
 
 /*
 }
 
 /*
- *     obdfs_find_entry()
+ *      obdfs_find_entry()
  *
  * finds an entry in the specified directory with the wanted name. It
  * returns the cache buffer in which the entry was found, and the entry
  *
  * finds an entry in the specified directory with the wanted name. It
  * returns the cache buffer in which the entry was found, and the entry
@@ -62,126 +64,124 @@ static inline int ext2_match (int len, const char * const name,
  * entry - you'll have to do that yourself if you want to.
  */
 static struct page * obdfs_find_entry (struct inode * dir,
  * entry - you'll have to do that yourself if you want to.
  */
 static struct page * obdfs_find_entry (struct inode * dir,
-                                      const char * const name, int namelen,
-                                      struct ext2_dir_entry_2 ** res_dir,
-                                      int lock)
+                                       const char * const name, int namelen,
+                                       struct ext2_dir_entry_2 ** res_dir,
+                                       int lock)
 {
 {
-       struct super_block * sb;
-       unsigned long offset;
-       struct page * page;
-
-       ENTRY;
-       CDEBUG(D_INFO, "find entry for %*s\n", namelen, name);
-
-       *res_dir = NULL;
-       sb = dir->i_sb;
-
-       if (namelen > EXT2_NAME_LEN)
-               return NULL;
-
-       CDEBUG(D_INFO, "dirsize is %Ld\n", dir->i_size);
-
-       page = 0;
-       offset = 0;
-       while ( offset < dir->i_size ) {
-               struct ext2_dir_entry_2 * de;
-               char * dlimit;
-
-               page = obdfs_getpage(dir, offset, 0, lock);
-
-               if ( !page ) {
-                       CDEBUG(D_INFO, "No page, offset %lx\n", offset);
-                       return NULL;
-               }
-
-               de = (struct ext2_dir_entry_2 *) page_address(page);
-               dlimit = (char *)page_address(page) + PAGE_SIZE; 
-               while ((char *) de < dlimit) {
-                       /* this code is executed quadratically often */
-                       /* do minimal checking `by hand' */
-                       int de_len;
-                       /* CDEBUG(D_INFO, "Entry %p len %d, page at %#lx - %#lx , offset %lx\n",
-                              de, le16_to_cpu(de->rec_len), page_address(page),
-                              page_address(page) + PAGE_SIZE, offset); */
-
-                       if ((char *) de + namelen <= dlimit &&
-                           ext2_match (namelen, name, de)) {
-                               /* found a match -
-                                  just to be sure, do a full check */
-                               if (!obdfs_check_dir_entry("ext2_find_entry",
-                                                         dir, de, page, offset))
-                                       goto failure;
-                               *res_dir = de;
-                               EXIT;
-                               return page;
-                       }
-                       /* prevent looping on a bad block */
-                       de_len = le16_to_cpu(de->rec_len);
-                       if (de_len <= 0) {
-                               printk("Bad entry at %p len %d\n", de, de_len);
-                               goto failure;
-                       }
-                       offset += de_len;
-                       de = (struct ext2_dir_entry_2 *)
-                               ((char *) de + de_len);
-                       /* CDEBUG(D_INFO, "Next while %lx\n", offset); */
-               }
-               if ( lock ) 
-                       UnlockPage(page);
-               page_cache_release(page);
-               page = NULL;
-               CDEBUG(D_INFO, "Next for %lx\n", offset);
-       }
+        struct super_block * sb;
+        unsigned long offset;
+        struct page * page;
+
+        ENTRY;
+        CDEBUG(D_INFO, "find entry for %*s\n", namelen, name);
+
+        *res_dir = NULL;
+        sb = dir->i_sb;
+
+        if (namelen > EXT2_NAME_LEN)
+                return NULL;
+
+        CDEBUG(D_INFO, "dirsize is %Ld\n", dir->i_size);
+
+        page = 0;
+        offset = 0;
+        while ( offset < dir->i_size ) {
+                struct ext2_dir_entry_2 * de;
+                char * dlimit;
+
+                page = obdfs_getpage(dir, offset, 0, lock);
+
+                if ( !page ) {
+                        CDEBUG(D_INFO, "No page, offset %lx\n", offset);
+                        return NULL;
+                }
+
+                de = (struct ext2_dir_entry_2 *) page_address(page);
+                dlimit = (char *)page_address(page) + PAGE_SIZE; 
+                while ((char *) de < dlimit) {
+                        /* this code is executed quadratically often */
+                        /* do minimal checking `by hand' */
+                        int de_len;
+                        /* CDEBUG(D_INFO, "Entry %p len %d, page at %#lx - %#lx , offset %lx\n",
+                               de, le16_to_cpu(de->rec_len), page_address(page),
+                               page_address(page) + PAGE_SIZE, offset); */
+
+                        if ((char *) de + namelen <= dlimit &&
+                            ext2_match (namelen, name, de)) {
+                                /* found a match -
+                                   just to be sure, do a full check */
+                                if (!obdfs_check_dir_entry("ext2_find_entry",
+                                                          dir, de, page, offset))
+                                        goto failure;
+                                *res_dir = de;
+                                EXIT;
+                                return page;
+                        }
+                        /* prevent looping on a bad block */
+                        de_len = le16_to_cpu(de->rec_len);
+                        if (de_len <= 0) {
+                                printk("Bad entry at %p len %d\n", de, de_len);
+                                goto failure;
+                        }
+                        offset += de_len;
+                        de = (struct ext2_dir_entry_2 *)
+                                ((char *) de + de_len);
+                        /* CDEBUG(D_INFO, "Next while %lx\n", offset); */
+                }
+                obd_unlock_page(page);
+                page_cache_release(page);
+                page = NULL;
+                CDEBUG(D_INFO, "Next for %lx\n", offset);
+        }
 
 failure:
 
 failure:
-       CDEBUG(D_INFO, "Negative case, page %p, offset %ld\n", page, offset);
-       if (page) {
-               if (lock) 
-                       UnlockPage(page);
-               page_cache_release(page);
-       }
-       EXIT;
-       return NULL;
+        CDEBUG(D_INFO, "Negative case, page %p, offset %ld\n", page, offset);
+        if (page) {
+                obd_unlock_page(page);
+                page_cache_release(page);
+        }
+        EXIT;
+        return NULL;
 } /* obdfs_find_entry */
 
 struct dentry *obdfs_lookup(struct inode *dir, struct dentry *dentry)
 {
 } /* obdfs_find_entry */
 
 struct dentry *obdfs_lookup(struct inode *dir, struct dentry *dentry)
 {
-       struct inode * inode;
-       struct ext2_dir_entry_2 * de;
-       struct page *page;
-       ENTRY;
-
-       if (dentry->d_name.len > EXT2_NAME_LEN)
-               return ERR_PTR(-ENAMETOOLONG);
-
-       page = obdfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
-                               &de, LOCKED);
-       inode = NULL;
-       if ( !page ) 
-               CDEBUG(D_INFO, "No page - negative entry.\n");
-       if ( page && !de ) {
-               CDEBUG(D_INODE, "Danger: PAGE but de.\n");
-               return ERR_PTR(-ENOENT);
-       }
-       if (page) {
-               unsigned long ino = le32_to_cpu(de->inode);
-               UnlockPage(page);
-               page_cache_release(page);
-               inode = iget(dir->i_sb, ino);
-
-               if (!inode) { 
-                       CDEBUG(D_INODE, "No inode.\n");
-                       EXIT;
-                       return ERR_PTR(-EACCES);
-               }
-       }
-       d_add(dentry, inode);
-       EXIT;
-       return NULL;
+        struct inode * inode;
+        struct ext2_dir_entry_2 * de;
+        struct page *page;
+        ENTRY;
+
+        if (dentry->d_name.len > EXT2_NAME_LEN)
+                return ERR_PTR(-ENAMETOOLONG);
+
+        page = obdfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
+                                &de, LOCKED);
+        inode = NULL;
+        if ( !page ) 
+                CDEBUG(D_INFO, "No page - negative entry.\n");
+        if ( page && !de ) {
+                CDEBUG(D_INODE, "Danger: PAGE but de.\n");
+                return ERR_PTR(-ENOENT);
+        }
+        if (page) {
+                unsigned long ino = le32_to_cpu(de->inode);
+                page_cache_release(page);
+                obd_unlock_page(page);
+                inode = iget(dir->i_sb, ino);
+
+                if (!inode) { 
+                        CDEBUG(D_INODE, "No inode.\n");
+                        EXIT;
+                        return ERR_PTR(-EACCES);
+                }
+        }
+        d_add(dentry, inode);
+        EXIT;
+        return NULL;
 } /* obdfs_lookup */
 
 /*
 } /* obdfs_lookup */
 
 /*
- *     obdfs_add_entry()
+ *      obdfs_add_entry()
  *
  * adds a file entry to the specified directory, using the same
  * semantics as ext2_find_entry(). It returns NULL if it failed.
  *
  * adds a file entry to the specified directory, using the same
  * semantics as ext2_find_entry(). It returns NULL if it failed.
@@ -198,161 +198,161 @@ struct dentry *obdfs_lookup(struct inode *dir, struct dentry *dentry)
  * on the inode protects this page as well.
  */
 static struct page *obdfs_add_entry (struct inode * dir,
  * on the inode protects this page as well.
  */
 static struct page *obdfs_add_entry (struct inode * dir,
-                                    const char * name, int namelen,
-                                    struct ext2_dir_entry_2 ** res_dir,
-                                    int *err)
+                                     const char * name, int namelen,
+                                     struct ext2_dir_entry_2 ** res_dir,
+                                     int *err)
 {
 {
-       unsigned long offset;
-       unsigned short rec_len;
-       struct page *page;
-       struct ext2_dir_entry_2 * de, * de1;
-       struct super_block * sb;
-
-       ENTRY;
-       *err = -EINVAL;
-       *res_dir = NULL;
-       if (!dir || !dir->i_nlink) {
-               CDEBUG(D_INODE, "bad directory\n");
-               EXIT;
-               return NULL;
-       }
-       sb = dir->i_sb;
-
-       if (!namelen) { 
-               CDEBUG(D_INODE, "bad directory\n");
-               EXIT;
-               return NULL;
-       }
-       /*
-        * Is this a busy deleted directory?  Can't create new files if so
-        */
-       if (dir->i_size == 0)
-       {
-               OIDEBUG(dir);
-               *err = -ENOENT;
-               EXIT;
-               return NULL;
-       }
-       page = obdfs_getpage(dir, 0, 0, LOCKED);
-       if (!page) {
-               EXIT;
-               return NULL;
-       }
-       rec_len = EXT2_DIR_REC_LEN(namelen);
-       /* CDEBUG(D_INFO, "reclen: %d\n", rec_len); */
-       /* PDEBUG(page, "starting search"); */
-       offset = 0;
-       de = (struct ext2_dir_entry_2 *) page_address(page);
-       *err = -ENOSPC;
-       while (1) {
-               /* CDEBUG(D_INFO,
-                      "Entry at %p, (page at %#lx - %#lx), offset %ld\n",
-                      de, page_address(page), page_address(page) + PAGE_SIZE,
-                      offset); */
-               if ((char *)de >= PAGE_SIZE + (char *)page_address(page)) {
-                       UnlockPage(page);
-                       page_cache_release(page);
-                       page = obdfs_getpage(dir, offset, 1, LOCKED);
-                       if (!page) {
-                               EXIT;
-                               return NULL;
-                       }
-                       /* PDEBUG(page, "new directory page"); */
-                       if (dir->i_size <= offset) {
-                               if (dir->i_size == 0) {
-                                       *err = -ENOENT;
-                                       EXIT;
-                                       return NULL;
-                               }
-
-                               CDEBUG(D_INFO, "creating next block\n");
-
-                               de = (struct ext2_dir_entry_2 *) page_address(page);
-                               de->inode = 0;
-                               de->rec_len = cpu_to_le16(PAGE_SIZE);
-                               dir->i_size = offset + PAGE_SIZE;
-                               dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-                               mark_inode_dirty(dir);
-                       } else {
-
-                               CDEBUG(D_INFO, "skipping to next block\n");
-
-                               de = (struct ext2_dir_entry_2 *) page_address(page);
-                       }
-               }
-               if (!obdfs_check_dir_entry ("ext2_add_entry", dir, de, page,
-                                          offset)) {
-                       *err = -ENOENT;
-                       UnlockPage(page);
-                       page_cache_release(page);
-                       EXIT;
-                       return NULL;
-               }
-               CDEBUG(D_INFO, "\n");
-               if (ext2_match (namelen, name, de)) {
-                               *err = -EEXIST;
-                               UnlockPage(page);
-                               page_cache_release(page);
-                               EXIT;
-                               return NULL;
-               }
-               /* CDEBUG(D_INFO, "Testing for enough space at de %p\n", de);*/
-               if ((le32_to_cpu(de->inode) == 0 && le16_to_cpu(de->rec_len) >= rec_len) ||
-                   (le16_to_cpu(de->rec_len) >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
-                       offset += le16_to_cpu(de->rec_len);
-                       /* CDEBUG(D_INFO,
-                              "Found enough space de %p, offset %#lx\n",
-                              de, offset); */
-                       if (le32_to_cpu(de->inode)) {
-                               /*CDEBUG(D_INFO, "Insert new in %p\n", de);*/
-                               de1 = (struct ext2_dir_entry_2 *) ((char *) de +
-                                       EXT2_DIR_REC_LEN(de->name_len));
-                               /*CDEBUG(D_INFO, "-- de1 at %p\n", de1);*/
-                               de1->rec_len = cpu_to_le16(le16_to_cpu(de->rec_len) -
-                                       EXT2_DIR_REC_LEN(de->name_len));
-                               de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
-                               de = de1;
-                       }
-                       /* CDEBUG(D_INFO,
-                              "Reclen adjusted; copy %d bytes to %p, "
-                              "page at %#lx EOP at %#lx\n",
-                              namelen, de->name, page_address(page),
-                              page_address(page) + PAGE_SIZE); */
-                       de->inode = 0;
-                       de->name_len = namelen;
-                       de->file_type = 0;
-                       memcpy (de->name, name, namelen);
-                       /*
-                        * XXX shouldn't update any times until successful
-                        * completion of syscall, but too many callers depend
-                        * on this.
-                        *
-                        * XXX similarly, too many callers depend on
-                        * ext2_new_inode() setting the times, but error
-                        * recovery deletes the inode, so the worst that can
-                        * happen is that the times are slightly out of date
-                        * and/or different from the directory change time.
-                        */
-                       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-                       dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-                       mark_inode_dirty(dir);
-                       dir->i_version = ++event;
-                       *res_dir = de;
-                       *err = 0;
-                       /* PDEBUG(page, "add_entry"); */
-                       /* XXX unlock page here */
-                       EXIT;
-                       return page;
-               }
-               offset += le16_to_cpu(de->rec_len);
-               de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-       }
-
-       UnlockPage(page);
-       page_cache_release(page);
-       /* PDEBUG(page, "add_entry"); */
-       EXIT;
-       return NULL;
+        unsigned long offset;
+        unsigned short rec_len;
+        struct page *page;
+        struct ext2_dir_entry_2 * de, * de1;
+        struct super_block * sb;
+
+        ENTRY;
+        *err = -EINVAL;
+        *res_dir = NULL;
+        if (!dir || !dir->i_nlink) {
+                CDEBUG(D_INODE, "bad directory\n");
+                EXIT;
+                return NULL;
+        }
+        sb = dir->i_sb;
+
+        if (!namelen) { 
+                CDEBUG(D_INODE, "bad directory\n");
+                EXIT;
+                return NULL;
+        }
+        /*
+         * Is this a busy deleted directory?  Can't create new files if so
+         */
+        if (dir->i_size == 0)
+        {
+                OIDEBUG(dir);
+                *err = -ENOENT;
+                EXIT;
+                return NULL;
+        }
+        page = obdfs_getpage(dir, 0, 0, LOCKED);
+        if (!page) {
+                EXIT;
+                return NULL;
+        }
+        rec_len = EXT2_DIR_REC_LEN(namelen);
+        /* CDEBUG(D_INFO, "reclen: %d\n", rec_len); */
+        /* PDEBUG(page, "starting search"); */
+        offset = 0;
+        de = (struct ext2_dir_entry_2 *) page_address(page);
+        *err = -ENOSPC;
+        while (1) {
+                /* CDEBUG(D_INFO,
+                       "Entry at %p, (page at %#lx - %#lx), offset %ld\n",
+                       de, page_address(page), page_address(page) + PAGE_SIZE,
+                       offset); */
+                if ((char *)de >= PAGE_SIZE + (char *)page_address(page)) {
+                        obd_unlock_page(page);
+                        page_cache_release(page);
+                        page = obdfs_getpage(dir, offset, 1, LOCKED);
+                        if (!page) {
+                                EXIT;
+                                return NULL;
+                        }
+                        /* PDEBUG(page, "new directory page"); */
+                        if (dir->i_size <= offset) {
+                                if (dir->i_size == 0) {
+                                        *err = -ENOENT;
+                                        EXIT;
+                                        return NULL;
+                                }
+
+                                CDEBUG(D_INFO, "creating next block\n");
+
+                                de = (struct ext2_dir_entry_2 *) page_address(page);
+                                de->inode = 0;
+                                de->rec_len = cpu_to_le16(PAGE_SIZE);
+                                dir->i_size = offset + PAGE_SIZE;
+                                dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
+                                mark_inode_dirty(dir);
+                        } else {
+
+                                CDEBUG(D_INFO, "skipping to next block\n");
+
+                                de = (struct ext2_dir_entry_2 *) page_address(page);
+                        }
+                }
+                if (!obdfs_check_dir_entry ("ext2_add_entry", dir, de, page,
+                                           offset)) {
+                        *err = -ENOENT;
+                        obd_unlock_page(page);
+                        page_cache_release(page);
+                        EXIT;
+                        return NULL;
+                }
+                CDEBUG(D_INFO, "\n");
+                if (ext2_match (namelen, name, de)) {
+                                *err = -EEXIST;
+                                obd_unlock_page(page);
+                                page_cache_release(page);
+                                EXIT;
+                                return NULL;
+                }
+                /* CDEBUG(D_INFO, "Testing for enough space at de %p\n", de);*/
+                if ((le32_to_cpu(de->inode) == 0 && le16_to_cpu(de->rec_len) >= rec_len) ||
+                    (le16_to_cpu(de->rec_len) >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
+                        offset += le16_to_cpu(de->rec_len);
+                        /* CDEBUG(D_INFO,
+                               "Found enough space de %p, offset %#lx\n",
+                               de, offset); */
+                        if (le32_to_cpu(de->inode)) {
+                                /*CDEBUG(D_INFO, "Insert new in %p\n", de);*/
+                                de1 = (struct ext2_dir_entry_2 *) ((char *) de +
+                                        EXT2_DIR_REC_LEN(de->name_len));
+                                /*CDEBUG(D_INFO, "-- de1 at %p\n", de1);*/
+                                de1->rec_len = cpu_to_le16(le16_to_cpu(de->rec_len) -
+                                        EXT2_DIR_REC_LEN(de->name_len));
+                                de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
+                                de = de1;
+                        }
+                        /* CDEBUG(D_INFO,
+                               "Reclen adjusted; copy %d bytes to %p, "
+                               "page at %#lx EOP at %#lx\n",
+                               namelen, de->name, page_address(page),
+                               page_address(page) + PAGE_SIZE); */
+                        de->inode = 0;
+                        de->name_len = namelen;
+                        de->file_type = 0;
+                        memcpy (de->name, name, namelen);
+                        /*
+                         * XXX shouldn't update any times until successful
+                         * completion of syscall, but too many callers depend
+                         * on this.
+                         *
+                         * XXX similarly, too many callers depend on
+                         * ext2_new_inode() setting the times, but error
+                         * recovery deletes the inode, so the worst that can
+                         * happen is that the times are slightly out of date
+                         * and/or different from the directory change time.
+                         */
+                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+                        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
+                        mark_inode_dirty(dir);
+                        dir->i_version = ++event;
+                        *res_dir = de;
+                        *err = 0;
+                        PDEBUG(page, "add_entry");
+                        /* XXX unlock page here */
+                        EXIT;
+                        return page;
+                }
+                offset += le16_to_cpu(de->rec_len);
+                de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+        }
+
+        obd_unlock_page(page);
+        page_cache_release(page);
+        /* PDEBUG(page, "add_entry"); */
+        EXIT;
+        return NULL;
 } /* obdfs_add_entry */
 
 /*
 } /* obdfs_add_entry */
 
 /*
@@ -360,55 +360,56 @@ static struct page *obdfs_add_entry (struct inode * dir,
  * previous entry
  */
 static int obdfs_delete_entry (struct ext2_dir_entry_2 * dir,
  * previous entry
  */
 static int obdfs_delete_entry (struct ext2_dir_entry_2 * dir,
-                             struct page * page)
+                              struct page * page)
 {
 {
-       struct ext2_dir_entry_2 * de, * pde;
-       int i;
-
-       i = 0;
-       pde = NULL;
-       de = (struct ext2_dir_entry_2 *) page_address(page);
-       while (i < PAGE_SIZE) {
-               if (!obdfs_check_dir_entry ("ext2_delete_entry", NULL, 
-                                          de, page, i))
-                       return -EIO;
-               if (de == dir)  {
-                       if (pde)
-                               pde->rec_len =
-                                       cpu_to_le16(le16_to_cpu(pde->rec_len) +
-                                                   le16_to_cpu(dir->rec_len));
-                       else
-                               dir->inode = 0;
-                       return 0;
-               }
-               i += le16_to_cpu(de->rec_len);
-               pde = de;
-               de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-       }
-       return -ENOENT;
+        struct ext2_dir_entry_2 * de, * pde;
+        int i;
+
+        i = 0;
+        pde = NULL;
+        de = (struct ext2_dir_entry_2 *) page_address(page);
+        while (i < PAGE_SIZE) {
+                if (!obdfs_check_dir_entry ("ext2_delete_entry", NULL, 
+                                           de, page, i))
+                        return -EIO;
+                if (de == dir)  {
+                        if (pde)
+                                pde->rec_len =
+                                        cpu_to_le16(le16_to_cpu(pde->rec_len) +
+                                                    le16_to_cpu(dir->rec_len));
+                        else
+                                dir->inode = 0;
+                        return 0;
+                }
+                i += le16_to_cpu(de->rec_len);
+                pde = de;
+                de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+        }
+        return -ENOENT;
 } /* obdfs_delete_entry */
 
 
 static inline void ext2_set_de_type(struct super_block *sb,
 } /* obdfs_delete_entry */
 
 
 static inline void ext2_set_de_type(struct super_block *sb,
-                               struct ext2_dir_entry_2 *de,
-                               umode_t mode) {
-       /* XXX fix this to check for obdfs feature, not ext2 feature */
-       if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
-               return;
-       if (S_ISREG(mode))
-               de->file_type = EXT2_FT_REG_FILE;
-       else if (S_ISDIR(mode))  
-               de->file_type = EXT2_FT_DIR;
-       else if (S_ISLNK(mode))
-               de->file_type = EXT2_FT_SYMLINK;
-       else if (S_ISSOCK(mode))
-               de->file_type = EXT2_FT_SOCK;
-       else if (S_ISFIFO(mode))  
-               de->file_type = EXT2_FT_FIFO;
-       else if (S_ISCHR(mode))
-               de->file_type = EXT2_FT_CHRDEV;
-       else if (S_ISBLK(mode))
-               de->file_type = EXT2_FT_BLKDEV;
+                                struct ext2_dir_entry_2 *de,
+                                umode_t mode) {
+        return;
+        /* XXX fix this to check for obdfs feature, not ext2 feature */
+        if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
+                return;
+        if (S_ISREG(mode))
+                de->file_type = EXT2_FT_REG_FILE;
+        else if (S_ISDIR(mode))  
+                de->file_type = EXT2_FT_DIR;
+        else if (S_ISLNK(mode))
+                de->file_type = EXT2_FT_SYMLINK;
+        else if (S_ISSOCK(mode))
+                de->file_type = EXT2_FT_SOCK;
+        else if (S_ISFIFO(mode))  
+                de->file_type = EXT2_FT_FIFO;
+        else if (S_ISCHR(mode))
+                de->file_type = EXT2_FT_CHRDEV;
+        else if (S_ISBLK(mode))
+                de->file_type = EXT2_FT_BLKDEV;
 }
 
 
 }
 
 
@@ -418,90 +419,90 @@ static inline void ext2_set_de_type(struct super_block *sb,
 #if 0
 static void show_dentry(struct list_head * dlist, int subdirs)
 {
 #if 0
 static void show_dentry(struct list_head * dlist, int subdirs)
 {
-       struct list_head *tmp = dlist;
-
-       while ((tmp = tmp->next) != dlist) {
-               struct dentry * dentry;
-               const char * unhashed = "";
-
-               if ( subdirs ) 
-                       dentry  = list_entry(tmp, struct dentry, d_child);
-               else 
-                       dentry  = list_entry(tmp, struct dentry, d_alias);
-
-               if (list_empty(&dentry->d_hash))
-                       unhashed = "(unhashed)";
-
-               if ( dentry->d_inode ) 
-                       printk("show_dentry: %s/%s, d_count=%d%s (ino %ld, dev %d, ct %d)\n",
-                              dentry->d_parent->d_name.name,
-                              dentry->d_name.name, dentry->d_count,
-                              unhashed, dentry->d_inode->i_ino, 
-                              dentry->d_inode->i_dev, 
-                              dentry->d_inode->i_count);
-               else 
-                       printk("show_dentry: %s/%s, d_count=%d%s \n",
-                              dentry->d_parent->d_name.name,
-                              dentry->d_name.name, dentry->d_count,
-                              unhashed);
-       }
+        struct list_head *tmp = dlist;
+
+        while ((tmp = tmp->next) != dlist) {
+                struct dentry * dentry;
+                const char * unhashed = "";
+
+                if ( subdirs ) 
+                        dentry  = list_entry(tmp, struct dentry, d_child);
+                else 
+                        dentry  = list_entry(tmp, struct dentry, d_alias);
+
+                if (list_empty(&dentry->d_hash))
+                        unhashed = "(unhashed)";
+
+                if ( dentry->d_inode ) 
+                        printk("show_dentry: %s/%s, d_count=%d%s (ino %ld, dev %d, ct %d)\n",
+                               dentry->d_parent->d_name.name,
+                               dentry->d_name.name, dentry->d_count,
+                               unhashed, dentry->d_inode->i_ino, 
+                               dentry->d_inode->i_dev, 
+                               dentry->d_inode->i_count);
+                else 
+                        printk("show_dentry: %s/%s, d_count=%d%s \n",
+                               dentry->d_parent->d_name.name,
+                               dentry->d_name.name, dentry->d_count,
+                               unhashed);
+        }
 } /* show_dentry */
 #endif
 
 
 static struct inode *obdfs_new_inode(struct inode *dir, int mode)
 {
 } /* show_dentry */
 #endif
 
 
 static struct inode *obdfs_new_inode(struct inode *dir, int mode)
 {
-       struct obdo *oa;
-       struct inode *inode;
-       int err;
-
-       ENTRY;
-       if (IOPS(dir, create) == NULL) {
-               printk(KERN_ERR __FUNCTION__ ": no create method!\n");
-               EXIT;
-               return ERR_PTR(-EIO);
-       }
-       oa = obdo_alloc();
-       if (!oa) {
-               EXIT;
-               return ERR_PTR(-ENOMEM);
-       }
-
-       /* Send a hint to the create method on the type of file to create */
-       oa->o_mode = mode;
-       oa->o_valid |= OBD_MD_FLMODE;
-
-       err = IOPS(dir, create)(IID(dir), oa);
-
-       if ( err ) {
-               CDEBUG(D_INODE, "fatal: creating new inode (err %d)\n", err);
-               obdo_free(oa);
-               EXIT;
-               return ERR_PTR(err);
-       }
-
-       inode = iget(dir->i_sb, (ino_t)oa->o_id);
-
-       if (!inode) {
-               CDEBUG(D_INODE, "fatal: get new inode %ld\n", (long)oa->o_id);
-               IOPS(dir, destroy)(IID(dir), oa);
-               obdo_free(oa);
-               EXIT;
-               return ERR_PTR(-EIO);
-       }
-
-       if (!list_empty(&inode->i_dentry)) {
-               CDEBUG(D_INODE, "New inode (%ld) has aliases!\n", inode->i_ino);
-               IOPS(dir, destroy)(IID(dir), oa);
-               obdo_free(oa);
-               iput(inode);
-               EXIT;
-               return ERR_PTR(-EIO);
-       }
-       obdo_free(oa);
-
-       EXIT;
-       return inode;
+        struct obdo *oa;
+        struct inode *inode;
+        int err;
+
+        ENTRY;
+        if (IOPS(dir, create) == NULL) {
+                printk(KERN_ERR __FUNCTION__ ": no create method!\n");
+                EXIT;
+                return ERR_PTR(-EIO);
+        }
+        oa = obdo_alloc();
+        if (!oa) {
+                EXIT;
+                return ERR_PTR(-ENOMEM);
+        }
+
+        /* Send a hint to the create method on the type of file to create */
+        oa->o_mode = mode;
+        oa->o_valid |= OBD_MD_FLMODE;
+
+        err = IOPS(dir, create)(IID(dir), oa);
+
+        if ( err ) {
+                CDEBUG(D_INODE, "fatal: creating new inode (err %d)\n", err);
+                obdo_free(oa);
+                EXIT;
+                return ERR_PTR(err);
+        }
+
+        inode = iget(dir->i_sb, (ino_t)oa->o_id);
+
+        if (!inode) {
+                CDEBUG(D_INODE, "fatal: get new inode %ld\n", (long)oa->o_id);
+                IOPS(dir, destroy)(IID(dir), oa);
+                obdo_free(oa);
+                EXIT;
+                return ERR_PTR(-EIO);
+        }
+
+        if (!list_empty(&inode->i_dentry)) {
+                CDEBUG(D_INODE, "New inode (%ld) has aliases!\n", inode->i_ino);
+                IOPS(dir, destroy)(IID(dir), oa);
+                obdo_free(oa);
+                iput(inode);
+                EXIT;
+                return ERR_PTR(-EIO);
+        }
+        obdo_free(oa);
+
+        EXIT;
+        return inode;
 } /* obdfs_new_inode */
 
 
 } /* obdfs_new_inode */
 
 
@@ -515,174 +516,173 @@ static struct inode *obdfs_new_inode(struct inode *dir, int mode)
  */
 int obdfs_create (struct inode * dir, struct dentry * dentry, int mode)
 {
  */
 int obdfs_create (struct inode * dir, struct dentry * dentry, int mode)
 {
-       struct inode * inode;
-       struct page *page;
-       struct ext2_dir_entry_2 * de;
-       int err = -EIO;
+        struct inode * inode;
+        struct page *page;
+        struct ext2_dir_entry_2 * de;
+        int err = -EIO;
 
         ENTRY;
 
         ENTRY;
-       inode = obdfs_new_inode(dir, mode);
-       if ( IS_ERR(inode) ) {
-               EXIT;
-               return PTR_ERR(inode);
-       }
-
-       inode->i_op = &obdfs_file_inode_operations;
-       mark_inode_dirty(inode);
-       page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-       if (!page) {
-               inode->i_nlink--;
-               mark_inode_dirty(inode);
-               iput (inode);
-               EXIT;
-               return err;
-       }
-       de->inode = cpu_to_le32(inode->i_ino);
-       ext2_set_de_type(dir->i_sb, de, S_IFREG);
-       dir->i_version = ++event;
-
-       err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
-       UnlockPage(page);
-
-       page_cache_release(page);
-       d_instantiate(dentry, inode);
-       EXIT;
-       return err;
+        inode = obdfs_new_inode(dir, mode);
+        if ( IS_ERR(inode) ) {
+                EXIT;
+                return PTR_ERR(inode);
+        }
+
+        inode->i_op = &obdfs_file_inode_operations;
+        mark_inode_dirty(inode);
+        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
+        if (!page) {
+                inode->i_nlink--;
+                mark_inode_dirty(inode);
+                iput (inode);
+                EXIT;
+                return err;
+        }
+        de->inode = cpu_to_le32(inode->i_ino);
+        ext2_set_de_type(dir->i_sb, de, S_IFREG);
+        dir->i_version = ++event;
+
+        err = obdfs_do_writepage(page, IS_SYNC(dir));
+        obd_unlock_page(page);
+        page_cache_release(page);
+        d_instantiate(dentry, inode);
+        EXIT;
+        return err;
 } /* obdfs_create */
 
 int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
 } /* obdfs_create */
 
 int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
-       struct inode * inode;
-       struct page *page;
-       struct ext2_dir_entry_2 * de;
-       struct obdfs_inode_info *oinfo;
-       int err;
+        struct inode * inode;
+        struct page *page;
+        struct ext2_dir_entry_2 * de;
+        struct obdfs_inode_info *oinfo;
+        int err;
 
         ENTRY;
 
         ENTRY;
-       inode = obdfs_new_inode(dir, mode);
-       if ( IS_ERR(inode) ) {
-               EXIT;
-               return PTR_ERR(inode);
-       }
-
-       inode->i_uid = current->fsuid;
-       init_special_inode(inode, mode, rdev);
-       oinfo = obdfs_i2info(inode);
-       ((obd_count *)oinfo->oi_inline)[0] = rdev;
-       oinfo->oi_flags |= OBD_FL_INLINEDATA;
-
-       page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-       if (!page)
-               goto out_no_entry;
-       de->inode = cpu_to_le32(inode->i_ino);
-       dir->i_version = ++event;
-       ext2_set_de_type(dir->i_sb, de, inode->i_mode);
-       mark_inode_dirty(inode);
-
-       err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
-       UnlockPage(page);
-
-       d_instantiate(dentry, inode);
-       page_cache_release(page);
-       err = 0;
+        inode = obdfs_new_inode(dir, mode);
+        if ( IS_ERR(inode) ) {
+                EXIT;
+                return PTR_ERR(inode);
+        }
+
+        inode->i_uid = current->fsuid;
+        init_special_inode(inode, mode, rdev);
+        oinfo = obdfs_i2info(inode);
+        ((obd_count *)oinfo->oi_inline)[0] = rdev;
+        oinfo->oi_flags |= OBD_FL_INLINEDATA;
+
+        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
+        if (!page)
+                goto out_no_entry;
+        de->inode = cpu_to_le32(inode->i_ino);
+        dir->i_version = ++event;
+        ext2_set_de_type(dir->i_sb, de, inode->i_mode);
+        mark_inode_dirty(inode);
+
+        err = obdfs_do_writepage(page, IS_SYNC(dir));
+        obd_unlock_page(page);
+
+        d_instantiate(dentry, inode);
+        page_cache_release(page);
+        err = 0;
 out:
 out:
-       return err;
+        return err;
 
 out_no_entry:
 
 out_no_entry:
-       inode->i_nlink--;
-       mark_inode_dirty(inode);
-       iput(inode);
-       goto out;
+        inode->i_nlink--;
+        mark_inode_dirty(inode);
+        iput(inode);
+        goto out;
 } /* obdfs_mknod */
 
 int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 {
 } /* obdfs_mknod */
 
 int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 {
-       struct inode * inode;
-       struct page *page, *inode_page;
-       struct ext2_dir_entry_2 * de;
-       int err;
-
-       ENTRY;
-
-       err = -EMLINK;
-       if (dir->i_nlink >= EXT2_LINK_MAX)
-               goto out;
-
-       mode |= S_IFDIR;
-       if (dir->i_mode & S_ISGID)
-               mode |= S_ISGID;
-
-       inode = obdfs_new_inode(dir, mode);
-       if ( IS_ERR(inode) ) {
-               EXIT;
-               return PTR_ERR(inode);
-       }
-
-       inode->i_op = &obdfs_dir_inode_operations;
-       inode->i_blocks = 0;    
-       inode_page = obdfs_getpage(inode, 0, 1, LOCKED);
-       if (!inode_page) {
-               inode->i_nlink--; /* is this nlink == 0? */
-               mark_inode_dirty(inode);
-               iput (inode);
-               return -EIO;
-       }
-       de = (struct ext2_dir_entry_2 *) page_address(inode_page);
-
-       /* create . and .. */
-       de->inode = cpu_to_le32(inode->i_ino);
-       de->name_len = 1;
-       de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
-       strcpy (de->name, ".");
-       ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-       de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-       de->inode = cpu_to_le32(dir->i_ino);
-       de->rec_len = cpu_to_le16(PAGE_SIZE - EXT2_DIR_REC_LEN(1));
-       de->name_len = 2;
-       strcpy (de->name, "..");
-       ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-       inode->i_nlink = 2;
-       
-       err = obdfs_do_writepage(inode, inode_page, IS_SYNC(inode));
-       inode->i_blocks = PAGE_SIZE/inode->i_sb->s_blocksize;
-       inode->i_size = PAGE_SIZE;
-       UnlockPage(inode_page);
-       page_cache_release(inode_page);
-       mark_inode_dirty(inode);
-       if (err) {
-               EXIT;
-               goto out_no_entry;
-       }
-
-       /* now deal with the parent */
-       page = obdfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-       if (!page) {
-               EXIT;
-               goto out_no_entry;
-       }
-
-       de->inode = cpu_to_le32(inode->i_ino);
-       ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-       dir->i_version = ++event;
-
-       dir->i_nlink++;
-       dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-       mark_inode_dirty(dir);
-       err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
-
-       UnlockPage(page);
-
-       page_cache_release(page);
-       d_instantiate(dentry, inode);
-       EXIT;
+        struct inode * inode;
+        struct page *page, *inode_page;
+        struct ext2_dir_entry_2 * de;
+        int err;
+
+        ENTRY;
+
+        err = -EMLINK;
+        if (dir->i_nlink >= EXT2_LINK_MAX)
+                goto out;
+
+        mode |= S_IFDIR;
+        if (dir->i_mode & S_ISGID)
+                mode |= S_ISGID;
+
+        inode = obdfs_new_inode(dir, mode);
+        if ( IS_ERR(inode) ) {
+                EXIT;
+                return PTR_ERR(inode);
+        }
+
+        inode->i_op = &obdfs_dir_inode_operations;
+        inode->i_blocks = 0;    
+        inode_page = obdfs_getpage(inode, 0, 1, LOCKED);
+        if (!inode_page) {
+                inode->i_nlink--; /* is this nlink == 0? */
+                mark_inode_dirty(inode);
+                iput (inode);
+                return -EIO;
+        }
+        de = (struct ext2_dir_entry_2 *) page_address(inode_page);
+
+        /* create . and .. */
+        de->inode = cpu_to_le32(inode->i_ino);
+        de->name_len = 1;
+        de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
+        strcpy (de->name, ".");
+        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
+        de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+        de->inode = cpu_to_le32(dir->i_ino);
+        de->rec_len = cpu_to_le16(PAGE_SIZE - EXT2_DIR_REC_LEN(1));
+        de->name_len = 2;
+        strcpy (de->name, "..");
+        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
+        inode->i_nlink = 2;
+        
+        err = obdfs_do_writepage(inode_page, IS_SYNC(inode));
+        inode->i_blocks = PAGE_SIZE/inode->i_sb->s_blocksize;
+        inode->i_size = PAGE_SIZE;
+        obd_unlock_page(inode_page);
+        page_cache_release(inode_page);
+        mark_inode_dirty(inode);
+        if (err) {
+                EXIT;
+                goto out_no_entry;
+        }
+
+        /* now deal with the parent */
+        page = obdfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
+        if (!page) {
+                EXIT;
+                goto out_no_entry;
+        }
+
+        de->inode = cpu_to_le32(inode->i_ino);
+        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
+        dir->i_version = ++event;
+
+        dir->i_nlink++;
+        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
+        mark_inode_dirty(dir);
+        err = obdfs_do_writepage(page, IS_SYNC(dir));
+
+        obd_unlock_page(page);
+
+        page_cache_release(page);
+        d_instantiate(dentry, inode);
+        EXIT;
 out:
 out:
-       return err;
+        return err;
 
 out_no_entry:
 
 out_no_entry:
-       inode->i_nlink = 0;
-       mark_inode_dirty(inode);
-       iput (inode);
-       goto out;
+        inode->i_nlink = 0;
+        mark_inode_dirty(inode);
+        iput (inode);
+        goto out;
 } /* obdfs_mkdir */
 
 
 } /* obdfs_mkdir */
 
 
@@ -691,450 +691,449 @@ out_no_entry:
  */
 static int empty_dir (struct inode * inode)
 {
  */
 static int empty_dir (struct inode * inode)
 {
-       unsigned long offset;
-       struct page *page;
-       struct ext2_dir_entry_2 * de, * de1;
-       struct super_block * sb;
-
-       sb = inode->i_sb;
-       if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
-           !(page = obdfs_getpage (inode, 0, 0, LOCKED))) {
-               ext2_warning (inode->i_sb, "empty_dir",
-                             "bad directory (dir #%lu) - no data block",
-                             inode->i_ino);
-               return 1;
-       }
-       de = (struct ext2_dir_entry_2 *) page_address(page);
-       de1 = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-       if (le32_to_cpu(de->inode) != inode->i_ino || !le32_to_cpu(de1->inode) || 
-           strcmp (".", de->name) || strcmp ("..", de1->name)) {
-               ext2_warning (inode->i_sb, "empty_dir",
-                             "bad directory (dir #%lu) - no `.' or `..'",
-                             inode->i_ino);
-               page_cache_release(page);
-               return 1;
-       }
-       offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
-       de = (struct ext2_dir_entry_2 *) ((char *) de1 + le16_to_cpu(de1->rec_len));
-       while (offset < inode->i_size ) {
-               if (!page || (void *) de >= (void *) (page_address(page) + PAGE_SIZE)) {
-                       if (page) {
-                               UnlockPage(page);
-                               page_cache_release(page);
-                       }
-                       page = obdfs_getpage(inode, offset, 0, LOCKED);
-                       if (!page) {
+        unsigned long offset;
+        struct page *page;
+        struct ext2_dir_entry_2 * de, * de1;
+        struct super_block * sb;
+
+        sb = inode->i_sb;
+        if (inode->i_size < EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) ||
+            !(page = obdfs_getpage (inode, 0, 0, LOCKED))) {
+                ext2_warning (inode->i_sb, "empty_dir",
+                              "bad directory (dir #%lu) - no data block",
+                              inode->i_ino);
+                return 1;
+        }
+        de = (struct ext2_dir_entry_2 *) page_address(page);
+        de1 = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+        if (le32_to_cpu(de->inode) != inode->i_ino || !le32_to_cpu(de1->inode) || 
+            strcmp (".", de->name) || strcmp ("..", de1->name)) {
+                ext2_warning (inode->i_sb, "empty_dir",
+                              "bad directory (dir #%lu) - no `.' or `..'",
+                              inode->i_ino);
+                page_cache_release(page);
+                return 1;
+        }
+        offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
+        de = (struct ext2_dir_entry_2 *) ((char *) de1 + le16_to_cpu(de1->rec_len));
+        while (offset < inode->i_size ) {
+                if (!page || (void *) de >= (void *) (page_address(page) + PAGE_SIZE)) {
+                        if (page) {
+                                obd_unlock_page(page);
+                                page_cache_release(page);
+                        }
+                        page = obdfs_getpage(inode, offset, 0, LOCKED);
+                        if (!page) {
 #if 0
 #if 0
-                               ext2_error (sb, "empty_dir",
-                                           "directory #%lu contains a hole at offset %lu",
-                                           inode->i_ino, offset);
+                                ext2_error (sb, "empty_dir",
+                                            "directory #%lu contains a hole at offset %lu",
+                                            inode->i_ino, offset);
 #endif
 #endif
-                               offset += sb->s_blocksize;
-                               continue;
-                       }
-                       de = (struct ext2_dir_entry_2 *) page_address(page);
-               }
-               if (!obdfs_check_dir_entry ("empty_dir", inode, de, page,
-                                          offset)) {
-                       UnlockPage(page);
-                       page_cache_release(page);
-                       return 1;
-               }
-               if (le32_to_cpu(de->inode)) {
-                       UnlockPage(page);
-                       page_cache_release(page);
-                       return 0;
-               }
-               offset += le16_to_cpu(de->rec_len);
-               de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-       }
-       UnlockPage(page);
-       page_cache_release(page);
-       return 1;
+                                offset += sb->s_blocksize;
+                                continue;
+                        }
+                        de = (struct ext2_dir_entry_2 *) page_address(page);
+                }
+                if (!obdfs_check_dir_entry ("empty_dir", inode, de, page,
+                                           offset)) {
+                        obd_unlock_page(page);
+                        page_cache_release(page);
+                        return 1;
+                }
+                if (le32_to_cpu(de->inode)) {
+                        obd_unlock_page(page);
+                        page_cache_release(page);
+                        return 0;
+                }
+                offset += le16_to_cpu(de->rec_len);
+                de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+        }
+        obd_unlock_page(page);
+        page_cache_release(page);
+        return 1;
 } /* empty_dir */
 
 int obdfs_rmdir (struct inode * dir, struct dentry *dentry)
 {
 } /* empty_dir */
 
 int obdfs_rmdir (struct inode * dir, struct dentry *dentry)
 {
-       int retval;
-       struct inode * inode;
-       struct page *page;
-       struct ext2_dir_entry_2 * de;
-
-       ENTRY;
-
-       retval = -ENOENT;
-       page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, LOCKED);
-       if (!page)
-               goto end_rmdir;
-
-       inode = dentry->d_inode;
-       DQUOT_INIT(inode);
-
-       retval = -EIO;
-       if (le32_to_cpu(de->inode) != inode->i_ino)
-               goto end_rmdir;
-
-       retval = -ENOTEMPTY;
-       if (!empty_dir (inode))
-               goto end_rmdir;
-
-       retval = obdfs_delete_entry (de, page);
-       dir->i_version = ++event;
-       if (retval)
-               goto end_rmdir;
-       retval = obdfs_do_writepage(dir, page, IS_SYNC(dir));
-       /* XXX handle err? */
-       UnlockPage(page);
-
-       if (inode->i_nlink != 2)
-               ext2_warning (inode->i_sb, "ext2_rmdir",
-                             "empty directory has nlink!=2 (%d)",
-                             inode->i_nlink);
-       inode->i_version = ++event;
-       inode->i_nlink = 0;
-       inode->i_size = 0;
-       mark_inode_dirty(inode);
-       dir->i_nlink--;
-       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-       mark_inode_dirty(dir);
-       d_delete(dentry);
+        int retval;
+        struct inode * inode;
+        struct page *page;
+        struct ext2_dir_entry_2 * de;
+
+        ENTRY;
+
+        retval = -ENOENT;
+        page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, LOCKED);
+        if (!page)
+                goto end_rmdir;
+
+        inode = dentry->d_inode;
+        DQUOT_INIT(inode);
+
+        retval = -EIO;
+        if (le32_to_cpu(de->inode) != inode->i_ino)
+                goto end_rmdir;
+
+        retval = -ENOTEMPTY;
+        if (!empty_dir (inode))
+                goto end_rmdir;
+
+        retval = obdfs_delete_entry (de, page);
+        dir->i_version = ++event;
+        if (retval)
+                goto end_rmdir;
+        retval = obdfs_do_writepage(page, IS_SYNC(dir));
+        /* XXX handle err? */
+        obd_unlock_page(page);
+
+        if (inode->i_nlink != 2)
+                ext2_warning (inode->i_sb, "ext2_rmdir",
+                              "empty directory has nlink!=2 (%d)",
+                              inode->i_nlink);
+        inode->i_version = ++event;
+        inode->i_nlink = 0;
+        inode->i_size = 0;
+        mark_inode_dirty(inode);
+        dir->i_nlink--;
+        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
+        mark_inode_dirty(dir);
+        d_delete(dentry);
 
 end_rmdir:
 
 end_rmdir:
-       if ( page )
-               page_cache_release(page);
-       EXIT;
-       return retval;
+        if ( page )
+                page_cache_release(page);
+        EXIT;
+        return retval;
 } /* obdfs_rmdir */
 
 int obdfs_unlink(struct inode * dir, struct dentry *dentry)
 {
 } /* obdfs_rmdir */
 
 int obdfs_unlink(struct inode * dir, struct dentry *dentry)
 {
-       int retval;
-       struct inode * inode;
-       struct page *page;
-       struct ext2_dir_entry_2 * de;
+        int retval;
+        struct inode * inode;
+        struct page *page;
+        struct ext2_dir_entry_2 * de;
 
         ENTRY;
 
 
         ENTRY;
 
-       retval = -ENOENT;
-       page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, LOCKED);
-       if (!page)
-               goto end_unlink;
-
-       inode = dentry->d_inode;
-       DQUOT_INIT(inode);
-
-       retval = -EIO;
-       if (le32_to_cpu(de->inode) != inode->i_ino)
-               goto end_unlink;
-       
-       if (!inode->i_nlink) {
-               ext2_warning (inode->i_sb, "ext2_unlink",
-                             "Deleting nonexistent file (%lu), %d",
-                             inode->i_ino, inode->i_nlink);
-               inode->i_nlink = 1;
-       }
-       retval = obdfs_delete_entry (de, page);
-       if (retval)
-               goto end_unlink;
-       dir->i_version = ++event;
-       retval = obdfs_do_writepage(dir, page, IS_SYNC(dir));
-       /* XXX handle err? */
-       UnlockPage(page);
-
-       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-       mark_inode_dirty(dir);
-       inode->i_nlink--;
-       mark_inode_dirty(inode);
-       inode->i_ctime = dir->i_ctime;
-       d_delete(dentry);       /* This also frees the inode */
+        retval = -ENOENT;
+        page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, LOCKED);
+        if (!page)
+                goto end_unlink;
+
+        inode = dentry->d_inode;
+        DQUOT_INIT(inode);
+
+        retval = -EIO;
+        if (le32_to_cpu(de->inode) != inode->i_ino)
+                goto end_unlink;
+        
+        if (!inode->i_nlink) {
+                ext2_warning (inode->i_sb, "ext2_unlink",
+                              "Deleting nonexistent file (%lu), %d",
+                              inode->i_ino, inode->i_nlink);
+                inode->i_nlink = 1;
+        }
+        retval = obdfs_delete_entry (de, page);
+        if (retval)
+                goto end_unlink;
+        dir->i_version = ++event;
+        retval = obdfs_do_writepage(page, IS_SYNC(dir));
+        /* XXX handle err? */
+        obd_unlock_page(page);
+
+        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
+        mark_inode_dirty(dir);
+        inode->i_nlink--;
+        mark_inode_dirty(inode);
+        inode->i_ctime = dir->i_ctime;
+        d_delete(dentry);       /* This also frees the inode */
 
 end_unlink:
 
 end_unlink:
-       if (page)
-               page_cache_release(page);
-       EXIT;
-       return retval;
+        if (page)
+                page_cache_release(page);
+        EXIT;
+        return retval;
 } /* obdfs_unlink */
 
 int obdfs_symlink (struct inode * dir, struct dentry *dentry,
 } /* obdfs_unlink */
 
 int obdfs_symlink (struct inode * dir, struct dentry *dentry,
-                  const char * symname)
+                   const char * symname)
 {
 {
-       struct inode * inode;
-       struct ext2_dir_entry_2 * de;
-       struct obdfs_inode_info *oinfo;
-       struct page* page = NULL, * name_page = NULL;
-       char * link;
-       int l, err;
+        struct inode * inode;
+        struct ext2_dir_entry_2 * de;
+        struct obdfs_inode_info *oinfo;
+        struct page* page = NULL, * name_page = NULL;
+        char * link;
+        int l, err;
 
         ENTRY;
 
         ENTRY;
-       err = -ENAMETOOLONG;
-       l = strlen(symname)+1;
-       if (l > PAGE_SIZE) {
-               EXIT;
-               goto out;
-       }
-
-       inode = obdfs_new_inode(dir, S_IFLNK);
-       if ( IS_ERR(inode) ) {
-               EXIT;
-               goto out;
-       }
-
-       inode->i_mode = S_IFLNK | S_IRWXUGO;
-       oinfo = obdfs_i2info(inode);
-
-       if (l >= sizeof(oinfo->oi_inline)) {
-               CDEBUG(D_INFO, "l=%d, normal symlink\n", l);
-               inode->i_op = &obdfs_symlink_inode_operations;
-
-               name_page = obdfs_getpage(inode, 0, 1, LOCKED);
-               if (!name_page) {
-                       EXIT;
-                       err = -ENOMEM;
-                       goto out_no_entry;
-               }
-               link = (char *)page_address(name_page);
-       } else {
-               CDEBUG(D_INFO, "l=%d, fast symlink\n", l);
-               inode->i_op = &obdfs_fast_symlink_inode_operations;
-               link = oinfo->oi_inline;
-               oinfo->oi_flags |= OBD_FL_INLINEDATA;
-       }
-       memcpy(link, symname, l);
-       if (name_page) {
-               err = obdfs_do_writepage(inode, name_page, IS_SYNC(inode));
-               /* PDEBUG(name_page, "symlink"); */
-               UnlockPage(name_page);
-               page_cache_release(name_page);
-               if (err) {
-                       EXIT;
-                       goto out_no_entry;
-               }
-       }
-       inode->i_size = l-1;
-       mark_inode_dirty(inode);
-
-       page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len,
-                               &de, &err);
-       if (!page)
-               goto out_no_entry;
-       de->inode = cpu_to_le32(inode->i_ino);
-       ext2_set_de_type(dir->i_sb, de, S_IFLNK);
-       dir->i_version = ++event;
-       err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
-       UnlockPage(page);
-
-       d_instantiate(dentry, inode);
+        err = -ENAMETOOLONG;
+        l = strlen(symname)+1;
+        if (l > PAGE_SIZE) {
+                EXIT;
+                goto out;
+        }
+
+        inode = obdfs_new_inode(dir, S_IFLNK);
+        if ( IS_ERR(inode) ) {
+                EXIT;
+                goto out;
+        }
+
+        inode->i_mode = S_IFLNK | S_IRWXUGO;
+        oinfo = obdfs_i2info(inode);
+
+        if (l >= sizeof(oinfo->oi_inline)) {
+                CDEBUG(D_INFO, "l=%d, normal symlink\n", l);
+                inode->i_op = &obdfs_symlink_inode_operations;
+
+                name_page = obdfs_getpage(inode, 0, 1, LOCKED);
+                if (!name_page) {
+                        EXIT;
+                        err = -ENOMEM;
+                        goto out_no_entry;
+                }
+                link = (char *)page_address(name_page);
+        } else {
+                CDEBUG(D_INFO, "l=%d, fast symlink\n", l);
+                inode->i_op = &obdfs_fast_symlink_inode_operations;
+                link = oinfo->oi_inline;
+                oinfo->oi_flags |= OBD_FL_INLINEDATA;
+        }
+        memcpy(link, symname, l);
+        if (name_page) {
+                err = obdfs_do_writepage(name_page, IS_SYNC(inode));
+                /* PDEBUG(name_page, "symlink"); */
+                obd_unlock_page(name_page);
+                page_cache_release(name_page);
+                if (err) {
+                        EXIT;
+                        goto out_no_entry;
+                }
+        }
+        inode->i_size = l-1;
+        mark_inode_dirty(inode);
+
+        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len,
+                                &de, &err);
+        if (!page)
+                goto out_no_entry;
+        de->inode = cpu_to_le32(inode->i_ino);
+        ext2_set_de_type(dir->i_sb, de, S_IFLNK);
+        dir->i_version = ++event;
+        err = obdfs_do_writepage(page, IS_SYNC(dir));
+        obd_unlock_page(page);
+
+        d_instantiate(dentry, inode);
 out:
 out:
-       EXIT;
-       return err;
+        EXIT;
+        return err;
 
 out_no_entry:
 
 out_no_entry:
-       inode->i_nlink--;
-       mark_inode_dirty(inode);
-       iput (inode);
-       goto out;
+        inode->i_nlink--;
+        mark_inode_dirty(inode);
+        iput (inode);
+        goto out;
 } /* obdfs_symlink */
 
 int obdfs_link (struct dentry * old_dentry,
 } /* obdfs_symlink */
 
 int obdfs_link (struct dentry * old_dentry,
-               struct inode * dir, struct dentry *dentry)
+                struct inode * dir, struct dentry *dentry)
 {
 {
-       struct inode *inode = old_dentry->d_inode;
-       struct ext2_dir_entry_2 * de;
-       struct page *page;
-       int err;
+        struct inode *inode = old_dentry->d_inode;
+        struct ext2_dir_entry_2 * de;
+        struct page *page;
+        int err;
 
         ENTRY;
 
 
         ENTRY;
 
-       if (S_ISDIR(inode->i_mode))
-               return -EPERM;
+        if (S_ISDIR(inode->i_mode))
+                return -EPERM;
 
 
-       if (inode->i_nlink >= EXT2_LINK_MAX)
-               return -EMLINK;
+        if (inode->i_nlink >= EXT2_LINK_MAX)
+                return -EMLINK;
 
 
-       page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-       if (!page)
-               return err;
+        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
+        if (!page)
+                return err;
 
 
-       de->inode = cpu_to_le32(inode->i_ino);
-       ext2_set_de_type(dir->i_sb, de, inode->i_mode);
-       dir->i_version = ++event;
+        de->inode = cpu_to_le32(inode->i_ino);
+        ext2_set_de_type(dir->i_sb, de, inode->i_mode);
+        dir->i_version = ++event;
 
 
-       err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
-       UnlockPage(page);
+        err = obdfs_do_writepage(page, IS_SYNC(dir));
+        obd_unlock_page(page);
 
 
-       page_cache_release(page);
-       inode->i_nlink++;
-       inode->i_ctime = CURRENT_TIME;
-       mark_inode_dirty(inode);
-       inode->i_count++;
-       d_instantiate(dentry, inode);
-       return err;
+        page_cache_release(page);
+        inode->i_nlink++;
+        inode->i_ctime = CURRENT_TIME;
+        mark_inode_dirty(inode);
+        atomic_inc(&inode->i_count);
+        d_instantiate(dentry, inode);
+        return err;
 } /* obdfs_link */
 
 #define PARENT_INO(buffer) \
 } /* obdfs_link */
 
 #define PARENT_INO(buffer) \
-       ((struct ext2_dir_entry_2 *) ((char *) buffer + \
-       le16_to_cpu(((struct ext2_dir_entry_2 *) buffer)->rec_len)))->inode
+        ((struct ext2_dir_entry_2 *) ((char *) buffer + \
+        le16_to_cpu(((struct ext2_dir_entry_2 *) buffer)->rec_len)))->inode
 
 /*
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
 int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry,
 
 /*
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
 int obdfs_rename (struct inode * old_dir, struct dentry *old_dentry,
-                          struct inode * new_dir, struct dentry *new_dentry)
+                           struct inode * new_dir, struct dentry *new_dentry)
 {
 {
-       struct inode * old_inode, * new_inode;
-       struct page * old_page, * new_page, * dir_page;
-       struct ext2_dir_entry_2 * old_de, * new_de;
-       int retval;
+        struct inode * old_inode, * new_inode;
+        struct page * old_page, * new_page, * dir_page;
+        struct ext2_dir_entry_2 * old_de, * new_de;
+        int retval;
 
         ENTRY;
 
 
         ENTRY;
 
-       new_page = dir_page = NULL;
-
-       /* does the old entry exist? - if not get out */
-       old_page = obdfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de, NOLOCK);
-       /* PDEBUG(old_page, "rename - old page"); */
-       /*
-        *  Check for inode number is _not_ due to possible IO errors.
-        *  We might rmdir the source, keep it as pwd of some process
-        *  and merrily kill the link to whatever was created under the
-        *  same name. Goodbye sticky bit ;-<
-        */
-       old_inode = old_dentry->d_inode;
-       retval = -ENOENT;
-       if (!old_page || le32_to_cpu(old_de->inode) != old_inode->i_ino) {
-               EXIT;
-               goto end_rename;
-       }
-
-       /* find new inode */
-       new_inode = new_dentry->d_inode;
-       new_page = obdfs_find_entry (new_dir, new_dentry->d_name.name,
-                               new_dentry->d_name.len, &new_de, NOLOCK);
-       /* PDEBUG(new_page, "rename - new page "); */
-       if (new_page) {
-               if (!new_inode) {
-                       page_cache_release(new_page);
-                       new_page = NULL;
-               } else {
-                       DQUOT_INIT(new_inode);
-               }
-       }
-       /* in this case we to check more ... */
-       if (S_ISDIR(old_inode->i_mode)) {
-               /* can only rename into empty new directory */
-               if (new_inode) {
-                       retval = -ENOTEMPTY;
-                       if (!empty_dir (new_inode)) {
-                               EXIT;
-                               goto end_rename;
-                       }
-               }
-               retval = -EIO;
-               dir_page = obdfs_getpage (old_inode, 0, 0, LOCKED);
-               /* PDEBUG(dir_page, "rename dir page"); */
-
-               if (!dir_page) {
-                       EXIT;
-                       goto end_rename;
-               }
-               if (le32_to_cpu(PARENT_INO(page_address(dir_page))) !=
-                   old_dir->i_ino) {
-                       EXIT;
-                       goto end_rename;
-               }
-               retval = -EMLINK;
-               if (!new_inode && new_dir!=old_dir &&
-                               new_dir->i_nlink >= EXT2_LINK_MAX) {
-                       EXIT;
-                       goto end_rename;
-               }
-       }
-       /* create the target dir entry */
-       if (!new_page) {
-               new_page = obdfs_add_entry (new_dir, new_dentry->d_name.name,
-                                           new_dentry->d_name.len, &new_de,
-                                           &retval);
-               /* PDEBUG(new_page, "rename new page"); */
-               if (!new_page) {
-                       EXIT;
-                       goto end_rename;
-               }
-       }
-       new_dir->i_version = ++event;
-
-       /*
-        * remove the old entry
-        */
-       new_de->inode = le32_to_cpu(old_inode->i_ino);
-       if (EXT2_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
-                                     EXT2_FEATURE_INCOMPAT_FILETYPE))
-               new_de->file_type = old_de->file_type;
-       
-       obdfs_delete_entry (old_de, old_page);
-
-       old_dir->i_version = ++event;
-       if (new_inode) {
-               new_inode->i_nlink--;
-               new_inode->i_ctime = CURRENT_TIME;
-               mark_inode_dirty(new_inode);
-       }
-       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-       old_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-       mark_inode_dirty(old_dir);
-       if (dir_page) {
-               PARENT_INO(page_address(dir_page)) =le32_to_cpu(new_dir->i_ino);
-               retval = obdfs_do_writepage(old_inode, dir_page,
-                                           IS_SYNC(old_inode));
-               /* XXX handle err - not sure if this is correct */
-               if (retval) {
-                       EXIT;
-                       goto end_rename;
-               }
-               old_dir->i_nlink--;
-               mark_inode_dirty(old_dir);
-               if (new_inode) {
-                       new_inode->i_nlink--;
-                       mark_inode_dirty(new_inode);
-               } else {
-                       new_dir->i_nlink++;
-                       new_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-                       mark_inode_dirty(new_dir);
-               }
-       }
-       if ( old_page != new_page ) {
-               unsigned long index = old_page->index;
-               /* lock the old_page and release unlocked copy */
-               CDEBUG(D_INFO, "old_page at %p\n", old_page);
-               page_cache_release(old_page);
-               old_page = obdfs_getpage(old_dir, index << PAGE_SHIFT, 0,
-                                        LOCKED);
-               CDEBUG(D_INFO, "old_page at %p\n", old_page);
-               retval = obdfs_do_writepage(old_dir, old_page,IS_SYNC(old_dir));
-               /* XXX handle err - not sure if this is correct */
-               if (retval) {
-                       EXIT;
-                       goto end_rename;
-               }
-       }
-
-       retval = obdfs_do_writepage(new_dir, new_page, IS_SYNC(new_dir));
+        new_page = dir_page = NULL;
+
+        /* does the old entry exist? - if not get out */
+        old_page = obdfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de, NOLOCK);
+        /* PDEBUG(old_page, "rename - old page"); */
+        /*
+         *  Check for inode number is _not_ due to possible IO errors.
+         *  We might rmdir the source, keep it as pwd of some process
+         *  and merrily kill the link to whatever was created under the
+         *  same name. Goodbye sticky bit ;-<
+         */
+        old_inode = old_dentry->d_inode;
+        retval = -ENOENT;
+        if (!old_page || le32_to_cpu(old_de->inode) != old_inode->i_ino) {
+                EXIT;
+                goto end_rename;
+        }
+
+        /* find new inode */
+        new_inode = new_dentry->d_inode;
+        new_page = obdfs_find_entry (new_dir, new_dentry->d_name.name,
+                                new_dentry->d_name.len, &new_de, NOLOCK);
+        /* PDEBUG(new_page, "rename - new page "); */
+        if (new_page) {
+                if (!new_inode) {
+                        page_cache_release(new_page);
+                        new_page = NULL;
+                } else {
+                        DQUOT_INIT(new_inode);
+                }
+        }
+        /* in this case we to check more ... */
+        if (S_ISDIR(old_inode->i_mode)) {
+                /* can only rename into empty new directory */
+                if (new_inode) {
+                        retval = -ENOTEMPTY;
+                        if (!empty_dir (new_inode)) {
+                                EXIT;
+                                goto end_rename;
+                        }
+                }
+                retval = -EIO;
+                dir_page = obdfs_getpage (old_inode, 0, 0, LOCKED);
+                /* PDEBUG(dir_page, "rename dir page"); */
+
+                if (!dir_page) {
+                        EXIT;
+                        goto end_rename;
+                }
+                if (le32_to_cpu(PARENT_INO(page_address(dir_page))) !=
+                    old_dir->i_ino) {
+                        EXIT;
+                        goto end_rename;
+                }
+                retval = -EMLINK;
+                if (!new_inode && new_dir!=old_dir &&
+                                new_dir->i_nlink >= EXT2_LINK_MAX) {
+                        EXIT;
+                        goto end_rename;
+                }
+        }
+        /* create the target dir entry */
+        if (!new_page) {
+                new_page = obdfs_add_entry (new_dir, new_dentry->d_name.name,
+                                            new_dentry->d_name.len, &new_de,
+                                            &retval);
+                /* PDEBUG(new_page, "rename new page"); */
+                if (!new_page) {
+                        EXIT;
+                        goto end_rename;
+                }
+        }
+        new_dir->i_version = ++event;
+
+        /*
+         * remove the old entry
+         */
+        new_de->inode = le32_to_cpu(old_inode->i_ino);
+        if (EXT2_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
+                                      EXT2_FEATURE_INCOMPAT_FILETYPE))
+                new_de->file_type = old_de->file_type;
+        
+        obdfs_delete_entry (old_de, old_page);
+
+        old_dir->i_version = ++event;
+        if (new_inode) {
+                new_inode->i_nlink--;
+                new_inode->i_ctime = CURRENT_TIME;
+                mark_inode_dirty(new_inode);
+        }
+        old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+        old_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
+        mark_inode_dirty(old_dir);
+        if (dir_page) {
+                PARENT_INO(page_address(dir_page)) =le32_to_cpu(new_dir->i_ino);
+                retval = obdfs_do_writepage(dir_page, IS_SYNC(old_inode));
+                /* XXX handle err - not sure if this is correct */
+                if (retval) {
+                        EXIT;
+                        goto end_rename;
+                }
+                old_dir->i_nlink--;
+                mark_inode_dirty(old_dir);
+                if (new_inode) {
+                        new_inode->i_nlink--;
+                        mark_inode_dirty(new_inode);
+                } else {
+                        new_dir->i_nlink++;
+                        new_dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
+                        mark_inode_dirty(new_dir);
+                }
+        }
+        if ( old_page != new_page ) {
+                unsigned long index = old_page->index;
+                /* lock the old_page and release unlocked copy */
+                CDEBUG(D_INFO, "old_page at %p\n", old_page);
+                page_cache_release(old_page);
+                old_page = obdfs_getpage(old_dir, index << PAGE_SHIFT, 0,
+                                         LOCKED);
+                CDEBUG(D_INFO, "old_page at %p\n", old_page);
+                retval = obdfs_do_writepage(old_page,IS_SYNC(old_dir));
+                /* XXX handle err - not sure if this is correct */
+                if (retval) {
+                        EXIT;
+                        goto end_rename;
+                }
+        }
+
+        retval = obdfs_do_writepage(new_page, IS_SYNC(new_dir));
 
 end_rename:
 
 end_rename:
-       if (old_page && PageLocked(old_page) )
-               UnlockPage(old_page);
-       if (old_page)
-               page_cache_release(old_page);
-       if (new_page && PageLocked(new_page) )
-               UnlockPage(new_page);
-       if (new_page)
-               page_cache_release(new_page);
-       if (dir_page && PageLocked(dir_page) )
-               UnlockPage(dir_page);
-       if (dir_page)
-               page_cache_release(dir_page);
-
-       return retval;
+        if (old_page && PageLocked(old_page) )
+                obd_unlock_page(old_page);
+        if (old_page)
+                page_cache_release(old_page);
+        if (new_page && PageLocked(new_page) )
+                obd_unlock_page(new_page);
+        if (new_page)
+                page_cache_release(new_page);
+        if (dir_page && PageLocked(dir_page) )
+                obd_unlock_page(dir_page);
+        if (dir_page)
+                page_cache_release(dir_page);
+
+        return retval;
 } /* obdfs_rename */
 } /* obdfs_rename */
index ce58fd6..7b8a368 100644 (file)
 /* SYNCHRONOUS I/O for an inode */
 static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
 {
 /* SYNCHRONOUS I/O for an inode */
 static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
 {
-       obd_count        num_obdo = 1;
-       obd_count        bufs_per_obdo = 1;
-       struct obdo     *oa;
-       char            *buf = (char *)page_address(page);
-       obd_size         count = PAGE_SIZE;
-       obd_off          offset = ((obd_off)page->index) << PAGE_SHIFT;
-       obd_flag         flags = create ? OBD_BRW_CREATE : 0;
-       int              err;
-
-       ENTRY;
-       if (IOPS(inode, brw) == NULL) {
-               printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
-               EXIT;
-               return -EIO;
-       }
-
-       oa = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD);
-       if ( IS_ERR(oa) ) {
-               EXIT;
-               return PTR_ERR(oa);
-       }
-       obdfs_from_inode(oa, inode);
-
-       err = IOPS(inode, brw)(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
-                              &buf, &count, &offset, &flags);
-
-       if ( !err )
-               obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
-
-       obdo_free(oa);
-       
-       EXIT;
-       return err;
+        obd_count        num_obdo = 1;
+        obd_count        bufs_per_obdo = 1;
+        struct obdo     *oa;
+        char            *buf = (char *)page_address(page);
+        obd_size         count = PAGE_SIZE;
+        obd_off          offset = ((obd_off)page->index) << PAGE_SHIFT;
+        obd_flag         flags = create ? OBD_BRW_CREATE : 0;
+        int              err;
+
+        ENTRY;
+        if (IOPS(inode, brw) == NULL) {
+                printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
+                EXIT;
+                return -EIO;
+        }
+
+        oa = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD);
+        if ( IS_ERR(oa) ) {
+                EXIT;
+                return PTR_ERR(oa);
+        }
+        obdfs_from_inode(oa, inode);
+
+        err = IOPS(inode, brw)(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
+                               &buf, &count, &offset, &flags);
+
+        if ( !err )
+                obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
+
+        obdo_free(oa);
+        
+        EXIT;
+        return err;
 } /* obdfs_brw */
 
 /* returns the page unlocked, but with a reference */
 } /* obdfs_brw */
 
 /* returns the page unlocked, but with a reference */
-int obdfs_readpage(struct dentry *dentry, struct page *page)
+int obdfs_readpage(struct file *file, struct page *page)
 {
 {
-       struct inode *inode = dentry->d_inode;
-       int rc;
-
-       ENTRY;
-       /* PDEBUG(page, "READ"); */
-       rc = obdfs_brw(READ, inode, page, 0);
-       if ( !rc ) {
-               SetPageUptodate(page);
-               UnlockPage(page);
-       } 
-       /* PDEBUG(page, "READ"); */
-       EXIT;
-       return rc;
+        struct dentry *dentry = file->f_dentry;
+        struct inode *inode = dentry->d_inode;
+        int rc;
+
+        ENTRY;
+        /* PDEBUG(page, "READ"); */
+        rc = obdfs_brw(READ, inode, page, 0);
+        if ( !rc ) {
+                SetPageUptodate(page);
+                obd_unlock_page(page);
+        } 
+        /* PDEBUG(page, "READ"); */
+        EXIT;
+        return rc;
 } /* obdfs_readpage */
 
 static kmem_cache_t *obdfs_pgrq_cachep = NULL;
 
 int obdfs_init_pgrqcache(void)
 {
 } /* obdfs_readpage */
 
 static kmem_cache_t *obdfs_pgrq_cachep = NULL;
 
 int obdfs_init_pgrqcache(void)
 {
-       ENTRY;
-       if (obdfs_pgrq_cachep == NULL) {
-               CDEBUG(D_CACHE, "allocating obdfs_pgrq_cache\n");
-               obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq",
-                                                     sizeof(struct obdfs_pgrq),
-                                                     0, SLAB_HWCACHE_ALIGN,
-                                                     NULL, NULL);
-               if (obdfs_pgrq_cachep == NULL) {
-                       EXIT;
-                       return -ENOMEM;
-               } else {
-                       CDEBUG(D_CACHE, "allocated cache at %p\n",
-                              obdfs_pgrq_cachep);
-               }
-       } else {
-               CDEBUG(D_CACHE, "using existing cache at %p\n",
-                      obdfs_pgrq_cachep);
-       }
-       EXIT;
-       return 0;
+        ENTRY;
+        if (obdfs_pgrq_cachep == NULL) {
+                CDEBUG(D_CACHE, "allocating obdfs_pgrq_cache\n");
+                obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq",
+                                                      sizeof(struct obdfs_pgrq),
+                                                      0, SLAB_HWCACHE_ALIGN,
+                                                      NULL, NULL);
+                if (obdfs_pgrq_cachep == NULL) {
+                        EXIT;
+                        return -ENOMEM;
+                } else {
+                        CDEBUG(D_CACHE, "allocated cache at %p\n",
+                               obdfs_pgrq_cachep);
+                }
+        } else {
+                CDEBUG(D_CACHE, "using existing cache at %p\n",
+                       obdfs_pgrq_cachep);
+        }
+        EXIT;
+        return 0;
 } /* obdfs_init_wreqcache */
 
 inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq)
 {
 } /* obdfs_init_wreqcache */
 
 inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq)
 {
-       --obdfs_cache_count;
-       CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n",
-              pgrq->rq_page, obdfs_cache_count);
-       list_del(&pgrq->rq_plist);
-       OBDClearCachePage(pgrq->rq_page);
-       kmem_cache_free(obdfs_pgrq_cachep, pgrq);
+        --obdfs_cache_count;
+        CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n",
+               pgrq->rq_page, obdfs_cache_count);
+        list_del(&pgrq->rq_plist);
+        OBDClearCachePage(pgrq->rq_page);
+        kmem_cache_free(obdfs_pgrq_cachep, pgrq);
 }
 
 void obdfs_cleanup_pgrqcache(void)
 {
 }
 
 void obdfs_cleanup_pgrqcache(void)
 {
-       ENTRY;
-       if (obdfs_pgrq_cachep != NULL) {
-               CDEBUG(D_CACHE, "destroying obdfs_pgrqcache at %p, count %ld\n",
-                      obdfs_pgrq_cachep, obdfs_cache_count);
-               if (kmem_cache_destroy(obdfs_pgrq_cachep))
-                       printk(KERN_INFO __FUNCTION__
-                              ": unable to free all of cache\n");
-               obdfs_pgrq_cachep = NULL;
-       } else
-               printk(KERN_INFO __FUNCTION__ ": called with NULL pointer\n");
-
-       EXIT;
+        ENTRY;
+        if (obdfs_pgrq_cachep != NULL) {
+                CDEBUG(D_CACHE, "destroying obdfs_pgrqcache at %p, count %ld\n",
+                       obdfs_pgrq_cachep, obdfs_cache_count);
+                if (kmem_cache_destroy(obdfs_pgrq_cachep))
+                        printk(KERN_INFO __FUNCTION__
+                               ": unable to free all of cache\n");
+                obdfs_pgrq_cachep = NULL;
+        } else
+                printk(KERN_INFO __FUNCTION__ ": called with NULL pointer\n");
+
+        EXIT;
 } /* obdfs_cleanup_wreqcache */
 
 
 /* called with the list lock held */
 static struct page *obdfs_find_page_index(struct inode *inode,
 } /* obdfs_cleanup_wreqcache */
 
 
 /* called with the list lock held */
 static struct page *obdfs_find_page_index(struct inode *inode,
-                                         unsigned long index)
+                                          unsigned long index)
 {
 {
-       struct list_head *page_list = obdfs_iplist(inode);
-       struct list_head *tmp;
-       struct page *page;
-
-       ENTRY;
-
-       CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n",
-              inode->i_ino, index);
-       OIDEBUG(inode);
-
-       if (list_empty(page_list)) {
-               EXIT;
-               return NULL;
-       }
-       tmp = page_list;
-       while ( (tmp = tmp->next) != page_list ) {
-               struct obdfs_pgrq *pgrq;
-
-               pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
-               page = pgrq->rq_page;
-               if (index == page->index) {
-                       CDEBUG(D_INFO,
-                              "INDEX SEARCH found page %p, index %ld\n",
-                              page, index);
-                       EXIT;
-                       return page;
-               }
-       } 
-
-       EXIT;
-       return NULL;
+        struct list_head *page_list = obdfs_iplist(inode);
+        struct list_head *tmp;
+        struct page *page;
+
+        ENTRY;
+
+        CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n",
+               inode->i_ino, index);
+        OIDEBUG(inode);
+
+        if (list_empty(page_list)) {
+                EXIT;
+                return NULL;
+        }
+        tmp = page_list;
+        while ( (tmp = tmp->next) != page_list ) {
+                struct obdfs_pgrq *pgrq;
+
+                pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
+                page = pgrq->rq_page;
+                if (index == page->index) {
+                        CDEBUG(D_INFO,
+                               "INDEX SEARCH found page %p, index %ld\n",
+                               page, index);
+                        EXIT;
+                        return page;
+                }
+        
+
+        EXIT;
+        return NULL;
 } /* obdfs_find_page_index */
 
 
 /* call and free pages from Linux page cache: called with io lock on inodes */
 int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
 } /* obdfs_find_page_index */
 
 
 /* call and free pages from Linux page cache: called with io lock on inodes */
 int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
-                   obd_count num_obdos, struct obdo **obdos,
-                   obd_count *oa_bufs, struct page **pages, char **bufs,
-                   obd_size *counts, obd_off *offsets, obd_flag *flags)
+                    obd_count num_obdos, struct obdo **obdos,
+                    obd_count *oa_bufs, struct page **pages, char **bufs,
+                    obd_size *counts, obd_off *offsets, obd_flag *flags)
 {
 {
-       int err;
-
-       ENTRY;
-       if (IOPS(inodes[0], brw) == NULL) {
-               printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
-               EXIT;
-               return -EIO;
-       }
-
-       CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
-              num_io, num_obdos);
-       if (obd_debug_level & D_INFO) { /* DEBUGGING */
-               int i;
-               printk("OBDOS: ");
-               for (i = 0; i < num_obdos; i++)
-                       printk("%ld:0x%p ", (long)obdos[i]->o_id, obdos[i]);
-
-               printk("\nPAGES: ");
-               for (i = 0; i < num_io; i++)
-                       printk("0x%p ", pages[i]);
-               printk("\n");
-       }
-
-       err = IOPS(inodes[0], brw)(WRITE, IID(inodes[0]), num_obdos, obdos,
-                                 oa_bufs, bufs, counts, offsets, flags);
-
-       CDEBUG(D_INFO, "BRW done\n");
-       /* release the pages from the page cache */
-       while ( num_io > 0 ) {
-               --num_io;
-               CDEBUG(D_INFO, "calling put_page for %p, index %ld\n",
-                      pages[num_io], pages[num_io]->index);
-               /* PDEBUG(pages[num_io], "do_vec_wr"); */
-               put_page(pages[num_io]);
-               /* PDEBUG(pages[num_io], "do_vec_wr"); */
-       }
-       CDEBUG(D_INFO, "put_page done\n");
-
-       while ( num_obdos > 0) {
-               --num_obdos;
-               CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id);
-               /* copy o_blocks to i_blocks */
-               obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]);
-               obdo_free(obdos[num_obdos]);
-       }
-       CDEBUG(D_INFO, "obdo_free done\n");
-       EXIT;
-       return err;
+        int err;
+
+        ENTRY;
+        if (IOPS(inodes[0], brw) == NULL) {
+                printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
+                EXIT;
+                return -EIO;
+        }
+
+        CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
+               num_io, num_obdos);
+        if (obd_debug_level & D_INFO) { /* DEBUGGING */
+                int i;
+                printk("OBDOS: ");
+                for (i = 0; i < num_obdos; i++)
+                        printk("%ld:0x%p ", (long)obdos[i]->o_id, obdos[i]);
+
+                printk("\nPAGES: ");
+                for (i = 0; i < num_io; i++)
+                        printk("0x%p ", pages[i]);
+                printk("\n");
+        }
+
+        err = IOPS(inodes[0], brw)(WRITE, IID(inodes[0]), num_obdos, obdos,
+                                  oa_bufs, bufs, counts, offsets, flags);
+
+        CDEBUG(D_INFO, "BRW done\n");
+        /* release the pages from the page cache */
+        while ( num_io > 0 ) {
+                --num_io;
+                CDEBUG(D_INFO, "calling put_page for %p, index %ld\n",
+                       pages[num_io], pages[num_io]->index);
+                /* PDEBUG(pages[num_io], "do_vec_wr"); */
+                put_page(pages[num_io]);
+                /* PDEBUG(pages[num_io], "do_vec_wr"); */
+        }
+        CDEBUG(D_INFO, "put_page done\n");
+
+        while ( num_obdos > 0) {
+                --num_obdos;
+                CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id);
+                /* copy o_blocks to i_blocks */
+                obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]);
+                obdo_free(obdos[num_obdos]);
+        }
+        CDEBUG(D_INFO, "obdo_free done\n");
+        EXIT;
+        return err;
 }
 
 
 }
 
 
@@ -244,95 +245,97 @@ int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
  */
 static int obdfs_add_page_to_cache(struct inode *inode, struct page *page)
 {
  */
 static int obdfs_add_page_to_cache(struct inode *inode, struct page *page)
 {
-       int err = 0;
-       ENTRY;
-
-       /* The PG_obdcache bit is cleared by obdfs_pgrq_del() BEFORE the page
-        * is written, so at worst we will write the page out twice.
-        *
-        * If the page has the PG_obdcache bit set, then the inode MUST be
-        * on the superblock dirty list so we don't need to check this.
-        * Dirty inodes are removed from the superblock list ONLY when they
-        * don't have any more cached pages.  It is possible to have an inode
-        * with no dirty pages on the superblock list, but not possible to
-        * have an inode with dirty pages NOT on the superblock dirty list.
-        */
-       if (!OBDAddCachePage(page)) {
-               struct obdfs_pgrq *pgrq;
-               pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL);
-               if (!pgrq) {
-                       OBDClearCachePage(page);
-                       EXIT;
-                       return -ENOMEM;
-               }
-               /* not really necessary since we set all pgrq fields here
-               memset(pgrq, 0, sizeof(*pgrq)); 
-               */
-               
-               pgrq->rq_page = page;
-               pgrq->rq_jiffies = jiffies;
-               get_page(pgrq->rq_page);
-
-               obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
-               list_add(&pgrq->rq_plist, obdfs_iplist(inode));
-               obdfs_cache_count++;
-
-               /* If inode isn't already on superblock inodes list, add it.
-                *
-                * We increment the reference count on the inode to keep it
-                * from being freed from memory.  This _should_ be an iget()
-                * with an iput() in both flush_reqs() and put_inode(), but
-                * since put_inode() is called from iput() we can't call iput()
-                * again there.  Instead we just increment/decrement i_count,
-                * which is mostly what iget/iput do for an inode in memory.
-                */
-               if ( list_empty(obdfs_islist(inode)) ) {
-                       inode->i_count++;
-                       CDEBUG(D_INFO,
-                              "adding inode %ld to superblock list %p\n",
-                              inode->i_ino, obdfs_slist(inode));
-                       list_add(obdfs_islist(inode), obdfs_slist(inode));
-               }
-               obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
-       }
-
-       /* XXX For testing purposes, we can write out the page here.
-       err = obdfs_flush_reqs(obdfs_slist(inode), ~0UL);
-        */
-
-       EXIT;
-       return err;
+        int err = 0;
+        ENTRY;
+
+        /* The PG_obdcache bit is cleared by obdfs_pgrq_del() BEFORE the page
+         * is written, so at worst we will write the page out twice.
+         *
+         * If the page has the PG_obdcache bit set, then the inode MUST be
+         * on the superblock dirty list so we don't need to check this.
+         * Dirty inodes are removed from the superblock list ONLY when they
+         * don't have any more cached pages.  It is possible to have an inode
+         * with no dirty pages on the superblock list, but not possible to
+         * have an inode with dirty pages NOT on the superblock dirty list.
+         */
+        if (!OBDAddCachePage(page)) {
+                struct obdfs_pgrq *pgrq;
+                pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL);
+                if (!pgrq) {
+                        OBDClearCachePage(page);
+                        EXIT;
+                        return -ENOMEM;
+                }
+                /* not really necessary since we set all pgrq fields here
+                memset(pgrq, 0, sizeof(*pgrq)); 
+                */
+                
+                pgrq->rq_page = page;
+                pgrq->rq_jiffies = jiffies;
+                get_page(pgrq->rq_page);
+
+                obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
+                list_add(&pgrq->rq_plist, obdfs_iplist(inode));
+                obdfs_cache_count++;
+
+                /* If inode isn't already on superblock inodes list, add it.
+                 *
+                 * We increment the reference count on the inode to keep it
+                 * from being freed from memory.  This _should_ be an iget()
+                 * with an iput() in both flush_reqs() and put_inode(), but
+                 * since put_inode() is called from iput() we can't call iput()
+                 * again there.  Instead we just increment/decrement i_count,
+                 * which is mostly what iget/iput do for an inode in memory.
+                 */
+                if ( list_empty(obdfs_islist(inode)) ) {
+                        atomic_inc(&inode->i_count);
+                        CDEBUG(D_INFO,
+                               "adding inode %ld to superblock list %p\n",
+                               inode->i_ino, obdfs_slist(inode));
+                        list_add(obdfs_islist(inode), obdfs_slist(inode));
+                }
+                obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
+        }
+
+        /* XXX For testing purposes, we can write out the page here.
+        err = obdfs_flush_reqs(obdfs_slist(inode), ~0UL);
+         */
+
+        EXIT;
+        return err;
 } /* obdfs_add_page_to_cache */
 
 
 /* select between SYNC and ASYNC I/O methods */
 } /* obdfs_add_page_to_cache */
 
 
 /* select between SYNC and ASYNC I/O methods */
-int obdfs_do_writepage(struct inode *inode, struct page *page, int sync)
+int obdfs_do_writepage(struct page *page, int sync)
 {
 {
-       int err;
-
-       ENTRY;
-       /* PDEBUG(page, "WRITEPAGE"); */
-       if ( sync )
-               err = obdfs_brw(WRITE, inode, page, 1);
-       else {
-               err = obdfs_add_page_to_cache(inode, page);
-               CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n",
-                      inode->i_ino, page, err, Page_Uptodate(page));
-       }
-               
-       if ( !err )
-               SetPageUptodate(page);
-       /* PDEBUG(page,"WRITEPAGE"); */
-       EXIT;
-       return err;
+        struct inode *inode = page->mapping->host;
+        int err;
+
+        ENTRY;
+        /* PDEBUG(page, "WRITEPAGE"); */
+        if ( sync )
+                err = obdfs_brw(WRITE, inode, page, 1);
+        else {
+                err = obdfs_add_page_to_cache(inode, page);
+                CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n",
+                       inode->i_ino, page, err, Page_Uptodate(page));
+        }
+                
+        if ( !err )
+                SetPageUptodate(page);
+        /* PDEBUG(page,"WRITEPAGE"); */
+        EXIT;
+        return err;
 } /* obdfs_do_writepage */
 
 /* returns the page unlocked, but with a reference */
 } /* obdfs_do_writepage */
 
 /* returns the page unlocked, but with a reference */
-int obdfs_writepage(struct dentry *dentry, struct page *page)
+int obdfs_writepage(struct page *page)
 {
 {
-       return obdfs_do_writepage(dentry->d_inode, page, 0);
+        return obdfs_do_writepage(page, 0);
 }
 
 }
 
+
 /*
  * This does the "real" work of the write. The generic routine has
  * allocated the page, locked it, done all the page alignment stuff
 /*
  * This does the "real" work of the write. The generic routine has
  * allocated the page, locked it, done all the page alignment stuff
@@ -345,31 +348,31 @@ int obdfs_writepage(struct dentry *dentry, struct page *page)
  * Return value is the number of bytes written.
  */
 int obdfs_write_one_page(struct file *file, struct page *page,
  * Return value is the number of bytes written.
  */
 int obdfs_write_one_page(struct file *file, struct page *page,
-                        unsigned long offset, unsigned long bytes,
-                        const char * buf)
+                         unsigned long offset, unsigned long bytes,
+                         const char * buf)
 {
 {
-       struct inode *inode = file->f_dentry->d_inode;
-       int err;
-
-       ENTRY;
-       /* We check for complete page writes here, as we then don't have to
-        * get the page before writing over everything anyways.
-        */
-       if ( !Page_Uptodate(page) && (offset != 0 || bytes != PAGE_SIZE) ) {
-               err = obdfs_brw(READ, inode, page, 0);
-               if ( err )
-                       return err;
-               SetPageUptodate(page);
-       }
-
-       if (copy_from_user((u8*)page_address(page) + offset, buf, bytes))
-               return -EFAULT;
-
-       lock_kernel();
-       err = obdfs_writepage(file->f_dentry, page);
-       unlock_kernel();
-
-       return (err < 0 ? err : bytes);
+        struct inode *inode = file->f_dentry->d_inode;
+        int err;
+
+        ENTRY;
+        /* We check for complete page writes here, as we then don't have to
+         * get the page before writing over everything anyways.
+         */
+        if ( !Page_Uptodate(page) && (offset != 0 || bytes != PAGE_SIZE) ) {
+                err = obdfs_brw(READ, inode, page, 0);
+                if ( err )
+                        return err;
+                SetPageUptodate(page);
+        }
+
+        if (copy_from_user((u8*)page_address(page) + offset, buf, bytes))
+                return -EFAULT;
+
+        lock_kernel();
+        err = obdfs_writepage(page);
+        unlock_kernel();
+
+        return (err < 0 ? err : bytes);
 } /* obdfs_write_one_page */
 
 /* 
 } /* obdfs_write_one_page */
 
 /* 
@@ -381,104 +384,109 @@ int obdfs_write_one_page(struct file *file, struct page *page,
  * modeled on NFS code.
  */
 struct page *obdfs_getpage(struct inode *inode, unsigned long offset,
  * modeled on NFS code.
  */
 struct page *obdfs_getpage(struct inode *inode, unsigned long offset,
-                          int create, int locked)
+                           int create, int locked)
 {
 {
-       struct page * page;
-       int index;
-       int err;
-
-       ENTRY;
-
-       offset = offset & PAGE_CACHE_MASK;
-       CDEBUG(D_INFO, "ino: %ld, offset %ld, create %d, locked %d\n",
-              inode->i_ino, offset, create, locked);
-       index = offset >> PAGE_CACHE_SHIFT;
-
-       page = grab_cache_page(&inode->i_data, index);
-
-       /* Yuck, no page */
-       if (! page) {
-           printk(KERN_WARNING " grab_cache_page says no dice ...\n");
-           EXIT;
-           return NULL;
-       }
-
-       /* PDEBUG(page, "GETPAGE: got page - before reading\n"); */
-       /* now check if the data in the page is up to date */
-       if ( Page_Uptodate(page)) { 
-               if (!locked)
-                       UnlockPage(page);
-               EXIT;
-               return page;
-       } 
+        struct page * page;
+        int index;
+        int err;
+
+        ENTRY;
+
+        offset = offset & PAGE_CACHE_MASK;
+        CDEBUG(D_INFO, "ino: %ld, offset %ld, create %d, locked %d\n",
+               inode->i_ino, offset, create, locked);
+        index = offset >> PAGE_CACHE_SHIFT;
+
+        page = grab_cache_page(&inode->i_data, index);
+
+        /* Yuck, no page */
+        if (! page) {
+            printk(KERN_WARNING " grab_cache_page says no dice ...\n");
+            EXIT;
+            return NULL;
+        }
+
+        /* PDEBUG(page, "GETPAGE: got page - before reading\n"); */
+        /* now check if the data in the page is up to date */
+        if ( Page_Uptodate(page)) { 
+                if (!locked) {
+                        if (PageLocked(page))
+                                obd_unlock_page(page);
+                } else {
+                        printk("file %s, line %d: expecting locked page\n",
+                               __FILE__, __LINE__); 
+                }
+                EXIT;
+                return page;
+        } 
 
 
 #ifdef EXT2_OBD_DEBUG
 
 
 #ifdef EXT2_OBD_DEBUG
-       if ((obd_debug_level & D_INFO) && obdfs_find_page_index(inode, index)) {
-               CDEBUG(D_INFO, "OVERWRITE: found dirty page %p, index %ld\n",
-                      page, page->index);
-       }
+        if ((obd_debug_level & D_INFO) && obdfs_find_page_index(inode, index)) {
+                CDEBUG(D_INFO, "OVERWRITE: found dirty page %p, index %ld\n",
+                       page, page->index);
+        }
 #endif
 
 #endif
 
-       err = obdfs_brw(READ, inode, page, create);
-
-       if ( err ) {
-               SetPageError(page);
-               UnlockPage(page);
-               EXIT;
-               return page;
-       }
-
-       if ( !locked )
-               UnlockPage(page);
-       SetPageUptodate(page);
-       /* PDEBUG(page,"GETPAGE - after reading"); */
-       EXIT;
-       return page;
+        err = obdfs_brw(READ, inode, page, create);
+
+        if ( err ) {
+                SetPageError(page);
+                obd_unlock_page(page);
+                EXIT;
+                return page;
+        }
+
+        if ( !locked )
+                obd_unlock_page(page);
+        SetPageUptodate(page);
+        /* PDEBUG(page,"GETPAGE - after reading"); */
+        EXIT;
+        return page;
 } /* obdfs_getpage */
 
 
 void obdfs_truncate(struct inode *inode)
 {
 } /* obdfs_getpage */
 
 
 void obdfs_truncate(struct inode *inode)
 {
-       struct obdo *oa;
-       int err;
-       ENTRY;
-
-       obdfs_dequeue_pages(inode);
-
-       if (IOPS(inode, punch) == NULL) {
-               printk(KERN_ERR __FUNCTION__ ": no punch method!\n");
-               EXIT;
-               return;
-       }
-       oa = obdo_alloc();
-       if ( !oa ) {
-               /* XXX This would give an inconsistent FS, so deal with it as
-                * best we can for now - an obdo on the stack is not pretty.
-                */
-               struct obdo obdo;
-
-               printk(__FUNCTION__ ": obdo_alloc failed - using stack!\n");
-
-               obdo.o_valid = OBD_MD_FLNOTOBD;
-               obdfs_from_inode(&obdo, inode);
-
-               err = IOPS(inode, punch)(IID(inode), &obdo, obdo.o_size, 0);
-       } else {
-               oa->o_valid = OBD_MD_FLNOTOBD;
-               obdfs_from_inode(oa, inode);
-
-               CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
-                      (long)oa->o_id, oa->o_size);
-               err = IOPS(inode, punch)(IID(inode), oa, oa->o_size, 0);
-
-               obdo_free(oa);
-       }
-
-       if (err) {
-               printk(__FUNCTION__ ": obd_truncate fails (%d)\n", err);
-               EXIT;
-               return;
-       }
-       EXIT;
+        struct obdo *oa;
+        int err;
+        ENTRY;
+
+        obdfs_dequeue_pages(inode);
+
+        if (IOPS(inode, punch) == NULL) {
+                printk(KERN_ERR __FUNCTION__ ": no punch method!\n");
+                EXIT;
+                return;
+        }
+        oa = obdo_alloc();
+        if ( !oa ) {
+                /* XXX This would give an inconsistent FS, so deal with it as
+                 * best we can for now - an obdo on the stack is not pretty.
+                 */
+                struct obdo obdo;
+
+                printk(__FUNCTION__ ": obdo_alloc failed - using stack!\n");
+
+                obdo.o_valid = OBD_MD_FLNOTOBD;
+                obdfs_from_inode(&obdo, inode);
+
+                err = IOPS(inode, punch)(IID(inode), &obdo, obdo.o_size, 0);
+        } else {
+                oa->o_valid = OBD_MD_FLNOTOBD;
+                obdfs_from_inode(oa, inode);
+
+                CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
+                       (long)oa->o_id, oa->o_size);
+                err = IOPS(inode, punch)(IID(inode), oa, oa->o_size, 0);
+
+                obdo_free(oa);
+        }
+
+        if (err) {
+                printk(__FUNCTION__ ": obd_truncate fails (%d)\n", err);
+                EXIT;
+                return;
+        }
+        EXIT;
 } /* obdfs_truncate */
 } /* obdfs_truncate */
index 191cb87..04853f9 100644 (file)
@@ -4,6 +4,7 @@
  * Copryright (C) 1996 Peter J. Braam <braam@stelias.com>
  * Copryright (C) 1999 Stelias Computing Inc. <braam@stelias.com>
  * Copryright (C) 1999 Seagate Technology Inc.
  * Copryright (C) 1996 Peter J. Braam <braam@stelias.com>
  * Copryright (C) 1999 Stelias Computing Inc. <braam@stelias.com>
  * Copryright (C) 1999 Seagate Technology Inc.
+ * Copryright (C) 2001 Mountain View Data, Inc.
  *
  */
 
  *
  */
 
@@ -33,6 +34,7 @@
 #include <linux/obdfs.h>
 
 struct list_head obdfs_super_list;
 #include <linux/obdfs.h>
 
 struct list_head obdfs_super_list;
+struct address_space_operations obdfs_aops;
 struct super_operations obdfs_super_operations;
 long obdfs_cache_count = 0;
 long obdfs_mutex_start = 0;
 struct super_operations obdfs_super_operations;
 long obdfs_cache_count = 0;
 long obdfs_mutex_start = 0;
@@ -40,212 +42,227 @@ long obd_memory = 0;
 
 static char *obdfs_read_opt(const char *opt, char *data)
 {
 
 static char *obdfs_read_opt(const char *opt, char *data)
 {
-       char *value;
-       char *retval;
-
-       CDEBUG(D_INFO, "option: %s, data %s\n", opt, data);
-       if ( strncmp(opt, data, strlen(opt)) )
-               return NULL;
-
-       if ( (value = strchr(data, '=')) == NULL )
-               return NULL;
-
-       value++;
-       OBD_ALLOC(retval, char *, strlen(value) + 1);
-       if ( !retval ) {
-               printk(KERN_ALERT __FUNCTION__ ": out of memory!\n");
-               return NULL;
-       }
-       
-       memcpy(retval, value, strlen(value)+1);
-       CDEBUG(D_PSDEV, "Assigned option: %s, value %s\n", opt, retval);
-       return retval;
+        char *value;
+        char *retval;
+
+        CDEBUG(D_INFO, "option: %s, data %s\n", opt, data);
+        if ( strncmp(opt, data, strlen(opt)) )
+                return NULL;
+
+        if ( (value = strchr(data, '=')) == NULL )
+                return NULL;
+
+        value++;
+        OBD_ALLOC(retval, char *, strlen(value) + 1);
+        if ( !retval ) {
+                printk(KERN_ALERT __FUNCTION__ ": out of memory!\n");
+                return NULL;
+        }
+        
+        memcpy(retval, value, strlen(value)+1);
+        CDEBUG(D_PSDEV, "Assigned option: %s, value %s\n", opt, retval);
+        return retval;
 }
 
 static void obdfs_options(char *options, char **dev, char **vers)
 {
 }
 
 static void obdfs_options(char *options, char **dev, char **vers)
 {
-       char *this_char;
-
-       if (!options)
-               return;
-
-       for (this_char = strtok (options, ",");
-            this_char != NULL;
-            this_char = strtok (NULL, ",")) {
-               CDEBUG(D_INFO, "this_char %s\n", this_char);
-               if ( (!*dev && (*dev = obdfs_read_opt("device", this_char)))||
-                    (!*vers && (*vers = obdfs_read_opt("version", this_char))) )
-                       continue;
-               
-       }
+        char *this_char;
+
+        if (!options)
+                return;
+
+        for (this_char = strtok (options, ",");
+             this_char != NULL;
+             this_char = strtok (NULL, ",")) {
+                CDEBUG(D_INFO, "this_char %s\n", this_char);
+                if ( (!*dev && (*dev = obdfs_read_opt("device", this_char)))||
+                     (!*vers && (*vers = obdfs_read_opt("version", this_char))) )
+                        continue;
+                
+        }
 }
 
 static int obdfs_getdev(char *devpath, int *dev)
 {
 }
 
 static int obdfs_getdev(char *devpath, int *dev)
 {
-       struct dentry *dentry;
-       kdev_t devno;
-
-       dentry = lookup_dentry(devpath, NULL, 0);
-       if (IS_ERR(dentry))
-               return PTR_ERR(dentry);
-       
-       if (!S_ISCHR(dentry->d_inode->i_mode))
-               return -ENODEV;
-
-       devno = dentry->d_inode->i_rdev;
-       if ( MAJOR(devno) != OBD_PSDEV_MAJOR ) 
-               return -ENODEV;
-       
-       if ( MINOR(devno) >= MAX_OBD_DEVICES ) 
-               return -ENODEV;
-
-       *dev = devno;
-       return 0;
+        struct dentry *dentry;
+        kdev_t devno;
+        struct nameidata nd;
+        int error = 0; 
+
+        ENTRY;
+        if (path_init(devpath, LOOKUP_POSITIVE, &nd))
+                error = path_walk(devpath, &nd);
+        if (error)
+                return error;
+
+        dentry = nd.dentry;
+        if (!S_ISCHR(dentry->d_inode->i_mode))
+                return -ENODEV;
+
+        devno = dentry->d_inode->i_rdev;
+        if ( MAJOR(devno) != OBD_PSDEV_MAJOR ) 
+                return -ENODEV;
+        
+        if ( MINOR(devno) >= MAX_OBD_DEVICES ) 
+                return -ENODEV;
+
+        *dev = devno;
+        return 0;
 }
 
 
 static struct super_block * obdfs_read_super(struct super_block *sb, 
 }
 
 
 static struct super_block * obdfs_read_super(struct super_block *sb, 
-                                           void *data, int silent)
+                                            void *data, int silent)
 {
         struct inode *root = 0; 
 {
         struct inode *root = 0; 
-       struct obdfs_sb_info *sbi = (struct obdfs_sb_info *)(&sb->u.generic_sbp);
-       struct obd_device *obddev;
-       char *device = NULL;
-       char *version = NULL;
-       int devno;
-       int err;
-       unsigned long blocksize;
-       unsigned long blocksize_bits;
-       unsigned long root_ino;
-       int scratch;
-       
-
-       ENTRY;
+        struct obdfs_sb_info *sbi = (struct obdfs_sb_info *)(&sb->u.generic_sbp);
+        struct obd_device *obddev;
+        char *device = NULL;
+        char *version = NULL;
+        int devno;
+        int err;
+        unsigned long blocksize;
+        unsigned long blocksize_bits;
+        unsigned long root_ino;
+        int scratch;
+        
+
+        ENTRY;
         MOD_INC_USE_COUNT; 
         MOD_INC_USE_COUNT; 
-       
-       memset(sbi, 0, sizeof(*sbi));
-       
-       obdfs_options(data, &device, &version);
-       if ( !device ) {
-               printk(__FUNCTION__ ": no device\n");
-               EXIT;
-               goto ERR;
-       }
-
-       if ( (err = obdfs_getdev(device, &devno)) ) {
-               printk("Cannot get devno of %s, error %d\n", device, err);
-               EXIT;
-               goto ERR;;
-       }
-
-       if ( MAJOR(devno) != OBD_PSDEV_MAJOR ) {
-               printk(__FUNCTION__ ": wrong major number %d!\n", MAJOR(devno));
-               EXIT;
-               goto ERR;
-       }
-               
-       if ( MINOR(devno) >= MAX_OBD_DEVICES ) {
-               printk(__FUNCTION__ ": minor of %s too high (%d)\n",
-                      device, MINOR(devno));
-               EXIT;
-               goto ERR;
-       } 
-
-       obddev = &obd_dev[MINOR(devno)];
-
-       if ( ! (obddev->obd_flags & OBD_ATTACHED) || 
-            ! (obddev->obd_flags & OBD_SET_UP) ){
-               printk("device %s not attached or not set up (%d)\n", 
-                      device, MINOR(devno));
-               EXIT;
-               goto ERR;;
-       } 
-
-       sbi->osi_obd = obddev;
-       sbi->osi_ops = sbi->osi_obd->obd_type->typ_ops;
-       
-       sbi->osi_conn.oc_dev = obddev;
+        
+        memset(sbi, 0, sizeof(*sbi));
+        
+        CDEBUG(D_INFO, "\n"); 
+        obdfs_options(data, &device, &version);
+        if ( !device ) {
+                printk(__FUNCTION__ ": no device\n");
+                EXIT;
+                goto ERR;
+        }
+
+        CDEBUG(D_INFO, "\n"); 
+        if ( (err = obdfs_getdev(device, &devno)) ) {
+                printk("Cannot get devno of %s, error %d\n", device, err);
+                EXIT;
+                goto ERR;;
+        }
+
+        CDEBUG(D_INFO, "\n"); 
+        if ( MAJOR(devno) != OBD_PSDEV_MAJOR ) {
+                printk(__FUNCTION__ ": wrong major number %d!\n", MAJOR(devno));
+                EXIT;
+                goto ERR;
+        }
+                
+        CDEBUG(D_INFO, "\n"); 
+        if ( MINOR(devno) >= MAX_OBD_DEVICES ) {
+                printk(__FUNCTION__ ": minor of %s too high (%d)\n",
+                       device, MINOR(devno));
+                EXIT;
+                goto ERR;
+        } 
+
+        CDEBUG(D_INFO, "\n"); 
+        obddev = &obd_dev[MINOR(devno)];
+
+        CDEBUG(D_INFO, "\n"); 
+        if ( ! (obddev->obd_flags & OBD_ATTACHED) || 
+             ! (obddev->obd_flags & OBD_SET_UP) ){
+                printk("device %s not attached or not set up (%d)\n", 
+                       device, MINOR(devno));
+                EXIT;
+                goto ERR;;
+        } 
+
+        CDEBUG(D_INFO, "\n"); 
+        sbi->osi_obd = obddev;
+        sbi->osi_ops = sbi->osi_obd->obd_type->typ_ops;
+        
+        sbi->osi_conn.oc_dev = obddev;
         err = sbi->osi_ops->o_connect(&sbi->osi_conn);
         err = sbi->osi_ops->o_connect(&sbi->osi_conn);
-       if ( err ) {
-               printk("OBDFS: cannot connect to %s\n", device);
-               EXIT;
-               goto ERR;
-       }
-
-       /* list of dirty inodes, and a mutex to hold while modifying it */
-       INIT_LIST_HEAD(&sbi->osi_inodes);
-       sema_init(&sbi->osi_list_mutex, 1);
-
-       sbi->osi_super = sb;
-
-       err = sbi->osi_ops->o_get_info(&sbi->osi_conn, strlen("blocksize"),
-                                      "blocksize", &scratch,
-                                      (void *)&blocksize);
-       if ( err ) {
-               printk("getinfo call to drive failed (blocksize)\n");
-               EXIT;
-               goto ERR;
-       }
-
-       err = sbi->osi_ops->o_get_info(&sbi->osi_conn, strlen("blocksize_bits"),
-                                      "blocksize_bits", &scratch,
-                                      (void *)&blocksize_bits);
-       if ( err ) {
-               printk("getinfo call to drive failed (blocksize_bits)\n");
-               EXIT;
-               goto ERR;
-       }
-
-       err = sbi->osi_ops->o_get_info(&sbi->osi_conn, strlen("root_ino"), 
-                                      "root_ino", &scratch, (void *)&root_ino);
-       if ( err ) {
-               printk("getinfo call to drive failed (root_ino)\n");
-               EXIT;
-               goto ERR;
-       }
-       
-        lock_super(sb);
-       
+        if ( err ) {
+                printk("OBDFS: cannot connect to %s\n", device);
+                EXIT;
+                goto ERR;
+        }
+
+        CDEBUG(D_INFO, "\n"); 
+        /* list of dirty inodes, and a mutex to hold while modifying it */
+        INIT_LIST_HEAD(&sbi->osi_inodes);
+        sema_init(&sbi->osi_list_mutex, 1);
+
+        CDEBUG(D_INFO, "\n"); 
+        sbi->osi_super = sb;
+
+        CDEBUG(D_INFO, "\n"); 
+        err = sbi->osi_ops->o_get_info(&sbi->osi_conn, strlen("blocksize"),
+                                       "blocksize", &scratch,
+                                       (void *)&blocksize);
+        if ( err ) {
+                printk("getinfo call to drive failed (blocksize)\n");
+                EXIT;
+                goto ERR;
+        }
+
+        CDEBUG(D_INFO, "\n"); 
+        err = sbi->osi_ops->o_get_info(&sbi->osi_conn, strlen("blocksize_bits"),
+                                       "blocksize_bits", &scratch,
+                                       (void *)&blocksize_bits);
+        if ( err ) {
+                printk("getinfo call to drive failed (blocksize_bits)\n");
+                EXIT;
+                goto ERR;
+        }
+
+        CDEBUG(D_INFO, "\n"); 
+        err = sbi->osi_ops->o_get_info(&sbi->osi_conn, strlen("root_ino"), 
+                                       "root_ino", &scratch, (void *)&root_ino);
+        if ( err ) {
+                printk("getinfo call to drive failed (root_ino)\n");
+                EXIT;
+                goto ERR;
+        }
+        
+        CDEBUG(D_INFO, "\n"); 
         sb->s_blocksize = blocksize;
         sb->s_blocksize_bits = (unsigned char)blocksize_bits;
         sb->s_magic = OBDFS_SUPER_MAGIC;
         sb->s_op = &obdfs_super_operations;
 
         sb->s_blocksize = blocksize;
         sb->s_blocksize_bits = (unsigned char)blocksize_bits;
         sb->s_magic = OBDFS_SUPER_MAGIC;
         sb->s_op = &obdfs_super_operations;
 
-       /* XXX how to get "sb->s_flags |= MS_RDONLY" here for snapshots? */
+        /* XXX how to get "sb->s_flags |= MS_RDONLY" here for snapshots? */
 
 
-       /* make root inode */
-       root = iget(sb, root_ino);
+        /* make root inode */
+        CDEBUG(D_INFO, "\n"); 
+        root = iget(sb, root_ino);
         if (!root || is_bad_inode(root)) {
         if (!root || is_bad_inode(root)) {
-           printk("OBDFS: bad iget for root\n");
-           sb->s_dev = 0;
-           err = -ENOENT;
-           unlock_super(sb);
-           EXIT;
-           goto ERR;
-       } 
-       
-       CDEBUG(D_INFO, "obdfs_read_super: sbdev %d, rootino: %ld, dev %s, "
-              "minor: %d, blocksize: %ld, blocksize bits %ld\n", 
-              sb->s_dev, root->i_ino, device, MINOR(devno), 
-              blocksize, blocksize_bits);
-       sb->s_root = d_alloc_root(root);
-       list_add(&sbi->osi_list, &obdfs_super_list);
-       unlock_super(sb);
-       OBD_FREE(device, strlen(device) + 1);
-       if (version)
-               OBD_FREE(version, strlen(version) + 1);
-       EXIT;  
+            printk("OBDFS: bad iget for root\n");
+            sb->s_dev = 0;
+            err = -ENOENT;
+            EXIT;
+            goto ERR;
+        } 
+        
+        CDEBUG(D_INFO, "obdfs_read_super: sbdev %d, rootino: %ld, dev %s, "
+               "minor: %d, blocksize: %ld, blocksize bits %ld\n", 
+               sb->s_dev, root->i_ino, device, MINOR(devno), 
+               blocksize, blocksize_bits);
+        sb->s_root = d_alloc_root(root);
+        list_add(&sbi->osi_list, &obdfs_super_list);
+        OBD_FREE(device, strlen(device) + 1);
+        if (version)
+                OBD_FREE(version, strlen(version) + 1);
+        EXIT;  
         return sb;
 
 ERR:
         return sb;
 
 ERR:
-       MOD_DEC_USE_COUNT;
-       if (device)
-               OBD_FREE(device, strlen(device) + 1);
-       if (version)
-               OBD_FREE(version, strlen(version) + 1);
-       if (sbi) {
-               sbi->osi_super = NULL;
-       }
+        MOD_DEC_USE_COUNT;
+        if (device)
+                OBD_FREE(device, strlen(device) + 1);
+        if (version)
+                OBD_FREE(version, strlen(version) + 1);
+        if (sbi) {
+                sbi->osi_super = NULL;
+        }
         if (root) {
                 iput(root);
         }
         if (root) {
                 iput(root);
         }
@@ -260,89 +277,95 @@ static void obdfs_put_super(struct super_block *sb)
 
         ENTRY;
         sb->s_dev = 0;
 
         ENTRY;
         sb->s_dev = 0;
-       
-       sbi = (struct obdfs_sb_info *) &sb->u.generic_sbp;
-       obdfs_flush_reqs(&sbi->osi_inodes, ~0UL);
+        
+        sbi = (struct obdfs_sb_info *) &sb->u.generic_sbp;
+        obdfs_flush_reqs(&sbi->osi_inodes, ~0UL);
 
 
-       OPS(sb,disconnect)(ID(sb));
-       list_del(&sbi->osi_list);
-       memset(sbi, 0, sizeof(*sbi));
-       
-       printk(KERN_INFO "OBDFS: Bye bye.\n");
+        OPS(sb,disconnect)(ID(sb));
+        list_del(&sbi->osi_list);
+        memset(sbi, 0, sizeof(*sbi));
+        
+        printk(KERN_INFO "OBDFS: Bye bye.\n");
 
         MOD_DEC_USE_COUNT;
 
         MOD_DEC_USE_COUNT;
-       EXIT;
+        EXIT;
 } /* obdfs_put_super */
 
 
 /* all filling in of inodes postponed until lookup */
 static void obdfs_read_inode(struct inode *inode)
 {
 } /* obdfs_put_super */
 
 
 /* all filling in of inodes postponed until lookup */
 static void obdfs_read_inode(struct inode *inode)
 {
-       struct obdo *oa;
-
-       ENTRY;
-       oa = obdo_fromid(IID(inode), inode->i_ino,
-                        OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS);
-       if ( IS_ERR(oa) ) {
-               printk(__FUNCTION__ ": obdo_fromid failed\n");
-               EXIT;
-               return /* PTR_ERR(oa) */;
-       }
-
-       ODEBUG(oa);
-       obdfs_to_inode(inode, oa);
-       INIT_LIST_HEAD(obdfs_iplist(inode)); /* list of dirty pages on inode */
-       INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */
-
-       obdo_free(oa);
-       /* OIDEBUG(inode); */
-
-       if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &obdfs_file_inode_operations;
-               EXIT;
-       } else if (S_ISDIR(inode->i_mode)) {
-               inode->i_op = &obdfs_dir_inode_operations;
-               EXIT;
-       } else if (S_ISLNK(inode->i_mode)) {
-               inode->i_op = inode->i_blocks
-                               ?&obdfs_symlink_inode_operations
-                               :&obdfs_fast_symlink_inode_operations;
-               EXIT;
-       } else {
-               init_special_inode(inode, inode->i_mode,
-                                  ((int *)obdfs_i2info(inode)->oi_inline)[0]);
-       }
-
-       return;
+        struct obdo *oa;
+
+        ENTRY;
+        oa = obdo_fromid(IID(inode), inode->i_ino,
+                         OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS);
+        if ( IS_ERR(oa) ) {
+                printk(__FUNCTION__ ": obdo_fromid failed\n");
+                EXIT;
+                return /* PTR_ERR(oa) */;
+        }
+
+        ODEBUG(oa);
+        obdfs_to_inode(inode, oa);
+        INIT_LIST_HEAD(obdfs_iplist(inode)); /* list of dirty pages on inode */
+        INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */
+
+        obdo_free(oa);
+        /* OIDEBUG(inode); */
+
+        if (S_ISREG(inode->i_mode)) {
+                inode->i_op = &obdfs_file_inode_operations;
+                inode->i_fop = &obdfs_file_operations;
+                inode->i_mapping->a_ops = &obdfs_aops;
+                EXIT;
+        } else if (S_ISDIR(inode->i_mode)) {
+                inode->i_op = &obdfs_dir_inode_operations;
+                inode->i_fop = &obdfs_dir_operations; 
+                EXIT;
+        } else if (S_ISLNK(inode->i_mode)) {
+                if (inode->i_blocks) { 
+                        inode->i_op = &obdfs_symlink_inode_operations;
+                        inode->i_mapping->a_ops = &obdfs_aops;
+                }else {
+                        inode->i_op = &obdfs_fast_symlink_inode_operations;
+                }
+                EXIT;
+        } else {
+                init_special_inode(inode, inode->i_mode,
+                                   ((int *)obdfs_i2info(inode)->oi_inline)[0]);
+        }
+
+        return;
 } /* obdfs_read_inode */
 
 } /* obdfs_read_inode */
 
-static void obdfs_write_inode(struct inode *inode) 
+static void obdfs_write_inode(struct inode *inode, int wait
 {
 {
-       struct obdo *oa;
-       int err;
-       
-       ENTRY;
-       if (IOPS(inode, setattr) == NULL) {
-               printk(KERN_ERR __FUNCTION__ ": no setattr method!\n");
-               EXIT;
-               return;
-       }
-       oa = obdo_alloc();
-       if ( !oa ) {
-               printk(__FUNCTION__ ": obdo_alloc failed\n");
-               EXIT;
-               return;
-       }
-
-       oa->o_valid = OBD_MD_FLNOTOBD;
-       obdfs_from_inode(oa, inode);
-       err = IOPS(inode, setattr)(IID(inode), oa);
-
-       if ( err )
-               printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
-
-       EXIT;
-       obdo_free(oa);
+        struct obdo *oa;
+        int err;
+        
+        ENTRY;
+        if (IOPS(inode, setattr) == NULL) {
+                printk(KERN_ERR __FUNCTION__ ": no setattr method!\n");
+                EXIT;
+                return;
+        }
+        oa = obdo_alloc();
+        if ( !oa ) {
+                printk(__FUNCTION__ ": obdo_alloc failed\n");
+                EXIT;
+                return;
+        }
+
+        oa->o_valid = OBD_MD_FLNOTOBD;
+        obdfs_from_inode(oa, inode);
+        err = IOPS(inode, setattr)(IID(inode), oa);
+
+        if ( err )
+                printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
+
+        EXIT;
+        obdo_free(oa);
 } /* obdfs_write_inode */
 
 
 } /* obdfs_write_inode */
 
 
@@ -353,115 +376,112 @@ static void obdfs_write_inode(struct inode *inode)
  */
 static void obdfs_put_inode(struct inode *inode)
 {
  */
 static void obdfs_put_inode(struct inode *inode)
 {
-       ENTRY;
-       if (inode->i_nlink) {
-               EXIT;
-               return;
-       }
-
-       obdfs_dequeue_pages(inode);
-       EXIT;
+        ENTRY;
+        if (inode->i_nlink) {
+                EXIT;
+                return;
+        }
+
+        obdfs_dequeue_pages(inode);
+        EXIT;
 } /* obdfs_put_inode */
 
 
 static void obdfs_delete_inode(struct inode *inode)
 {
 } /* obdfs_put_inode */
 
 
 static void obdfs_delete_inode(struct inode *inode)
 {
-       struct obdo *oa;
-       int err;
+        struct obdo *oa;
+        int err;
 
         ENTRY;
 
         ENTRY;
-       if (IOPS(inode, destroy) == NULL) {
-               printk(KERN_ERR __FUNCTION__ ": no destroy method!\n");
-               EXIT;
-               return;
-       }
-
-       oa = obdo_alloc();
-       if ( !oa ) {
-               printk(__FUNCTION__ ": obdo_alloc failed\n");
-               EXIT;
-               return;
-       }
-       oa->o_valid = OBD_MD_FLNOTOBD;
-       obdfs_from_inode(oa, inode);
-
-       ODEBUG(oa);
-       err = IOPS(inode, destroy)(IID(inode), oa);
-       obdo_free(oa);
-
-       if (err) {
-               printk(__FUNCTION__ ": obd_destroy fails (%d)\n", err);
-               EXIT;
-               return;
-       }
-
-       EXIT;
+        if (IOPS(inode, destroy) == NULL) {
+                printk(KERN_ERR __FUNCTION__ ": no destroy method!\n");
+                EXIT;
+                return;
+        }
+
+        oa = obdo_alloc();
+        if ( !oa ) {
+                printk(__FUNCTION__ ": obdo_alloc failed\n");
+                EXIT;
+                return;
+        }
+        oa->o_valid = OBD_MD_FLNOTOBD;
+        obdfs_from_inode(oa, inode);
+
+        ODEBUG(oa);
+        err = IOPS(inode, destroy)(IID(inode), oa);
+        obdo_free(oa);
+
+        if (err) {
+                printk(__FUNCTION__ ": obd_destroy fails (%d)\n", err);
+                EXIT;
+                return;
+        }
+
+        EXIT;
 } /* obdfs_delete_inode */
 
 
 } /* obdfs_delete_inode */
 
 
-static int obdfs_notify_change(struct dentry *de, struct iattr *attr)
+int obdfs_notify_change(struct dentry *de, struct iattr *attr)
 {
 {
-       struct inode *inode = de->d_inode;
-       struct obdo *oa;
-       int err;
-
-       ENTRY;
-       if (IOPS(inode, setattr) == NULL) {
-               printk(KERN_ERR __FUNCTION__ ": no setattr method!\n");
-               EXIT;
-               return -EIO;
-       }
-       oa = obdo_alloc();
-       if ( !oa ) {
-               printk(__FUNCTION__ ": obdo_alloc failed\n");
-               return -ENOMEM;
-       }
-
-       oa->o_id = inode->i_ino;
-       obdo_from_iattr(oa, attr);
+        struct inode *inode = de->d_inode;
+        struct obdo *oa;
+        int err;
+
+        ENTRY;
+        if (IOPS(inode, setattr) == NULL) {
+                printk(KERN_ERR __FUNCTION__ ": no setattr method!\n");
+                EXIT;
+                return -EIO;
+        }
+        oa = obdo_alloc();
+        if ( !oa ) {
+                printk(__FUNCTION__ ": obdo_alloc failed\n");
+                return -ENOMEM;
+        }
+
+        oa->o_id = inode->i_ino;
+        obdo_from_iattr(oa, attr);
         err = IOPS(inode, setattr)(IID(inode), oa);
 
         err = IOPS(inode, setattr)(IID(inode), oa);
 
-       if ( err )
-               printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
+        if ( err )
+                printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err);
 
 
-       EXIT;
-       obdo_free(oa);
+        EXIT;
+        obdo_free(oa);
         return err;
 } /* obdfs_notify_change */
 
 
         return err;
 } /* obdfs_notify_change */
 
 
-static int obdfs_statfs(struct super_block *sb, struct statfs *buf, 
-                      int bufsize)
+static int obdfs_statfs(struct super_block *sb, struct statfs *buf)
 {
 {
-       struct statfs tmp;
-       int err;
+        struct statfs tmp;
+        int bufsize = sizeof(*buf);
+        int err;
 
 
-       ENTRY;
+        ENTRY;
 
 
-       err = OPS(sb,statfs)(ID(sb), &tmp);
-       if ( err ) { 
-               printk(__FUNCTION__ ": obd_statfs fails (%d)\n", err);
-               return err;
-       }
-       copy_to_user(buf, &tmp, (bufsize<sizeof(tmp)) ? bufsize : sizeof(tmp));
+        err = OPS(sb,statfs)(ID(sb), &tmp);
+        if ( err ) { 
+                printk(__FUNCTION__ ": obd_statfs fails (%d)\n", err);
+                return err;
+        }
+        copy_to_user(buf, &tmp, (bufsize<sizeof(tmp)) ? bufsize : sizeof(tmp));
 
 
-       EXIT;
+        EXIT;
 
 
-       return err; 
+        return err; 
 }
 
 /* exported operations */
 struct super_operations obdfs_super_operations =
 {
 }
 
 /* exported operations */
 struct super_operations obdfs_super_operations =
 {
-       obdfs_read_inode,       /* read_inode */
-       obdfs_write_inode,      /* write_inode */
-       obdfs_put_inode,        /* put_inode */
-       obdfs_delete_inode,     /* delete_inode */
-       obdfs_notify_change,    /* notify_change */
-       obdfs_put_super,        /* put_super */
-       NULL,                   /* write_super */
-       obdfs_statfs,           /* statfs */
-       NULL                    /* remount_fs */
+        read_inode: obdfs_read_inode,
+        write_inode: obdfs_write_inode,
+        put_inode: obdfs_put_inode,
+        delete_inode: obdfs_delete_inode,
+        put_super: obdfs_put_super,
+        statfs: obdfs_statfs
 };
 
 struct file_system_type obdfs_fs_type = {
 };
 
 struct file_system_type obdfs_fs_type = {
@@ -470,38 +490,47 @@ struct file_system_type obdfs_fs_type = {
 
 int init_obdfs(void)
 {
 
 int init_obdfs(void)
 {
-       int err;
+        int err;
 
 
-       printk(KERN_INFO "OBDFS v0.1, braam@stelias.com\n");
+        printk(KERN_INFO "OBDFS v0.1, braam@stelias.com\n");
 
 
-       obdfs_sysctl_init();
+        obdfs_sysctl_init();
 
 
-       INIT_LIST_HEAD(&obdfs_super_list);
-       err = obdfs_init_pgrqcache();
-       if (err)
-               return err;
+        INIT_LIST_HEAD(&obdfs_super_list);
+        err = obdfs_init_pgrqcache();
+        if (err)
+                return err;
 
 
-       obdfs_flushd_init();
-       return register_filesystem(&obdfs_fs_type);
+        obdfs_flushd_init();
+        return register_filesystem(&obdfs_fs_type);
 }
 
 }
 
+struct address_space_operations obdfs_aops = {
+        readpage: obdfs_readpage,
+        writepage: obdfs_writepage,
+        sync_page: block_sync_page,
+        prepare_write: NULL, 
+        commit_write: generic_commit_write,
+        bmap: NULL
+};
+
 
 #ifdef MODULE
 int init_module(void)
 {
 
 #ifdef MODULE
 int init_module(void)
 {
-       return init_obdfs();
+        return init_obdfs();
 }
 
 void cleanup_module(void)
 {
         ENTRY;
 
 }
 
 void cleanup_module(void)
 {
         ENTRY;
 
-       obdfs_flushd_cleanup();
-       obdfs_sysctl_clean();
-       obdfs_cleanup_pgrqcache();
-       unregister_filesystem(&obdfs_fs_type);
-       CDEBUG(D_MALLOC, "OBDFS mem used %ld\n", obd_memory);
-       EXIT;
+        obdfs_flushd_cleanup();
+        obdfs_sysctl_clean();
+        obdfs_cleanup_pgrqcache();
+        unregister_filesystem(&obdfs_fs_type);
+        CDEBUG(D_MALLOC, "OBDFS mem used %ld\n", obd_memory);
+        EXIT;
 }
 
 #endif
 }
 
 #endif
index 046d408..396176c 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <linux/fs.h>
  */
 
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
 
 static int obdfs_fast_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
 
 static int obdfs_fast_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
-       char *s = obdfs_i2info(dentry->d_inode)->oi_inline;
-       return vfs_readlink(dentry, buffer, buflen, s);
+        char *s = obdfs_i2info(dentry->d_inode)->oi_inline;
+        return vfs_readlink(dentry, buffer, buflen, s);
 }
 
 }
 
-static struct dentry *obdfs_fast_follow_link(struct dentry *dentry, struct dentry *base, unsigned flags)
+static int obdfs_fast_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 {
-       char *s = obdfs_i2info(dentry->d_inode)->oi_inline;
-       return vfs_follow_link(dentry, base, flags, s);
+        char *s = obdfs_i2info(dentry->d_inode)->oi_inline;
+        return vfs_follow_link(nd, s); 
 }
 
 struct inode_operations obdfs_fast_symlink_inode_operations = {
 }
 
 struct inode_operations obdfs_fast_symlink_inode_operations = {
-       readlink:       obdfs_fast_readlink,
-       follow_link:    obdfs_fast_follow_link,
+        readlink:       obdfs_fast_readlink,
+        follow_link:    obdfs_fast_follow_link,
 };
 
 static int obdfs_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
 };
 
 static int obdfs_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
-       struct page *page = NULL;
-       int res;
+        struct page *page = NULL;
+        int res;
 
 
-       ENTRY;
-       OIDEBUG(dentry->d_inode);
-       page = obdfs_getpage(dentry->d_inode, 0, 0, 0);
-       /* PDEBUG(page, "readlink"); */
-       if (!page) {
-               EXIT;
-               return 0;
-       }
-       res = vfs_readlink(dentry, buffer, buflen, (char *)page_address(page));
-       page_cache_release(page);
-       EXIT;
-       return res;
+        ENTRY;
+        OIDEBUG(dentry->d_inode);
+        page = obdfs_getpage(dentry->d_inode, 0, 0, 0);
+        /* PDEBUG(page, "readlink"); */
+        if (!page) {
+                EXIT;
+                return 0;
+        }
+        res = vfs_readlink(dentry, buffer, buflen, (char *)page_address(page));
+        page_cache_release(page);
+        EXIT;
+        return res;
 } /* obdfs_readlink */
 
 } /* obdfs_readlink */
 
-static struct dentry * obdfs_follow_link(struct dentry * dentry,
-                                        struct dentry *base,
-                                        unsigned int follow)
+static int obdfs_follow_link(struct dentry * dentry,
+                             struct nameidata *nd)
 {
 {
-       struct page *page = NULL;
-       struct dentry *res;
+        struct page *page = NULL;
+        int res;
 
 
-       ENTRY;
-       OIDEBUG(dentry->d_inode);
-       page = obdfs_getpage(dentry->d_inode, 0, 0, 0);
-       /* PDEBUG(page, "follow_link"); */
-       if (!page) {
-               dput(base);
-               EXIT;
-               return ERR_PTR(-EIO);
-       }
-       res = vfs_follow_link(dentry, base, follow, (char *)page_address(page));
-       page_cache_release(page);
-       EXIT;
-       return res;
+        ENTRY;
+        OIDEBUG(dentry->d_inode);
+        page = obdfs_getpage(dentry->d_inode, 0, 0, 0);
+        /* PDEBUG(page, "follow_link"); */
+        if (!page) {
+                dput(nd->dentry);
+                EXIT;
+                return -EIO;
+        }
+        res = vfs_follow_link(nd, (char *)page_address(page));
+        page_cache_release(page);
+        EXIT;
+        return res;
 }
 
 struct inode_operations obdfs_symlink_inode_operations = {
 }
 
 struct inode_operations obdfs_symlink_inode_operations = {