From eef0dc3356976bad84f7aefb6595f10443a5980d Mon Sep 17 00:00:00 2001 From: adilger Date: Wed, 31 Mar 2004 18:18:04 +0000 Subject: [PATCH] Land b_smallfix onto HEAD (20040330_2312) b=2947, b=2543, b=1557, b=2009 --- lnet/libcfs/debug.c | 2 +- lustre/ChangeLog | 4 + lustre/include/linux/lustre_lite.h | 5 + lustre/include/linux/obd.h | 3 +- lustre/liblustre/rw.c | 2 +- lustre/llite/Makefile.am | 2 +- lustre/llite/Makefile.mk | 2 +- lustre/llite/file.c | 19 +- lustre/llite/llite_internal.h | 22 ++- lustre/llite/llite_lib.c | 16 ++ lustre/llite/rw.c | 90 +++++++-- lustre/llite/rw24.c | 44 ----- lustre/llite/rw26.c | 38 ---- lustre/llite/special.c | 382 +++++++++++++++++++++++++++++++++++++ lustre/lov/lov_obd.c | 23 ++- lustre/mds/handler.c | 2 +- lustre/obdecho/echo_client.c | 3 +- lustre/obdfilter/filter.c | 2 + lustre/obdfilter/filter_lvb.c | 19 +- lustre/osc/osc_request.c | 25 ++- lustre/portals/libcfs/debug.c | 2 +- lustre/tests/llmountcleanup.sh | 3 +- lustre/tests/recovery-small.sh | 21 +- lustre/tests/sanity.sh | 103 +++++++--- lustre/tests/test-framework.sh | 1 + 25 files changed, 654 insertions(+), 181 deletions(-) create mode 100644 lustre/llite/special.c diff --git a/lnet/libcfs/debug.c b/lnet/libcfs/debug.c index 95d5be7..8043ac4 100644 --- a/lnet/libcfs/debug.c +++ b/lnet/libcfs/debug.c @@ -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", diff --git a/lustre/ChangeLog b/lustre/ChangeLog index bc3cab9..343b989 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -4,6 +4,10 @@ tbd Cluster File Systems, Inc. - 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) diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h index 5c6be08..1c66b53 100644 --- a/lustre/include/linux/lustre_lite.h +++ b/lustre/include/linux/lustre_lite.h @@ -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 diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index c5de023..354ce2f 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -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 diff --git a/lustre/liblustre/rw.c b/lustre/liblustre/rw.c index 546ab73..ae70a99 100644 --- a/lustre/liblustre/rw.c +++ b/lustre/liblustre/rw.c @@ -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; diff --git a/lustre/llite/Makefile.am b/lustre/llite/Makefile.am index 18c3a3a..96b59e6 100644 --- a/lustre/llite/Makefile.am +++ b/lustre/llite/Makefile.am @@ -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 diff --git a/lustre/llite/Makefile.mk b/lustre/llite/Makefile.mk index 40345b6..06dd10e 100644 --- a/lustre/llite/Makefile.mk +++ b/lustre/llite/Makefile.mk @@ -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 diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 21fcfce..6e867ff 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -30,10 +30,9 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) #include #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 -}; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 4f1277c..b0d2fa3 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 2aad640..89dcec9 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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; } diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 11e6df8..01ad4a1 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -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 diff --git a/lustre/llite/rw24.c b/lustre/llite/rw24.c index 22ffe38..71e194d 100644 --- a/lustre/llite/rw24.c +++ b/lustre/llite/rw24.c @@ -49,50 +49,6 @@ #include "llite_internal.h" #include -/* 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; diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index c8c7cbb..d048848 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -51,44 +51,6 @@ #include "llite_internal.h" #include -/* 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 index 0000000..7243811 --- /dev/null +++ b/lustre/llite/special.c @@ -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 + * Author: Andreas Dilger + * + * 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 +#include +#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include +#endif +#include +#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, +}; diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index b5a2773..9a83e4d 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -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; diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 4a723bf..3f2aff3 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -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); diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 136d357..5d174fe 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -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; diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index f1f5f1c..5836499 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -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); diff --git a/lustre/obdfilter/filter_lvb.c b/lustre/obdfilter/filter_lvb.c index 9206a7c..4b8413d 100644 --- a/lustre/obdfilter/filter_lvb.c +++ b/lustre/obdfilter/filter_lvb.c @@ -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: diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index ea9836b..15ce6fe 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -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); diff --git a/lustre/portals/libcfs/debug.c b/lustre/portals/libcfs/debug.c index 95d5be7..8043ac4 100644 --- a/lustre/portals/libcfs/debug.c +++ b/lustre/portals/libcfs/debug.c @@ -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", diff --git a/lustre/tests/llmountcleanup.sh b/lustre/tests/llmountcleanup.sh index cdcbaa8..15277d6 100755 --- a/lustre/tests/llmountcleanup.sh +++ b/lustre/tests/llmountcleanup.sh @@ -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 diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh index 7f10811..a016065 100755 --- a/lustre/tests/recovery-small.sh +++ b/lustre/tests/recovery-small.sh @@ -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 diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index c20e2ec..d9eabce 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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. diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 96fa7b5..36eceb9 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -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"} -- 1.8.3.1