From 088e426ec8970591c9ccb4a54fc15758451be3a9 Mon Sep 17 00:00:00 2001 From: adilger Date: Mon, 13 Dec 1999 20:54:41 +0000 Subject: [PATCH] all: significant overhaul by Peter to avoid problems with OBD metadata 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 | 97 +++++++++++++++++++++++++++++++++----- lustre/include/linux/obd_snap.h | 12 ++--- lustre/include/linux/obd_support.h | 26 ++++++---- lustre/obdclass/obdcontrol | 41 ++++++++++++++-- lustre/obdfs/rw.c | 24 +--------- 5 files changed, 144 insertions(+), 56 deletions(-) diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 4dec562..259d031 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -222,6 +222,7 @@ static __inline__ obdattr *obd_empty_oa(void) { obdattr *res = NULL; OBD_ALLOC(res, obdattr *, sizeof(*res)); + memset(res, 0, sizeof (*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)); - if ( !res ) + if ( !res ) { + EXIT; 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)); + EXIT; 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; } -/* #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 */ - a->i_blocks = b->i_blocks; + dst->i_blocks = src->i_blocks; } #endif /* __LINUX_CLASS_OBD_H */ diff --git a/lustre/include/linux/obd_snap.h b/lustre/include/linux/obd_snap.h index 53f8986..e2b79d2 100644 --- a/lustre/include/linux/obd_snap.h +++ b/lustre/include/linux/obd_snap.h @@ -1,8 +1,7 @@ #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 @@ -10,13 +9,14 @@ /* maximum number of snapshots per device must fit in "u" area of struct inode */ -#define SNAP_MAX 8 +#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_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 */ - 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) ; diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index ba262a3..b270399 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -60,13 +60,18 @@ extern int obd_print_entry; #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){\ @@ -128,6 +133,10 @@ static inline void inode_to_iattr(struct inode *inode, struct iattr *tmp) 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; @@ -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; - 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)); diff --git a/lustre/obdclass/obdcontrol b/lustre/obdclass/obdcontrol index 51f63df..6c5510e 100755 --- a/lustre/obdclass/obdcontrol +++ b/lustre/obdclass/obdcontrol @@ -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_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); @@ -109,7 +112,8 @@ my %commands = '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"}, @@ -328,7 +332,7 @@ sub TestExt2Iterator { } -sub TestSnapIterator { +sub SnapDelete { 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); - 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"; @@ -353,6 +383,7 @@ sub TestSnapIterator { } + sub SnapPrint { my $err = 0; my $type = "snap_obd"; diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index a07cd50..a48332f 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -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); - 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 */ @@ -247,9 +227,7 @@ struct inode_operations obdfs_inode_ops = { NULL, /* get_block */ obdfs_readpage, /* readpage */ obdfs_writepage, /* writepage */ - NULL, /* flushpage */ NULL, /* truncate */ NULL, /* permission */ - NULL, /* smap */ NULL /* revalidate */ }; -- 1.8.3.1