From f1294d6cbf046a74837aebfa8d959ba81c55b759 Mon Sep 17 00:00:00 2001 From: adilger Date: Mon, 15 Mar 2004 21:58:20 +0000 Subject: [PATCH] Update b1_2 from HEAD (20040315_1445) b=2898, b=2926 --- lustre/ChangeLog | 2 + lustre/include/linux/obd_support.h | 18 + lustre/ldlm/ldlm_lib.c | 19 +- lustre/lvfs/fsfilt_tmpfs.c | 654 ------------------------------- lustre/mds/mds_reint.c | 10 +- lustre/obdclass/class_obd.c | 3 + lustre/obdclass/lprocfs_status.c | 2 +- lustre/obdclass/sysctl.c | 17 +- lustre/scripts/lmake | 4 +- lustre/scripts/lustre-kernel-2.4.spec.in | 2 +- lustre/scripts/lustre.spec.in | 2 +- lustre/tests/.RC_CURRENT.tag | 2 +- lustre/tests/ltmpfs-sanity.sh | 10 - lustre/tests/ltmpfs.sh | 1 - lustre/tests/replay-single.sh | 10 + 15 files changed, 71 insertions(+), 685 deletions(-) delete mode 100644 lustre/lvfs/fsfilt_tmpfs.c delete mode 100755 lustre/tests/ltmpfs-sanity.sh delete mode 100755 lustre/tests/ltmpfs.sh diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 3d74556..f6eed85 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -10,6 +10,8 @@ tbd Cluster File Systems, Inc. - fix destroying of named logs (2325) - overwrite old logs when running lconf --write_conf (2264) - bump LLOG_CHUNKSIZE to 8k to allow for larger clusters (2306) + - fix race in target_handle_connect (2898) + - mds_reint_create() should take same inode create lock (2926) 2004-03-04 Cluster File Systems, Inc. * version 1.2.0 diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index 41fb301..c39cb6f 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -39,6 +39,7 @@ extern unsigned int obd_fail_loc; extern unsigned int obd_timeout; extern char obd_lustre_upcall[128]; extern unsigned int obd_sync_filter; +extern wait_queue_head_t obd_race_waitq; #define OBD_FAIL_MDS 0x100 #define OBD_FAIL_MDS_HANDLE_UNPACK 0x101 @@ -129,6 +130,7 @@ extern unsigned int obd_sync_filter; #define OBD_FAIL_OBD_LOGD_NET 0x602 #define OBD_FAIL_TGT_REPLY_NET 0x700 +#define OBD_FAIL_TGT_CONN_RACE 0x701 /* preparation for a more advanced failure testbed (not functional yet) */ #define OBD_FAIL_MASK_SYS 0x0000FF00 @@ -174,6 +176,22 @@ do { \ } \ } while(0) +/* The idea here is to synchronise two threads to force a race. The + * first thread that calls this with a matching fail_loc is put to + * sleep. The next thread that calls with the same fail_loc wakes up + * the first and continues. */ +#define OBD_RACE(id) \ +do { \ + if (OBD_FAIL_CHECK_ONCE(id)) { \ + CERROR("obd_race id %x sleeping\n", (id)); \ + sleep_on(&obd_race_waitq); \ + CERROR("obd_fail_race id %x awake\n", (id)); \ + } else if ((obd_fail_loc & OBD_FAIL_MASK_LOC) == \ + ((id) & OBD_FAIL_MASK_LOC)) { \ + wake_up(&obd_race_waitq); \ + } \ +} while(0) + #define fixme() CDEBUG(D_OTHER, "FIXME\n"); #ifdef __KERNEL__ diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index bcaed00..0d514db 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -372,8 +372,11 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) struct list_head *p; char *str, *tmp; int rc = 0, abort_recovery; + unsigned long flags; ENTRY; + OBD_RACE(OBD_FAIL_TGT_CONN_RACE); + LASSERT_REQSWAB (req, 0); str = lustre_msg_string(req->rq_reqmsg, 0, sizeof(tgtuuid) - 1); if (str == NULL) { @@ -386,7 +389,7 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) if (!target) { target = class_name2obd(str); } - + if (!target || target->obd_stopping || !target->obd_set_up) { CERROR("UUID '%s' is not available for connect\n", str); GOTO(out, rc = -ENODEV); @@ -498,6 +501,17 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) export = req->rq_export = class_conn2export(&conn); LASSERT(export != NULL); + spin_lock_irqsave(&export->exp_lock, flags); + if (export->exp_conn_cnt >= req->rq_reqmsg->conn_cnt) { + CERROR("%s: already connected at a higher conn_cnt: %d > %d\n", + cluuid.uuid, export->exp_conn_cnt, + req->rq_reqmsg->conn_cnt); + spin_unlock_irqrestore(&export->exp_lock, flags); + GOTO(out, rc = -EALREADY); + } + export->exp_conn_cnt = req->rq_reqmsg->conn_cnt; + spin_unlock_irqrestore(&export->exp_lock, flags); + /* request from liblustre? */ if (lustre_msg_get_op_flags(req->rq_reqmsg) & MSG_CONNECT_LIBCLIENT) export->exp_libclient = 1; @@ -507,9 +521,6 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) export->exp_connection = ptlrpc_get_connection(&req->rq_peer, &remote_uuid); - LASSERT(export->exp_conn_cnt < req->rq_reqmsg->conn_cnt); - export->exp_conn_cnt = req->rq_reqmsg->conn_cnt; - if (rc == EALREADY) { /* We indicate the reconnection in a flag, not an error code. */ lustre_msg_add_op_flags(req->rq_repmsg, MSG_CONNECT_RECONNECT); diff --git a/lustre/lvfs/fsfilt_tmpfs.c b/lustre/lvfs/fsfilt_tmpfs.c deleted file mode 100644 index 808ee25..0000000 --- a/lustre/lvfs/fsfilt_tmpfs.c +++ /dev/null @@ -1,654 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/lib/fsfilt_tmpfs.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2002, 2003, 2004 Cluster File Systems, Inc. - * Author: Yury Umanets - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* prefix is needed because tmpfs xattr patch deos not support namespaces - * yet. */ -#define XATTR_LUSTRE_MDS_LOV_EA "trusted.lov" -#define XATTR_LUSTRE_MDS_OBJID "system.lustre_mds_objid" - -/* structure instance of to be returned as a transaction handle. This is not - * needed for now, but probably we will need to save something during modifying - * an inode and this is useful for us. */ -struct tmpfs_trans { - int op; -}; - -static kmem_cache_t *trans_cache; -static atomic_t trans_count = ATOMIC_INIT(0); - -/* ext2 directory stuff. It is needed for fs_readpage(), which is used for - * reading directoris on MDS. Probably this should be moved to somewhere more - * convenient? */ -#define EXT2_NAME_LEN (255) - -struct ext2_dirent { - __u32 inode; - __u16 rec_len; - __u8 name_len; - __u8 file_type; - char name[0]; -}; - -typedef struct ext2_dirent ext2_dirent_t; - -struct fetch_hint { - int stop; - int count; - __u16 chunk; - void *dirent; - __u16 rec_len; - struct file *file; -}; - -typedef struct fetch_hint fetch_hint_t; - -#define EXT2_ENT_PAD 4 -#define EXT2_ENT_ROUND (EXT2_ENT_PAD - 1) -#define EXT2_ENT_LEN(len) (((len) + 8 + EXT2_ENT_ROUND) & ~EXT2_ENT_ROUND) - -/* starts new transaction on tmpfs for metadata operations. That if for create - * file, delete it, etc. That is everything except of read/write data. Returns - * pointer to transaction handle to be used later. What we have to do here? - * Seems nothing for a while. */ -static void * -fsfilt_tmpfs_mtd_start(struct inode *inode, int op, void *desc_private) -{ - int rc; - struct kstatfs sfs; - struct tmpfs_trans *trans; - - CDEBUG(D_INFO, "Metadata operation 0x%x is started on " - "inode 0x%lx\n", op, inode->i_ino); - - if ((rc = vfs_statfs(inode->i_sb, &sfs))) - return ERR_PTR(rc); - - if (sfs.f_bfree == 0) - return ERR_PTR(-ENOSPC); - - OBD_SLAB_ALLOC(trans, trans_cache, GFP_NOFS, - sizeof(*trans)); - - if (trans == NULL) - return NULL; - - atomic_inc(&trans_count); - - trans->op = op; - return trans; -} - -/* commits changes on passed @inode using passed transaction @handle. Should we - * do something here? */ -static int -fsfilt_tmpfs_mtd_commit(struct inode *inode, void *handle, int force_sync) -{ - struct tmpfs_trans *trans; - - trans = (struct tmpfs_trans *)handle; - - OBD_SLAB_FREE(trans, trans_cache, sizeof(*trans)); - atomic_dec(&trans_count); - - CDEBUG(D_INFO, "Metadata operation 0x%x is " - "finished on inode 0x%lx\n", trans->op, - inode->i_ino); - - return 0; -} - -/* starts new transaction for read/write operations. Seems, that here we do - * nothing also. */ -static void * -fsfilt_tmpfs_io_start(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_local *nb, - void *desc_private) -{ - int rc; - struct kstatfs sfs; - struct tmpfs_trans *trans; - - ENTRY; - - CDEBUG(D_INFO, "IO operation is started on inode 0x%lx\n", - fso->fso_dentry->d_inode->i_ino); - - /* check if we still have free space on filesystem. */ - if ((rc = vfs_statfs(fso->fso_dentry->d_inode->i_sb, &sfs))) - RETURN(ERR_PTR(rc)); - - if (sfs.f_bfree == 0) - RETURN(ERR_PTR(-ENOSPC)); - - OBD_SLAB_ALLOC(trans, trans_cache, GFP_NOFS, - sizeof(*trans)); - - if (trans == NULL) - RETURN(NULL); - - atomic_inc(&trans_count); - - trans->op = 0; - RETURN(trans); -} - -/* commits changes on passed @inode using passed transaction @handle. This is - * called from direct_io() with handle obtained from brw_start(). */ -static int -fsfilt_tmpfs_io_commit(struct inode *inode, void *handle, void **wh) -{ - struct tmpfs_trans *trans; - - trans = (struct tmpfs_trans *)handle; - - OBD_SLAB_FREE(trans, trans_cache, sizeof(*trans)); - atomic_dec(&trans_count); - - CDEBUG(D_INFO, "IO operation is finished on inode " - "0x%lx\n", inode->i_ino); - - /* wait handle is not used. */ - *wh = NULL; - - return 0; -} - -/* waits for transaction started by io_commit() to be finished on passed wait - * handle. What should we do here? Nothing so far. */ -static int -fsfilt_tmpfs_commit_wait(struct inode *inode, void *wh) -{ - CDEBUG(D_INFO, "commit wait is called\n"); - return 0; -} - -/* implements additional ioctl fucntions. Nothing do here. */ -static int -fsfilt_tmpfs_iocontrol(struct inode * inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int rc = -ENOTTY; - - ENTRY; - - if (inode->i_fop->ioctl) - rc = inode->i_fop->ioctl(inode, file, cmd, arg); - - RETURN(rc); -} - -/* fills @osfs by statfs info for tmpfs. Should we do some correcting - here? Probably later. */ -static int -fsfilt_tmpfs_statfs(struct super_block *sb, struct obd_statfs *osfs) -{ - int rc; - struct kstatfs sfs; - - if (!sb->s_op->statfs) - return -ENOSYS; - - memset(&sfs, 0, sizeof(sfs)); - - /* trying to be consistent with other parts of tmpfs filter and call - * sb->s_op->statfs() instead of using vfs_statfs(). */ - lock_kernel(); - rc = sb->s_op->statfs(sb, &sfs); - unlock_kernel(); - - if (rc == 0) - statfs_pack(osfs, &sfs); - - return rc; -} - -/* make sure, that all dirty buffers are stored onto device. This is nothing to - * do for tmpfs in principle, but we will not aim to be smarter than tmpfs is - * and call sb->s_op->sync_fs() is any. */ -static int -fsfilt_tmpfs_sync(struct super_block *sb) -{ - if (sb->s_op->sync_fs) - return sb->s_op->sync_fs(sb); - - return 0; -} - -/* uses inode setattr method if any, or does default actions otherwise. */ -static int fsfilt_tmpfs_setattr(struct dentry *dentry, void *handle, - struct iattr *iattr, int do_trunc) -{ - int rc; - struct inode *inode = dentry->d_inode; - - lock_kernel(); - - /* preventing vmtruncate() to be called on inode_setattr(). */ - if (iattr->ia_valid & ATTR_SIZE && !do_trunc) { - iattr->ia_valid &= ~ATTR_SIZE; - inode->i_size = iattr->ia_size; - } - - iattr->ia_mode = (inode->i_mode & S_IFMT) | - (iattr->ia_mode & ~S_IFMT); - - iattr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET); - - if (inode->i_op->setattr) { - rc = inode->i_op->setattr(dentry, iattr); - } else { - if (!(rc = inode_change_ok(inode, iattr))) - rc = inode_setattr(inode, iattr); - } - - unlock_kernel(); - - return rc; -} - -/* nothing to do here. */ -static int -fsfilt_tmpfs_setup(struct super_block *sb) -{ - return 0; -} - -/* sets lmm into inode xattrs using passed transaction @handle. */ -static int -fsfilt_tmpfs_set_md(struct inode *inode, void *handle, - void *lmm, int lmm_size) -{ - int rc; - - lock_kernel(); - - rc = shmem_xattr_set(inode, XATTR_LUSTRE_MDS_LOV_EA, - lmm, lmm_size, 0); - - unlock_kernel(); - - if (rc) { - CERROR("error adding MD data to inode %lu: rc = %d\n", - inode->i_ino, rc); - } - - return rc; -} - -/* gets lmm from inode xattrs. */ -static int -fsfilt_tmpfs_get_md(struct inode *inode, void *lmm, - int lmm_size) -{ - int rc; - - LASSERT(down_trylock(&inode->i_sem) != 0); - - lock_kernel(); - - /* getting new key first. */ - rc = shmem_xattr_get(inode, XATTR_LUSTRE_MDS_LOV_EA, - lmm, lmm_size); - - /* check for old one. */ - if (rc == -ENODATA) { - rc = shmem_xattr_get(inode, XATTR_LUSTRE_MDS_OBJID, - lmm, lmm_size); - } - - unlock_kernel(); - - if (lmm == NULL) - return (rc == -ENODATA) ? 0 : rc; - - if (rc < 0) { - CDEBUG(D_INFO, "error getting EA %s from inode %lu: rc = %d\n", - XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); - - memset(lmm, 0, lmm_size); - return (rc == -ENODATA) ? 0 : rc; - } - - return rc; -} - -/* reads data from passed @file to @buf. */ -static ssize_t -fsfilt_tmpfs_read(struct file *file, char *buf, - size_t count, loff_t *off) -{ - struct inode *inode = file->f_dentry->d_inode; - - if (!S_ISREG(inode->i_mode)) - return -EINVAL; - - return file->f_op->read(file, buf, count, off); -} - -/* writes data to regular @file. */ -static ssize_t -fsfilt_tmpfs_write(struct file *file, char *buf, - size_t count, loff_t *off) -{ - struct inode *inode = file->f_dentry->d_inode; - - if (!S_ISREG(inode->i_mode)) - return -EINVAL; - - return file->f_op->write(file, buf, count, off); -} - -/* puts passed page to page cache. */ -static int -fsfilt_tmpfs_putpage(struct inode *inode, struct page *page, - int lazy_cache) -{ - struct page *shmem_page; - struct shmem_inode_info *info = SHMEM_I(inode); - - down(&info->sem); - - /* getting page from shmem. It may be read from swap. And this is the - * reason, why we do not just add passed @page to pacge cache. */ - shmem_page = shmem_getpage_locked(inode, page->index); - - if (IS_ERR(shmem_page)) { - up(&info->sem); - return PTR_ERR(shmem_page); - } - - up(&info->sem); - - copy_page(kmap(shmem_page), kmap(page)); - kunmap(page); kunmap(shmem_page); - - /* taking care about possible cache aliasing. */ - if (inode->i_mapping->i_mmap_shared != NULL) - flush_dcache_page(shmem_page); - - SetPageDirty(shmem_page); - UnlockPage(shmem_page); - page_cache_release(shmem_page); - - return 0; -} - -/* returns inode page by its @index. */ -static struct page * -fsfilt_tmpfs_getpage(struct inode *inode, long int index) -{ - struct page *page; - - page = shmem_getpage_unlocked(inode, index); - - if (IS_ERR(page)) - return page; - - /* taking care about possible cache aliasing. */ - if (inode->i_mapping->i_mmap_shared != NULL) - flush_dcache_page(page); - - return page; -} - -/* fills up passed @buf by entry data. Used from readdir(). */ -static int -fillent(void *buf, const char *name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) -{ - __u16 rec_len; - fetch_hint_t *hint = (fetch_hint_t *)buf; - ext2_dirent_t *entry = hint->dirent; - - rec_len = EXT2_ENT_LEN(namlen); - - if ((hint->stop = (hint->chunk < rec_len))) - return -ENOENT; - - entry->file_type = 0; - - hint->count++; - hint->chunk -= rec_len; - hint->rec_len = rec_len; - hint->dirent += rec_len; - - entry->name_len = namlen; - entry->inode = cpu_to_le32(ino); - memcpy(entry->name, name, namlen); - entry->rec_len = cpu_to_le16(rec_len); - - return 0; -} - -/* this should be the same as in tmpfs. Should it be not hardcoded? */ -#define BOGO_ENTRY_SIZE (20) - -/* mostly needed for reading directory from @file on MDS. */ -static ssize_t -fsfilt_tmpfs_readpage(struct file *file, char *buf, - size_t count, loff_t *off) -{ - int rc = 0; - struct inode *inode = file->f_dentry->d_inode; - - if (S_ISREG(inode->i_mode)) { - rc = file->f_op->read(file, buf, count, off); - } else if (S_ISDIR(inode->i_mode)) { - int error; - loff_t offset; - fetch_hint_t hint; - ext2_dirent_t *dirent; - - /* positioning to passed @off. */ - offset = *(long int *)off / BOGO_ENTRY_SIZE; - - if (file->f_op->llseek(file, offset, 0) != offset) - return -ENOENT; - - /* reading @count bytesof data. */ - while (count > 0) { - hint.count = 0; - hint.file = file; - hint.dirent = buf; - hint.chunk = count; - hint.rec_len = count; - - if ((error = vfs_readdir(file, fillent, &hint)) < 0) - return error; - - /* we should have something after vfs_readdir() is - * finished. */ - LASSERT(hint.count != 0); - - /* last entry should be extended up to free page - * size. */ - if (hint.chunk > 0) { - __u16 rec_len; - - hint.dirent -= hint.rec_len; - dirent = (ext2_dirent_t *)hint.dirent; - - rec_len = le16_to_cpu(dirent->rec_len); - dirent->rec_len = cpu_to_le16(rec_len + hint.chunk); - } - - count -= PAGE_CACHE_SIZE; - *off += PAGE_CACHE_SIZE; - rc += PAGE_CACHE_SIZE; - } - - UPDATE_ATIME(inode); - } else { - rc = -EINVAL; - } - - return rc; -} - -static int -fsfilt_tmpfs_add_journal_cb(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func, - void *cb_data) -{ - cb_func(obd, last_rcvd, cb_data, 0); - return 0; -} - -static int -fsfilt_tmpfs_prep_san_write(struct inode *inode, long *blocks, - int nblocks, loff_t newsize) -{ - /* we do not need block numbers and other stuff, as it will not be - * used. */ - blocks[0] = 0; - - if (newsize > inode->i_size) - inode->i_size = newsize; - - return 0; -} - -/* this is used for reading configuration */ -static int -fsfilt_tmpfs_read_record(struct file *file, void *buf, - int size, loff_t *off) -{ - int error; - struct inode *inode = file->f_dentry->d_inode; - - lock_kernel(); - - if (inode->i_size < *off + size) { - size = inode->i_size - *off; - unlock_kernel(); - - if (size < 0) { - return -EIO; - } else if (size == 0) { - return 0; - } - } else { - unlock_kernel(); - } - - if ((error = fsfilt_tmpfs_read(file, buf, size, off)) < 0) - return error; - - return 0; -} - -/* this is used for writing configuration */ -static int -fsfilt_tmpfs_write_record(struct file *file, void *buf, - int size, loff_t *off, int sync) -{ - int error; - - if ((error = fsfilt_tmpfs_write(file, buf, size, off)) < 0) - return error; - - return 0; -} - -static struct fsfilt_operations fsfilt_tmpfs_ops = { - fs_type: "tmpfs", - fs_owner: THIS_MODULE, - fs_start: fsfilt_tmpfs_mtd_start, - fs_commit: fsfilt_tmpfs_mtd_commit, - fs_brw_start: fsfilt_tmpfs_io_start, - fs_commit_async: fsfilt_tmpfs_io_commit, - fs_commit_wait: fsfilt_tmpfs_commit_wait, - fs_iocontrol: fsfilt_tmpfs_iocontrol, - fs_set_md: fsfilt_tmpfs_set_md, - fs_get_md: fsfilt_tmpfs_get_md, - fs_readpage: fsfilt_tmpfs_readpage, - fs_getpage: fsfilt_tmpfs_getpage, - fs_putpage: fsfilt_tmpfs_putpage, - fs_add_journal_cb: fsfilt_tmpfs_add_journal_cb, - fs_statfs: fsfilt_tmpfs_statfs, - fs_sync: fsfilt_tmpfs_sync, - fs_prep_san_write: fsfilt_tmpfs_prep_san_write, - fs_write_record: fsfilt_tmpfs_write_record, - fs_read_record: fsfilt_tmpfs_read_record, - fs_setattr: fsfilt_tmpfs_setattr, - fs_setup: fsfilt_tmpfs_setup, -}; - -static int __init -fsfilt_tmpfs_init(void) -{ - int rc; - - trans_cache = kmem_cache_create("fsfilt_tmpfs_trans", - sizeof(struct tmpfs_trans), - 0, 0, NULL, NULL); - if (!trans_cache) { - CERROR("error allocating fsfilt transaction handle cache\n"); - GOTO(out, rc = -ENOMEM); - } - - if ((rc = fsfilt_register_ops(&fsfilt_tmpfs_ops))) - kmem_cache_destroy(trans_cache); -out: - return rc; -} - -static void __exit -fsfilt_tmpfs_exit(void) -{ - int rc; - - fsfilt_unregister_ops(&fsfilt_tmpfs_ops); - rc = kmem_cache_destroy(trans_cache); - - if (rc || atomic_read(&trans_count)) { - CERROR("can't free fsfilt trans cache: count %d, rc = %d\n", - atomic_read(&trans_count), rc); - } -} - -module_init(fsfilt_tmpfs_init); -module_exit(fsfilt_tmpfs_exit); - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre tmpfs Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 40c49f3..9e5f972 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -655,9 +655,6 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, inode->i_ino, inode->i_generation); } else { struct lustre_handle child_ino_lockh; - struct ldlm_res_id child_res_id = - { .name = { inode->i_ino, 0 } }; - int lock_flags = 0; CDEBUG(D_INODE, "created ino %lu with gen %x\n", inode->i_ino, inode->i_generation); @@ -668,12 +665,7 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, * in unlink, to avoid replay problems if this reply * makes it out to the client but the unlink's does not. * See bug 2029 for more detail.*/ - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, - child_res_id, LDLM_PLAIN, NULL, - LCK_EX, &lock_flags, - mds_blocking_ast, - ldlm_completion_ast, NULL, NULL, - NULL, 0, NULL, &child_ino_lockh); + rc = mds_lock_new_child(obd, inode, &child_ino_lockh); if (rc != ELDLM_OK) { CERROR("error locking for unlink/create sync: " "%d\n", rc); diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index 5e2c305..e3351a6 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -88,6 +88,8 @@ unsigned int obd_timeout = 100; char obd_lustre_upcall[128] = "DEFAULT"; /* or NONE or /full/path/to/upcall */ unsigned int obd_sync_filter; /* = 0, don't sync by default */ +DECLARE_WAIT_QUEUE_HEAD(obd_race_waitq); + #ifdef __KERNEL__ /* opening /dev/obd */ static int obd_class_open(struct inode * inode, struct file * file) @@ -375,6 +377,7 @@ void *obd_psdev = NULL; EXPORT_SYMBOL(obd_dev); EXPORT_SYMBOL(obdo_cachep); EXPORT_SYMBOL(obd_fail_loc); +EXPORT_SYMBOL(obd_race_waitq); EXPORT_SYMBOL(obd_timeout); EXPORT_SYMBOL(obd_lustre_upcall); EXPORT_SYMBOL(obd_sync_filter); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 119ca99..a90a6e1 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -138,7 +138,7 @@ void lprocfs_remove(struct proc_dir_entry *root) LASSERT(root != NULL); parent = root->parent; LASSERT(parent != NULL); - + while (1) { while (temp->subdir != NULL) temp = temp->subdir; diff --git a/lustre/obdclass/sysctl.c b/lustre/obdclass/sysctl.c index f474985..8c93a48 100644 --- a/lustre/obdclass/sysctl.c +++ b/lustre/obdclass/sysctl.c @@ -54,11 +54,14 @@ enum { OBD_SYNCFILTER, /* XXX temporary, as we play with sync osts.. */ }; +int proc_fail_loc(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp); + static ctl_table obd_table[] = { {OBD_FAIL_LOC, "fail_loc", &obd_fail_loc, sizeof(int), 0644, NULL, &proc_dointvec}, {OBD_TIMEOUT, "timeout", &obd_timeout, sizeof(int), 0644, NULL, - &proc_dointvec}, + &proc_fail_loc}, /* XXX need to lock so we avoid update races with recovery upcall! */ {OBD_UPCALL, "upcall", obd_lustre_upcall, 128, 0644, NULL, &proc_dostring, &sysctl_string }, @@ -88,3 +91,15 @@ void obd_sysctl_clean (void) obd_table_header = NULL; #endif } + +int proc_fail_loc(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int rc; + int old_fail_loc = obd_fail_loc; + + rc = proc_dointvec(table,write,filp,buffer,lenp); + if (old_fail_loc != obd_fail_loc) + wake_up(&obd_race_waitq); + return rc; +} diff --git a/lustre/scripts/lmake b/lustre/scripts/lmake index c114961..8a5143e 100755 --- a/lustre/scripts/lmake +++ b/lustre/scripts/lmake @@ -359,8 +359,8 @@ install_kernel() mkdir -p "$DESTDIR/boot/efi/redhat" install -m 755 vmlinux "$DESTDIR/boot/efi/redhat/vmlinux-${FULL_VERSION}" install -m 755 vmlinuz "$DESTDIR/boot/efi/redhat/vmlinuz-${FULL_VERSION}" - ln -sf "efi/vmlinux-${FULL_VERSION}" "$DESTDIR/boot/vmlinux-${FULL_VERSION}" - ln -sf "efi/vmlinuz-${FULL_VERSION}" "$DESTDIR/boot/vmlinuz-${FULL_VERSION}" + ln -sf "efi/redhat/vmlinux-${FULL_VERSION}" "$DESTDIR/boot/vmlinux-${FULL_VERSION}" + ln -sf "efi/redhat/vmlinuz-${FULL_VERSION}" "$DESTDIR/boot/vmlinuz-${FULL_VERSION}" ;; *) cp vmlinuz "$DESTDIR/boot/vmlinuz-${FULL_VERSION}" diff --git a/lustre/scripts/lustre-kernel-2.4.spec.in b/lustre/scripts/lustre-kernel-2.4.spec.in index 0999212..3fef13d 100644 --- a/lustre/scripts/lustre-kernel-2.4.spec.in +++ b/lustre/scripts/lustre-kernel-2.4.spec.in @@ -129,7 +129,7 @@ Release: %{release}%{?targetboard:%{targetboard}}%{?debuglevel_1:.dbg} %define KVERREL %{PACKAGE_VERSION}-%{kextraver}%{?targetboard:%{targetboard}}%{?debuglevel_1:.dbg} License: GPL Group: System Environment/Kernel -ExclusiveArch: %{all_x86} x86_64 +ExclusiveArch: %{all_x86} x86_64 ia64 ExclusiveOS: Linux Obsoletes: kernel-modules, kernel-sparc Provides: kernel = %{version} diff --git a/lustre/scripts/lustre.spec.in b/lustre/scripts/lustre.spec.in index 3b9c6dc..6a82bb0 100644 --- a/lustre/scripts/lustre.spec.in +++ b/lustre/scripts/lustre.spec.in @@ -1,5 +1,5 @@ # lustre.spec -%define version 1.2.0.4 +%define version 1.2.0.5 %define kversion @LINUXRELEASE@ %define linuxdir @LINUX@ %define enable_doc @ENABLE_DOC@ diff --git a/lustre/tests/.RC_CURRENT.tag b/lustre/tests/.RC_CURRENT.tag index 9cb6c4a..c64690b 100644 --- a/lustre/tests/.RC_CURRENT.tag +++ b/lustre/tests/.RC_CURRENT.tag @@ -1 +1 @@ -RC_1_3_0_2 +RC_1_3_0_4 diff --git a/lustre/tests/ltmpfs-sanity.sh b/lustre/tests/ltmpfs-sanity.sh deleted file mode 100755 index a6d921e..0000000 --- a/lustre/tests/ltmpfs-sanity.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Currently the following tests do not pass: -# 47 - due to unresolvable symbol in UML local libc -# 52a, 52b - due to not implemented ioctl() in tmpfs -# 57a - due to inability to be supplied to tmpfs -# 56 - due to some unknown reason yet. - -NAME=local FSTYPE=tmpfs MDSDEV=tmpfs OSTDEV=tmpfs sh llmount.sh && \ -START=: CLEAN=: EXCEPT="47 52a 52b 56 57a" sh sanity.sh diff --git a/lustre/tests/ltmpfs.sh b/lustre/tests/ltmpfs.sh deleted file mode 100755 index c561572..0000000 --- a/lustre/tests/ltmpfs.sh +++ /dev/null @@ -1 +0,0 @@ -NAME=local FSTYPE=tmpfs MDSDEV=tmpfs OSTDEV=tmpfs sh llmount.sh diff --git a/lustre/tests/replay-single.sh b/lustre/tests/replay-single.sh index ef241b2..8b1c6e3 100755 --- a/lustre/tests/replay-single.sh +++ b/lustre/tests/replay-single.sh @@ -854,6 +854,16 @@ test_43() { } run_test 43 "mds osc import failure during recovery; don't LBUG" +test_44() { + mdcdev=`awk '/mds_svc_MNT/ {print $1}' < /proc/fs/lustre/devices` + do_facet mds "sysctl -w lustre.fail_loc=0x80000701" + $LCTL --device $mdcdev recover + df $MOUNT + do_facet mds "sysctl -w lustre.fail_loc=0" + return 0 +} +run_test 44 "race in target handle connect" + equals_msg test complete, cleaning up $CLEANUP -- 1.8.3.1