# define sk_prot prot
# define sk_sndbuf sndbuf
# define sk_socket socket
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
# define sk_wmem_queued wmem_queued
#endif
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",
tbd Cluster File Systems, Inc. <info@clusterfs.com>
- * version 1.2.x
- * Bug fixes
+ * version 1.2.2
+ * bug fixes
- don't copy lvb into (possibly NULL) reply on error (2983)
+ - 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)
2004-03-22 Cluster File Systems, Inc. <info@clusterfs.com>
* version 1.2.1
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
struct list_head loi_write_item;
int loi_kms_valid:1;
- __u64 loi_kms; /* known minimum size */
- __u64 loi_rss; /* recently seen size */
- __u64 loi_mtime; /* recently seen mtime */
+ __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)
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
}
/* 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;
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
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
#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;
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);
}
__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
}
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);
#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
-};
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);
/* 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 *,
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);
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;
} 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;
}
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;
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. */
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)
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
#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;
-
- 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_24(struct page *page)
{
struct inode *inode = page->mapping->host;
#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;
--- /dev/null
+/* -*- 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,
+};
continue;
memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
-
+
/* XXX: LOV STACKING: use real "obj_mdp" sub-data */
err = obd_create(lov->tgts[i].ltd_exp, tmp_oa, &obj_mdp, oti);
if (err)
if (stripes > lov->desc.ld_active_tgt_count)
RETURN(-EFBIG);
- if (stripes > ost_count)
+ if (stripes < ost_count)
stripes = ost_count;
} else {
stripes = ost_count;
/* 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))
/* 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 = {
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;
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)
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 {
}
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;
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);
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;
CDEBUG(D_INODE, "%s: server subdir_count: %u\n",
obd->obd_name, le16_to_cpu(fsd->fsd_subdir_count));
CDEBUG(D_INODE, "%s: last_rcvd clients: %lu\n", obd->obd_name,
- last_rcvd_size <= FILTER_LR_CLIENT_START ? 0 :
- (last_rcvd_size-FILTER_LR_CLIENT_START) /FILTER_LR_CLIENT_SIZE);
+ last_rcvd_size <= le32_to_cpu(fsd->fsd_client_start) ? 0 :
+ (last_rcvd_size - le32_to_cpu(fsd->fsd_client_start)) /
+ le16_to_cpu(fsd->fsd_client_size));
if (!obd->obd_replayable) {
CWARN("%s: recovery support OFF\n", obd->obd_name);
if (obd->obd_recoverable_clients) {
CWARN("RECOVERY: %d recoverable clients, last_rcvd "
- LPU64"\n", obd->obd_recoverable_clients,
- le64_to_cpu(fsd->fsd_last_transno));
+ LPU64"\n", obd->obd_recoverable_clients,
+ le64_to_cpu(fsd->fsd_last_transno));
obd->obd_next_recovery_transno = obd->obd_last_committed + 1;
obd->obd_recovering = 1;
}
if (filter->fo_last_objid_files != NULL)
OBD_FREE(filter->fo_last_objid_files,
FILTER_GROUPS * sizeof(struct file *));
+ if (filter->fo_dentry_O != NULL) {
+ f_dput(filter->fo_dentry_O);
+ filter->fo_dentry_O = NULL;
+ }
RETURN(0);
}
sprintf(name, "O/%d/LAST_ID", i);
filp = filp_open(name, O_CREAT | O_RDWR, 0700);
- if (IS_ERR(dentry)) {
- rc = PTR_ERR(dentry);
+ if (IS_ERR(filp)) {
+ rc = PTR_ERR(filp);
CERROR("cannot create %s: rc = %d\n", name, rc);
GOTO(cleanup, rc);
}
RETURN(0);
cleanup:
- switch (cleanup_phase) {
- case 2:
- filter_cleanup_groups(obd);
- case 1:
- f_dput(filter->fo_dentry_O);
- filter->fo_dentry_O = NULL;
- default:
- break;
- }
+ filter_cleanup_groups(obd);
return rc;
}
i, rc);
}
- filp_close(filter->fo_rcvd_filp, 0);
+ rc = filp_close(filter->fo_rcvd_filp, 0);
filter->fo_rcvd_filp = NULL;
if (rc)
CERROR("error closing %s: rc = %d\n", LAST_RCVD, rc);
filter_cleanup_groups(obd);
- f_dput(filter->fo_dentry_O);
filter_free_server_data(filter);
pop_ctxt(&saved, &obd->obd_ctxt, NULL);
}
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) {
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);
dev_clear_rdonly(2);
- if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2)
- RETURN(-EINVAL);
-
obd->obd_fsops = fsfilt_get_ops(lcfg->lcfg_inlbuf2);
if (IS_ERR(obd->obd_fsops))
RETURN(PTR_ERR(obd->obd_fsops));
int n = 0;
int rc;
+ if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2)
+ RETURN(-EINVAL);
+
if (!strcmp(lcfg->lcfg_inlbuf2, "ext3")) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
/* bug 1577: implement async-delete for 2.5 */
* has and what we think it has, don't grant very much and let the
* client consume its grant first. Either it just has lots of RPCs
* in flight, or it was evicted and its grants will soon be used up. */
- if (current_grant < want) {
- if (current_grant > fed->fed_grant + FILTER_GRANT_CHUNK)
- want = 65536;
+ if (current_grant < want &&
+ current_grant < fed->fed_grant + FILTER_GRANT_CHUNK) {
grant = min((want >> blockbits) / 2,
(fs_space_left >> blockbits) / 8);
grant <<= blockbits;
lvb->lvb_size = dentry->d_inode->i_size;
lvb->lvb_mtime = LTIME_S(dentry->d_inode->i_mtime);
- CDEBUG(D_DLMTRACE, "res: "LPU64" initial lvb size: "LPU64", mtime: "
- LPU64"\n", res->lr_name.name[0], lvb->lvb_size, lvb->lvb_mtime);
+ lvb->lvb_blocks = dentry->d_inode->i_blocks;
+ 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:
if (oa)
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);
}
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:
struct lustre_cfg* lcfg = buf;
char *option = NULL;
- if (!lcfg->lcfg_inlbuf2)
+ if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2)
RETURN(-EINVAL);
/* for extN/ext3 filesystem, we must mount it with 'writeback' mode */
}
osc_update_grant(cli, body);
+ memcpy(oa, &body->oa, sizeof(*oa));
if (req->rq_reqmsg->opc == OST_WRITE) {
if (rc > 0) {
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 =
/* 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;
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;
}
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,
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--;
//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);
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;
}
* 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;
}
&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);
# define sk_prot prot
# define sk_sndbuf sndbuf
# define sk_socket socket
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
# define sk_wmem_queued wmem_queued
#endif
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",
# lustre.spec
-%define version 1.2.1
+%define version 1.2.1.1
%define kversion @LINUXRELEASE@
%define linuxdir @LINUX@
%define enable_doc @ENABLE_DOC@
+++ /dev/null
-#!/bin/bash
-
-config=${1:-ba-echo.xml}
-
-LMC_REAL="${LMC:-../utils/lmc} -m $config"
-LMC="save_cmd"
-
-TCPBUF=1048576
-OST=${OST:-ba-ost-1}
-CLIENT=${CLIENT:-`hostname`}
-
-UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt}
-
-h2tcp () {
- echo "${1}"
-}
-BATCH=/tmp/lmc-batch.$$
-save_cmd() {
- echo "$@" >> $BATCH
-}
-
-[ -f $config ] && rm $config
-
-# Client node
-${LMC} --add net --node $CLIENT --tcpbuf $TCPBUF --nid '*' --nettype tcp
-
-OST_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST`
-[ "$OST_UUID" ] && OST_UUID="--ostuuid=$OST_UUID" || echo "$OST: no UUID"
-
-# server node
-${LMC} --add net --node $OST --tcpbuf $TCPBUF --nid $OST --nettype tcp
-${LMC} --add ost --node $OST --ost ost1 --osdtype=obdecho $OST_UUID
-
-# osc on client
-${LMC} --add echo_client --node $CLIENT --ost ost1
-
-$LMC_REAL --batch $BATCH
-rm -f $BATCH
+++ /dev/null
-#!/bin/bash
-
-# There are configurations for three machines in this config file: the OST,
-# the MDS/client, other clients
-#
-# To start your cluster using the ba-mount.xml file that this produces, first
-# run:
-# > lconf ba-mount.xml
-# on the MDS/client, and then run:
-# > lconf --node client ba-mount.xml
-# on any other clients.
-
-config=${1:-ba-mount.xml}
-
-LMC_REAL="${LMC:-../utils/lmc} -m $config"
-LMC="save_cmd"
-
-TCPBUF=1048576
-OST=${OST:-ba-ost-1}
-MDS=`hostname`
-
-UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt}
-
-h2tcp () {
- echo "${1}"
-}
-BATCH=/tmp/lmc-batch.$$
-save_cmd() {
- echo "$@" >> $BATCH
-}
-
-[ -f $config ] && rm $config
-
-# MDS/client node
-${LMC} --add net --node $MDS --tcpbuf $TCPBUF --nid $MDS --nettype tcp
-${LMC} --add mds --node $MDS --mds mds1 --dev /tmp/mds1 --size 50000
-
-OST_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST`
-[ "$OST_UUID" ] && OST_UUID="--ostuuid $OST_UUID" || echo "$OST: no UUID"
-
-# server node
-${LMC} --add net --node $OST --tcpbuf $TCPBUF --nid $OST --nettype tcp
-${LMC} --add ost --node $OST --ost ost1 $OST_UUID --dev bluearc
-
-# mount point on the MDS/client
-${LMC} --add mtpt --node $MDS --path /mnt/lustre --mds mds1 --lov ost1
-
-# other clients
-${LMC} --add net --node client --tcpbuf $TCPBUF --nid '*' --nettype tcp
-${LMC} --add mtpt --node client --path /mnt/lustre --mds mds1 --lov ost1
-
-$LMC_REAL --batch $BATCH
-rm -f $BATCH
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
mv $TMP/debug $TMP/debug-leak.`date +%s`
exit 254
fi
+lsmod | grep portals && echo "modules still loaded" && exit 1
exit $rc
run_test 20a "ldlm_handle_enqueue error (should return error)"
test_20b() { # bug 2986 - ldlm_handle_enqueue error during open
- mkdir $DIR/$tdir
+ mkdir -p $DIR/$tdir
touch $DIR/$tdir/${tfile}
cancel_lru_locks OSC
#define OBD_FAIL_LDLM_ENQUEUE_EXTENT_ERR 0x308
[ -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
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
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)"
# 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
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
}
}
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
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
$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}'`
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"}