Whamcloud - gitweb
Updated snapshot files for new obdo methods. No testing yet.
authoradilger <adilger>
Tue, 11 Jan 2000 08:36:16 +0000 (08:36 +0000)
committeradilger <adilger>
Tue, 11 Jan 2000 08:36:16 +0000 (08:36 +0000)
lustre/demos/baseclean.sh
lustre/include/linux/obd_class.h
lustre/include/linux/obd_snap.h
lustre/include/linux/obd_snap_support.h
lustre/include/linux/obdfs.h
lustre/obdclass/genops.c
lustre/obdfs/flushd.c
lustre/obdfs/namei.c
lustre/obdfs/rw.c
lustre/obdfs/super.c
lustre/obdfs/symlink.c

index 0daf84b..abe4d73 100755 (executable)
@@ -27,7 +27,6 @@ fi
 rmmod loop > /dev/null 2>&1
 
 if [ "$TMPFILE" -a -f "$TMPFILE" ]; then
-    echo -n "Remove $TMPFILE [N/y]? "
     rm -i $TMPFILE
 fi
 
index 2cd4c29..804d66a 100644 (file)
@@ -216,6 +216,7 @@ static __inline__ struct obdo *obdo_fromid(struct obd_conn *conn, obd_id id)
        }
        memset(res, 0, sizeof(*res));
        res->o_id = id;
+       res->o_valid = ~OBD_MD_FLOBDMD;
        if (OBP(conn->oc_dev, getattr)(conn, res)) {
                OBD_FREE(res, sizeof(*res));
                EXIT;
@@ -363,29 +364,41 @@ static __inline__ void obdo_to_inode(struct inode *dst, struct obdo *src)
                dst->i_generation = src->o_generation;
 }
 
-static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src)
+static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src,
+                                 obd_flag compare)
 {
-       int res = 1;
-
-       if ( src->o_valid & OBD_MD_FLMODE )
-               res = (res && (dst->o_mode == src->o_mode));
-       if ( src->o_valid & OBD_MD_FLUID )
-               res = (res && (dst->o_uid == src->o_uid));
-       if ( src->o_valid & OBD_MD_FLGID )
-               res = (res && (dst->o_gid == src->o_gid));
-       if ( src->o_valid & OBD_MD_FLSIZE )
-               res = (res && (dst->o_size == src->o_size));
-       if ( src->o_valid & OBD_MD_FLATIME )
-               res = (res && (dst->o_atime == src->o_atime));
-       if ( src->o_valid & OBD_MD_FLMTIME )
-               res = (res && (dst->o_mtime == src->o_mtime));
-       if ( src->o_valid & OBD_MD_FLCTIME )
-               res = (res && (dst->o_ctime == src->o_ctime));
-       if ( src->o_valid & OBD_MD_FLFLAGS )
-               res = (res && (dst->o_flags == src->o_flags));
-       /* allocation of space */
-       if ( src->o_valid & OBD_MD_FLBLOCKS )
-               res = (res && (dst->o_blocks == src->o_blocks));
+       int res = 0;
+
+       if ( compare & OBD_MD_FLATIME )
+               res = (res || (dst->o_atime != src->o_atime));
+       if ( compare & OBD_MD_FLMTIME )
+               res = (res || (dst->o_mtime != src->o_mtime));
+       if ( compare & OBD_MD_FLCTIME )
+               res = (res || (dst->o_ctime != src->o_ctime));
+       if ( compare & OBD_MD_FLSIZE )
+               res = (res || (dst->o_size != src->o_size));
+       if ( compare & OBD_MD_FLBLOCKS ) /* allocation of space */
+               res = (res || (dst->o_blocks != src->o_blocks));
+       if ( compare & OBD_MD_FLBLKSZ )
+               res = (res || (dst->o_blksize != src->o_blksize));
+       if ( compare & OBD_MD_FLMODE )
+               res = (res || (dst->o_mode != src->o_mode));
+       if ( compare & OBD_MD_FLUID )
+               res = (res || (dst->o_uid != src->o_uid));
+       if ( compare & OBD_MD_FLGID )
+               res = (res || (dst->o_gid != src->o_gid));
+       if ( compare & OBD_MD_FLFLAGS ) 
+               res = (res || (dst->o_flags != src->o_flags));
+       if ( compare & OBD_MD_FLNLINK )
+               res = (res || (dst->o_nlink != src->o_nlink));
+       if ( compare & OBD_MD_FLGENER )
+               res = (res || (dst->o_generation != src->o_generation));
+       /* XXX Don't know if thses should be included here
+       if ( compare & OBD_MD_FLINLINE )
+               res = (res || memcmp(dst->o_inline, src->o_inline));
+       if ( compare & OBD_MD_FLOBDMD )
+               res = (res || memcmp(dst->o_obdmd, src->o_obdmd));
+       */
        return res;
 }
 
index e2b79d2..9d1ba8c 100644 (file)
@@ -3,72 +3,20 @@
 
 #define OBD_SNAP_MAGIC 0xfffffff3   /* an unlikely block number */
 
-/* maximum number of snapshot tables we maintain in the kernel */
-#define SNAP_MAX_TABLES 8
-
-
-/* maximum number of snapshots per device 
-   must fit in "u" area of struct inode */
-#define SNAP_MAX  (EXT2_N_BLOCKS-1)
-
-
 /* ioctls for manipulating snapshots 40 - 60 */
 #define OBD_SNAP_SETTABLE      _IOWR('f', 40, long)
 #define OBD_SNAP_PRINTTABLE    _IOWR('f', 41, long)
 #define OBD_SNAP_DELETE        _IOWR('f', 42, long)
 #define OBD_SNAP_RESTORE       _IOWR('f', 43, long)
 
-
-
-/* if time is 0 this designates the "current" snapshot, i.e.
-   the head of the tree 
-*/
-struct snap {
-       time_t time;
-       int index;
-};
-
-/* snap ioctl data for attach: current always in first slot of this array */
-struct snap_obd_data {
-       int          snap_dev;  /* which device contains the data */
-       unsigned int snap_index;/* which snapshot is ours */
-       unsigned int snap_table;/* which table do we use */
-};
-
-
-/* snap ioctl data for table fiddling */
-struct snap_table_data {
-       int             tblcmd_no;      /* which table */
-       unsigned int    tblcmd_count;   /* how many snaps */
-       struct snap     tblcmd_snaps[SNAP_MAX]; /* sorted times! */
-};
-
-
-struct snap_table {
-       spinlock_t          tbl_lock;
-       unsigned int tbl_count; /* how many snapshots exist in this table*/
-       int tbl_used;  /* bitmap of snaps in use by a device */
-       time_t tbl_times[SNAP_MAX];
-       int tbl_index[SNAP_MAX];
-};
-
-
 /* this is the obd device descriptor: 
  - current snapshot ends up in first slot of this array
* - current snapshot ends up in first slot of this array
  */
 struct snap_obd {
        unsigned int snap_index;  /* which snapshot index are we accessing */
        int snap_tableno;
 };
 
-
-/* stored as inline data in the objects */
-struct snap_object_data {
-       int od_magic;
-       /* id of snaps of object; slot 0 has the current data */
-       unsigned long od_ids[SNAP_MAX];
-};
-
 void snap_use(int table_no, int snap_index) ;
 void snap_unuse(int table_no, int snap_index) ;
 int snap_is_used(int table_no, int snap_index) ;
index ca4e615..ff8fc9a 100644 (file)
@@ -1,6 +1,58 @@
 #ifndef __OBD_SNAP_SUPP_H
 #define __OBD_SNAP_SUPP_H
 
+/* What we use to point to IDs in the obdmd data for snapshots.  If we use
+ * obd_id (8 bytes) instead of ino_t (4 bytes), we halve the number of
+ * available snapshot slots (14 in 56 bytes vs. 7 in 56 bytes until we
+ * increase the size of OBD_OBDMDSZ).
+ */
+typedef ino_t  snap_id;
+
+/* maximum number of snapshot tables we maintain in the kernel */
+#define SNAP_MAX_TABLES 8
+
+/* maximum number of snapshots per device 
+   must fit in "o_obdmd" area of struct obdo */
+#define SNAP_MAX ((OBD_OBDMDSZ - sizeof(uint32_t))/sizeof(snap_id))
+
+struct snap_md {
+       uint32_t m_magic;
+       snap_id  m_ids[SNAP_MAX];       /* id of snaps; slot 0 has current id */
+};
+
+
+/* if time is 0 this designates the "current" snapshot, i.e.
+   the head of the tree 
+*/
+struct snap {
+       time_t time;
+       int index;
+};
+
+/* snap ioctl data for attach: current always in first slot of this array */
+struct snap_obd_data {
+       int          snap_dev;  /* which device contains the data */
+       unsigned int snap_index;/* which snapshot is ours */
+       unsigned int snap_table;/* which table do we use */
+};
+
+
+/* snap ioctl data for table fiddling */
+struct snap_table_data {
+       int             tblcmd_no;      /* which table */
+       unsigned int    tblcmd_count;   /* how many snaps */
+       struct snap     tblcmd_snaps[SNAP_MAX]; /* sorted times! */
+};
+
+
+struct snap_table {
+       spinlock_t          tbl_lock;
+       unsigned int tbl_count; /* how many snapshots exist in this table*/
+       int tbl_used;  /* bitmap of snaps in use by a device */
+       time_t tbl_times[SNAP_MAX];
+       int tbl_index[SNAP_MAX];
+};
+
 struct snap_iterdata {
        struct obd_conn *conn;
        struct obd_conn *ch_conn;
@@ -11,11 +63,17 @@ struct snap_iterdata {
        time_t prevtime;
 };
 
-
 inline struct obd_conn *child_conn(struct obd_conn *conn);
-int snap_deleteobj(obd_id id, void *data);
-int snap_restoreobj(obd_id id, void *data);
-int snap_printobj(obd_id id, void *data);
+int snap_deleteobj(obd_id id, obd_gr group, void *data);
+int snap_restoreobj(obd_id id, obd_gr group, void *data);
+int snap_printobj(obd_id id, obd_gr group, void *data);
 int snap_iocontrol(int cmd, struct obd_conn *conn, int len, void *karg, void *uarg);
 
+/* In the future, this function may have to deal with offsets into the obdmd.
+ * Currently, we assume we have the whole obdmd struct.
+ */
+static __inline__ struct snap_md *snap_obdmd(struct obdo *oa)
+{
+       return ((struct snap_md *)(&oa->o_obdmd));
+}
 #endif
index cad8f07..405bdb2 100644 (file)
@@ -58,8 +58,8 @@ struct obdfs_super_info {
 /* list of all OBDFS super blocks  */
 struct list_head obdfs_super_list;
 struct obdfs_super_entry {
-       struct list_head sl_chain;
-       struct obdfs_super_info *sl_sbi;
+       struct list_head         sl_chain;
+       struct obdfs_super_info *sl_sbi;
 };
 
 struct obdfs_pgrq {
@@ -70,25 +70,25 @@ struct obdfs_pgrq {
 };
 
 struct obdfs_sb_info {
-       struct obd_conn osi_conn;
-       struct super_block *osi_super;
-       struct obd_device *osi_obd;
-       struct obd_ops *osi_ops;     
-       ino_t           osi_rootino; /* which root inode */
-       int             osi_minor;   /* minor of /dev/obdX */
-       struct list_head osi_list;  /* linked list of inodes to write */
+       struct obd_conn          osi_conn;
+       struct super_block      *osi_super;
+       struct obd_device       *osi_obd;
+       struct obd_ops          *osi_ops;     
+       ino_t                    osi_rootino; /* which root inode */
+       int                      osi_minor;   /* minor of /dev/obdX */
+       struct list_head         osi_list;  /* linked list of inodes to write */
 };
 
 struct obdfs_inode_info {
        int              oi_flags;
        struct list_head oi_pages;
-       char            *oi_inline;
+       char             oi_inline[OBD_INLINESZ];
 };
 
 
-#define OBD_LIST(inode)        (((struct obdfs_inode_info *)(&(inode)->u.generic_ip))->oi_pages)
-#define WREQ(entry)    (list_entry(entry, struct obdfs_pgrq, rq_list))
-#define OBD_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip))
+#define OBDFS_LIST(inode) (((struct obdfs_inode_info *)(&(inode)->u.generic_ip))->oi_pages)
+#define WREQ(entry)       (list_entry(entry, struct obdfs_pgrq, rq_list))
+#define OBDFS_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip))
 
 void obdfs_sysctl_init(void);
 void obdfs_sysctl_clean(void);
@@ -98,16 +98,9 @@ extern struct inode_operations obdfs_file_inode_operations;
 extern struct inode_operations obdfs_dir_inode_operations;
 extern struct inode_operations obdfs_symlink_inode_operations;
 
-static inline struct obd_ops *iops(struct inode *i)
+static inline int obdfs_has_inline(struct inode *inode)
 {
-       struct obdfs_sb_info *sbi = (struct obdfs_sb_info *) &i->i_sb->u.generic_sbp;
-       return sbi->osi_ops;
-}
-
-static inline struct obd_conn *iid(struct inode *i)
-{
-       struct obdfs_sb_info *sbi = (struct obdfs_sb_info *) &i->i_sb->u.generic_sbp;
-       return &sbi->osi_conn;
+       return (OBDFS_INFO(inode)->oi_flags & OBD_FL_INLINEDATA);
 }
 
 #define NOLOCK 0
index 10a69dc..fc79194 100644 (file)
@@ -38,6 +38,7 @@ int obd_init_obdo_cache(void)
 {
        ENTRY;
        if (obdo_cachep == NULL) {
+               CDEBUG(D_INODE, "allocating obdo_cache\n");
                obdo_cachep = kmem_cache_create("obdo_cache",
                                                sizeof(struct obdo),
                                                0, SLAB_HWCACHE_ALIGN,
@@ -45,7 +46,11 @@ int obd_init_obdo_cache(void)
                if (obdo_cachep == NULL) {
                        EXIT;
                        return -ENOMEM;
+               } else {
+                       CDEBUG(D_INODE, "allocated cache at %p\n", obdo_cachep);
                }
+       } else {
+               CDEBUG(D_INODE, "using existing cache at %p\n", obdo_cachep);
        }
        EXIT;
        return 0;
@@ -55,8 +60,11 @@ void obd_cleanup_obdo_cache(void)
 {
        ENTRY;
        if (obdo_cachep != NULL) {
+               /*
+               CDEBUG(D_INODE, "shrinking obdo_cache at %p\n", obdo_cachep);
                if (kmem_cache_shrink(obdo_cachep))
                        printk(KERN_INFO "obd_cleanup_obdo_cache: unable to free all of cache\n");
+               */
        } else
                printk(KERN_INFO "obd_cleanup_obdo_cache: called with NULL cache pointer\n");
 
@@ -239,16 +247,15 @@ void lck_page(struct page *page)
                 ___wait_on_page(page);
 }
 
-/* XXX this should return errors correctly, so should migrate!!! */
 int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
                  struct obd_conn *src_conn, struct obdo *src,
                  obd_size count, obd_off offset)
 {
        struct page *page;
        unsigned long index = 0;
-       int rc;
-       ENTRY;
+       int err = 0;
 
+       ENTRY;
        CDEBUG(D_INODE, "src: ino %Ld blocks %Ld, size %Ld, dst: ino %Ld\n", 
               src->o_id, src->o_blocks, src->o_size, dst->o_id);
        page = alloc_page(GFP_USER);
@@ -260,26 +267,34 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
        lck_page(page);
        
        while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
-               obd_size count = PAGE_SIZE;
+               obd_size brw_count;
                
+               brw_count = PAGE_SIZE;
+
                page->index = index;
-               rc = OBP(src_conn->oc_dev, brw)
+               err = OBP(src_conn->oc_dev, brw)
                        (READ, src_conn, src, (char *)page_address(page), 
-                        &count, (page->index) << PAGE_SHIFT, 0);
+                        &brw_count, (page->index) << PAGE_SHIFT, 0);
 
-               if ( rc != 0  ) 
+               if ( err ) {
+                       EXIT;
                        break;
+               }
                CDEBUG(D_INODE, "Read page %ld ...\n", page->index);
 
-               rc = OBP(dst_conn->oc_dev, brw)
+               err = OBP(dst_conn->oc_dev, brw)
                        (WRITE, dst_conn, dst, (char *)page_address(page), 
-                        &count, (page->index) << PAGE_SHIFT, 1);
-               if ( rc != 0)
+                        &brw_count, (page->index) << PAGE_SHIFT, 1);
+
+               /* XXX should handle dst->o_size, dst->o_blocks here */
+               if ( err ) {
+                       EXIT;
                        break;
+               }
 
                CDEBUG(D_INODE, "Wrote page %ld ...\n", page->index);
                
-               index ++;
+               index++;
        }
        dst->o_size = src->o_size;
        dst->o_blocks = src->o_blocks;
@@ -288,5 +303,5 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
        __free_page(page);
 
        EXIT;
-       return 0;
+       return err;
 }
index e94b6bf..8a3eaf4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * OBDFS Super operations - also used for Lustre file system
  *
 *
+ *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  * Copryright (C) 1999 Stelias Computing Inc. <braam@stelias.com>
  * Copryright (C) 1999 Seagate Technology Inc.
@@ -82,7 +82,7 @@ static void obdfs_flush_dirty_pages(int check_time)
        while ( (sl = sl->next) != &obdfs_super_list ) {
                struct obdfs_super_entry *entry = 
                        list_entry(sl, struct obdfs_super_entry, sl_chain);
-               struct obdfs_super_info *sbi = entry->sl_sbi;
+               sbi = entry->sl_sbi;
 
                /* walk write requests here */
                obdfs_flush_reqs(sbi, jiffies);
@@ -96,6 +96,7 @@ static void obdfs_flush_dirty_pages(int check_time)
                sbi = entry->sl_sbi;
 
                /* walk write requests here */
+               /* XXX should jiffies be 0 here? */
                obdfs_flush_reqs(sbi, jiffies);
        }
 }
@@ -107,15 +108,17 @@ static int pupdate(void *unused)
        struct task_struct * tsk = current;
        int interval;
        
-       pupdated = current;
        tsk->session = 1;
        tsk->pgrp = 1;
        strcpy(tsk->comm, "pupdate");
+       pupdated = current;
+
+       printk("pupdate() activated...\n");
 
        /* sigstop and sigcont will stop and wakeup kupdate */
        spin_lock_irq(&tsk->sigmask_lock);
        sigfillset(&tsk->blocked);
-       siginitsetinv(&current->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP));
+       siginitsetinv(&tsk->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP));
        recalc_sigpending(tsk);
        spin_unlock_irq(&tsk->sigmask_lock);
 
@@ -130,6 +133,7 @@ static int pupdate(void *unused)
                else
                {
                stop_pupdate:
+                       printk("pupdate() stopped...\n");
                        tsk->state = TASK_STOPPED;
                        MOD_DEC_USE_COUNT;
                        schedule(); /* wait for SIGCONT */
@@ -149,7 +153,6 @@ static int pupdate(void *unused)
                        if (stopped)
                                goto stop_pupdate;
                }
-               printk("pupdate() activated...\n");
                /* flush_inodes(); */
                obdfs_flush_dirty_pages(1);
        }
index 22fdde1..4c8419f 100644 (file)
@@ -485,7 +485,9 @@ struct inode *obdfs_new_inode(struct inode *dir)
                return ERR_PTR(-EIO);
        }
 
+       INIT_LIST_HEAD(&OBDFS_LIST(inode));
        obdo_free(oa);
+
        EXIT;
        return inode;
 } /* obdfs_new_inode */
@@ -622,12 +624,12 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
        strcpy (de->name, "..");
        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
        
+       /* XXX handle err */
        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);
-       /* XXX handle err */
 
        inode->i_nlink = 2;
        inode->i_mode = S_IFDIR | mode;
@@ -649,12 +651,12 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
        mark_inode_dirty(dir);
        err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
+       /* XXX handle err? */
 
        UnlockPage(page);
 
        page_cache_release(page);
        d_instantiate(dentry, inode);
-       err = 0;
 out:
        EXIT;
        return err;
@@ -766,6 +768,7 @@ int obdfs_rmdir (struct inode * dir, struct dentry *dentry)
        if (retval)
                goto end_rmdir;
        err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
+       /* XXX handle err? */
        UnlockPage(page);
 
        if (inode->i_nlink != 2)
@@ -822,6 +825,7 @@ int obdfs_unlink(struct inode * dir, struct dentry *dentry)
                goto end_unlink;
        dir->i_version = ++event;
        err = obdfs_do_writepage(dir, page, IS_SYNC(dir));
+       /* XXX handle err? */
        UnlockPage(page);
 
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
@@ -840,7 +844,8 @@ end_unlink:
        return retval;
 } /* obdfs_unlink */
 
-int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symname)
+int obdfs_symlink (struct inode * dir, struct dentry *dentry,
+                  const char * symname)
 {
        struct ext2_dir_entry_2 * de;
        struct inode * inode;
@@ -852,7 +857,7 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna
 
         ENTRY;
        inode = obdfs_new_inode(dir);
-       oinfo = OBD_INFO(inode);
+       oinfo = OBDFS_INFO(inode);
        if ( IS_ERR(inode) ) {
                EXIT;
                return PTR_ERR(inode);
@@ -860,11 +865,10 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna
 
        inode->i_mode = S_IFLNK | S_IRWXUGO;
        inode->i_op = &obdfs_symlink_inode_operations;
-       for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
-            symname [l]; l++)
+       for (l = 0; l < inode->i_sb->s_blocksize - 1 && symname [l]; l++)
                ;
 
-       if (l >= sizeof (oinfo->oi_inline)) {
+       if (l >= sizeof(OBDFS_INFO(inode)->oi_inline)) {
                CDEBUG(D_INODE, "l=%d, normal symlink\n", l);
 
                name_page = obdfs_getpage(inode, 0, 1, LOCKED);
@@ -888,7 +892,8 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna
                link[i++] = c;
        link[i] = 0;
        if (name_page) {
-               obdfs_do_writepage(inode, name_page, IS_SYNC(inode));
+               err = obdfs_do_writepage(inode, name_page, IS_SYNC(inode));
+               /* XXX handle err */
                PDEBUG(name_page, "symlink");
                UnlockPage(name_page);
                page_cache_release(name_page);
index f58704b..e72d1b8 100644 (file)
@@ -54,7 +54,9 @@ static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
        err = IOPS(inode, brw)(rw, IID(inode), obdo, (char *)page_address(page),
                               &count, (page->index) >> PAGE_SHIFT, create);
 
-       obdo_to_inode(inode, obdo); /* copy o_blocks to i_blocks */
+       if ( !err )
+               obdo_to_inode(inode, obdo); /* copy o_blocks to i_blocks */
+
        obdo_free(obdo);
        
        EXIT;
@@ -79,29 +81,45 @@ int obdfs_readpage(struct dentry *dentry, struct page *page)
        return rc;
 } /* obdfs_readpage */
 
-static kmem_cache_t *obdfs_pgrq_cachep;
+static kmem_cache_t *obdfs_pgrq_cachep = NULL;
 
 int obdfs_init_pgrqcache(void)
 {
        ENTRY;
-       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;
+               CDEBUG(D_INODE, "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_INODE, "allocated cache at %p\n",
+                              obdfs_pgrq_cachep);
+               }
+       } else {
+               CDEBUG(D_INODE, "using existing cache at %p\n",
+                      obdfs_pgrq_cachep);
        }
-
        EXIT;
        return 0;
 } /* obdfs_init_wreqcache */
 
 void obdfs_cleanup_pgrqcache(void)
 {
-       if (obdfs_pgrq_cachep != NULL)
-               kmem_cache_destroy(obdfs_pgrq_cachep);
-       obdfs_pgrq_cachep = NULL;
+       ENTRY;
+       if (obdfs_pgrq_cachep != NULL) {
+               /*
+               CDEBUG(D_INODE, "shrinking obdfs_pgrqcache at %p\n",
+                      obdfs_pgrq_cachep);
+               if (kmem_cache_shrink(obdfs_pgrq_cachep))
+                       printk(KERN_INFO "obd_cleanup_pgrqcache: unable to free all of cache\n");
+               */
+       } else
+               printk(KERN_INFO "obd_cleanup_pgrqcache: called with NULL cache pointer\n");
+
        EXIT;
 } /* obdfs_cleanup_wreqcache */
 
@@ -113,7 +131,7 @@ void obdfs_cleanup_pgrqcache(void)
 static struct obdfs_pgrq *
 obdfs_find_in_page_cache(struct inode *inode, struct page *page)
 {
-       struct list_head *page_list = &OBD_LIST(inode);
+       struct list_head *page_list = &OBDFS_LIST(inode);
        struct list_head *tmp;
        struct obdfs_pgrq *pgrq;
 
@@ -148,25 +166,29 @@ obdfs_remove_from_page_cache(struct obdfs_pgrq *pgrq)
 {
        struct inode *inode = pgrq->rq_inode;
        struct page *page = pgrq->rq_page;
-       int rc;
+       int err;
 
        ENTRY;
        CDEBUG(D_INODE, "removing inode %ld page %p, pgrq: %p\n",
               inode->i_ino, page, pgrq);
-       rc = obdfs_brw(WRITE, inode, page, 1);
+       OIDEBUG(inode);
+       PDEBUG(page, "REM_CACHE");
+       err = obdfs_brw(WRITE, inode, page, 1);
        /* XXX probably should handle error here somehow.  I think that
         *     ext2 also does the same thing - discard write even if error?
         */
        put_page(page);
         list_del(&pgrq->rq_list);
        kmem_cache_free(obdfs_pgrq_cachep, pgrq);
+       OIDEBUG(inode);
 
        EXIT;
-       return rc;
+       return err;
 } /* obdfs_remove_from_page_cache */
 
 /*
  * Add a page to the write request cache list for later writing
+ * ASYNCHRONOUS write method.
  */
 static int obdfs_add_to_page_cache(struct inode *inode, struct page *page)
 {
@@ -186,7 +208,7 @@ static int obdfs_add_to_page_cache(struct inode *inode, struct page *page)
        pgrq->rq_inode = inode;
 
        get_page(pgrq->rq_page);
-       list_add(&pgrq->rq_list, &OBD_LIST(inode));
+       list_add(&pgrq->rq_list, &OBDFS_LIST(inode));
 
        /* For testing purposes, we write out the page here.
         * In the future, a flush daemon will write out the page.
@@ -203,6 +225,7 @@ static int obdfs_add_to_page_cache(struct inode *inode, struct page *page)
 } /* obdfs_add_to_page_cache */
 
 
+/* select between SYNC and ASYNC I/O methods */
 int obdfs_do_writepage(struct inode *inode, struct page *page, int sync)
 {
        int err;
@@ -234,10 +257,12 @@ int obdfs_writepage(struct dentry *dentry, struct page *page)
  *
  * If the writer ends up delaying the write, the writer needs to
  * increment the page use counts until he is done with the 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;
@@ -250,16 +275,15 @@ int obdfs_write_one_page(struct file *file, struct page *page,
                else
                        return err;
        }
-       bytes -= copy_from_user((u8*)page_address(page) + offset, buf, bytes);
-       err = -EFAULT;
 
-       if (bytes) {
-               lock_kernel();
-               err = obdfs_writepage(file->f_dentry, page);
-               unlock_kernel();
-       }
+       if (copy_from_user((u8*)page_address(page) + offset, buf, bytes))
+               return -EFAULT;
 
-       return err;
+       lock_kernel();
+       err = obdfs_writepage(file->f_dentry, page);
+       unlock_kernel();
+
+       return (err < 0 ? err : bytes);
 } /* obdfs_write_one_page */
 
 /* 
index daaf8cb..6e61ea7 100644 (file)
@@ -292,18 +292,11 @@ static void obdfs_put_super(struct super_block *sb)
        EXIT;
 }
 
-inline int obdfs_has_inline(struct inode *inode)
-{
-       struct obdfs_inode_info *oinfo = OBD_INFO(inode);
-       
-       return (oinfo->oi_flags & OBD_FL_INLINEDATA);
-}
-
 void inline obdfs_from_inode(struct obdo *oa, struct inode *inode)
 {
        obdo_from_inode(oa, inode);
        if (obdfs_has_inline(inode)) {
-               struct obdfs_inode_info *oinfo = OBD_INFO(inode);
+               struct obdfs_inode_info *oinfo = OBDFS_INFO(inode);
 
                memcpy(oa->o_inline, oinfo->oi_inline, OBD_INLINESZ);
                oa->o_flags |= OBD_FL_INLINEDATA;
@@ -314,7 +307,7 @@ void inline obdfs_to_inode(struct inode *inode, struct obdo *oa)
 {
        obdo_to_inode(inode, oa);
        if (obdo_has_inline(oa)) {
-               struct obdfs_inode_info *oinfo = OBD_INFO(inode);
+               struct obdfs_inode_info *oinfo = OBDFS_INFO(inode);
 
                memcpy(oinfo->oi_inline, oa->o_inline, OBD_INLINESZ);
                oinfo->oi_flags |= OBD_FL_INLINEDATA;
@@ -351,7 +344,7 @@ void obdfs_read_inode(struct inode *inode)
 
        ODEBUG(oa);
        obdfs_to_inode(inode, oa);
-       INIT_LIST_HEAD(&OBD_LIST(inode));
+       INIT_LIST_HEAD(&OBDFS_LIST(inode));
 
        obdo_free(oa);
        OIDEBUG(inode);
index 767f469..dc567b8 100644 (file)
 #include <linux/obd_support.h> /* for ENTRY and EXIT only */
 #include <linux/obdfs.h>
 
-/*
-static int obdfs_readlink (struct dentry *, char *, int);
-static struct dentry *obdfs_follow_link(struct dentry *, struct dentry *, unsigned int);
-*/
-
-/*
- * symlinks can't do much...
- */
-struct inode_operations obdfs_symlink_inode_operations = {
-       NULL,                   /* no file-operations */
-       NULL,                   /* create */
-       NULL,                   /* lookup */
-       NULL,                   /* link */
-       NULL,                   /* unlink */
-       NULL,                   /* symlink */
-       NULL,                   /* mkdir */
-       NULL,                   /* rmdir */
-       NULL,                   /* mknod */
-       NULL,                   /* rename */
-       obdfs_readlink,         /* readlink */
-       obdfs_follow_link,      /* follow_link */
-       NULL,                   /* get_block */
-       NULL,                   /* readpage */
-       NULL,                   /* writepage */
-       NULL,                   /* truncate */
-       NULL,                   /* permission */
-       NULL                    /* revalidate */
-};
-
 /* static */
-struct dentry * obdfs_follow_link(struct dentry * dentry,
-                                        struct dentry *base,
+struct dentry * obdfs_follow_link(struct dentry * dentry, struct dentry *base,
                                         unsigned int follow)
 {
        struct inode *inode = dentry->d_inode;
@@ -69,8 +39,8 @@ struct dentry * obdfs_follow_link(struct dentry * dentry,
        char * link;
 
        ENTRY;
-       link = (char *) inode->u.ext2_i.i_data;
-       if (inode->i_blocks) {
+       link = OBDFS_INFO(inode)->oi_inline;
+       if (!obdfs_has_inline(inode)) {
                OIDEBUG(inode);
                page = obdfs_getpage(inode, 0, 0, 0);
                PDEBUG(page, "follow_link");
@@ -102,8 +72,8 @@ int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen)
        if (buflen > inode->i_sb->s_blocksize - 1)
                buflen = inode->i_sb->s_blocksize - 1;
 
-       link = (char *) inode->u.ext2_i.i_data;
-       if (inode->i_blocks) {
+       link = OBDFS_INFO(inode)->oi_inline;
+       if (!obdfs_has_inline(inode)) {
                OIDEBUG(inode);
                page = obdfs_getpage(inode, 0, 0, 0);
                PDEBUG(page, "readlink");
@@ -125,3 +95,28 @@ int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen)
        EXIT;
        return i;
 } /* obdfs_readlink */
+
+/*
+ * symlinks can't do much...
+ */
+struct inode_operations obdfs_symlink_inode_operations = {
+       NULL,                   /* no file-operations */
+       NULL,                   /* create */
+       NULL,                   /* lookup */
+       NULL,                   /* link */
+       NULL,                   /* unlink */
+       NULL,                   /* symlink */
+       NULL,                   /* mkdir */
+       NULL,                   /* rmdir */
+       NULL,                   /* mknod */
+       NULL,                   /* rename */
+       obdfs_readlink,         /* readlink */
+       obdfs_follow_link,      /* follow_link */
+       NULL,                   /* get_block */
+       NULL,                   /* readpage */
+       NULL,                   /* writepage */
+       NULL,                   /* truncate */
+       NULL,                   /* permission */
+       NULL                    /* revalidate */
+};
+