Whamcloud - gitweb
Update b1_2 from HEAD (20040315_1445)
authoradilger <adilger>
Mon, 15 Mar 2004 21:58:20 +0000 (21:58 +0000)
committeradilger <adilger>
Mon, 15 Mar 2004 21:58:20 +0000 (21:58 +0000)
b=2898, b=2926

15 files changed:
lustre/ChangeLog
lustre/include/linux/obd_support.h
lustre/ldlm/ldlm_lib.c
lustre/lvfs/fsfilt_tmpfs.c [deleted file]
lustre/mds/mds_reint.c
lustre/obdclass/class_obd.c
lustre/obdclass/lprocfs_status.c
lustre/obdclass/sysctl.c
lustre/scripts/lmake
lustre/scripts/lustre-kernel-2.4.spec.in
lustre/scripts/lustre.spec.in
lustre/tests/.RC_CURRENT.tag
lustre/tests/ltmpfs-sanity.sh [deleted file]
lustre/tests/ltmpfs.sh [deleted file]
lustre/tests/replay-single.sh

index 3d74556..f6eed85 100644 (file)
@@ -10,6 +10,8 @@ tbd  Cluster File Systems, Inc. <info@clusterfs.com>
        - 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. <info@clusterfs.com>
        * version 1.2.0
index 41fb301..c39cb6f 100644 (file)
@@ -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__
index bcaed00..0d514db 100644 (file)
@@ -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 (file)
index 808ee25..0000000
+++ /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 <umka@clusterfs.com>
- *
- *   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 <linux/fs.h>
-#include <linux/jbd.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <linux/quotaops.h>
-#include <linux/ext3_fs.h>
-#include <linux/ext3_jbd.h>
-#include <linux/version.h>
-#include <linux/kp30.h>
-#include <linux/lustre_fsfilt.h>
-#include <linux/obd.h>
-#include <linux/obd_class.h>
-#include <linux/module.h>
-#include <linux/shmem_fs.h>
-
-/* 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. <info@clusterfs.com>");
-MODULE_DESCRIPTION("Lustre tmpfs Filesystem Helper v0.1");
-MODULE_LICENSE("GPL");
index 40c49f3..9e5f972 100644 (file)
@@ -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);
index 5e2c305..e3351a6 100644 (file)
@@ -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);
index 119ca99..a90a6e1 100644 (file)
@@ -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;
index f474985..8c93a48 100644 (file)
@@ -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;
+}
index c114961..8a5143e 100755 (executable)
@@ -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}"
index 0999212..3fef13d 100644 (file)
@@ -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}
index 3b9c6dc..6a82bb0 100644 (file)
@@ -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/ltmpfs-sanity.sh b/lustre/tests/ltmpfs-sanity.sh
deleted file mode 100755 (executable)
index a6d921e..0000000
+++ /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 (executable)
index c561572..0000000
+++ /dev/null
@@ -1 +0,0 @@
-NAME=local FSTYPE=tmpfs MDSDEV=tmpfs OSTDEV=tmpfs sh llmount.sh
index ef241b2..8b1c6e3 100755 (executable)
@@ -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