Whamcloud - gitweb
Land b_smallfix onto HEAD (20040330_2312)
authoradilger <adilger>
Wed, 31 Mar 2004 18:18:04 +0000 (18:18 +0000)
committeradilger <adilger>
Wed, 31 Mar 2004 18:18:04 +0000 (18:18 +0000)
b=2947, b=2543, b=1557, b=2009

25 files changed:
lnet/libcfs/debug.c
lustre/ChangeLog
lustre/include/linux/lustre_lite.h
lustre/include/linux/obd.h
lustre/liblustre/rw.c
lustre/llite/Makefile.am
lustre/llite/Makefile.mk
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/rw.c
lustre/llite/rw24.c
lustre/llite/rw26.c
lustre/llite/special.c [new file with mode: 0644]
lustre/lov/lov_obd.c
lustre/mds/handler.c
lustre/obdecho/echo_client.c
lustre/obdfilter/filter.c
lustre/obdfilter/filter_lvb.c
lustre/osc/osc_request.c
lustre/portals/libcfs/debug.c
lustre/tests/llmountcleanup.sh
lustre/tests/recovery-small.sh
lustre/tests/sanity.sh
lustre/tests/test-framework.sh

index 95d5be7..8043ac4 100644 (file)
@@ -592,7 +592,7 @@ int portals_debug_init(unsigned long bufsize)
         debug_buf = vmalloc(bufsize + DEBUG_OVERFLOW);
         if (debug_buf == NULL)
                 return -ENOMEM;
-        memset(debug_buf, 0, debug_size);
+        memset(debug_buf, 0, bufsize + DEBUG_OVERFLOW);
         debug_wrapped = 0;
 
         //printk(KERN_INFO "Portals: allocated %lu byte debug buffer at %p.\n",
index bc3cab9..343b989 100644 (file)
@@ -4,6 +4,10 @@ tbd  Cluster File Systems, Inc. <info@clusterfs.com>
        - clear page cache after eviction  (2766)
        - don't copy lvb into (possibly NULL) reply on error (2983)
        - don't deref dentry after dput, don't free lvb on error (2922)
+       - use the kms to determine writeback rpc length (2947)
+       - update client's i_blocks count via lvb messages (2543)
+       - handle intent open/close of special files properly (1557)
+       - mount MDS with errors=remount-ro, like obdfilter (2009)
        * miscellania
        - allow default OST striping configuration per directory (1414)
 
index 5c6be08..1c66b53 100644 (file)
@@ -88,6 +88,11 @@ struct ll_inode_info {
         struct list_head        lli_pending_write_llaps;
 
         struct list_head        lli_close_item;
+
+        struct file_operations *ll_save_ifop;
+        struct file_operations *ll_save_ffop;
+        struct file_operations *ll_save_wfop;
+        struct file_operations *ll_save_wrfop;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
         struct inode            lli_vfs_inode;
 #endif
index c5de023..354ce2f 100644 (file)
@@ -61,6 +61,7 @@ struct lov_oinfo {                 /* per-stripe data structure */
         __u64 loi_kms;             /* known minimum size */
         __u64 loi_rss;             /* recently seen size */
         __u64 loi_mtime;           /* recently seen mtime */
+        __u64 loi_blocks;          /* recently seen blocks */
 };
 
 static inline void loi_init(struct lov_oinfo *loi)
@@ -123,7 +124,7 @@ struct obd_async_page_ops {
         int  (*ap_make_ready)(void *data, int cmd);
         int  (*ap_refresh_count)(void *data, int cmd);
         void (*ap_fill_obdo)(void *data, int cmd, struct obdo *oa);
-        void (*ap_completion)(void *data, int cmd, int rc);
+        void (*ap_completion)(void *data, int cmd, struct obdo *oa, int rc);
 };
 
 /* the `oig' is passed down from a caller of obd rw methods.  the callee
index 546ab73..ae70a99 100644 (file)
@@ -388,7 +388,7 @@ static void llu_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
 }
 
 /* called for each page in a completed rpc.*/
-static void llu_ap_completion(void *data, int cmd, int rc)
+static void llu_ap_completion(void *data, int cmd, struct obdo *oa, int rc)
 {
         struct ll_async_page *llap;
         struct page *page;
index 18c3a3a..96b59e6 100644 (file)
@@ -10,7 +10,7 @@ modulefs_DATA = llite.o
 EXTRA_PROGRAMS = llite
 
 COMMON_SRC = dcache.c dir.c file.c llite_close.c llite_lib.c llite_nfs.c rw.c \
-             lproc_llite.c namei.c symlink.c llite_internal.h
+             lproc_llite.c namei.c special.c symlink.c llite_internal.h
 
 if LINUX25
 llite_SOURCES = $(COMMON_SRC) rw26.c super25.c
index 40345b6..06dd10e 100644 (file)
@@ -8,4 +8,4 @@ include $(src)/../portals/Kernelenv
 obj-y += llite.o
 llite-objs := llite_lib.o dcache.o super.o rw.o \
        super25.o file.o dir.o symlink.o namei.o lproc_llite.o \
-       rw26.o llite_nfs.o llite_close.o
+       rw26.o llite_nfs.o llite_close.o special.o
index 21fcfce..6e867ff 100644 (file)
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 #include <linux/lustre_compat25.h>
 #endif
-
 #include "llite_internal.h"
 
-static int ll_mdc_close(struct obd_export *mdc_exp, struct inode *inode,
+int ll_mdc_close(struct obd_export *mdc_exp, struct inode *inode,
                         struct file *file)
 {
         struct ll_file_data *fd = file->private_data;
@@ -140,7 +139,7 @@ static int ll_intent_file_open(struct file *file, void *lmm,
         RETURN(rc);
 }
 
-static int ll_local_open(struct file *file, struct lookup_intent *it)
+int ll_local_open(struct file *file, struct lookup_intent *it)
 {
         struct ptlrpc_request *req = it->d.lustre.it_data;
         struct ll_inode_info *lli = ll_i2info(file->f_dentry->d_inode);
@@ -612,6 +611,7 @@ static int ll_glimpse_callback(struct ldlm_lock *lock, void *reqp)
 }
 
 __u64 lov_merge_size(struct lov_stripe_md *lsm, int kms);
+__u64 lov_merge_blocks(struct lov_stripe_md *lsm);
 __u64 lov_merge_mtime(struct lov_stripe_md *lsm, __u64 current_time);
 
 /* NB: lov_merge_size will prefer locally cached writes if they extend the
@@ -637,9 +637,11 @@ int ll_glimpse_size(struct inode *inode, struct ost_lvb *lvb)
         }
 
         lvb->lvb_size = lov_merge_size(lli->lli_smd, 0);
+        inode->i_blocks = lov_merge_blocks(lli->lli_smd);
         //inode->i_mtime = lov_merge_mtime(lli->lli_smd, inode->i_mtime);
 
-        CDEBUG(D_DLMTRACE, "glimpse: size: "LPU64"\n", lvb->lvb_size);
+        CDEBUG(D_DLMTRACE, "glimpse: size: "LPU64", blocks: "LPU64"\n",
+               lvb->lvb_size, lvb->lvb_blocks);
 
         obd_cancel(sbi->ll_osc_exp, lli->lli_smd, LCK_PR, &lockh);
 
@@ -1453,12 +1455,3 @@ struct inode_operations ll_file_inode_operations = {
 #endif
 };
 
-struct inode_operations ll_special_inode_operations = {
-        setattr_raw:    ll_setattr_raw,
-        setattr:        ll_setattr,
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        getattr_it:     ll_getattr,
-#else
-        revalidate_it:  ll_inode_revalidate_it,
-#endif
-};
index 4f1277c..b0d2fa3 100644 (file)
@@ -147,13 +147,7 @@ void ll_prepare_mdc_op_data(struct mdc_op_data *,
 int ll_prepare_write(struct file *, struct page *, unsigned from, unsigned to);
 int ll_commit_write(struct file *, struct page *, unsigned from, unsigned to);
 void ll_inode_fill_obdo(struct inode *inode, int cmd, struct obdo *oa);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#define ll_ap_completion ll_ap_completion_24
-void ll_ap_completion_24(void *data, int cmd, int rc);
-#else
-#define ll_ap_completion ll_ap_completion_26
-void ll_ap_completion_26(void *data, int cmd, int rc);
-#endif
+void ll_ap_completion(void *data, int cmd, struct obdo *oa, int rc);
 void ll_removepage(struct page *page);
 int ll_sync_page(struct page *page);
 int ll_readpage(struct file *file, struct page *page);
@@ -166,7 +160,6 @@ void ll_truncate(struct inode *inode);
 /* llite/file.c */
 extern struct file_operations ll_file_operations;
 extern struct inode_operations ll_file_inode_operations;
-extern struct inode_operations ll_special_inode_operations;
 extern int ll_inode_revalidate_it(struct dentry *, struct lookup_intent *);
 int ll_extent_lock(struct ll_file_data *, struct inode *,
                    struct lov_stripe_md *, int mode, ldlm_policy_data_t *,
@@ -177,6 +170,9 @@ int ll_file_open(struct inode *inode, struct file *file);
 int ll_file_release(struct inode *inode, struct file *file);
 int ll_lsm_getattr(struct obd_export *, struct lov_stripe_md *, struct obdo *);
 int ll_glimpse_size(struct inode *inode, struct ost_lvb *lvb);
+int ll_local_open(struct file *file, struct lookup_intent *it);
+int ll_mdc_close(struct obd_export *mdc_exp, struct inode *inode,
+                 struct file *file);
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 int ll_getattr(struct vfsmount *mnt, struct dentry *de,
                struct lookup_intent *it, struct kstat *stat);
@@ -225,6 +221,16 @@ __u32 get_uuid2int(const char *name, int len);
 struct dentry *ll_fh_to_dentry(struct super_block *sb, __u32 *data, int len,
                                int fhtype, int parent);
 int ll_dentry_to_fh(struct dentry *, __u32 *datap, int *lenp, int need_parent);
+
+/* llite/special.c */
+extern struct inode_operations ll_special_inode_operations;
+extern struct file_operations ll_special_chr_inode_fops;
+extern struct file_operations ll_special_chr_file_fops;
+extern struct file_operations ll_special_blk_inode_fops;
+extern struct file_operations ll_special_fifo_inode_fops;
+extern struct file_operations ll_special_fifo_file_fops;
+extern struct file_operations ll_special_sock_inode_fops;
+
 /* llite/symlink.c */
 extern struct inode_operations ll_fast_symlink_inode_operations;
 
index 2aad640..89dcec9 100644 (file)
@@ -1156,10 +1156,26 @@ void ll_read_inode2(struct inode *inode, void *opaque)
         } else {
                 inode->i_op = &ll_special_inode_operations;
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#warning "need to fix this for 2.6 also"
                 init_special_inode(inode, inode->i_mode,
                                    kdev_t_to_nr(inode->i_rdev));
 #else
                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
+
+                lli->ll_save_ifop = inode->i_fop;
+                if (S_ISCHR(inode->i_mode))
+                        inode->i_fop = &ll_special_chr_inode_fops;
+                else if (S_ISBLK(inode->i_mode))
+                        inode->i_fop = &ll_special_blk_inode_fops;
+                else if (S_ISFIFO(inode->i_mode))
+                        inode->i_fop = &ll_special_fifo_inode_fops;
+                else if (S_ISSOCK(inode->i_mode))
+                        inode->i_fop = &ll_special_sock_inode_fops;
+                CWARN("saved %p, replaced with %p\n", lli->ll_save_ifop,
+                      inode->i_fop);
+                if (lli->ll_save_ifop->owner)
+                        CWARN("%p has owner %p\n", lli->ll_save_ifop,
+                              lli->ll_save_ifop->owner);
 #endif
                 EXIT;
         }
index 11e6df8..01ad4a1 100644 (file)
@@ -208,21 +208,6 @@ int ll_prepare_write(struct file *file, struct page *page, unsigned from,
         return rc;
 }
 
-int ll_write_count(struct page *page)
-{
-        struct inode *inode = page->mapping->host;
-
-        /* catch race with truncate */
-        if (((loff_t)page->index << PAGE_SHIFT) >= inode->i_size)
-                return 0;
-
-        /* catch sub-page write at end of file */
-        if (((loff_t)page->index << PAGE_SHIFT) + PAGE_SIZE > inode->i_size)
-                return inode->i_size % PAGE_SIZE;
-
-        return PAGE_SIZE;
-}
-
 struct ll_async_page *llap_from_cookie(void *cookie)
 {
         struct ll_async_page *llap = cookie;
@@ -264,9 +249,26 @@ static int ll_ap_make_ready(void *data, int cmd)
         RETURN(0);
 }
 
+/* We have two reasons for giving llite the opportunity to change the 
+ * write length of a given queued page as it builds the RPC containing
+ * the page: 
+ *
+ * 1) Further extending writes may have landed in the page cache
+ *    since a partial write first queued this page requiring us
+ *    to write more from the page cache.
+ * 2) We might have raced with truncate and want to avoid performing
+ *    write RPCs that are just going to be thrown away by the 
+ *    truncate's punch on the storage targets.
+ *
+ * The kms serves these purposes as it is set at both truncate and extending
+ * writes.
+ */
 static int ll_ap_refresh_count(void *data, int cmd)
 {
         struct ll_async_page *llap;
+        struct lov_stripe_md *lsm;
+        struct page *page;
+        __u64 kms;
         ENTRY;
 
         /* readpage queues with _COUNT_STABLE, shouldn't get here. */
@@ -276,7 +278,19 @@ static int ll_ap_refresh_count(void *data, int cmd)
         if (IS_ERR(llap))
                 RETURN(PTR_ERR(llap));
 
-        return ll_write_count(llap->llap_page);
+        page = llap->llap_page;
+        lsm = ll_i2info(page->mapping->host)->lli_smd;
+        kms = lov_merge_size(lsm, 1);
+
+        /* catch race with truncate */
+        if (((__u64)page->index << PAGE_SHIFT) >= kms)
+                return 0;
+
+        /* catch sub-page write at end of file */
+        if (((__u64)page->index << PAGE_SHIFT) + PAGE_SIZE > kms)
+                return kms % PAGE_SIZE;
+
+        return PAGE_SIZE;
 }
 
 void ll_inode_fill_obdo(struct inode *inode, int cmd, struct obdo *oa)
@@ -461,6 +475,50 @@ out:
         RETURN(rc);
 }
 
+/* called for each page in a completed rpc.*/
+void ll_ap_completion(void *data, int cmd, struct obdo *oa, int rc)
+{
+        struct ll_async_page *llap;
+        struct page *page;
+        ENTRY;
+
+        llap = llap_from_cookie(data);
+        if (IS_ERR(llap)) {
+                EXIT;
+                return;
+        }
+
+        page = llap->llap_page;
+        LASSERT(PageLocked(page));
+
+        LL_CDEBUG_PAGE(D_PAGE, page, "completing cmd %d with %d\n", cmd, rc);
+
+        if (rc == 0)  {
+                if (cmd == OBD_BRW_READ) {
+                        if (!llap->llap_defer_uptodate)
+                                SetPageUptodate(page);
+                } else {
+                        llap->llap_write_queued = 0;
+                }
+                ClearPageError(page);
+        } else {
+                if (cmd == OBD_BRW_READ)
+                        llap->llap_defer_uptodate = 0;
+                SetPageError(page);
+        }
+
+
+        unlock_page(page);
+
+        if (0 && cmd == OBD_BRW_WRITE) {
+                llap_write_complete(page->mapping->host, llap);
+                ll_try_done_writing(page->mapping->host);
+        }
+
+        page_cache_release(page);
+        EXIT;
+}
+
 /* the kernel calls us here when a page is unhashed from the page cache.
  * the page will be locked and the kernel is holding a spinlock, so
  * we need to be careful.  we're just tearing down our book-keeping
index 22ffe38..71e194d 100644 (file)
 #include "llite_internal.h"
 #include <linux/lustre_compat25.h>
 
-/* called for each page in a completed rpc.*/
-void ll_ap_completion_24(void *data, int cmd, int rc)
-{
-        struct ll_async_page *llap;
-        struct page *page;
-        ENTRY;
-
-        llap = llap_from_cookie(data);
-        if (IS_ERR(llap)) {
-                EXIT;
-                return;
-        }
-
-        page = llap->llap_page;
-        LASSERT(PageLocked(page));
-
-        LL_CDEBUG_PAGE(D_PAGE, page, "completing cmd %d with %d\n", cmd, rc);
-
-        if (rc == 0)  {
-                if (cmd == OBD_BRW_READ) {
-                        if (!llap->llap_defer_uptodate)
-                                SetPageUptodate(page);
-                } else {
-                        llap->llap_write_queued = 0;
-                }
-                ClearPageError(page);
-        } else {
-                if (cmd == OBD_BRW_READ)
-                        llap->llap_defer_uptodate = 0;
-                SetPageError(page);
-        }
-
-
-        unlock_page(page);
-
-        if (0 && cmd == OBD_BRW_WRITE) {
-                llap_write_complete(page->mapping->host, llap);
-                ll_try_done_writing(page->mapping->host);
-        }
-
-        page_cache_release(page);
-        EXIT;
-}
-
 static int ll_writepage_24(struct page *page)
 {
         struct inode *inode = page->mapping->host;
index c8c7cbb..d048848 100644 (file)
 #include "llite_internal.h"
 #include <linux/lustre_compat25.h>
 
-/* called for each page in a completed rpc.*/
-void ll_ap_completion_26(void *data, int cmd, int rc)
-{
-        struct ll_async_page *llap;
-        struct page *page;
-
-        llap = llap_from_cookie(data);
-        if (IS_ERR(llap)) {
-                EXIT;
-                return;
-        }
-
-        page = llap->llap_page;
-        LASSERT(PageLocked(page));
-
-        if (rc == 0)  {
-                if (cmd == OBD_BRW_READ) {
-                        if (!llap->llap_defer_uptodate)
-                                SetPageUptodate(page);
-                } else {
-                        llap->llap_write_queued = 0;
-                }
-        } else {
-                SetPageError(page);
-        }
-
-        LL_CDEBUG_PAGE(D_PAGE, page, "io complete, unlocking\n");
-
-        unlock_page(page);
-
-        if (0 && cmd == OBD_BRW_WRITE) {
-                llap_write_complete(page->mapping->host, llap);
-                ll_try_done_writing(page->mapping->host);
-        }
-
-        page_cache_release(page);
-}
-
 static int ll_writepage_26(struct page *page, struct writeback_control *wbc)
 {
         struct inode *inode = page->mapping->host;
diff --git a/lustre/llite/special.c b/lustre/llite/special.c
new file mode 100644 (file)
index 0000000..7243811
--- /dev/null
@@ -0,0 +1,382 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Special file handling for Lustre.
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Wang Di <wangdi@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@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_LLITE
+#include <linux/lustre_dlm.h>
+#include <linux/lustre_lite.h>
+#include <linux/pagemap.h>
+#include <linux/file.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <linux/lustre_compat25.h>
+#endif
+#include <asm/poll.h>
+#include "llite_internal.h"
+
+#define INODE_OPS 1
+#define FILE_OPS 2
+
+static struct file_operations **get_save_fops(struct file* filp, int mode)
+{
+        struct inode *inode = filp->f_dentry->d_inode;
+        struct ll_inode_info *lli = ll_i2info(inode);
+
+        if (mode == INODE_OPS) {
+                return &(lli->ll_save_ifop);
+        } else if (mode == FILE_OPS) {
+                if (S_ISFIFO(inode->i_mode)) {
+                        switch (filp->f_mode) {
+                        case 1: /*O_RDONLY*/
+                                return &(lli->ll_save_ffop);
+                        case 2: /*O_WRONLY*/
+                                return &(lli->ll_save_wfop);
+                        case 3: /* O_RDWR */
+                                return &(lli->ll_save_wrfop);
+                        default:
+                                return NULL;
+                        }
+                }
+                return &(lli->ll_save_ffop);
+        } else {
+                CERROR("invalid special file ops %d\n", mode);
+                LBUG();
+        }
+}
+
+static void save_fops(struct file *filp, struct inode *inode,
+                      struct file_operations *sfops)
+{
+        if (sfops != filp->f_op) {
+                struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+
+                *pfop = filp->f_op;
+                if (S_ISCHR(inode->i_mode))
+                        filp->f_op = &ll_special_chr_file_fops;
+                else if (S_ISFIFO(inode->i_mode))
+                        filp->f_op = &ll_special_fifo_file_fops;
+
+                CWARN("saved %p, replaced with %p\n", *pfop, filp->f_op);
+                if ((*pfop)->owner)
+                        CWARN("%p has owner %p\n", *pfop,(*pfop)->owner);
+        }
+}
+
+static ssize_t ll_special_file_read(struct file *filp, char *buf,
+                                    size_t count, loff_t *ppos)
+{
+        struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->read)
+                rc = (*pfop)->read(filp, buf, count, ppos);
+
+        RETURN(rc);
+}
+
+static ssize_t ll_special_file_write(struct file *filp, const char *buf,
+                                     size_t count, loff_t *ppos)
+{
+        struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->write)
+                rc = (*pfop)->write(filp, buf, count, ppos);
+
+        RETURN(rc);
+}
+
+static int ll_special_file_ioctl(struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg)
+{
+        struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+        int rc = -ENOTTY;
+
+        if (pfop && *pfop && (*pfop)->ioctl) {
+                struct file_operations *sfops = filp->f_op;
+
+                rc = (*pfop)->ioctl(inode, filp, cmd, arg);
+                save_fops(filp, inode, sfops);
+        }
+        RETURN(rc);
+}
+
+static loff_t ll_special_file_seek(struct file *filp, loff_t offset, int origin)
+{
+        struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+        int rc = 0;
+
+        if (pfop && *pfop && (*pfop)->llseek)
+                rc = (*pfop)->llseek(filp, offset, origin);
+        else
+                rc = default_llseek(filp, offset, origin);
+
+        RETURN(rc);
+}
+
+
+#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
+
+static unsigned int ll_special_file_poll(struct file *filp,
+                                         struct poll_table_struct *poll_table)
+{
+        struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+        int rc = DEFAULT_POLLMASK;
+
+        if (pfop && *pfop && (*pfop)->poll)
+                rc = (*pfop)->poll(filp, poll_table);
+
+        RETURN(rc);
+}
+
+static int ll_special_file_open(struct inode *inode, struct file *filp)
+{
+        struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->open)
+                rc = (*pfop)->open(inode, filp);
+
+        RETURN(rc);
+}
+
+static ssize_t ll_special_read(struct file *filp, char *buf, size_t count,
+                               loff_t *ppos)
+{
+        struct file_operations **pfop = get_save_fops(filp, INODE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->read)
+                rc = (*pfop)->read(filp, buf, count, ppos);
+
+        RETURN(rc);
+}
+
+static ssize_t ll_special_write(struct file *filp, const char *buf,
+                                size_t count, loff_t *ppos)
+{
+        struct file_operations **pfop = get_save_fops(filp, INODE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->write)
+                rc = (*pfop)->write(filp, buf, count, ppos);
+
+        RETURN(rc);
+}
+
+static int ll_special_ioctl(struct inode *inode, struct file *filp,
+                            unsigned int cmd, unsigned long arg)
+{
+        struct file_operations **pfop = get_save_fops(filp, INODE_OPS);
+        int rc = -ENOTTY;
+
+        if (pfop && *pfop && (*pfop)->ioctl) {
+                struct file_operations *sfops = filp->f_op;
+
+                rc = (*pfop)->ioctl(inode, filp, cmd, arg);
+                /* sometimes, file_operations will be changed in ioctl */
+                save_fops(filp, inode, sfops);
+        }
+
+        RETURN(rc);
+}
+
+static int ll_special_mmap(struct file * filp, struct vm_area_struct * vma)
+{
+        struct file_operations **pfop = get_save_fops(filp, INODE_OPS);
+        int rc = -ENODEV;
+
+        if (pfop && *pfop && (*pfop)->mmap)
+                rc = (*pfop)->mmap(filp, vma);
+
+        RETURN(rc);
+}
+
+static loff_t ll_special_seek(struct file *filp, loff_t offset, int origin)
+{
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        int    rc = 0;
+
+        if (pfop && *pfop && (*pfop)->llseek)
+                rc = (*pfop)->llseek(filp, offset, origin);
+        else
+                rc = default_llseek(filp, offset, origin);
+
+        RETURN(rc);
+}
+
+static int ll_special_fsync(struct file *filp, struct dentry *dentry, int data)
+{
+        struct file_operations **pfop = get_save_fops(filp, INODE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->fsync)
+                rc = (*pfop)->fsync(filp, dentry, data);
+
+        RETURN(rc);
+}
+
+static int ll_special_file_fasync(int fd, struct file *filp, int on)
+{
+        struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->fasync)
+                rc = (*pfop)->fasync(fd, filp, on);
+
+        RETURN(rc);
+}
+
+static int ll_special_release_internal(struct inode *inode, struct file *filp,
+                                       int mode)
+{
+       struct file_operations **pfop = get_save_fops(filp, mode);
+       struct ll_sb_info *sbi = ll_i2sbi(inode);
+       int rc = 0, err;
+       ENTRY;
+
+        if (pfop && *pfop) {
+                if ((*pfop)->release)
+                        rc = (*pfop)->release(inode, filp);
+                /* FIXME fops_put */
+        }
+
+        lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
+
+        err = ll_mdc_close(sbi->ll_mdc_exp, inode, filp);
+        if (err && rc == 0)
+                rc = err;
+
+        RETURN(rc);
+}
+
+static int ll_special_open(struct inode *inode, struct file *filp)
+{
+        struct file_operations **pfop = get_save_fops(filp, INODE_OPS);
+        struct file_operations *sfops = filp->f_op;
+        struct ptlrpc_request *req;
+        struct lookup_intent *it;
+        int rc = -EINVAL, err;
+        ENTRY;
+
+        if (pfop && *pfop) {
+                /* FIXME fops_get */
+                if ((*pfop)->open) {
+                        rc = (*pfop)->open(inode, filp);
+
+                        /* sometimes file_operations will be changed in open */
+                        save_fops(filp, inode, sfops);
+                }
+        }
+
+        lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
+
+        it = filp->f_it;
+
+        err = ll_local_open(filp, it);
+        if (rc != 0) {
+                CERROR("error opening special file: rc %d", rc);
+                ll_mdc_close(ll_i2sbi(inode)->ll_mdc_exp, inode, filp);
+        } else if (err) {
+                if (pfop && *pfop && (*pfop)->release)
+                        (*pfop)->release(inode, filp);
+                /* FIXME fops_put */
+                rc = err;
+        }
+
+        req = it->d.lustre.it_data;
+        if (req)
+                ptlrpc_req_finished(req);
+
+        RETURN(rc);
+}
+
+static int ll_special_release(struct inode *inode, struct file *filp)
+{
+        return ll_special_release_internal(inode, filp, INODE_OPS);
+}
+
+static int ll_special_file_release(struct inode *inode, struct file *filp)
+{
+        return ll_special_release_internal(inode, filp, FILE_OPS);
+}
+
+struct inode_operations ll_special_inode_operations = {
+        setattr_raw:    ll_setattr_raw,
+        setattr:        ll_setattr,
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+        getattr_it:     ll_getattr,
+#else
+        revalidate_it:  ll_inode_revalidate_it,
+#endif
+};
+
+struct file_operations ll_special_chr_inode_fops = {
+        owner:          THIS_MODULE,
+        open:           ll_special_open,
+};
+
+struct file_operations ll_special_blk_inode_fops = {
+        owner:          THIS_MODULE,
+        read:           ll_special_read,
+        write:          ll_special_write,
+        ioctl:          ll_special_ioctl,
+        open:           ll_special_open,
+        release:        ll_special_release,
+        mmap:           ll_special_mmap,
+        llseek:         ll_special_seek,
+        fsync:          ll_special_fsync,
+};
+
+struct file_operations ll_special_fifo_inode_fops = {
+        owner:          THIS_MODULE,
+        open:           ll_special_open,
+};
+
+struct file_operations ll_special_sock_inode_fops = {
+        owner:          THIS_MODULE,
+        open:           ll_special_open
+};
+
+struct file_operations ll_special_chr_file_fops = {
+        owner:          THIS_MODULE,
+       llseek:         ll_special_file_seek,
+       read:           ll_special_file_read,
+       write:          ll_special_file_write,
+       poll:           ll_special_file_poll,
+       ioctl:          ll_special_file_ioctl,
+       open:           ll_special_file_open,
+       release:        ll_special_file_release,
+       fasync:         ll_special_file_fasync,
+};
+
+struct file_operations ll_special_fifo_file_fops = {
+        owner:          THIS_MODULE,
+       llseek:         ll_special_file_seek,
+       read:           ll_special_file_read,
+       write:          ll_special_file_write,
+       poll:           ll_special_file_poll,
+       ioctl:          ll_special_file_ioctl,
+       open:           ll_special_file_open,
+       release:        ll_special_file_release,
+};
index b5a2773..9a83e4d 100644 (file)
@@ -1808,7 +1808,8 @@ static void lov_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
         /* XXX woah, shouldn't we be altering more here?  size? */
         oa->o_id = lap->lap_loi_id;
 }
-static void lov_ap_completion(void *data, int cmd, int rc)
+
+static void lov_ap_completion(void *data, int cmd, struct obdo *oa, int rc)
 {
         struct lov_async_page *lap = lap_from_cookie(data);
         if (IS_ERR(lap))
@@ -1817,7 +1818,7 @@ static void lov_ap_completion(void *data, int cmd, int rc)
         /* in a raid1 regime this would down a count of many ios
          * in flight, onl calling the caller_ops completion when all
          * the raid1 ios are complete */
-        lap->lap_caller_ops->ap_completion(lap->lap_caller_data, cmd, rc);
+        lap->lap_caller_ops->ap_completion(lap->lap_caller_data, cmd, oa, rc);
 }
 
 static struct obd_async_page_ops lov_async_page_ops = {
@@ -2063,6 +2064,7 @@ static int lov_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
                 submd->lsm_oinfo->loi_kms_valid = loi->loi_kms_valid;
                 submd->lsm_oinfo->loi_rss = loi->loi_rss;
                 submd->lsm_oinfo->loi_kms = loi->loi_kms;
+                submd->lsm_oinfo->loi_blocks = loi->loi_blocks;
                 loi->loi_mtime = submd->lsm_oinfo->loi_mtime;
                 /* XXX submd is not fully initialized here */
                 *flags = save_flags;
@@ -2083,6 +2085,7 @@ static int lov_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
 
                         LASSERT(lock != NULL);
                         loi->loi_rss = tmp;
+                        loi->loi_blocks = submd->lsm_oinfo->loi_blocks;
                         /* Extend KMS up to the end of this lock and no further
                          * A lock on [x,y] means a KMS of up to y + 1 bytes! */
                         if (tmp > lock->l_policy_data.l_extent.end)
@@ -2105,6 +2108,7 @@ static int lov_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
                            save_flags & LDLM_FL_HAS_INTENT) {
                         memset(lov_lockhp, 0, sizeof(*lov_lockhp));
                         loi->loi_rss = submd->lsm_oinfo->loi_rss;
+                        loi->loi_blocks = submd->lsm_oinfo->loi_blocks;
                         CDEBUG(D_INODE, "glimpsed, setting rss="LPU64"; leaving"
                                " kms="LPU64"\n", loi->loi_rss, loi->loi_kms);
                 } else {
@@ -2693,6 +2697,21 @@ __u64 lov_merge_size(struct lov_stripe_md *lsm, int kms)
 }
 EXPORT_SYMBOL(lov_merge_size);
 
+/* Merge blocks */
+__u64 lov_merge_blocks(struct lov_stripe_md *lsm)
+{
+        struct lov_oinfo *loi;
+        __u64 blocks = 0;
+        int i;
+
+        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count;
+             i++, loi++) {
+                blocks += loi->loi_blocks;
+        }
+        return blocks;
+}
+EXPORT_SYMBOL(lov_merge_blocks);
+
 __u64 lov_merge_mtime(struct lov_stripe_md *lsm, __u64 current_time)
 {
         struct lov_oinfo *loi;
index 4a723bf..3f2aff3 100644 (file)
@@ -1381,7 +1381,7 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf)
                 RETURN(-ENOMEM);
 
         memset((void *)page, 0, PAGE_SIZE);
-        sprintf((char *)page, "iopen_nopriv");
+        sprintf((char *)page, "iopen_nopriv,errors=remount-ro");
 
         mnt = do_kern_mount(lcfg->lcfg_inlbuf2, 0,
                             lcfg->lcfg_inlbuf1, (void *)page);
index 136d357..5d174fe 100644 (file)
@@ -710,7 +710,8 @@ static void ec_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
 
         memcpy(oa, &eap->eap_eas->eas_oa, sizeof(*oa));
 }
-static void ec_ap_completion(void *data, int cmd, int rc)
+
+static void ec_ap_completion(void *data, int cmd, struct obdo *oa, int rc)
 {
         struct echo_async_page *eap = eap_from_cookie(data);
         struct echo_async_state *eas;
index f1f5f1c..5836499 100644 (file)
@@ -1104,6 +1104,7 @@ static int filter_intent_policy(struct ldlm_namespace *ns,
         res_lvb = res->lr_lvb_data;
         LASSERT(res_lvb != NULL);
         reply_lvb->lvb_size = res_lvb->lvb_size;
+        reply_lvb->lvb_blocks = res_lvb->lvb_blocks;
         up(&res->lr_lvb_sem);
 
         list_for_each(tmp, &res->lr_granted) {
@@ -1143,6 +1144,7 @@ static int filter_intent_policy(struct ldlm_namespace *ns,
 
         down(&res->lr_lvb_sem);
         reply_lvb->lvb_size = res_lvb->lvb_size;
+        reply_lvb->lvb_blocks = res_lvb->lvb_blocks;
         up(&res->lr_lvb_sem);
 
         LDLM_LOCK_PUT(l);
index 9206a7c..4b8413d 100644 (file)
@@ -71,10 +71,12 @@ static int filter_lvbo_init(struct ldlm_resource *res)
 
         lvb->lvb_size = dentry->d_inode->i_size;
         lvb->lvb_mtime = LTIME_S(dentry->d_inode->i_mtime);
+        lvb->lvb_blocks = dentry->d_inode->i_blocks;
         f_dput(dentry);
-
-        CDEBUG(D_DLMTRACE, "res: "LPU64" initial lvb size: "LPU64", mtime: "
-               LPU64"\n", res->lr_name.name[0], lvb->lvb_size, lvb->lvb_mtime);
+        CDEBUG(D_DLMTRACE, "res: "LPU64" initial lvb size: "LPU64", "
+               "mtime: "LPU64", blocks: "LPU64"\n",
+               res->lr_name.name[0], lvb->lvb_size,
+               lvb->lvb_mtime, lvb->lvb_blocks);
 
  out:
         /* Don't free lvb data on lookup error */
@@ -134,6 +136,12 @@ static int filter_lvbo_update(struct ldlm_resource *res, struct lustre_msg *m,
                                lvb->lvb_mtime, new->lvb_mtime);
                         lvb->lvb_mtime = new->lvb_mtime;
                 }
+                if (new->lvb_blocks > lvb->lvb_blocks || !increase) {
+                        CDEBUG(D_DLMTRACE, "res: "LPU64" updating lvb blocks: "
+                               LPU64" -> "LPU64"\n", res->lr_name.name[0],
+                               lvb->lvb_blocks, new->lvb_blocks);
+                        lvb->lvb_blocks = new->lvb_blocks;
+                }
                 GOTO(out, rc = 0);
         }
 
@@ -158,6 +166,11 @@ static int filter_lvbo_update(struct ldlm_resource *res, struct lustre_msg *m,
                        lvb->lvb_mtime, LTIME_S(dentry->d_inode->i_mtime));
                 lvb->lvb_mtime = LTIME_S(dentry->d_inode->i_mtime);
         }
+        CDEBUG(D_DLMTRACE, "res: "LPU64" updating lvb blocks from disk: "
+               LPU64" -> %lu\n", res->lr_name.name[0],
+               lvb->lvb_blocks, dentry->d_inode->i_blocks);
+        lvb->lvb_blocks = dentry->d_inode->i_blocks;
+
         f_dput(dentry);
 
  out:
index ea9836b..15ce6fe 100644 (file)
@@ -852,6 +852,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, struct obdo *oa,
         }
 
         osc_update_grant(cli, body);
+        memcpy(oa, &body->oa, sizeof(*oa));
 
         if (req->rq_reqmsg->opc == OST_WRITE) {
                 if (rc > 0) {
@@ -878,8 +879,6 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, struct obdo *oa,
         if (rc < requested_nob)
                 handle_short_read(rc, page_count, pga);
 
-        memcpy(oa, &body->oa, sizeof(*oa));
-
 #if CHECKSUM_BULK
         if (oa->o_valid & OBD_MD_FLCKSUM) {
                 const struct ptlrpc_peer *peer =
@@ -1196,8 +1195,8 @@ unlock:
 
 /* this must be called holding the loi list lock to give coverage to exit_cache,
  * async_flag maintenance, and oap_request */
-static void osc_complete_oap(struct client_obd *cli,
-                             struct osc_async_page *oap, int sent, int rc)
+static void osc_ap_completion(struct client_obd *cli, struct obdo *oa,
+                              struct osc_async_page *oap, int sent, int rc)
 {
         osc_exit_cache(cli, oap, sent);
         oap->oap_async_flags = 0;
@@ -1208,6 +1207,9 @@ static void osc_complete_oap(struct client_obd *cli,
                 oap->oap_request = NULL;
         }
 
+        if (rc == 0 && oa != NULL)
+                oap->oap_loi->loi_blocks = oa->o_blocks;
+
         if (oap->oap_oig) {
                 oig_complete_one(oap->oap_oig, &oap->oap_occ, rc);
                 oap->oap_oig = NULL;
@@ -1216,7 +1218,7 @@ static void osc_complete_oap(struct client_obd *cli,
         }
 
         oap->oap_caller_ops->ap_completion(oap->oap_caller_data, oap->oap_cmd,
-                                           rc);
+                                           oa, rc);
 }
 
 static int brw_interpret_oap(struct ptlrpc_request *request,
@@ -1247,7 +1249,7 @@ static int brw_interpret_oap(struct ptlrpc_request *request,
 
         spin_lock(&cli->cl_loi_list_lock);
 
-        /* We need to decrement before osc_complete_oap->osc_wake_cache_waiters
+        /* We need to decrement before osc_ap_completion->osc_wake_cache_waiters
          * is called so we know whether to go to sync BRWs or wait for more
          * RPCs to complete */
         cli->cl_brw_in_flight--;
@@ -1261,7 +1263,7 @@ static int brw_interpret_oap(struct ptlrpc_request *request,
                        //oap->oap_page, oap->oap_page->index, oap);
 
                 list_del_init(&oap->oap_rpc_item);
-                osc_complete_oap(cli, oap, 1, rc);
+                osc_ap_completion(cli, aa->aa_oa, oap, 1, rc);
         }
 
         osc_wake_cache_waiters(cli);
@@ -1436,7 +1438,7 @@ static int osc_send_oap_rpc(struct client_obd *cli, struct lov_oinfo *loi,
                 if (oap->oap_count <= 0) {
                         CDEBUG(D_CACHE, "oap %p count %d, completing\n", oap,
                                oap->oap_count);
-                        osc_complete_oap(cli, oap, 0, oap->oap_count);
+                        osc_ap_completion(cli, aa->aa_oa, oap, 0, oap->oap_count);
                         continue;
                 }
 
@@ -1468,7 +1470,8 @@ static int osc_send_oap_rpc(struct client_obd *cli, struct lov_oinfo *loi,
                          * were between the pending list and the rpc */
                         if (oap->oap_interrupted) {
                                 CDEBUG(D_INODE, "oap %p interrupted\n", oap);
-                                osc_complete_oap(cli, oap, 0, oap->oap_count);
+                                osc_ap_completion(cli, aa->aa_oa, oap, 0, 
+                                                  oap->oap_count);
                                 continue;
                         }
 
@@ -2461,8 +2464,10 @@ static int osc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
                               &lvb, sizeof(lvb), lustre_swab_ost_lvb, lockh);
 
         if ((*flags & LDLM_FL_HAS_INTENT && rc == ELDLM_LOCK_ABORTED) || !rc) {
-                CDEBUG(D_INODE, "received kms == "LPU64"\n", lvb.lvb_size);
+                CDEBUG(D_INODE, "received kms == "LPU64", blocks == "LPU64"\n",
+                       lvb.lvb_size, lvb.lvb_blocks);
                 lsm->lsm_oinfo->loi_rss = lvb.lvb_size;
+                lsm->lsm_oinfo->loi_blocks = lvb.lvb_blocks;
         }
 
         RETURN(rc);
index 95d5be7..8043ac4 100644 (file)
@@ -592,7 +592,7 @@ int portals_debug_init(unsigned long bufsize)
         debug_buf = vmalloc(bufsize + DEBUG_OVERFLOW);
         if (debug_buf == NULL)
                 return -ENOMEM;
-        memset(debug_buf, 0, debug_size);
+        memset(debug_buf, 0, bufsize + DEBUG_OVERFLOW);
         debug_wrapped = 0;
 
         //printk(KERN_INFO "Portals: allocated %lu byte debug buffer at %p.\n",
index cdcbaa8..15277d6 100755 (executable)
@@ -39,7 +39,7 @@ if [ "$BUSY" ]; then
        mv $TMP/debug $TMP/debug-busy.`date +%s`
        exit 255
 fi
-LEAK_LUSTRE=`dmesg | tail -40 | grep "obd mem.*leaked"`
+LEAK_LUSTRE=`dmesg | tail -30 | grep "obd mem.*leaked"`
 LEAK_PORTALS=`dmesg | tail -20 | grep "Portals memory leaked"`
 if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then
        echo "$LEAK_LUSTRE" 1>&2
@@ -47,5 +47,6 @@ if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then
        mv $TMP/debug $TMP/debug-leak.`date +%s`
        exit 254
 fi
+lsmod | grep portals && echo "modules still loaded" && exit 1
 
 exit $rc
index 7f10811..a016065 100755 (executable)
@@ -293,27 +293,32 @@ test_18b() {
 run_test 18b "eviction and reconnect clears page cache (2766)"
 
 test_19a() {   # bug 2983 - ldlm_handle_enqueue cleanup
-       mkdir -p $DIR/d19
-       multiop $DIR/d19/f19a O_wc &
+       mkdir -p $DIR/$tdir
+       multiop $DIR/$tdir/${tfile} O_wc &
        MULTI_PID=$!
        usleep 500
        cancel_lru_locks OSC
 #define OBD_FAIL_LDLM_ENQUEUE_EXTENT_ERR 0x308
        do_facet ost sysctl -w lustre.fail_loc=0x80000308
+       set -vx
        kill -USR1 $MULTI_PID
-       wait $MULTI_PID && error "multiop didn't fail enqueue" || true
+       wait $MULTI_PID
+       rc=$?
+       [ $rc -eq 0 ] && error "multiop didn't fail enqueue: rc $rc" || true
+       set +vx
 }
-run_test 19a "ldlm_handle_enqueue error (should return error) ==="
+run_test 19a "ldlm_handle_enqueue error (should return error)
 
 test_19b() {   # bug 2986 - ldlm_handle_enqueue error during open
-       mkdir $DIR/d19
-       touch $DIR/d19/f19b
+       mkdir $DIR/$tdir
+       touch $DIR/$tdir/${tfile}
        cancel_lru_locks OSC
 #define OBD_FAIL_LDLM_ENQUEUE_EXTENT_ERR 0x308
        do_facet ost sysctl -w lustre.fail_loc=0x80000308
-       dd if=/etc/hosts of=$DIR/d19/f19b && error "didn't fail enqueue" || true
+       dd if=/etc/hosts of=$DIR/$tdir/$tfile && \
+               error "didn't fail open enqueue" || true
 }
-run_test 19b "ldlm_handle_enqueue error (should return error) ==="
+run_test 19b "ldlm_handle_enqueue error (should return error)"
 
 
 $CLEANUP
index c20e2ec..d9eabce 100644 (file)
@@ -155,7 +155,9 @@ DIR=${DIR:-$MOUNT}
 [ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && exit 99
 
 LOVNAME=`cat /proc/fs/lustre/llite/fs0/lov/common_name`
-STRIPECOUNT=`cat /proc/fs/lustre/lov/$LOVNAME/numobd`
+OSTCOUNT=`cat /proc/fs/lustre/lov/$LOVNAME/numobd`
+STRIPECOUNT=`cat /proc/fs/lustre/lov/$LOVNAME/stripecount`
+STRIPESIZE=`cat /proc/fs/lustre/lov/$LOVNAME/stripesize`
 
 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
@@ -702,7 +704,7 @@ test_27a() {
 run_test 27a "one stripe file =================================="
 
 test_27c() {
-       [ "$STRIPECOUNT" -lt "2" ] && echo "skipping 2-stripe test" && return
+       [ "$OSTCOUNT" -lt "2" ] && echo "skipping 2-stripe test" && return
        if [ ! -d $DIR/d27 ]; then
                mkdir $DIR/d27
        fi
@@ -764,7 +766,7 @@ test_27j() {
         if [ ! -d $DIR/d27 ]; then
                 mkdir $DIR/d27
         fi
-        $LSTRIPE $DIR/d27/f27j 65536 $STRIPECOUNT 1 && error || true
+        $LSTRIPE $DIR/d27/f27j 65536 $OSTCOUNT 1 && error || true
 }
 run_test 27j "lstripe with bad stripe offset (should return error)"
 
@@ -1243,7 +1245,7 @@ stop_kupdated() {
 # ensure that all stripes have some grant before we test client-side cache
 setup_test42() {
        [ "$SETUP_TEST42" ] && return
-       for i in `seq -f $DIR/f42-%g 1 $STRIPECOUNT`; do
+       for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
                dd if=/dev/zero of=$i bs=4k count=1
                rm $i
        done
@@ -1380,7 +1382,7 @@ test_43c() {
 run_test 43c "md5sum of copy into lustre========================"
 
 test_44() {
-       [  "$STRIPECOUNT" -lt "2" ] && echo "skipping 2-stripe test" && return
+       [  "$OSTCOUNT" -lt "2" ] && echo "skipping 2-stripe test" && return
        dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=127
        dd if=$DIR/f1 bs=4k count=1
 }
@@ -1588,13 +1590,54 @@ test_53() {
 }
 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
 
-test_54() {
+test_54a() {
        $SOCKETSERVER $DIR/socket &
        sleep 1
        $SOCKETCLIENT $DIR/socket || error
        $MUNLINK $DIR/socket
 }
-run_test 54 "unix damain socket test ==========================="
+run_test 54a "unix damain socket test =========================="
+
+test_54b() {
+       f="$DIR/f54b"
+       mknod $f c 1 3
+       chmod 0666 $f
+       dd if=/dev/zero of=$f bs=`page_size` count=1 
+}
+run_test 54b "char device works in lustre ======================"
+
+test_54c() {
+       tfile="$DIR/f54c"
+       tdir="$DIR/d54c"
+       loopdev="$DIR/loop54c"
+       
+       for i in `seq 3 7`; do
+               rm -f $loopdev
+               mknod $loopdev b 7 $i
+               losetup $loopdev > /dev/null 2>&1 || break
+       done
+       echo "make a loop file system with $tfile on $loopdev ($i)..."  
+       dd if=/dev/zero of=$tfile bs=`page_size` seek=1024 count=1 > /dev/null
+       losetup $loopdev $tfile || error "can't set up $loopdev for $tfile"
+       mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
+       mkdir -p $tdir
+       mount -t ext2 $loopdev $tdir || error "error mounting $loopdev on $tdir"
+       dd if=/dev/zero of=$tdir/tmp bs=`page_size` count=30 || error "dd write"
+       df $tdir
+       dd if=$tdir/tmp of=/dev/zero bs=`page_size` count=30 || error "dd read"
+       umount $tdir
+       losetup -d $loopdev
+       rm $loopdev
+}
+run_test 54c "block device works in lustre ====================="
+
+test_54d() {
+       f="$DIR/f54d"
+       string="aaaaaa"
+       mknod $f p
+       [ "$string" = `echo $string > $f | cat $f` ] || error
+}
+run_test 54d "fifo device works in lustre ======================"
 
 test_55() {
         rm -rf $DIR/d55
@@ -1607,7 +1650,7 @@ test_55() {
         rm -rf $DIR/d55/*
         umount $DIR/d55 || error
 }
-run_test 55 "check iopen_connect_dentry()======================="
+run_test 55 "check iopen_connect_dentry() ======================"
 
 test_56() {
         rm -rf $DIR/d56
@@ -1647,7 +1690,7 @@ test_56() {
         $LFIND --obd wrong_uuid $DIR/d56 2>&1 | grep -q "unknown obduuid" || \
                 error "lfs find --obd wrong_uuid should return error information"
 
-        [  "$STRIPECOUNT" -lt 2 ] && \
+        [  "$OSTCOUNT" -lt 2 ] && \
                 echo "skipping other lfs find --obd test" && return
         FILENUM=`$LFIND --recursive $DIR/d56 | sed -n '/^[      ]*1[    ]/p' | wc -l`
         OBDUUID=`$LFIND --recursive $DIR/d56 | sed -n '/^[      ]*1:/p' | awk '{print $2}'`
@@ -1793,48 +1836,48 @@ test_65() {
        LFS=${LFS:-lfs}
        LVERIFY=${LVERIFY:-ll_dirstripe_verify}
 
-        stripecount=`cat /proc/fs/lustre/lov/*/stripecount | head -1`
-        if [ $stripecount -eq 0 ]; then
-                stripecount=1
-        fi
-        stripesize=`cat /proc/fs/lustre/lov/*/stripesize | head -1`
-        ostcount=`cat /proc/fs/lustre/lov/*/numobd | head -1`
-
-        echo -n "case 1: dir has no stripe info..."
+        echo "dir has no stripe info"
         mkdir $DIR/d65
         touch $DIR/d65/f1
         $LVERIFY $DIR/d65 $DIR/d65/f1 || error
-       echo "pass"
 
-       echo -n "case 2: setstripe $(($stripesize * 2)) 0 1 ..."
-               $LFS setstripe $DIR/d65 $(($stripesize * 2)) 0 1 || error
+       echo "setstripe $(($STRIPESIZE * 2)) 0 1"
+               $LFS setstripe $DIR/d65 $(($STRIPESIZE * 2)) 0 1 || error
         touch $DIR/d65/f2
         $LVERIFY $DIR/d65 $DIR/d65/f2 || error
-        echo "pass"
 
         if [ $ostcount -gt 1 ]; then
-               echo -n "case 3: setstripe $(($stripesize * 4)) 1 $(($ostcount - 1)) ..."
-               $LFS setstripe $DIR/d65 $(($stripesize * 4)) 1 \
-                       $(($ostcount - 1)) || error
+               echo "setstripe $(($STRIPESIZE * 4)) 1 $(($OSTCOUNT - 1))"
+               $LFS setstripe $DIR/d65 $(($STRIPESIZE * 4)) 1 \
+                       $(($OSTCOUNT - 1)) || error
                 touch $DIR/d65/f3
                 $LVERIFY $DIR/d65 $DIR/d65/f3 || error
-                echo "pass"
         fi
 
-        echo -n "case 4: setstripe  $stripesize -1 $(($stripecount - 1)) ..."
-        $LFS setstripe $DIR/d65 $stripesize -1 $(($stripecount - 1)) || error
+        [ $STRIPECOUNT -eq 0 ] && sc=1 || sc=$(($STRIPECOUNT - 1))
+
+        echo "setstripe  $STRIPESIZE -1 $sc"
+        $LFS setstripe $DIR/d65 $STRIPESIZE -1 $sc || error
         touch $DIR/d65/f4 $DIR/d65/f5
         $LVERIFY $DIR/d65 $DIR/d65/f4 $DIR/d65/f5 || error
-        echo "pass"
 
-       echo -n "case 5: setstripe 0 -1 0 (default) ..."
+       echo "setstripe 0 -1 0 (default)"
         $LFS setstripe $DIR/d65 0 -1 0 || error
         touch $DIR/d65/f6
         $LVERIFY $DIR/d65 $DIR/d65/f6 || error
-        echo "pass"
 }
 run_test 65 "Verify that the files are created using parent dir's stripe info"
 
+# bug 2543 - update blocks count on client
+test_66() {
+       COUNT=${COUNT:-8}
+       dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
+       sync
+       BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
+       [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
+}
+run_test 66 "update inode blocks count on client ==============="
+
 # on the LLNL clusters, runas will still pick up root's $TMP settings,
 # which will not be writable for the runas user, and then you get a CVS
 # error message with a corrupt path string (CVS bug) and panic.
index 96fa7b5..36eceb9 100644 (file)
@@ -31,6 +31,7 @@ init_test_env() {
     export LTESTDIR=${LTESTDIR:-$LUSTRE/../ltest}
 
     [ -d /r ] && export ROOT=/r
+    export TMP=${TMP:-$ROOT/tmp}
 
     export PATH=:$PATH:$LUSTRE/utils:$LUSTRE/tests
     export LLMOUNT=${LLMOUNT:-"llmount"}