From a679032a54782f700fce08e452e2603c6c15228a Mon Sep 17 00:00:00 2001 From: adilger Date: Thu, 13 Jan 2000 20:58:09 +0000 Subject: [PATCH] snap/*.c: get attribtutes from child connection, fixed obdo_fromid() to return error codes as ERR_PTR obdfs/flushd.c: pupdated will now exit on SIGTERM, not extra SIGSTOP required --- lustre/demos/basesetup.sh | 2 +- lustre/demos/config.sh | 9 ++-- lustre/demos/obdfsclean.sh | 3 +- lustre/include/linux/obd_class.h | 27 +++++++----- lustre/include/linux/obdfs.h | 5 +++ lustre/obdfs/dir.c | 2 +- lustre/obdfs/flushd.c | 9 ++-- lustre/obdfs/namei.c | 17 ++++---- lustre/obdfs/rw.c | 12 +++-- lustre/obdfs/super.c | 94 +++++++++++++++++++++++++--------------- 10 files changed, 104 insertions(+), 76 deletions(-) diff --git a/lustre/demos/basesetup.sh b/lustre/demos/basesetup.sh index 86c65e8..fcf382f 100755 --- a/lustre/demos/basesetup.sh +++ b/lustre/demos/basesetup.sh @@ -25,7 +25,7 @@ if [ "$LOOPDEV" -a "`losetup $LOOPDEV 2> /dev/null`" ]; then exit 2 fi -[ "$LOOPDEV" ] && plog losetup $LOOPDEV $TMPFILE +[ "$LOOPDEV" ] && losetup $LOOPDEV $TMPFILE # Ensure that we have the correct devices for OBD to work [ ! -c /dev/obd0 ] && mknod /dev/obd0 c $OBDMAJ 0 [ ! -c /dev/obd1 ] && mknod /dev/obd1 c $OBDMAJ 1 diff --git a/lustre/demos/config.sh b/lustre/demos/config.sh index 3bdd707..c72a010 100644 --- a/lustre/demos/config.sh +++ b/lustre/demos/config.sh @@ -27,19 +27,16 @@ SNAPTABLE="/tmp/obdfs.snaptable" # A simple routine called by most of the scripts to help debugging. The # kernel code has a lot of debugging statements, so this helps us keep # track of what is going on in user-land to generate the kernel messages. -# We append directly to the messages file instead of using logger so that -# our checkpoints are not lost when the syslogd is very busy. plog () { if [ "$1" = "log" ]; then shift - echo "******** $* **********" >> /var/log/messages + logger -p kern.info "******** $* **********" echo "$*" else - echo "****start**** $* *****" >> /var/log/messages + logger -p kern.info "****start**** $* *****" echo "$*" $* - # sleep 3 # to allow messages to be flushed - echo "*****end***** $* *****" >> /var/log/messages + logger -p kern.info "*****end***** $* *****" fi } diff --git a/lustre/demos/obdfsclean.sh b/lustre/demos/obdfsclean.sh index 82a2351..b153ed8 100755 --- a/lustre/demos/obdfsclean.sh +++ b/lustre/demos/obdfsclean.sh @@ -4,8 +4,7 @@ OBDDIR="`dirname $0`/.." . $OBDDIR/demos/config.sh plog umount $MNTOBD -killall -STOP pupd # stop the OBDFS flush daemon (both signals required) -plog killall pupd +killall pupdated # stop the OBDFS flush daemon rmmod obdfs plog log "CLEANUP/DETACH" diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 64b8385..f74f3f7 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -175,12 +175,14 @@ extern void obd_cleanup_obdo_cache(void); static inline int obdo_has_inline(struct obdo *obdo) { - return obdo->o_obdflags & OBD_FL_INLINEDATA; + return (obdo->o_valid & OBD_MD_FLINLINE && + obdo->o_obdflags & OBD_FL_INLINEDATA); }; static inline int obdo_has_obdmd(struct obdo *obdo) { - return obdo->o_obdflags & OBD_FL_OBDMDEXISTS; + return (obdo->o_valid & OBD_MD_FLOBDMD && + obdo->o_obdflags & OBD_FL_OBDMDEXISTS); }; /* support routines */ @@ -208,19 +210,20 @@ static __inline__ void obdo_free(struct obdo *oa) static __inline__ struct obdo *obdo_fromid(struct obd_conn *conn, obd_id id) { struct obdo *res = NULL; + int err; res = kmem_cache_alloc(obdo_cachep, SLAB_KERNEL); if ( !res ) { EXIT; - return NULL; + return ERR_PTR(-ENOMEM); } memset(res, 0, sizeof(*res)); res->o_id = id; - res->o_valid = ~OBD_MD_FLOBDMD; - if (OBP(conn->oc_dev, getattr)(conn, res)) { + res->o_valid = OBD_MD_FLALL; + if ((err = OBP(conn->oc_dev, getattr)(conn, res))) { OBD_FREE(res, sizeof(*res)); EXIT; - return NULL; + return ERR_PTR(err); } EXIT; return res; @@ -266,7 +269,8 @@ static inline void obdo_from_iattr(struct obdo *oa, struct iattr *attr) static __inline__ void obdo_cpy_md(struct obdo *dst, struct obdo *src) { - CDEBUG(D_INODE, "src obdo flags 0x%x\n", src->o_valid); + CDEBUG(D_INODE, "src obdo %Ld valid 0x%x, dst obdo %Ld\n", + src->o_id, src->o_valid, dst->o_id); if ( src->o_valid & OBD_MD_FLATIME ) dst->o_atime = src->o_atime; if ( src->o_valid & OBD_MD_FLMTIME ) @@ -303,7 +307,8 @@ static __inline__ void obdo_cpy_md(struct obdo *dst, struct obdo *src) static __inline__ void obdo_from_inode(struct obdo *dst, struct inode *src) { - CDEBUG(D_INODE, "dst obdo flags 0x%08x\n", dst->o_valid); + CDEBUG(D_INODE, "src inode %ld, dst obdo %Ld valid 0x%08x\n", + src->i_ino, dst->o_id, dst->o_valid); if ( dst->o_valid & OBD_MD_FLID ) dst->o_id = src->i_ino; if ( dst->o_valid & OBD_MD_FLATIME ) @@ -335,7 +340,8 @@ static __inline__ void obdo_from_inode(struct obdo *dst, struct inode *src) static __inline__ void obdo_to_inode(struct inode *dst, struct obdo *src) { - CDEBUG(D_INODE, "src obdo flags 0x%08x\n", src->o_valid); + CDEBUG(D_INODE, "src obdo %Ld valid 0x%08x, dst inode %ld\n", + src->o_id, src->o_valid, dst->i_ino); if ( src->o_valid & OBD_MD_FLID ) dst->i_ino = src->o_id; if ( src->o_valid & OBD_MD_FLATIME ) @@ -364,6 +370,7 @@ static __inline__ void obdo_to_inode(struct inode *dst, struct obdo *src) dst->i_generation = src->o_generation; } +/* returns FALSE if comparison (by flags) is same, TRUE if changed */ static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src, obd_flag compare) { @@ -393,7 +400,7 @@ static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src, res = (res || (dst->o_nlink != src->o_nlink)); if ( compare & OBD_MD_FLGENER ) res = (res || (dst->o_generation != src->o_generation)); - /* XXX Don't know if thses should be included here + /* XXX Don't know if thses should be included here - wasn't previously if ( compare & OBD_MD_FLINLINE ) res = (res || memcmp(dst->o_inline, src->o_inline)); if ( compare & OBD_MD_FLOBDMD ) diff --git a/lustre/include/linux/obdfs.h b/lustre/include/linux/obdfs.h index 405bdb2..1b921be 100644 --- a/lustre/include/linux/obdfs.h +++ b/lustre/include/linux/obdfs.h @@ -103,6 +103,11 @@ static inline int obdfs_has_inline(struct inode *inode) return (OBDFS_INFO(inode)->oi_flags & OBD_FL_INLINEDATA); } +static inline int obdfs_has_obdmd(struct inode *inode) +{ + return (OBDFS_INFO(inode)->oi_flags & OBD_FL_OBDMDEXISTS); +} + #define NOLOCK 0 #define LOCKED 1 diff --git a/lustre/obdfs/dir.c b/lustre/obdfs/dir.c index c106e8e..ab5174d 100644 --- a/lustre/obdfs/dir.c +++ b/lustre/obdfs/dir.c @@ -142,8 +142,8 @@ static int obdfs_readdir(struct file * filp, void * dirent, filldir_t filldir) stored = 0; offset = filp->f_pos & (PAGE_SIZE - 1); + OIDEBUG(inode); while (!error && !stored && filp->f_pos < inode->i_size) { - OIDEBUG(inode); page = obdfs_getpage(inode, offset, 0, LOCKED); PDEBUG(page, "readdir"); if (!page) { diff --git a/lustre/obdfs/flushd.c b/lustre/obdfs/flushd.c index 86c01fa..27d93a4 100644 --- a/lustre/obdfs/flushd.c +++ b/lustre/obdfs/flushd.c @@ -115,15 +115,15 @@ static int pupdate(void *unused) tsk->session = 1; tsk->pgrp = 1; - sprintf(tsk->comm, "pupd"); + sprintf(tsk->comm, "pupdated"); pupdated = current; - printk("pupdate() activated...\n"); + printk("pupdated activated...\n"); /* sigstop and sigcont will stop and wakeup pupdate */ spin_lock_irq(&tsk->sigmask_lock); sigfillset(&tsk->blocked); - siginitsetinv(&tsk->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP)); + siginitsetinv(&tsk->blocked, sigmask(SIGTERM)); recalc_sigpending(tsk); spin_unlock_irq(&tsk->sigmask_lock); @@ -138,10 +138,9 @@ static int pupdate(void *unused) else { stop_pupdate: - printk("pupdate() stopped...\n"); tsk->state = TASK_STOPPED; MOD_DEC_USE_COUNT; - printk("RETURN from PUPD\n"); + printk("pupdated stopped...\n"); return 0; } /* check for sigstop */ diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index e2c77af..7a4960f 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -152,17 +152,18 @@ failure: return NULL; } /* obdfs_find_entry */ -struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry) +struct dentry *obdfs_lookup(struct inode *dir, struct dentry *dentry) { - struct inode * inode; - struct ext2_dir_entry_2 * de; - struct page * page; + struct inode *inode; + struct ext2_dir_entry_2 *de; + struct page *page; ENTRY; if (dentry->d_name.len > EXT2_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); - page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, LOCKED); + page = obdfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, + &de, LOCKED); inode = NULL; if ( !page ) CDEBUG(D_INODE, "No page - negative entry.\n"); @@ -336,7 +337,7 @@ static struct page *obdfs_add_entry (struct inode * dir, dir->i_version = ++event; *res_dir = de; *err = 0; - PDEBUG(page, "addentry"); + PDEBUG(page, "add_entry"); CDEBUG(D_INODE, "Regular exit from add_entry"); EXIT; return page; @@ -350,7 +351,7 @@ static struct page *obdfs_add_entry (struct inode * dir, UnlockPage(page); page_cache_release(page); - PDEBUG(page, "addentry"); + PDEBUG(page, "add_entry"); EXIT; return NULL; } /* obdfs_add_entry */ @@ -549,7 +550,6 @@ int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) int err; ENTRY; - inode = obdfs_new_inode(dir, mode); if ( IS_ERR(inode) ) { EXIT; @@ -888,7 +888,6 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, oinfo->oi_flags |= OBD_FL_INLINEDATA; CDEBUG(D_INODE, "l=%d, fast symlink\n", l); - } i = 0; while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++))) diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index 9e19ee1..1d3e1c8 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -43,19 +43,17 @@ static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create) int err; ENTRY; - obdo = obdo_alloc(); - if ( ! obdo ) { + obdo = obdo_fromid(IID(inode), inode->i_ino); + if ( IS_ERR(obdo) ) { EXIT; - return -ENOMEM; + return PTR_ERR(obdo); } - obdo->o_id = inode->i_ino; - err = IOPS(inode, brw)(rw, IID(inode), obdo, (char *)page_address(page), &count, (page->index) >> PAGE_SHIFT, create); if ( !err ) - obdo_to_inode(inode, obdo); /* copy o_blocks to i_blocks */ + obdfs_to_inode(inode, obdo); /* copy o_blocks to i_blocks */ obdo_free(obdo); @@ -167,7 +165,7 @@ obdfs_remove_from_page_cache(struct obdfs_pgrq *pgrq) int err; ENTRY; - CDEBUG(D_INODE, "removing inode %ld page %p, pgrq: %p\n", + CDEBUG(D_INODE, "writing inode %ld page %p, pgrq: %p\n", inode->i_ino, page, pgrq); OIDEBUG(inode); PDEBUG(page, "REM_CACHE"); diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index 6c598a8..f2c91e7 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -284,32 +284,42 @@ static void obdfs_put_super(struct super_block *sb) MOD_DEC_USE_COUNT; EXIT; -} +} /* obdfs_put_super */ void inline obdfs_from_inode(struct obdo *oa, struct inode *inode) { - obdo_from_inode(oa, inode); + struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); - CDEBUG(D_INODE, "oinfo flags 0x%08x\n", OBDFS_INFO(inode)->oi_flags); + CDEBUG(D_INODE, "inode %ld (%p)\n", inode->i_ino, inode); + obdo_from_inode(oa, inode); if (obdfs_has_inline(inode)) { - struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); - - CDEBUG(D_INODE, "inode %ld has inline data\n", inode->i_ino); + CDEBUG(D_INODE, "inode has inline data\n"); memcpy(oa->o_inline, oinfo->oi_inline, OBD_INLINESZ); oa->o_obdflags |= OBD_FL_INLINEDATA; + oa->o_valid |= OBD_MD_FLINLINE; } -} + if (obdfs_has_obdmd(inode)) { + CDEBUG(D_INODE, "inode %ld has obdmd data\n"); + oa->o_obdflags |= OBD_FL_OBDMDEXISTS; + } +} /* obdfs_from_inode */ void inline obdfs_to_inode(struct inode *inode, struct obdo *oa) { + struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); + + CDEBUG(D_INODE, "inode %ld (%p)\n", inode->i_ino, inode); obdo_to_inode(inode, oa); if (obdo_has_inline(oa)) { - struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); - + CDEBUG(D_INODE, "obdo has inline data\n"); memcpy(oinfo->oi_inline, oa->o_inline, OBD_INLINESZ); oinfo->oi_flags |= OBD_FL_INLINEDATA; } -} + if (obdo_has_obdmd(oa)) { + CDEBUG(D_INODE, "obdo has obdmd data\n"); + oinfo->oi_flags |= OBD_FL_OBDMDEXISTS; + } +} /* obdfs_to_inode */ /* all filling in of inodes postponed until lookup */ void obdfs_read_inode(struct inode *inode) @@ -330,7 +340,7 @@ void obdfs_read_inode(struct inode *inode) INIT_LIST_HEAD(&OBDFS_INFO(inode)->oi_pages); err = IOPS(inode, getattr)(IID(inode), oa); - if (err) { + if ( err ) { printk("obdfs_read_inode: obd_getattr fails (%d)\n", err); obdo_free(oa); EXIT; @@ -351,12 +361,12 @@ void obdfs_read_inode(struct inode *inode) else if (S_ISLNK(inode->i_mode)) inode->i_op = &obdfs_symlink_inode_operations; else - /* XXX what do we pass here??? */ - init_special_inode(inode, inode->i_mode, 0 /* XXX XXX */ ); + init_special_inode(inode, inode->i_mode, + ((long *)OBDFS_INFO(inode)->oi_inline)[0]); EXIT; return; -} +} /* obdfs_read_inode */ static void obdfs_write_inode(struct inode *inode) { @@ -365,20 +375,30 @@ static void obdfs_write_inode(struct inode *inode) ENTRY; oa = obdo_alloc(); - oa->o_valid = OBD_MD_FLALL; + if ( !oa ) { + printk("obdfs_write_inode: obdo_alloc failed\n"); + return; + } + + oa->o_valid = ~OBD_MD_FLOBDMD; obdfs_from_inode(oa, inode); err = IOPS(inode, setattr)(IID(inode), oa); - obdo_free(oa); - - if (err) { + if ( err ) { printk("obdfs_write_inode: obd_setattr fails (%d)\n", err); EXIT; - return; + } else { + /* Copy back attributes from oa, as there may have been + * changes at the target (e.g. obdo becomes a redirector + * in the snapshot layer). + */ + obdfs_to_inode(inode, oa); + EXIT; } - - EXIT; -} + + obdo_free(oa); +} /* obdfs_write_inode */ + static void obdfs_delete_inode(struct inode *inode) { @@ -387,20 +407,20 @@ static void obdfs_delete_inode(struct inode *inode) ENTRY; oa = obdo_alloc(); - /* XXX we currently assume "id" is all that's needed for destroy */ - oa->o_id = inode->i_ino; + oa->o_valid = ~OBD_MD_FLOBDMD; + obdfs_from_inode(oa, inode); + err = IOPS(inode, destroy)(IID(inode), oa); obdo_free(oa); if (err) { printk("obdfs_delete_node: obd_destroy fails (%d)\n", err); + EXIT; return; } EXIT; -} - - +} /* obdfs_delete_inode */ static int obdfs_notify_change(struct dentry *de, struct iattr *attr) @@ -411,26 +431,30 @@ static int obdfs_notify_change(struct dentry *de, struct iattr *attr) ENTRY; oa = obdo_alloc(); - if (!oa) { - printk("obdfs_notify_change: obdo_alloc fails\n"); + if ( !oa ) { + printk("obdfs_notify_change: obdo_alloc failed\n"); return -ENOMEM; } oa->o_id = inode->i_ino; obdo_from_iattr(oa, attr); err = IOPS(inode, setattr)(IID(inode), oa); - obdo_free(oa); if ( err ) { printk("obdfs_notify_change: obd_setattr fails (%d)\n", err); - return err; + EXIT; + } else { + /* Copy back attributes from oa, as there may have been + * changes at the target (e.g. obdo becomes a redirector + * in the snapshot layer). + */ + obdfs_to_inode(inode, oa); + EXIT; } - inode_setattr(inode, attr); - CDEBUG(D_INODE, "inode blocks now %ld\n", inode->i_blocks); - EXIT; + obdo_free(oa); return err; -} +} /* obdfs_notify_change */ static int obdfs_statfs(struct super_block *sb, struct statfs *buf, -- 1.8.3.1