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
{
obdattr *res = NULL;
OBD_ALLOC(res, obdattr *, sizeof(*res));
+ memset(res, 0, sizeof (*res));
return res;
}
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 */
#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 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)
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) ;
#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){\
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;
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));
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);
'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"},
}
-sub TestSnapIterator {
+sub SnapDelete {
my $err = 0;
my $type = "snap_obd";
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";
}
+
sub SnapPrint {
my $err = 0;
my $type = "snap_obd";
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 */
NULL, /* get_block */
obdfs_readpage, /* readpage */
obdfs_writepage, /* writepage */
- NULL, /* flushpage */
NULL, /* truncate */
NULL, /* permission */
- NULL, /* smap */
NULL /* revalidate */
};