From 5fc31e4b5d23bdfa8948003bbf3312ce89924e6d Mon Sep 17 00:00:00 2001 From: adilger Date: Fri, 7 Jan 2000 19:36:01 +0000 Subject: [PATCH] Working on add_to_page_cache oops. --- lustre/demos/basesetup.sh | 5 --- lustre/demos/obdfssetup.sh | 1 + lustre/demos/snapsetup.sh | 2 ++ lustre/include/linux/obd_class.h | 63 ++++++++++++++++++++++---------------- lustre/include/linux/obd_support.h | 2 +- lustre/include/linux/obdfs.h | 8 +++-- lustre/obdclass/class_obd.c | 21 +++++++++++-- lustre/obdclass/genops.c | 10 +++--- lustre/obdfs/namei.c | 25 ++++++++------- lustre/obdfs/rw.c | 30 +++++++++++++----- lustre/obdfs/super.c | 16 +++++----- 11 files changed, 114 insertions(+), 69 deletions(-) diff --git a/lustre/demos/basesetup.sh b/lustre/demos/basesetup.sh index be60196..fcf382f 100755 --- a/lustre/demos/basesetup.sh +++ b/lustre/demos/basesetup.sh @@ -5,11 +5,6 @@ OBDDIR="`dirname $0`/.." # source config info . $OBDDIR/demos/config.sh -[ ! -d $MNTOBD ] && mkdir $MNTOBD -[ ! -d $MNTSNAP ] && mkdir $MNTSNAP -[ ! -d $MNTSNAP2 ] && mkdir $MNTSNAP2 - - # temp file if [ "$TMPFILE" -a -f $TMPFILE ]; then echo "$TMPFILE exists; I'm unwilling to overwrite it. Remove [N/y]?" 1>&2 diff --git a/lustre/demos/obdfssetup.sh b/lustre/demos/obdfssetup.sh index f26a388..6b992f7 100755 --- a/lustre/demos/obdfssetup.sh +++ b/lustre/demos/obdfssetup.sh @@ -21,4 +21,5 @@ setup $BASEDEV quit EOF +[ ! -d "$MNTOBD" ] && mkdir $MNTOBD plog mount -t obdfs -odevice=/dev/obd0 none $MNTOBD diff --git a/lustre/demos/snapsetup.sh b/lustre/demos/snapsetup.sh index b28bbd6..c1fee96 100755 --- a/lustre/demos/snapsetup.sh +++ b/lustre/demos/snapsetup.sh @@ -67,5 +67,7 @@ EOF # one where changes are made, while $MNTSNAP will contain the original # files at the point when the snapshot was taken. +[ ! -d "$MNTOBD" ] && mkdir $MNTOBD +[ ! -d "$MNTSNAP" ] && mkdir $MNTSNAP plog mount -t obdfs -odevice=/dev/obd1 none $MNTOBD plog mount -t obdfs -oro,device=/dev/obd2 none $MNTSNAP diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 14b5625..5ba16a8 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -82,9 +82,9 @@ struct obdo { */ -#define OBD_PSDEV_MAJOR 186 -#define MAX_OBD_DEVICES 8 -#define MAX_MULTI 16 +#define OBD_PSDEV_MAJOR 186 +#define MAX_OBD_DEVICES 8 +#define MAX_MULTI 16 extern struct obd_device obd_dev[MAX_OBD_DEVICES]; @@ -124,30 +124,41 @@ struct obd_device { struct obd_ops { - int (*o_iocontrol)(int cmd, struct obd_conn *, int len, void *karg, void *uarg); - int (*o_get_info)(struct obd_conn *, obd_count keylen, void *key, obd_count *vallen, void **val); - int (*o_set_info)(struct obd_conn *, obd_count keylen, void *key, obd_count vallen, void *val); - int (*o_attach)(struct obd_device *, obd_count len, void *); - int (*o_detach)(struct obd_device *); + int (*o_iocontrol)(int cmd, struct obd_conn *, int len, void *karg, + void *uarg); + int (*o_get_info)(struct obd_conn *, obd_count keylen, void *key, + obd_count *vallen, void **val); + int (*o_set_info)(struct obd_conn *, obd_count keylen, void *key, + obd_count vallen, void *val); + int (*o_attach)(struct obd_device *dev, obd_count len, void *data); + int (*o_detach)(struct obd_device *dev); int (*o_setup) (struct obd_device *dev, obd_count len, void *data); int (*o_cleanup)(struct obd_device *dev); int (*o_connect)(struct obd_conn *conn); - int (*o_disconnect)(struct obd_conn *); - int (*o_statfs)(struct obd_conn *, struct statfs *statfs); + int (*o_disconnect)(struct obd_conn *conn); + int (*o_statfs)(struct obd_conn *conn, struct statfs *statfs); int (*o_preallocate)(struct obd_conn *, obd_count *req, obd_id *ids); - int (*o_create)(struct obd_conn *, struct obdo *oa); - int (*o_destroy)(struct obd_conn *, struct obdo *oa); - int (*o_setattr)(struct obd_conn *, struct obdo *oa); - int (*o_getattr)(struct obd_conn *, struct obdo *oa); - int (*o_read)(struct obd_conn *, struct obdo *oa, char *buf, obd_size *count, obd_off offset); - int (*o_write)(struct obd_conn *, struct obdo *oa, char *buf, obd_size *count, obd_off offset); - int (*o_brw)(int rw, struct obd_conn * conn, struct obdo *oa, char *buf, obd_size count, obd_off offset, obd_flag flags); - int (*o_punch)(struct obd_conn *, struct obdo *tgt, obd_size count, obd_off offset); - int (*o_sync)(struct obd_conn *, struct obdo *tgt, obd_size count, obd_off offset); - int (*o_migrate)(struct obd_conn *, struct obdo *dst, struct obdo *src, obd_size count, obd_off offset); - int (*o_copy)(struct obd_conn *dstconn, struct obdo *dst, struct obd_conn *srconn, struct obdo *src, obd_size count, obd_off offset); - int (*o_iterate)(struct obd_conn *, int (*)(obd_id, void *), obd_id start, void *); - + int (*o_create)(struct obd_conn *conn, struct obdo *oa); + int (*o_destroy)(struct obd_conn *conn, struct obdo *oa); + int (*o_setattr)(struct obd_conn *conn, struct obdo *oa); + int (*o_getattr)(struct obd_conn *conn, struct obdo *oa); + int (*o_read)(struct obd_conn *conn, struct obdo *oa, char *buf, + obd_size *count, obd_off offset); + int (*o_write)(struct obd_conn *conn, struct obdo *oa, char *buf, + obd_size *count, obd_off offset); + int (*o_brw)(int rw, struct obd_conn *conn, struct obdo *oa, + char *buf, obd_size count, obd_off offset, obd_flag flags); + int (*o_punch)(struct obd_conn *conn, struct obdo *tgt, obd_size count, + obd_off offset); + int (*o_sync)(struct obd_conn *conn, struct obdo *tgt, obd_size count, + obd_off offset); + int (*o_migrate)(struct obd_conn *conn, struct obdo *dst, + struct obdo *src, obd_size count, obd_off offset); + int (*o_copy)(struct obd_conn *dstconn, struct obdo *dst, + struct obd_conn *srconn, struct obdo *src, + obd_size count, obd_off offset); + int (*o_iterate)(struct obd_conn *conn, int (*)(obd_id, obd_gr, void *), + obd_id *startid, obd_gr group, void *data); }; #define OBT(dev) dev->obd_type->typ_ops @@ -428,9 +439,9 @@ struct oic_generic { struct oic_prealloc_s { uint32_t cli_id; uint32_t alloc; /* user sets it to the number of inodes - * requesting to be preallocated. kernel - * sets it to the actual number * of - * succesfully preallocated inodes */ + * requesting to be preallocated. kernel + * sets it to the actual number of + * succesfully preallocated inodes */ obd_id ids[32]; /* actual inode numbers */ }; diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index 5521428..623b0f7 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -60,7 +60,7 @@ extern int obd_print_entry; #define CMD(cmd) (( cmd == READ ) ? "read" : "write") #define IDEBUG(inode) { \ - printk("]]%s line %d[[ ino %ld, blocks %ld, size %Ld, atm %ld, ctim %ld, mtm %ld, mode %o, uid %d, gid %d\n", \ + printk("]]%s line %d[[ ino %ld, blocks %ld, size %Ld, atm %ld, ctm %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,\ diff --git a/lustre/include/linux/obdfs.h b/lustre/include/linux/obdfs.h index 7ff6874..04c0f5f 100644 --- a/lustre/include/linux/obdfs.h +++ b/lustre/include/linux/obdfs.h @@ -76,9 +76,13 @@ struct obdfs_inode_info { char *oi_inline; }; -#define WB_NEXT(req) ((struct obdfs_wreq *) ((req)->wb_list.next)) -/* XXX page list should go on each inode instead of supberblock */ +#define OBD_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip)) + +/* this was used when the list was in the superblock #define OBD_LIST(inode) (((struct obdfs_sb_info *)(&(inode)->i_sb->u.generic_sbp))->osi_list) +*/ +#define OBD_LIST(inode) (OBD_INFO(inode)->oi_list) +#define WB_NEXT(req) ((struct obdfs_wreq *) ((req)->wb_list.next)) #define WREQ(entry) (list_entry(entry, struct obdfs_wreq, wb_list)) void obdfs_sysctl_init(void); diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index 24cadd0..45d2fcf 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -422,7 +422,6 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp, OBP(obddev, disconnect)(&conn); return 0; - /* XXX sync needs to be done */ case OBD_IOC_SYNC: { struct oic_range_s *range = karg; @@ -430,11 +429,27 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp, return -ENODEV; err = copy_from_user(range, (const void *)arg, sizeof(*range)); - if (err) { + + if ( err ) { + EXIT; + return err; + } + + if ( !OBT(obddev) || !OBP(obddev, sync) ) { + err = -EOPNOTSUPP; EXIT; return err; } + /* XXX sync needs to be tested/verified */ + err = OBP(obddev, sync)(&conn, &range->obdo, range->count, + range->offset); + + if ( err ) { + EXIT; + return err; + } + return put_user(err, (int *) arg); } case OBD_IOC_CREATE: { @@ -913,8 +928,8 @@ void cleanup_module(void) } } - obd_sysctl_clean(); obd_cleanup_obdo_cache(); + obd_sysctl_clean(); obd_init_magic = 0; EXIT; } diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index 37e795c..a756910 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -44,10 +44,8 @@ int obd_init_obdo_cache(void) return 0; } - obdo_cachep = kmem_cache_create("obdo_cache", - sizeof(struct obdo), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); + obdo_cachep = kmem_cache_create("obdo_cache", sizeof(struct obdo), + 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (obdo_cachep == NULL) { EXIT; return -ENOMEM; @@ -86,7 +84,6 @@ struct obd_client *gen_client(struct obd_conn *conn) } /* obd_client */ - /* a connection defines a context in which preallocation can be managed. */ int gen_connect (struct obd_conn *conn) { @@ -100,7 +97,7 @@ int gen_connect (struct obd_conn *conn) } INIT_LIST_HEAD(&cli->cli_prealloc_inodes); - /* this should probably spinlocked? */ + /* XXX this should probably spinlocked? */ cli->cli_id = ++conn->oc_dev->obd_gen_last_id; cli->cli_prealloc_quota = 0; cli->cli_obd = conn->oc_dev; @@ -286,6 +283,7 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst, } dst->o_size = src->o_size; dst->o_blocks = src->o_blocks; + dst->o_valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS); UnlockPage(page); __free_page(page); diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index 6b80666..8c7d018 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -353,7 +353,7 @@ static struct page *obdfs_add_entry (struct inode * dir, } /* - * ext2_delete_entry deletes a directory entry by merging it with the + * obdfs_delete_entry deletes a directory entry by merging it with the * previous entry */ static int obdfs_delete_entry (struct ext2_dir_entry_2 * dir, @@ -448,8 +448,10 @@ struct inode *obdfs_new_inode(struct inode *dir) struct obdo *obdo; struct inode *inode; struct obdfs_inode_info *oinfo; + ino_t ino; int err; + ENTRY; obdo = obdo_alloc(); if (!obdo) { EXIT; @@ -457,27 +459,29 @@ struct inode *obdfs_new_inode(struct inode *dir) } err = IOPS(dir, create)(IID(dir), obdo); - if ( err ) + ino = (ino_t)obdo->o_id; + obdo_free(obdo); + + if ( err ) { + EXIT; return ERR_PTR(err); + } + + inode = iget(dir->i_sb, ino); - inode = iget(dir->i_sb, (unsigned long)obdo->o_id); if (!inode) { - obdo_free(obdo); EXIT; return ERR_PTR(-EIO); } if (!list_empty(&inode->i_dentry)) { - CDEBUG(D_INODE, "New inode (%ld) has aliases!\n", - inode->i_ino); + CDEBUG(D_INODE, "New inode (%ld) has aliases!\n", inode->i_ino); iput(inode); EXIT; return ERR_PTR(-EIO); } - obdo_free(obdo); - - oinfo = inode->u.generic_ip; + oinfo = OBD_INFO(inode); INIT_LIST_HEAD(&oinfo->oi_list); EXIT; return inode; @@ -500,7 +504,6 @@ int obdfs_create (struct inode * dir, struct dentry * dentry, int mode) int err = -EIO; ENTRY; - inode = obdfs_new_inode(dir); if ( IS_ERR(inode) ) { EXIT; @@ -846,7 +849,7 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna ENTRY; inode = obdfs_new_inode(dir); - oinfo = inode->u.generic_ip; + oinfo = OBD_INFO(inode); if ( IS_ERR(inode) ) { EXIT; return PTR_ERR(inode); diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index b0f70fa..fd3ff34 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -69,7 +69,7 @@ int obdfs_readpage(struct dentry *dentry, struct page *page) struct inode *inode = dentry->d_inode; int rc; - ENTRY; + ENTRY; PDEBUG(page, "READ"); rc = obdfs_brw(READ, inode, page, 0); if (!rc) { @@ -158,7 +158,7 @@ obdfs_remove_from_page_cache(struct obdfs_wreq *wreq) * ext2 also does the same thing - discard write even if error? */ put_page(page); - list_del(&wreq->wb_list); + list_del(&wreq->wb_list); kmem_cache_free(obdfs_wreq_cachep, wreq); EXIT; @@ -186,20 +186,34 @@ obdfs_add_to_page_cache(struct inode *inode, struct page *page) wreq->wb_page = page; wreq->wb_inode = inode; + CDEBUG(D_INODE, "getting page %p\n", wreq->wb_page); get_page(wreq->wb_page); + CDEBUG(D_INODE, "adding wreq %p to inode %p\n", wreq, inode); + { struct obdfs_inode_info *oinfo = OBD_INFO(inode); + CDEBUG(D_INODE, "generic is %p\n", inode->u.generic_ip); + CDEBUG(D_INODE, "oinfo is %p\n", oinfo); + } + CDEBUG(D_INODE, "wreq_list %p\n", &wreq->wb_list); + return -EIO; + CDEBUG(D_INODE, "inode_list: next %p, prev %p\n", OBD_LIST(inode).next, + OBD_LIST(inode).prev); + CDEBUG(D_INODE, "inode_list_addr: %p\n", &OBD_LIST(inode)); + list_add(&wreq->wb_list, &OBD_LIST(inode)); /* For testing purposes, we write out the page here. * In the future, a flush daemon will write out the page. */ + printk(KERN_INFO "finding page in cache for write\n"); wreq = obdfs_find_in_page_cache(inode, page); if (!wreq) { CDEBUG(D_INODE, "XXXX Can't find page after adding it!!!\n"); + EXIT; return -EINVAL; - } else - return obdfs_remove_from_page_cache(wreq); + } - return 0; + EXIT; + return obdfs_remove_from_page_cache(wreq); } @@ -207,7 +221,7 @@ int obdfs_do_writepage(struct inode *inode, struct page *page, int sync) { int rc; - ENTRY; + ENTRY; PDEBUG(page, "WRITEPAGE"); if ( sync ) { rc = obdfs_brw(WRITE, inode, page, 1); @@ -240,7 +254,7 @@ int obdfs_writepage(struct dentry *dentry, struct page *page) int obdfs_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf) { long status; - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; ENTRY; if ( !Page_Uptodate(page) ) { @@ -281,7 +295,7 @@ struct page *obdfs_getpage(struct inode *inode, unsigned long offset, int create struct page * page; int rc; - ENTRY; + ENTRY; offset = offset & PAGE_CACHE_MASK; CDEBUG(D_INODE, "\n"); diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index 6e571f5..58ea060 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -294,17 +294,17 @@ static void obdfs_put_super(struct super_block *sb) inline int obdfs_has_inline(struct inode *inode) { - struct obdfs_inode_info *oinfo = inode->u.generic_ip; + 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) { - struct obdfs_inode_info *oinfo = inode->u.generic_ip; - obdo_from_inode(oa, inode); if (obdfs_has_inline(inode)) { + struct obdfs_inode_info *oinfo = OBD_INFO(inode); + memcpy(oa->o_inline, oinfo->oi_inline, OBD_INLINESZ); oa->o_flags |= OBD_FL_INLINEDATA; } @@ -312,10 +312,10 @@ void inline obdfs_from_inode(struct obdo *oa, struct inode *inode) void inline obdfs_to_inode(struct inode *inode, struct obdo *oa) { - struct obdfs_inode_info *oinfo = inode->u.generic_ip; - obdo_to_inode(inode, oa); if (obdo_has_inline(oa)) { + struct obdfs_inode_info *oinfo = OBD_INFO(inode); + memcpy(oinfo->oi_inline, oa->o_inline, OBD_INLINESZ); oinfo->oi_flags |= OBD_FL_INLINEDATA; } @@ -366,6 +366,7 @@ static void obdfs_write_inode(struct inode *inode) struct obdo *oa; int err; + ENTRY; oa = obdo_alloc(); oa->o_valid = OBD_MD_FLALL; obdfs_from_inode(oa, inode); @@ -375,10 +376,11 @@ static void obdfs_write_inode(struct inode *inode) if (err) { printk("obdfs_write_inode: obd_setattr fails (%d)\n", err); + EXIT; return; } - return; + EXIT; } static void obdfs_delete_inode(struct inode *inode) @@ -489,8 +491,8 @@ void cleanup_module(void) { ENTRY; - obdfs_sysctl_clean(); obdfs_cleanup_wreqcache(); + obdfs_sysctl_clean(); unregister_filesystem(&obdfs_fs_type); } -- 1.8.3.1