Whamcloud - gitweb
all: significant overhaul by Peter to avoid problems with OBD metadata
authoradilger <adilger>
Mon, 13 Dec 1999 20:54:41 +0000 (20:54 +0000)
committeradilger <adilger>
Mon, 13 Dec 1999 20:54:41 +0000 (20:54 +0000)
conflicting with ext2 block data in the inode.
class/obdcontrol: added proper commands for snapdelete/snaprestore
class/obdcontrol: device command now disconnects old session if any
ext2obd/*: updated for kernel 2.3.30
include/linux/obd_class.h: helper functions inode metadata cpy/cmp
include/linux/obd_snap.h: new magic less likely for block conflict
now that the redirector can have "i_blocks" set
obd/obdfs: updated for kernel 2.3.30
snap/snap.c: use new obd metadata copy helper routines
snap/snap.c: updated delete/restore snapshot iterator functions

lustre/include/linux/obd_class.h
lustre/include/linux/obd_snap.h
lustre/include/linux/obd_support.h
lustre/obdclass/obdcontrol
lustre/obdfs/rw.c

index 4dec562..259d031 100644 (file)
@@ -222,6 +222,7 @@ static __inline__ obdattr *obd_empty_oa(void)
 {
        obdattr *res = NULL;
        OBD_ALLOC(res, obdattr *, sizeof(*res));
 {
        obdattr *res = NULL;
        OBD_ALLOC(res, obdattr *, sizeof(*res));
+       memset(res, 0, sizeof (*res));
        return res;
 }
 
        return res;
 }
 
@@ -239,32 +240,102 @@ static __inline__ obdattr *obd_oa_fromid(struct obd_conn *conn,  objid id)
        obdattr *res = NULL;
 
        OBD_ALLOC(res, obdattr *, sizeof(*res));
        obdattr *res = NULL;
 
        OBD_ALLOC(res, obdattr *, sizeof(*res));
-       if ( !res ) 
+       if ( !res ) {
+               EXIT;
                return NULL;
                return NULL;
+       }
        memset(res, 0, sizeof(*res));
        res->i_ino = id;
        if (conn->oc_dev->obd_type->typ_ops->o_getattr(conn, res)) {
                OBD_FREE(res, sizeof(*res));
        memset(res, 0, sizeof(*res));
        res->i_ino = id;
        if (conn->oc_dev->obd_type->typ_ops->o_getattr(conn, res)) {
                OBD_FREE(res, sizeof(*res));
+               EXIT;
                return NULL;
        }
                return NULL;
        }
-       
+       EXIT;
+       return res;
+}
+
+#define OBD_MD_FLMODE   (1UL<<1)
+#define OBD_MD_FLUID    (1UL<<2)
+#define OBD_MD_FLGID    (1UL<<3)
+#define OBD_MD_FLSIZE   (1UL<<4)
+#define OBD_MD_FLATIME  (1UL<<5)
+#define OBD_MD_FLMTIME  (1UL<<6)
+#define OBD_MD_FLCTIME  (1UL<<7)
+#define OBD_MD_FLFLAGS  (1UL<<8)
+#define OBD_MD_FLBLOCKS (1UL<<9)
+#define OBD_MD_FLOBDMD  (1UL<<10)
+
+
+static __inline__ void obdo_cpy_md(obdattr *dst, obdattr *src, int mask)
+{
+       CDEBUG(D_INODE, "flags %x\n", mask);
+       if ( ! (mask & OBD_MD_FLMODE) ) 
+               dst->i_mode = src->i_mode;
+       if ( ! (mask & OBD_MD_FLUID) ) 
+               dst->i_uid = src->i_uid;
+       if ( ! (mask & OBD_MD_FLGID) ) 
+               dst->i_gid = src->i_gid;
+       if ( ! (mask & OBD_MD_FLSIZE) ) 
+               dst->i_size = src->i_size;
+       if ( ! (mask & OBD_MD_FLATIME) ) 
+               dst->i_atime = src->i_atime;
+       if ( ! (mask & OBD_MD_FLMTIME) ) 
+               dst->i_mtime = src->i_mtime;
+       if ( ! (mask & OBD_MD_FLCTIME) ) 
+               dst->i_ctime = src->i_ctime;
+       if ( ! (mask & OBD_MD_FLFLAGS) ) 
+               dst->i_flags = src->i_flags;
+       /* allocation of space */
+       if ( ! (mask & OBD_MD_FLBLOCKS) ) 
+               dst->i_blocks = src->i_blocks;
+       if ( ! (mask & OBD_MD_FLOBDMD)  &&  !src->i_blocks ) {
+               CDEBUG(D_IOCTL, "copying inline data: ino %ld\n", dst->i_ino);
+               memcpy(&dst->u.ext2_i.i_data, &src->u.ext2_i.i_data, 
+                      sizeof(src->u.ext2_i.i_data));
+       } else {
+                       CDEBUG(D_INODE, "XXXX cpy_obdmd: ino %ld iblocks not 0!\n", src->i_ino);
+       }
+}
+
+static __inline__ int obdo_cmp_md(obdattr *dst, obdattr *src, int mask)
+{
+       int res = 1;
+       if ( ! (mask & OBD_MD_FLMODE) ) 
+               res = (res && (dst->i_mode == src->i_mode));
+       if ( ! (mask & OBD_MD_FLUID) ) 
+               res = (res && (dst->i_uid == src->i_uid));
+       if ( ! (mask & OBD_MD_FLGID) ) 
+               res = (res && (dst->i_gid == src->i_gid));
+       if ( ! (mask & OBD_MD_FLSIZE) ) 
+               res = (res && (dst->i_size == src->i_size));
+       if ( ! (mask & OBD_MD_FLATIME) ) 
+               res = (res && (dst->i_atime == src->i_atime));
+       if ( ! (mask & OBD_MD_FLMTIME) ) 
+               res = (res && (dst->i_mtime == src->i_mtime));
+       if ( ! (mask & OBD_MD_FLCTIME) ) 
+               res = (res && (dst->i_ctime == src->i_ctime));
+       if ( ! (mask & OBD_MD_FLFLAGS) ) 
+               res = (res && (dst->i_flags == src->i_flags));
+       /* allocation of space */
+       if ( ! (mask & OBD_MD_FLBLOCKS) ) 
+               res = (res && (dst->i_blocks == src->i_blocks));
        return res;
 }
 
        return res;
 }
 
-/* #define obd_cpy_obdo(a,b) memcpy(a, b, sizeof(*a)) */
 
 
-static __inline__ void obd_cpy_appmd(obdattr *a, obdattr *b)
+static __inline__ void obd_cpy_appmd(obdattr *dst, obdattr *src)
 {
 {
-       a->i_mode = b->i_mode;
-       a->i_uid = b->i_uid;
-       a->i_gid = b->i_gid;
-       a->i_size = b->i_size;
-       a->i_atime = b->i_atime;
-       a->i_mtime = b->i_mtime;
-       a->i_ctime = b->i_ctime;
-       a->i_flags = b->i_flags;
+       dst->i_mode = src->i_mode;
+       dst->i_uid = src->i_uid;
+       dst->i_gid = src->i_gid;
+       dst->i_size = src->i_size;
+       dst->i_atime = src->i_atime;
+       dst->i_mtime = src->i_mtime;
+       dst->i_ctime = src->i_ctime;
+       dst->i_flags = src->i_flags;
        /* allocation of space */
        /* allocation of space */
-       a->i_blocks = b->i_blocks;
+       dst->i_blocks = src->i_blocks;
 }
 
 #endif /* __LINUX_CLASS_OBD_H */
 }
 
 #endif /* __LINUX_CLASS_OBD_H */
index 53f8986..e2b79d2 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef _OBD_SNAP
 #define _OBD_SNAP
 
 #ifndef _OBD_SNAP
 #define _OBD_SNAP
 
-#define OBD_SNAP_MAGIC 0x47224722
-
+#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 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 */
 
 /* maximum number of snapshots per device 
    must fit in "u" area of struct inode */
-#define SNAP_MAX  
+#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)
 
 
 /* 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_RUNIT         _IOWR('f', 42, long)
+#define OBD_SNAP_DELETE        _IOWR('f', 42, long)
+#define OBD_SNAP_RESTORE       _IOWR('f', 43, long)
 
 
 
 
 
 
@@ -66,11 +66,9 @@ struct snap_obd {
 struct snap_object_data {
        int od_magic;
        /* id of snaps of object; slot 0 has the current data */
 struct snap_object_data {
        int od_magic;
        /* id of snaps of object; slot 0 has the current data */
-       unsigned long od_ids[SNAP_MAX + 1]; 
+       unsigned long od_ids[SNAP_MAX];
 };
 
 };
 
-#define        this_snapidx(obd) (obd->u.snap.snap_index)
-
 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) ;
 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 ba262a3..b270399 100644 (file)
@@ -60,13 +60,18 @@ extern int obd_print_entry;
 #define CMD(cmd) (( cmd == READ ) ? "read" : "write")
 
 #define IDEBUG(inode) { \
 #define CMD(cmd) (( cmd == READ ) ? "read" : "write")
 
 #define IDEBUG(inode) { \
-       if ( !list_empty(&inode->i_data.pages) || inode->i_data.nrpages ) {\
-               struct page * page;\
-               printk("XXXXX: func %s line %d ino %ld list not empty, pages %ld\n", __FUNCTION__ , __LINE__,\
-                      inode->i_ino, inode->i_data.nrpages);\
-               page = list_entry(inode->i_data.pages.next, struct page , list);\
-               PDEBUG(page, "READ INODE");\
-       }}
+               printk("]]%s line %d[[  ino %ld, blocks %ld, size %Ld, atm %ld, ctim %ld, mtm %ld, mode %o, uid %d, gid %d\n", \
+                      __FUNCTION__ , __LINE__, \
+                      inode->i_ino, inode->i_blocks, inode->i_size,\
+                      inode->i_atime, inode->i_ctime, inode->i_mtime,\
+                      inode->i_mode, inode->i_uid, inode->i_gid);\
+               printk("blk: %d %d %d %d %d %d %d %d %d %d\n",\
+                      inode->u.ext2_i.i_data[0], inode->u.ext2_i.i_data[1],\
+                      inode->u.ext2_i.i_data[2], inode->u.ext2_i.i_data[3],\
+                      inode->u.ext2_i.i_data[4], inode->u.ext2_i.i_data[5],\
+                      inode->u.ext2_i.i_data[6], inode->u.ext2_i.i_data[7],\
+                      inode->u.ext2_i.i_data[8], inode->u.ext2_i.i_data[9]);\
+       }
 
 
 #define PDEBUG(page,cmd)       {if (page){\
 
 
 #define PDEBUG(page,cmd)       {if (page){\
@@ -128,6 +133,10 @@ static inline void inode_to_iattr(struct inode *inode, struct iattr *tmp)
        tmp->ia_valid = ~0;
 }
 
        tmp->ia_valid = ~0;
 }
 
+
+#define OBD_MAGIC_INL 0x77777770
+
+
 static inline void inode_cpy(struct inode *dest, struct inode *src)
 {
        dest->i_mode = src->i_mode;
 static inline void inode_cpy(struct inode *dest, struct inode *src)
 {
        dest->i_mode = src->i_mode;
@@ -140,7 +149,8 @@ static inline void inode_cpy(struct inode *dest, struct inode *src)
        dest->i_flags = src->i_flags;
        /* allocation of space */
        dest->i_blocks = src->i_blocks;
        dest->i_flags = src->i_flags;
        /* allocation of space */
        dest->i_blocks = src->i_blocks;
-       if ( !dest->i_blocks) {
+       if ( !src->i_blocks || 
+            OBD_MAGIC_INL == (OBD_MAGIC_INL & src->u.ext2_i.i_data[0])) {
                CDEBUG(D_IOCTL, "copying inline data: ino %ld\n", dest->i_ino);
                memcpy(&dest->u.ext2_i.i_data, &src->u.ext2_i.i_data, 
                       sizeof(src->u.ext2_i.i_data));
                CDEBUG(D_IOCTL, "copying inline data: ino %ld\n", dest->i_ino);
                memcpy(&dest->u.ext2_i.i_data, &src->u.ext2_i.i_data, 
                       sizeof(src->u.ext2_i.i_data));
index 51f63df..6c5510e 100755 (executable)
@@ -66,8 +66,11 @@ eval 'sub OBD_SNAP_SETTABLE () { &_IOC(3, ord(\'f\'), 40, 4);}' unless
 eval 'sub OBD_SNAP_PRINTTABLE () { &_IOC(3, ord(\'f\'), 41, 4);}' unless
   defined(&OBD_SNAP_PRINTTABLE);
 
 eval 'sub OBD_SNAP_PRINTTABLE () { &_IOC(3, ord(\'f\'), 41, 4);}' unless
   defined(&OBD_SNAP_PRINTTABLE);
 
-eval 'sub OBD_SNAP_RUNIT () { &_IOC(3, ord(\'f\'), 42, 4);}' unless
-  defined(&OBD_SNAP_RUNIT);
+eval 'sub OBD_SNAP_DELETE() { &_IOC(3, ord(\'f\'), 42, 4);}' unless
+  defined(&OBD_SNAP_DELETE);
+eval 'sub OBD_SNAP_RESTORE() { &_IOC(3, ord(\'f\'), 43, 4);}' unless
+  defined(&OBD_SNAP_RESTORE);
+
 eval 'sub OBD_EXT2_RUNIT () { &_IOC(3, ord(\'f\'), 61, 4);}' unless
   defined(&OBD_EXT2_RUNIT);
 
 eval 'sub OBD_EXT2_RUNIT () { &_IOC(3, ord(\'f\'), 61, 4);}' unless
   defined(&OBD_EXT2_RUNIT);
 
@@ -109,7 +112,8 @@ my %commands =
      'snapprint' => {func => "SnapPrint", doc => "snapprint tableno"},
 
      'testext2iterator' => {func => "TestExt2Iterator", doc => ""},
      'snapprint' => {func => "SnapPrint", doc => "snapprint tableno"},
 
      'testext2iterator' => {func => "TestExt2Iterator", doc => ""},
-     'testsnapiterator' => {func => "TestSnapIterator", doc => ""},
+     'snapdelete' => {func => "SnapDelete", doc => "snapdelete: delete connected snap obd"},
+     'snaprestore' => {func => "SnapRestore", doc => "snaprestore: restore connected old snap to current"},
 
      'snaptable' => {func => "SnapShotTable", doc => "snaptable: build a snapshot table (interactive)"},
      'copy' => {func => "Copy", doc => "copy srcid tgtid"},
 
      'snaptable' => {func => "SnapShotTable", doc => "snaptable: build a snapshot table (interactive)"},
      'copy' => {func => "Copy", doc => "copy srcid tgtid"},
@@ -328,7 +332,7 @@ sub TestExt2Iterator {
 }
 
 
 }
 
 
-sub TestSnapIterator { 
+sub SnapDelete { 
     my $err = 0;
     my $type = "snap_obd";
  
     my $err = 0;
     my $type = "snap_obd";
  
@@ -341,7 +345,33 @@ sub TestSnapIterator {
     print "type $type (len $len), datalen $datalen ($cl)\n";
     my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
 
     print "type $type (len $len), datalen $datalen ($cl)\n";
     my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
 
-    my $rc = ioctl(DEV_OBD, &OBD_SNAP_RUNIT, $packed);
+    my $rc = ioctl(DEV_OBD, &OBD_SNAP_DELETE, $packed);
+
+    if (!defined $rc) {
+       print STDERR "ioctl failed: $!\n";
+    } elsif ($rc eq "0 but true") {
+       print "Finished (success)\n";
+    } else {
+       print "ioctl returned error code $rc.\n";
+    }
+}
+
+
+sub SnapRestore { 
+    my $err = 0;
+    my $type = "snap_obd";
+    my $prevcurrent = shift;
+    $data = pack("i", $prevcurrent); # where the previous current snapshot now lives
+    $datalen = 4;
+
+    my $len = length($type);
+    my $cl = length($data);
+    my $add = pack("p", $data);
+    print "type $type (len $len), datalen $datalen ($cl)\n";
+    my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
+
+    my $rc = ioctl(DEV_OBD, &OBD_SNAP_RESTORE, $packed);
 
     if (!defined $rc) {
        print STDERR "ioctl failed: $!\n";
 
     if (!defined $rc) {
        print STDERR "ioctl failed: $!\n";
@@ -353,6 +383,7 @@ sub TestSnapIterator {
 }
 
 
 }
 
 
+
 sub SnapPrint { 
     my $err = 0;
     my $type = "snap_obd";
 sub SnapPrint { 
     my $err = 0;
     my $type = "snap_obd";
index a07cd50..a48332f 100644 (file)
@@ -159,27 +159,7 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create
        CDEBUG(D_INODE, "page_cache %p\n", page_cache);
 
        hash = page_hash(&inode->i_data, offset);
        CDEBUG(D_INODE, "page_cache %p\n", page_cache);
 
        hash = page_hash(&inode->i_data, offset);
- repeat:
-       CDEBUG(D_INODE, "Finding page\n");
-       IDEBUG(inode);
-
-       page = __find_lock_page(&inode->i_data, offset, hash); 
-       if ( page ) {
-               CDEBUG(D_INODE, "Page found freeing\n");
-               page_cache_free(page_cache);
-       } else {
-               page = page_cache;
-               if ( page->buffers ) {
-                       PDEBUG(page, "GETPAGE: buffers bug\n");
-                       UnlockPage(page);
-                       return NULL;
-               }
-               if (add_to_page_cache_unique(page, &inode->i_data, offset, hash)) {
-                       page_cache_release(page);
-                       CDEBUG(D_INODE, "Someone raced: try again\n");
-                       goto repeat;
-               }
-       }
+       page = grab_cache_page(&inode->i_data, offset);
 
        PDEBUG(page, "GETPAGE: got page - before reading\n");
        /* now check if the data in the page is up to date */
 
        PDEBUG(page, "GETPAGE: got page - before reading\n");
        /* now check if the data in the page is up to date */
@@ -247,9 +227,7 @@ struct inode_operations obdfs_inode_ops = {
        NULL,           /* get_block */
        obdfs_readpage, /* readpage */
        obdfs_writepage, /* writepage */
        NULL,           /* get_block */
        obdfs_readpage, /* readpage */
        obdfs_writepage, /* writepage */
-       NULL,           /* flushpage */
        NULL,           /* truncate */
        NULL,           /* permission */
        NULL,           /* truncate */
        NULL,           /* permission */
-       NULL,           /* smap */
        NULL            /* revalidate */
 };
        NULL            /* revalidate */
 };