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
# 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
}
. $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"
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 */
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;
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 )
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 )
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 )
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)
{
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 )
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
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) {
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);
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 */
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");
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;
UnlockPage(page);
page_cache_release(page);
- PDEBUG(page, "addentry");
+ PDEBUG(page, "add_entry");
EXIT;
return NULL;
} /* obdfs_add_entry */
int err;
ENTRY;
-
inode = obdfs_new_inode(dir, mode);
if ( IS_ERR(inode) ) {
EXIT;
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++)))
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);
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");
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)
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;
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)
{
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)
{
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)
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,