Whamcloud - gitweb
* update b_orphan from HEAD (HEAD_ORPHAN_UPDATE_PARENT_20040119_1101)
authortianying <tianying>
Mon, 19 Jan 2004 04:09:53 +0000 (04:09 +0000)
committertianying <tianying>
Mon, 19 Jan 2004 04:09:53 +0000 (04:09 +0000)
lustre/kernel_patches/patches/snapfs_core-2.4.20.patch
lustre/snapfs/clonefs.c
lustre/snapfs/file.c
lustre/snapfs/psdev.c
lustre/snapfs/sysctl.c
lustre/snapfs/utils/snapconf.c
lustre/snapfs/utils/snapctl.h

index e28baae..4f1067d 100644 (file)
@@ -2,8 +2,8 @@
 Index: linux-2.4.20-8/fs/ext3/snap.c
 ===================================================================
 --- linux-2.4.20-8.orig/fs/ext3/snap.c 2003-01-30 18:24:37.000000000 +0800
-+++ linux-2.4.20-8/fs/ext3/snap.c      2004-01-13 00:11:40.000000000 +0800
-@@ -0,0 +1,2645 @@
++++ linux-2.4.20-8/fs/ext3/snap.c      2004-01-18 01:48:54.000000000 +0800
+@@ -0,0 +1,2588 @@
 +/* fs/ext3/snap.c
 + *
 + * Copyright (c) 2002 Cluster File Systems, Inc. <info@clusterfs.com>
@@ -47,7 +47,6 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +#define EXT3_SNAP_INDEX EXT3_XATTR_INDEX_LUSTRE
 +
 +#ifdef EXT3_SNAP_DEBUG
-+       static long snap_kmem = 0;
 +       #define snap_debug(f, a...)                             \
 +       do {                                                    \
 +               printk (KERN_INFO "SNAP DEBUG: (%s, %d): %s: ", \
@@ -482,8 +481,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +       
 +      /* we update the new cowed ino list end in memory */ 
 +      SB_LAST_COWED_INO(pri->i_sb) = cpu_to_le32(pri->i_ino);
-+        snap_debug("cowed_inode_list_end %lu, append ino=%d\n",
-+                  last_inode->i_ino, le32_to_cpu(snaps->ino[index]));
++        snap_debug("cowed_inode_list_end %lu, append ino=%lu\n",
++                  last_inode->i_ino, pri->i_ino);
 +exit:
 +      if (last_inode)
 +              iput(last_inode);
@@ -829,8 +828,7 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +
 +      ext3_copy_meta(handle, dst, src);
 +
-+      snap_debug("migrating %ld data blocks from %lu to %lu\n",
-+                                      blocks, src->i_ino, dst->i_ino);
++      snap_debug("migrating data blocks from %lu to %lu\n", src->i_ino, dst->i_ino);
 +      /* Can't check blocks in case of EAs */
 +        memcpy(EXT3_I(dst)->i_data, EXT3_I(src)->i_data,
 +                            sizeof(EXT3_I(src)->i_data));
@@ -859,6 +857,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +        ext3_mark_inode_dirty(handle, src);
 +        ext3_mark_inode_dirty(handle, dst);
 +
++      truncate_inode_pages(src->i_mapping, 0);
++
 +      return SNAP_ERROR(err);
 +}
 +
@@ -976,18 +976,17 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +
 +static int ext3_copy_block (struct inode *dst, struct inode *src, int blk) 
 +{
-+      struct buffer_head *bh_dst, *bh_src;
++      struct buffer_head *bh_dst = NULL, *bh_src = NULL;
 +      int err = 0;
-+      int journal_data;
 +      handle_t *handle = NULL;
 +
-+      if (!ext3_bmap(src->i_mapping, blk))
-+              return 0;
-+
++      
++      snap_debug("copy blk %d from %lu to %lu \n", blk, src->i_ino, dst->i_ino);
 +      /* 
 +       * ext3_getblk() require handle!=NULL
 +       */
-+      journal_data = !S_ISREG(src->i_mode);
++      if (S_ISREG(src->i_mode))
++              return 0;
 +
 +      handle = ext3_journal_start(dst, SNAP_COPYBLOCK_TRANS_BLOCKS);
 +      if( !handle )
@@ -996,39 +995,29 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +      bh_src = ext3_bread(handle, src, blk, 0, &err);
 +      if (!bh_src) {
 +              snap_err("error for src blk %d, error %d\n", blk, err);
-+              err = -1;
-+              goto exit_stop;
++              goto exit_relese;
 +      }
 +      bh_dst = ext3_getblk(handle, dst, blk, 1, &err);
 +      if (!bh_dst) {
 +              snap_err("error for dst blk %d, error %d\n", blk, err);
-+              err = -1;
-+              goto exit_rels_src;
++              err = -ENOSPC;
++              goto exit_relese;
 +      }
 +      snap_debug("copy block %lu to %lu (%ld bytes)\n",
-+                       bh_src->b_blocknr, bh_dst->b_blocknr, 
-+                      src->i_sb->s_blocksize);
++                 bh_src->b_blocknr, bh_dst->b_blocknr, 
++                 src->i_sb->s_blocksize);
 +
-+      if(journal_data){
-+              ext3_journal_get_write_access(handle, bh_dst);
-+      }
++      ext3_journal_get_write_access(handle, bh_dst);
 +
 +      memcpy(bh_dst->b_data, bh_src->b_data, src->i_sb->s_blocksize);
 +
-+      if(journal_data){
-+              ext3_journal_dirty_metadata(handle, bh_dst);
-+      }else{
-+              mark_buffer_dirty(bh_dst);
-+              if (IS_SYNC(src)) {
-+                      ll_rw_block (WRITE, 1, &bh_dst);
-+                      wait_on_buffer (bh_dst);
-+              }
-+      }
-+      brelse(bh_dst);
-+exit_rels_src:
-+      brelse(bh_src);
-+exit_stop:
-+      ext3_journal_stop(handle, dst);
++      ext3_journal_dirty_metadata(handle, bh_dst);
++      err = 1;
++exit_relese:
++      if (bh_src) brelse(bh_src);
++      if (bh_dst) brelse(bh_dst);
++      if (handle)     
++              ext3_journal_stop(handle, dst);
 +      return err;
 +}
 +
@@ -1401,7 +1390,7 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +{
 +      struct inode *ind;
 +      handle_t *handle = NULL;
-+      int err;
++      int err = 0;
 +      int has_orphan = 0;
 +
 +      if( pri == pri->i_sb->u.ext3_sb.s_journal_inode ){
@@ -1457,8 +1446,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +      }
 +
 +      if (ind && !IS_ERR(ind)) {
-+              snap_err("existing indirect ino %lu for %lu: index %d\n",
-+                              ind->i_ino, pri->i_ino, index);
++              snap_debug("existing indirect ino %lu for %lu: index %d\n",
++                        ind->i_ino, pri->i_ino, index);
 +              err = 0;
 +              goto exit;
 +      }
@@ -1939,7 +1928,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +              pri->i_ino, (ulong)le32_to_cpu(snaps->ino[index]), index);
 +
 +      ind = iget(pri->i_sb, le32_to_cpu (snaps->ino[index]) );
-+      snap_debug("iget ind %lu, ref count = %d\n", ind->i_ino, ind->i_count);
++      snap_debug("iget ind %lu, ref count = %d\n", 
++                 ind->i_ino, atomic_read(&ind->i_count));
 +
 +      if ( !ind || IS_ERR(ind) || is_bad_inode(ind) ) {
 +              err = -EINVAL;
@@ -2004,7 +1994,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +      }
 +
 +      snap_debug("delete indirect ino %lu\n", ind->i_ino);
-+      snap_debug("iput ind %lu, ref count = %d\n", ind->i_ino, ind->i_count);
++      snap_debug("iput ind %lu, ref count = %d\n", 
++                  ind->i_ino, atomic_read(&ind->i_count));
 +      ind->i_nlink = 0;
 +      iput (ind);
 +
@@ -2283,7 +2274,6 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +      }
 +}
 +
-+#if 1 
 +static int find_snap_meta_index(
 +      struct table_snap_meta_data *snap_meta,
 +      char                        *name)
@@ -2294,9 +2284,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +      for( i = 0; i < TABLE_ITEM_COUNT; i++){
 +              /*compare name Max name Length 15*/
 +              if (snap_meta->array[i].name[0]){
-+                      if(strcmp(snap_meta->array[i].name, name))
-+                              continue;
-+                      return i;
++                      if(!strncmp(snap_meta->array[i].name, name, strlen(name)))
++                              return i;
 +              }
 +      }
 +      return -1; /* can not find */
@@ -2330,8 +2319,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +        struct inode                          *inode;
 +      struct buffer_head              *bh = NULL;
 +      struct table_snap_meta_data     *s_attr;
-+      unsigned long                   map_len = 0, index = 0, left_size;
-+        int                           i, error = 0;
++      unsigned long                   map_len = 0,  left_size;
++        int                           i, error = 0, index = 0;
 +      
 +      ino = SB_SNAPTABLE_INO(sb);     
 +      if (ino == 0){
@@ -2354,8 +2343,8 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +      s_attr = (struct table_snap_meta_data *)(bh->b_data);
 +      index = find_snap_meta_index(s_attr, name);
 +      if (index < 0) {
-+              snap_debug("not exit %s meta attr of table ino %llu \n", 
-+                                      name, ip->i_ino);
++              snap_debug("not exit %s meta attr of table ino %lu \n", 
++                                      name, inode->i_ino);
 +              error = 0;
 +              goto out_iput;
 +      }
@@ -2445,14 +2434,15 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +      s_attr = (struct table_snap_meta_data *)(bh->b_data);
 +      index = find_snap_meta_index(s_attr, name);
 +      if (index < 0 && !buf) {        
-+              snap_debug("%s meta attr of table ino %llu do not exist\n", 
++              snap_debug("%s meta attr of table ino %lu do not exist\n", 
 +                          name, inode->i_ino);
 +                error = 0;
++              brelse(bh);
 +              goto exit;
 +      }
 +      if (!buf) {
-+              snap_debug("delete the meta attr %s in the table ino %s",
-+                         *name, inode->ino);
++              snap_debug("delete the meta attr %s in the table ino %lu",
++                         name, inode->i_ino);
 +              /*Here we only delete the entry of the attr
 +               *FIXME, should we also delete the block of 
 +               * this attr
@@ -2462,6 +2452,7 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +              s_attr->array[index].len = 0;
 +              s_attr->count --;
 +              ext3_journal_dirty_metadata(handle, bh);
++              brelse(bh);
 +              goto exit;
 +      }
 +      new_len = (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
@@ -2472,11 +2463,13 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +              if (index < 0){
 +                      snap_err("table full of ino %lu \n", inode->i_ino);
 +                      error = index;
-+                      goto exit;
++                      brelse(bh);
++                      goto exit;
 +              }
 +      }
 +      s_attr->array[index].len = size;
 +      journal_dirty_metadata(handle, bh);
++      brelse(bh);
 +      /*put this attr to the snap table*/
 +      left_size = size;
 +      for(i = 0; i < new_len; i++) {
@@ -2486,8 +2479,9 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +                                    s_attr->array[index].start + i, 1, &error);
 +              if (!array_bh) {
 +                      snap_err("inode %lu Can not get the block of attr %s\n",  
-+                                      inode->i_ino, name);
++                                inode->i_ino, name);
 +                      error = -ENOSPC;
++                      brelse(array_bh);
 +                      goto exit;
 +              }
 +              ext3_journal_get_write_access(handle, array_bh);
@@ -2499,63 +2493,12 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +              left_size -= inode->i_sb->s_blocksize;
 +              brelse(array_bh);
 +      }
-+      ext3_journal_stop(handle, sb->s_root->d_inode); 
 +exit:
-+      brelse(bh);
++      if (handle)
++              ext3_journal_stop(handle, sb->s_root->d_inode); 
 +      iput(inode);
 +      return error;
 +}
-+#else
-+static int ext3_get_meta_attr(struct super_block *sb, 
-+                            char* name, char* buf, 
-+                            int *size)
-+{
-+        struct inode  *root_inode = sb->s_root->d_inode;
-+      int err = 0;
-+      
-+      if (!root_inode)
-+              return -EINVAL;
-+
-+      if (buf)
-+              err = ext3_xattr_get(root_inode, EXT3_SNAP_INDEX, name,
-+                           buf, *size);
-+      if (err == -ERANGE || !buf){
-+              /*get the size of the buf*/
-+              *size = ext3_xattr_get(root_inode, EXT3_SNAP_INDEX, name,
-+                                     NULL, *size);
-+      }
-+      
-+      return err;
-+}
-+/* 
-+ * set the meta info of the snap system
-+ * argument:
-+ *    buf     == NULL  delete "name" meta attr
-+ *            != NULL  set    "name" meta attr 
-+ * return value:
-+ *    = 0     ok;
-+ *    < 0     error;  
-+ */
-+
-+static int ext3_set_meta_attr(struct super_block *sb, char* name, 
-+                            char* buf, int size)
-+{
-+        struct inode  *root_inode = sb->s_root->d_inode;
-+        handle_t      *handle = NULL;
-+        int         error = 0;
-+              
-+
-+      handle = ext3_journal_start(root_inode, EXT3_XATTR_TRANS_BLOCKS);
-+      if(!handle)
-+              return -EINVAL;
-+      
-+      error = ext3_xattr_set(handle, root_inode, EXT3_SNAP_INDEX, name, buf, size, 0);        
-+      
-+      ext3_journal_stop(handle, root_inode); 
-+      
-+      return error;
-+}
-+#endif
 +
 +struct snapshot_operations ext3_snap_operations = {
 +      ops_version:            SNAP_VERSION(2,0,2),
@@ -2649,127 +2592,6 @@ Index: linux-2.4.20-8/fs/ext3/snap.c
 +
 +
 +
-Index: linux-2.4.20-8/fs/ext3/ioctl.c
-===================================================================
---- linux-2.4.20-8.orig/fs/ext3/ioctl.c        2004-01-05 10:54:00.000000000 +0800
-+++ linux-2.4.20-8/fs/ext3/ioctl.c     2004-01-13 00:10:14.000000000 +0800
-@@ -13,6 +13,12 @@
- #include <linux/ext3_jbd.h>
- #include <linux/sched.h>
- #include <asm/uaccess.h>
-+#include <linux/locks.h>
-+
-+#include <linux/snap.h>
-+extern struct snapshot_operations ext3_snap_operations;
-+extern int ext3_snap_print(struct super_block *sb, int index);
-+extern int ext3_snap_delete(struct super_block *sb, int index);
- int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
-@@ -189,6 +195,103 @@
-                       return ret;
-               }
- #endif
-+#if 0
-+      case EXT3_IOC_SNAP_SETFILECOW: {
-+              printk(KERN_INFO "set file cow on dev %x\n",inode->i_dev);
-+
-+              /* clear block cow feature*/
-+              if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
-+                                   EXT3_FEATURE_COMPAT_BLOCKCOW)) {
-+                      handle_t        *handle = ext3_journal_start(inode, 1);
-+                      
-+                      if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
-+                                      EXT3_FEATURE_COMPAT_SNAPFS)) {
-+                              printk(KERN_INFO "can't change cow level while  snapfs feature exist");
-+                              return -EPERM;
-+                      }
-+                      lock_super(inode->i_sb);
-+                      journal_get_write_access(handle, EXT3_SB(inode->i_sb)->s_sbh);
-+                      inode->i_sb->u.ext3_sb.s_es->s_feature_compat &=
-+                              cpu_to_le32(~EXT3_FEATURE_COMPAT_BLOCKCOW);
-+                      inode->i_sb->s_dirt = 1;
-+                      journal_dirty_metadata(handle, EXT3_SB(inode->i_sb)->s_sbh);
-+                      unlock_super(inode->i_sb);
-+                      ext3_journal_stop(handle, inode);
-+              }
-+              return 0;
-+      }
-+      case EXT3_IOC_CREATE_INDIR: {
-+              struct inode *ind;
-+              printk(KERN_INFO "create indirect on inode %lu\n",inode->i_ino);
-+                      ind = ext3_snap_operations.create_indirect(inode, 0, 1, 0);
-+              if (!ind || IS_ERR(ind))
-+                      return PTR_ERR(ind);
-+              printk(KERN_INFO "got indirect inode %lu\n",ind->i_ino);
-+              put_user(ind->i_ino,(int *) arg);
-+              iput(ind);
-+              return 0;
-+      }
-+      case EXT3_IOC_GET_INDIR: {
-+              struct inode *ind;
-+              int index = 1;
-+              if (get_user(index, (int *) arg))
-+                      return -EFAULT; 
-+
-+              printk(KERN_INFO "get indirect on inode %lu, index %d\n", 
-+                              inode->i_ino, index);
-+              ind = ext3_snap_operations.get_indirect(inode, NULL, index);
-+              if (!ind || IS_ERR(ind)) {
-+                      put_user(0,(int *) arg);
-+                      return PTR_ERR(ind);
-+              }
-+              printk(KERN_INFO "got indirect inode %lu for index %d\n",
-+                              ind->i_ino, index);
-+              put_user(ind->i_ino,(int *) arg);
-+              iput(ind);
-+              return 0;
-+      }
-+      case EXT3_IOC_IS_REDIR: {
-+              int is_redirector = 0;
-+              printk(KERN_INFO "checking if inode %lu is redirector via\n",
-+                      inode->i_ino);
-+              is_redirector = ext3_snap_operations.is_redirector(inode);
-+              printk(KERN_INFO "redirector: %s\n",is_redirector ? "yes":"no");
-+              put_user(is_redirector,(int *) arg);
-+
-+              return 0;
-+      }
-+      case EXT3_IOC_RESTORE_INDIR: {
-+              printk(KERN_INFO "restore indirect on inode %lu\n",inode->i_ino);
-+              return ext3_snap_operations.restore_indirect(inode, 1);
-+      }
-+      case EXT3_IOC_SNAP_PRINT: {
-+              int index = 1;
-+              if (get_user(index, (int *) arg))
-+                      return -EFAULT; 
-+              printk(KERN_INFO "print snap for index %d\n",index);
-+
-+              return ext3_snap_print(inode->i_sb, 1);
-+      }
-+      case EXT3_IOC_SNAP_DELETE: {
-+              int index = 1;
-+              if (get_user(index, (int *) arg))
-+                      return -EFAULT; 
-+
-+              // XXX: debug code , always set index = 1
-+              if(index !=1) index=1;
-+              printk(KERN_INFO "delete all cowed inode for index %d\n",index);
-+              return ext3_snap_delete(inode->i_sb, index);
-+      }
-+
-+      case EXT3_IOC_DESTROY_INDIR: {
-+              int index = 1;
-+              if (get_user(index, (int *) arg))
-+                      index = 1;
-+              printk(KERN_INFO "destroy indirect on ino %lu, index %d\n",
-+                              inode->i_ino, index);
-+              return ext3_snap_operations.destroy_indirect(inode, index, NULL);
-+      }
-+#endif
-       default:
-               return -ENOTTY;
-       }
 Index: linux-2.4.20-8/fs/ext3/Makefile
 ===================================================================
 --- linux-2.4.20-8.orig/fs/ext3/Makefile       2004-01-05 10:54:03.000000000 +0800
@@ -2786,7 +2608,7 @@ Index: linux-2.4.20-8/fs/ext3/Makefile
 Index: linux-2.4.20-8/fs/ext3/inode.c
 ===================================================================
 --- linux-2.4.20-8.orig/fs/ext3/inode.c        2004-01-05 10:54:03.000000000 +0800
-+++ linux-2.4.20-8/fs/ext3/inode.c     2004-01-13 00:10:14.000000000 +0800
++++ linux-2.4.20-8/fs/ext3/inode.c     2004-01-18 01:48:19.000000000 +0800
 @@ -1191,7 +1191,7 @@
   * So, if we see any bmap calls here on a modified, data-journaled file,
   * take extra steps to flush any blocks which might be in the cache. 
@@ -2799,16 +2621,8 @@ Index: linux-2.4.20-8/fs/ext3/inode.c
 Index: linux-2.4.20-8/fs/ext3/ialloc.c
 ===================================================================
 --- linux-2.4.20-8.orig/fs/ext3/ialloc.c       2004-01-05 10:54:03.000000000 +0800
-+++ linux-2.4.20-8/fs/ext3/ialloc.c    2004-01-13 00:10:14.000000000 +0800
-@@ -78,7 +78,6 @@
-       sb->u.ext3_sb.s_inode_bitmap[bitmap_nr] = bh;
-       return retval;
- }
--
- /*
-  * load_inode_bitmap loads the inode bitmap for a blocks group
-  *
-@@ -160,6 +159,13 @@
++++ linux-2.4.20-8/fs/ext3/ialloc.c    2004-01-16 20:48:29.000000000 +0800
+@@ -160,6 +160,13 @@
        return retval;
  }
  
@@ -2822,6 +2636,24 @@ Index: linux-2.4.20-8/fs/ext3/ialloc.c
  /*
   * NOTE! When we get the inode, we're the only people
   * that have access to it, and as such there are no
+Index: linux-2.4.20-8/fs/ext3/super.c
+===================================================================
+--- linux-2.4.20-8.orig/fs/ext3/super.c        2004-01-05 10:54:03.000000000 +0800
++++ linux-2.4.20-8/fs/ext3/super.c     2004-01-18 01:40:10.000000000 +0800
+@@ -1324,6 +1324,13 @@
+       sbi->s_mount_state = le16_to_cpu(es->s_state);
+       sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
+       sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
++#define EXT3_SNAP_FS
++#ifdef EXT3_SNAP_FS
++      init_MUTEX(&(sbi->s_snap_list_sem));
++      sbi->s_snaptable_ino = le32_to_cpu(es->s_snaptable_ino);
++      sbi->s_first_cowed_pri_ino = le32_to_cpu(es->s_first_cowed_pri_ino);
++      sbi->s_last_cowed_pri_ino = le32_to_cpu(es->s_last_cowed_pri_ino);
++#endif        
+       for (i=0; i < 4; i++)
+               sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
+       sbi->s_def_hash_version = es->s_def_hash_version;
 Index: linux-2.4.20-8/include/linux/snap.h
 ===================================================================
 --- linux-2.4.20-8.orig/include/linux/snap.h   2003-01-30 18:24:37.000000000 +0800
@@ -3096,7 +2928,7 @@ Index: linux-2.4.20-8/include/linux/snap.h
 Index: linux-2.4.20-8/include/linux/ext3_fs.h
 ===================================================================
 --- linux-2.4.20-8.orig/include/linux/ext3_fs.h        2004-01-05 10:54:03.000000000 +0800
-+++ linux-2.4.20-8/include/linux/ext3_fs.h     2004-01-13 00:10:14.000000000 +0800
++++ linux-2.4.20-8/include/linux/ext3_fs.h     2004-01-16 20:45:09.000000000 +0800
 @@ -183,7 +183,13 @@
  #define EXT3_INDEX_FL                 0x00001000 /* hash-indexed directory */
  #define EXT3_IMAGIC_FL                        0x00002000 /* AFS directory */
@@ -3144,15 +2976,15 @@ Index: linux-2.4.20-8/include/linux/ext3_fs.h
        __u8    s_reserved_char_pad;
        __u16   s_reserved_word_pad;
 -      __u32   s_reserved[192];        /* Padding to the end of the block */
-+      /* for snapfs */
 +      __u32   s_default_mount_opts;
 +        __u32   s_first_meta_bg;        /* First metablock group */
 +      __u32   s_mkfs_time;            /* When the filesystem was created */
++      /* for snapfs */
 +      __u32   s_first_cowed_pri_ino;  /* For snapfs,the first cowed primary inode */
 +      __u32   s_last_cowed_pri_ino;     /* last cowed ino in memory */
 +      __u32   s_snaptable_ino;        /* snaptable ino in memory */
 +      __u32   s_last_snap_orphan;     /* SnapFS: start of cowing indirect inode */
-+      __u32   s_reserved[185];        /* Padding to the end of the block,originally 204 */
++      __u32   s_reserved[186];        /* Padding to the end of the block,originally 204 */
  };
  
  #ifdef __KERNEL__
@@ -3225,13 +3057,13 @@ Index: linux-2.4.20-8/include/linux/ext3_jbd.h
 
 %diffstat
  fs/ext3/Makefile           |    2 
- fs/ext3/ialloc.c           |    8 
+ fs/ext3/ialloc.c           |    7 
  fs/ext3/inode.c            |    2 
- fs/ext3/ioctl.c            |  103 +
- fs/ext3/snap.c             | 2645 +++++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/snap.c             | 2588 +++++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/super.c            |    7 
  include/linux/ext3_fs.h    |   38 
  include/linux/ext3_fs_sb.h |    7 
  include/linux/ext3_jbd.h   |   27 
  include/linux/snap.h       |  266 ++++
- 9 files changed, 3092 insertions(+), 6 deletions(-)
+ 9 files changed, 2939 insertions(+), 5 deletions(-)
 
index 71a0735..b4f136c 100644 (file)
@@ -142,6 +142,8 @@ static void clonefs_put_super(struct super_block *sb)
        clone_sb = (struct snap_clone_info *)&sb->u.generic_sbp;
        dput(clone_sb->clone_cache->cache_sb->s_root);
        list_del(&clone_sb->clone_list_entry);
+       
+       put_snap_current_mnt(clone_sb->clone_cache->cache_sb);
 
        EXIT;
 }
index 78cc9ab..25eea66 100644 (file)
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/unistd.h>
+#include <linux/pagemap.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/snap.h>
 
 #include "snapfs_internal.h" 
 
-/* instantiate a file handle to the cache file */
-static void currentfs_prepare_snapfile(struct inode *inode,
-                                    struct file *clone_file, 
-                                    struct inode *cache_inode,
-                                    struct file *cache_file,
-                                    struct dentry *cache_dentry)
+static int has_pages(struct inode *inode, int index)
 {
-        cache_file->f_pos = clone_file->f_pos;
-        cache_file->f_mode = clone_file->f_mode;
-        cache_file->f_flags = clone_file->f_flags;
-        cache_file->f_count  = clone_file->f_count;
-        cache_file->f_owner  = clone_file->f_owner;
-       cache_file->f_dentry = cache_dentry;
-        cache_file->f_dentry->d_inode = cache_inode;
+       unsigned long offset = index << PAGE_CACHE_SHIFT;
+       unsigned long blk_start = offset >> inode->i_sb->s_blocksize_bits; 
+       unsigned long blk_end = (offset + PAGE_CACHE_SIZE) >> 
+                               inode->i_sb->s_blocksize_bits; 
+
+       while (blk_start <= blk_end) {
+               if (inode->i_mapping && inode->i_mapping->a_ops) {
+                       if (inode->i_mapping->a_ops->bmap(inode->i_mapping, 
+                                                         blk_start))
+                               return 1;
+               }
+               blk_start++;
+       }
+       return 0;
 }
 
-/* update the currentfs file struct after IO in cache file */
-static void currentfs_restore_snapfile(struct inode *cache_inode,
-                                  struct file *cache_file, 
-                                  struct inode *clone_inode,
-                                  struct file *clone_file)
+static int copy_back_page(struct inode *dst, 
+                         struct inode *src,
+                         unsigned long start,
+                         unsigned long end)
 {
-        cache_file->f_pos = clone_file->f_pos;
-}
+       char *kaddr_src, *kaddr_dst;
+        struct snap_cache *cache;
+       struct address_space_operations *c_aops;
+       struct page *src_page, *dst_page;
+       unsigned long index, offset, bytes;
+       int    err = 0;
+       ENTRY;
 
+       offset = (start & (PAGE_CACHE_SIZE -1)); /* Within page */
+       bytes = end - start;
+        index = start >> PAGE_CACHE_SHIFT;
+
+       if (!has_pages(src, index) || bytes > 4096) 
+               RETURN(0);
+
+       cache = snap_find_cache(src->i_dev);
+       if (!cache) 
+               RETURN(-EINVAL);
+       c_aops = filter_c2cfaops(cache->cache_filter);
+       
+       if (!c_aops) 
+               RETURN(-EINVAL);
+
+       src_page = grab_cache_page(src->i_mapping, index);
+       if (!src_page) {
+               CERROR("copy block %lu from %lu to %lu ENOMEM \n",
+                         index, src->i_ino, dst->i_ino);
+               RETURN(-ENOMEM);
+       }
+       
+       c_aops->readpage(NULL, src_page);
+       wait_on_page(src_page);
+       
+       kaddr_src = kmap(src_page);
+       if (!Page_Uptodate(src_page)) {
+               CERROR("Can not read page index %lu of inode %lu\n",
+                         index, src->i_ino);
+               err = -EIO;
+               goto unlock_src_page;
+       }
+       dst_page = grab_cache_page(dst->i_mapping, index);
+       if (!dst_page) {
+               CERROR("copy block %lu from %lu to %lu ENOMEM \n",
+                         index, src->i_ino, dst->i_ino);
+               err = -ENOMEM;
+               goto unlock_src_page;
+       }       
+       kaddr_dst = kmap(dst_page);
+
+       err = c_aops->prepare_write(NULL, dst_page, offset, offset + bytes);
+       if (err) 
+               goto unlock_dst_page; 
+       memcpy(kaddr_dst, kaddr_src, PAGE_CACHE_SIZE);
+       flush_dcache_page(dst_page);
+
+       err = c_aops->commit_write(NULL, dst_page, offset, offset + bytes);
+       if (err) 
+               goto unlock_dst_page; 
+       err = 1;
+unlock_dst_page:
+       kunmap(dst_page);
+       UnlockPage(dst_page);
+       page_cache_release(dst_page);
+unlock_src_page:
+       kunmap(src_page);
+       page_cache_release(src_page);
+       RETURN(err);
+}
 
 static ssize_t currentfs_write (struct file *filp, const char *buf, 
                                size_t count, loff_t *ppos)
 {
         struct snap_cache *cache;
        struct inode *inode = filp->f_dentry->d_inode;
-        ssize_t rc;
         struct file_operations *fops;
-       loff_t pos;
-       long block[2]={-1,-1}, mask, i;
+       long   start[2]={-1,-1}, end[2]={-1,-1};
        struct snap_table *table;
-       int slot = 0;
-       int index = 0;
-       struct address_space_operations *aops;
        struct inode *cache_inode = NULL;
-       struct snapshot_operations *snapops;
+       int slot = 0, index = 0, result = 0;
+       long i;
+        ssize_t rc;
+       loff_t pos;
   
        ENTRY;
 
@@ -83,68 +148,69 @@ static ssize_t currentfs_write (struct file *filp, const char *buf,
                 if (pos != *ppos)
                         RETURN(-EINVAL);
         }
-
-       /*
-        * we only need to copy back the first and last blocks
-        */
-       mask = inode->i_sb->s_blocksize-1;
-       if( pos & mask )
-               block[0] = pos >> inode->i_sb->s_blocksize_bits;
+       if (pos & PAGE_CACHE_MASK) {
+               start[0] = pos & PAGE_CACHE_MASK;
+               end[0] = pos;
+       }
        pos += count - 1;
-       if( (pos+1) &  mask )
-               block[1] = pos >> inode->i_sb->s_blocksize_bits;
-       if( block[0] == block[1] )
-               block[1] = -1;
+       if ((pos+1) & PAGE_CACHE_MASK) {
+               start[1] = pos;  
+               end[1] = PAGE_CACHE_ALIGN(pos);
+       }
+
+       if (((start[0] >> PAGE_CACHE_SHIFT) == (start[1] >> PAGE_CACHE_SHIFT)) ||
+           pos > inode->i_size) 
+               start[1] = -1;
        
-       aops = filter_c2cfaops(cache->cache_filter);
-       snapops = filter_c2csnapops(cache->cache_filter);
-
-       for( i=0; i<2; i++ ){
-               if(block[i]!=-1 && aops->bmap(inode->i_mapping, block[i])) {
-                       table = &snap_tables[cache->cache_snap_tableno];
-                       for (slot = table->tbl_count - 1; slot >= 1; slot--) {
-                               struct address_space_operations *c_aops = 
-                                       cache_inode->i_mapping->a_ops;
-                               cache_inode = NULL;
-                               index = table->snap_items[slot].index;
-                               cache_inode = snap_get_indirect(inode, NULL, index);
-
-                               if ( !cache_inode )  continue;
-
-                               if (c_aops->bmap(cache_inode->i_mapping, block[i])) {
-                                       CDEBUG(D_SNAP, "find cache_ino %lu\n",
-                                               cache_inode->i_ino);
-                                       if( snapops && snapops->copy_block) {
-                                               snapops->copy_block(inode, 
-                                                               cache_inode, block[i]);
-                                       }
-                                       iput(cache_inode);
-                                       break;
-                               }
-                                       iput(cache_inode);
-                       }
-               }
+       for (i = 0; i < 2; i++) {
+               if (start[i] == -1) 
+                       continue;
+               table = &snap_tables[cache->cache_snap_tableno];
+               /*Find the nearest page in snaptable and copy back it*/
+               for (slot = table->tbl_count - 1; slot >= 1; slot--) {
+                       cache_inode = NULL;
+                               index = table->snap_items[slot].index;
+                       cache_inode = snap_get_indirect(inode, NULL, index);
+
+                       if (!cache_inode)  continue;
+
+                       CDEBUG(D_SNAP, "find cache_ino %lu\n", cache_inode->i_ino);
+               
+                       result = copy_back_page(inode, cache_inode, start[i], end[i]);
+                       if (result == 1) {
+                               CDEBUG(D_SNAP, "copy page%lu back from ind %lu to %lu\n", 
+                                      (start[i] >> PAGE_CACHE_SHIFT), 
+                                      cache_inode->i_ino, 
+                                      inode->i_ino);
+                                       iput(cache_inode);
+                               result = 0;
+                               break;
+                       }
+                       if (result < 0) {
+                               iput(cache_inode);
+                               rc = result;
+                               goto exit;
+                       }
+                               iput(cache_inode);
+               }
        }
-        rc = fops->write(filp, buf, count, ppos);
+       rc = fops->write(filp, buf, count, ppos);
+exit:
         RETURN(rc);
 }
 
 static int currentfs_readpage(struct file *file, struct page *page)
 {
-       int result = 0;
        struct inode *inode = file->f_dentry->d_inode;
        unsigned long ind_ino = inode->i_ino;
        struct inode *pri_inode = NULL;
        struct inode *cache_inode = NULL;
-       struct file open_file;
-       struct dentry open_dentry ;
        struct address_space_operations *c_aops;
        struct snap_cache *cache;
-       long block;
        struct snap_table *table;
-       int slot = 0;
-       int index = 0;
-       int search_older = 0;
+       struct page *cache_page = NULL;
+       int rc = 0, slot = 0, index = 0, search_older = 0;
+       long block;
 
        ENTRY;
 
@@ -155,14 +221,14 @@ static int currentfs_readpage(struct file *file, struct page *page)
        
        c_aops = filter_c2cfaops(cache->cache_filter);
 
-       block = page->index >> inode->i_sb->s_blocksize_bits;
+       block = (page->index << PAGE_CACHE_SHIFT) >> inode->i_sb->s_blocksize_bits;
 
        /* if there is a block in the cache, return the cache readpage */
-       if( inode->i_blocks && c_aops->bmap(inode->i_mapping, block) ) {
+       if(c_aops->bmap(inode->i_mapping, block) ) {
                CDEBUG(D_SNAP, "block %lu in cache, ino %lu\n", 
                                block, inode->i_ino);
-               result = c_aops->readpage(file, page);
-               RETURN(result);
+               rc = c_aops->readpage(file, page);
+               RETURN(rc);
        }
 
        /*
@@ -179,10 +245,7 @@ static int currentfs_readpage(struct file *file, struct page *page)
 
        table = &snap_tables[cache->cache_snap_tableno];
 
-        for (slot = table->tbl_count - 1; slot >= 1; slot--)
-        {
-               struct address_space_operations *c_aops = 
-                                       cache_inode->i_mapping->a_ops;
+        for (slot = table->tbl_count - 1; slot >= 1; slot--) {
                cache_inode = NULL;
                 index = table->snap_items[slot].index;
                cache_inode = snap_get_indirect(inode, NULL, index);
@@ -197,30 +260,52 @@ static int currentfs_readpage(struct file *file, struct page *page)
                         break;
                 iput(cache_inode);
         }
-       if( pri_inode )
-               iput(pri_inode);
+       if (pri_inode) iput(pri_inode);
 
-       if ( !cache_inode )  
+       if (!cache_inode )  
                RETURN(-EINVAL);
 
-       currentfs_prepare_snapfile(inode, file, cache_inode, &open_file,
-                             &open_dentry);
-
        down(&cache_inode->i_sem);
 
-       if( c_aops->readpage ) {
-               CDEBUG(D_SNAP, "block %lu NOT in cache, use redirected ino %lu\n", 
-                      block, cache_inode->i_ino );
-               result = c_aops->readpage(&open_file, page);
-       }else {
-               CDEBUG(D_SNAP, "cache ino %lu, readpage is NULL\n", 
-                      cache_inode->i_ino);
-       }
+       /*Here we have changed a file to read,
+        *So we should rewrite generic file read here 
+        *FIXME later, the code is ugly
+        */
+       
+       cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
+       if (!cache_page) 
+               GOTO(exit_release, rc = -ENOMEM);
+       if ((rc = c_aops->readpage(file, cache_page)))
+               GOTO(exit_release, 0);
+       
+       wait_on_page(cache_page);
+
+       if (!Page_Uptodate(cache_page))
+               GOTO(exit_release, rc = -EIO);
+
+       memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
+
+       kunmap(cache_page);
+       page_cache_release(cache_page);
+
        up(&cache_inode->i_sem);
-       currentfs_restore_snapfile(inode, file, cache_inode, &open_file);
        iput(cache_inode);
-       RETURN(result);
+       
+       kunmap(page);
+       SetPageUptodate(page);
+       UnlockPage(page);
+
+       RETURN(rc);
+
+exit_release:
+       if (cache_page) 
+               page_cache_release(cache_page);
+       up(&cache_inode->i_sem);
+       iput(cache_inode);
+       UnlockPage(page);
+       RETURN(rc);
 }
+
 struct address_space_operations currentfs_file_aops = {
        readpage:       currentfs_readpage,
 };
index 764adcc..33b7608 100644 (file)
@@ -29,8 +29,6 @@
 #include "snapfs_internal.h" 
 
 
-int snap_print_entry = 1;
-int snap_debug_level = 0;
 int snap_inodes = 0;
 long snap_kmemory = 0;
 int snap_stack = 0;
index 1969081..b9d40d6 100644 (file)
@@ -40,12 +40,13 @@ static struct ctl_table_header *snapfs_table_header = NULL;
 /* These are global control options */
 #define ENTRY_CNT 3
 
+int snap_print_entry = 1;
+int snap_debug_level = 0;
+
 /* XXX - doesn't seem to be working in 2.2.15 */
 static struct ctl_table snapfs_ctltable[] =
 {
-#ifdef SNAP_DEBUG
        {PSDEV_DEBUG, "debug", &snap_debug_level, sizeof(int), 0644, NULL, &proc_dointvec},
-#endif
        {PSDEV_TRACE, "trace", &snap_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
        {0}
 };
index 4aad130..1b22b8d 100644 (file)
@@ -41,6 +41,8 @@ command_t cmdlist[] = {
           "dev <device> open available snap device\n"},
         {"add", snap_snap_add, 0, 
           "add [table_no] <snap_name> add snapshot to the device\n"},
+        {"del", snap_snap_del, 0,
+          "del [table_no] <snap_name> del snapshot to the device\n"},
         {"snap_list", snap_snap_list, 0, 
           "snap_list [table_no] list all the snapshots on the device\n"},
         
index fe9eb5d..6640b4a 100644 (file)
@@ -19,4 +19,5 @@ extern void init_snap_list(void);
 extern int snap_dev_open(int argc, char **argv);
 extern int snap_dev_list(int argc, char **argv);
 extern int snap_snap_add(int argc, char **argv);
+extern int snap_snap_del(int argc, char **argv);
 extern int snap_snap_list(int argc, char **argv);