From 04001cd3d9181dc71141ab96e746037c58c62ea2 Mon Sep 17 00:00:00 2001 From: zab Date: Tue, 25 Feb 2003 01:09:40 +0000 Subject: [PATCH] - bring b_devel changes into b_io in preparation for file size fixes --- lustre/extN/extN-san.diff | 88 +++++ lustre/include/liblustre.h | 424 +++++++++++++++++++++++ lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc | 1 + lustre/tests/acceptance-metadata-double.sh | 140 ++++++++ lustre/tests/statone.c | 60 ++++ 5 files changed, 713 insertions(+) create mode 100644 lustre/extN/extN-san.diff create mode 100644 lustre/include/liblustre.h create mode 100644 lustre/tests/acceptance-metadata-double.sh create mode 100644 lustre/tests/statone.c diff --git a/lustre/extN/extN-san.diff b/lustre/extN/extN-san.diff new file mode 100644 index 0000000..c961c3f --- /dev/null +++ b/lustre/extN/extN-san.diff @@ -0,0 +1,88 @@ +--- lustre/extN/inode.orig.c 2002-12-29 18:48:56.000000000 +0800 ++++ lustre/extN/inode.c 2002-12-29 19:17:24.000000000 +0800 +@@ -2728,3 +2728,85 @@ + * here, in extN_aops_journal_start() to ensure that the forthcoming "see if we + * need to extend" test in extN_prepare_write() succeeds. + */ ++ ++/* for each block: 1 ind + 1 dind + 1 tind ++ * for each block: 3 bitmap blocks ++ * for each block: 3 group descriptor blocks ++ * i inode block ++ * 1 superblock ++ * 2 * EXTN_SINGLEDATA_TRANS_BLOCKS for the quote files ++ * ((1+1+1) * 3 * nblocks) + 1 + 1 + 2 * EXTN_SINGLEDATA_TRANS_BLOCKS ++ * ++ * XXX assuming: ++ * (1) fs logic block size == page size ++ * (2) extN in writeback mode ++ */ ++static inline int extN_san_write_trans_blocks(int nblocks) ++{ ++ int ret; ++ ++ ret = (1 + 1 + 1) * 3 * nblocks + 1 + 1; ++ ++#ifdef CONFIG_QUOTA ++ ret += 2 * EXTN_SINGLEDATA_TRANS_BLOCKS; ++#endif ++ ++ return ret; ++} ++ ++/* Alloc blocks for an inode, while don't create any buffer/page ++ * for data I/O; set the inode size if file is extended. ++ * ++ * @inode: target inode ++ * @blocks: array of logic block number ++ * @nblocks: how many blocks need be alloced ++ * @newsize: new filesize we should set ++ * ++ * return: 0 success, otherwise failed ++ * (*blocks) contains physical block number alloced ++ * ++ * XXX this assume the fs block size == page size ++ */ ++int extN_prep_san_write(struct inode *inode, long *blocks, ++ int nblocks, loff_t newsize) ++{ ++ handle_t *handle; ++ struct buffer_head bh_tmp; ++ int needed_blocks; ++ int i, ret, ret2; ++ ++ needed_blocks = extN_san_write_trans_blocks(nblocks); ++ ++ lock_kernel(); ++ handle = extN_journal_start(inode, needed_blocks); ++ if (IS_ERR(handle)) { ++ unlock_kernel(); ++ return PTR_ERR(handle); ++ } ++ unlock_kernel(); ++ ++ /* alloc blocks one by one */ ++ for (i = 0; i < nblocks; i++) { ++ ret = extN_get_block_handle(handle, inode, blocks[i], ++ &bh_tmp, 1); ++ if (ret) ++ break; ++ ++ blocks[i] = bh_tmp.b_blocknr; ++ } ++ ++ /* set inode size if needed */ ++ if (!ret && (newsize > inode->i_size)) { ++ inode->i_size = newsize; ++ extN_mark_inode_dirty(handle, inode); ++ } ++ ++ lock_kernel(); ++ ret2 = extN_journal_stop(handle, inode); ++ unlock_kernel(); ++ ++ if (!ret) ++ ret = ret2; ++ return ret; ++} ++EXPORT_SYMBOL(extN_prep_san_write); diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h new file mode 100644 index 0000000..a27abb9 --- /dev/null +++ b/lustre/include/liblustre.h @@ -0,0 +1,424 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (C) 2001 Cluster File Systems, Inc. + * + * 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. + * + * User-space Lustre headers. + * + */ +#ifndef LIBLUSTRE_H__ +#define LIBLUSTRE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* definitions for liblustre */ + +/* always adopt 2.5 definitions */ +#define LINUX_VERSION_CODE 1 +#define KERNEL_VERSION(a,b,c) 0 + +static inline void inter_module_put(void *a) +{ + return; +} + +extern ptl_handle_ni_t tcpnal_ni; + +static inline void *inter_module_get(char *arg) +{ + + if (strcmp(arg, "tcpnal_ni") == 0 ) + return &tcpnal_ni; + else + return NULL; + +} + + +/* cheats for now */ + +struct work_struct { + void (*ws_task)(void *arg); + void *ws_arg; +}; + +static inline void prepare_work(struct work_struct *q, void (*t)(void *), + void *arg) +{ + q->ws_task = t; + q->ws_arg = arg; + return; +} + +static inline void schedule_work(struct work_struct *q) +{ + q->ws_task(q->ws_arg); +} + + +#define strnlen(a,b) strlen(a) +static inline void *kmalloc(int size, int prot) +{ + return malloc(size); +} +#define vmalloc malloc +#define vfree free +#define kfree(a) free(a) +#define GFP_KERNEL 1 +#define GFP_HIGHUSER 1 +#define IS_ERR(a) (abs((int)(a)) < 500 ? 1 : 0) +#define PTR_ERR(a) ((int)(a)) + +#define capable(foo) 1 +#define CAP_SYS_ADMIN 1 + +typedef struct { + void *cwd; + +}mm_segment_t; + +typedef void *read_proc_t; +typedef void *write_proc_t; + + +/* modules */ + +struct module { + int count; +}; + +static inline void MODULE_AUTHOR(char *name) +{ + printf("%s\n", name); +} +#define MODULE_DESCRIPTION(name) MODULE_AUTHOR(name) +#define MODULE_LICENSE(name) MODULE_AUTHOR(name) + +#define THIS_MODULE NULL +#define __init +#define __exit + +/* devices */ + +static inline int misc_register(void *foo) +{ + return 0; +} +#define misc_deregister misc_register + +#define __MOD_INC_USE_COUNT(m) (m->count++) +#define __MOD_DEC_USE_COUNT(m) (m->count--) +#define MOD_INC_USE_COUNT do {int a = 1; a++; } while (0) +#define MOD_DEC_USE_COUNT do {int a = 1; a++; } while (0) + +/* module initialization */ +extern int init_obdclass(void); +extern int ptlrpc_init(void); +extern int ldlm_init(void); +extern int osc_init(void); +extern int echo_client_init(void); + + +/* general stuff */ +#define jiffies 0 + +#define EXPORT_SYMBOL(S) + +typedef int spinlock_t; +typedef __u64 kdev_t; + +#define SPIN_LOCK_UNLOCKED 0 +#define spin_lock(l) do {int a = 1; a++; } while (0) +#define spin_unlock(l) do {int a= 1; a++; } while (0) +#define spin_lock_init(l) do {int a= 1; a++; } while (0) +static inline void spin_lock_bh(spinlock_t *l) +{ + return; +} +static inline void spin_unlock_bh(spinlock_t *l) +{ + return; +} +static inline void spin_lock_irqrestore(a,b) +{ + return; +} +static inline void spin_unlock_irqrestore(a,b) +{ + return; +} +static inline void spin_lock_irqsave(a,b) +{ + return; +} + +#define barrier() do {int a= 1; a++; } while (0) + +/* registering symbols */ + +#define ERESTARTSYS ERESTART +#define HZ 1 + +/* random */ + +static inline void get_random_bytes(void *ptr, int size) +{ + static int r; + int *p = (int *)ptr; + int *end = p + (size / sizeof(int)); + r = rand(); + while ( p + sizeof(int) < end ) { + *p = r; + p++; + } +} + +/* memory */ + +static inline int copy_from_user(void *a,void *b, int c) +{ + memcpy(a,b,c); + return 0; +} + +static inline int copy_to_user(void *a,void *b, int c) +{ + memcpy(a,b,c); + return 0; +} + + +/* slabs */ +typedef struct { + int size; +} kmem_cache_t; +#define SLAB_HWCACHE_ALIGN 0 +static inline kmem_cache_t *kmem_cache_create(name,objsize,c,d,e,f) +{ + return malloc(objsize); +}; + +static inline int kmem_cache_destroy(kmem_cache_t *a) +{ + free(a); + return 0; +} +#define kmem_cache_validate(a,b) 1 +#define kmem_cache_alloc(cache, prio) malloc(cache->size) +#define kmem_cache_free(cache, obj) OBD_FREE(obj, cache->size) +#define PORTAL_SLAB_ALLOC(lock,cache,size) do { lock = kmem_cache_alloc(cache,prio); } while (0) +#define PORTAL_SLAB_FREE(lock,cache,size) do { lock = kmem_cache_alloc(cache,prio); } while (0) + +struct page { + void *addr; + int index; +}; + +#define kmap(page) (page)->addr +#define kunmap(a) do { int foo = 1; foo++; } while (0) + +static inline struct page *alloc_pages(mask,foo) +{ + struct page *pg = malloc(sizeof(*pg)); + + if (!pg) + return NULL; +#ifdef MAP_ANONYMOUS + pg->addr = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_ANONYMOUS, 0, 0); +#else + pg->addr = malloc(PAGE_SIZE); +#endif + + if (!pg->addr) { + free(pg); + return NULL; + } + return pg; +} + +static inline void __free_pages(struct page *pg, int what) +{ +#ifdef MAP_ANONYMOUS + munmap(pg->addr, PAGE_SIZE); +#else + free(pg->addr); +#endif + free(pg); +} + +/* arithmetic */ +#define do_div(a,b) (a)/(b) + +/* dentries / intents */ +struct lookup_intent { + void *it_iattr; +}; + +struct iattr { + int mode; +}; + +struct dentry { + int d_count; +}; +struct file { + struct dentry *f_dentry; + void *private_data; +} ; + +struct vfsmount { + void *pwd; +}; +#define cpu_to_le32(x) ((__u32)(x)) + +/* semaphores */ +struct semaphore { + int count; +}; + +#define down(a) do {(a)->count++;} while (0) +#define up(a) do {(a)->count--;} while (0) +#define sema_init(a,b) do { (a)->count = b; } while (0) + +typedef struct { + struct list_head sleepers; +} wait_queue_head_t; + +typedef struct { + struct list_head sleeping; + void *process; +} wait_queue_t; + +struct signal { + int signal; +}; + +struct task_struct { + int state; + struct signal pending; + char comm[32]; + int pid; +}; + +extern struct task_struct *current; + + + +#define set_current_state(foo) do { current->state = foo; } while (0) + +#define init_waitqueue_entry(q,p) do { (q)->process = p; } while (0) +#define add_wait_queue(q,p) do { list_add(&(q)->sleepers, &(p)->sleeping); } while (0) +#define del_wait_queue(p) do { list_del(&(p)->sleeping); } while (0) +#define remove_wait_queue(q,p) do { list_del(&(p)->sleeping); } while (0) + +#define init_waitqueue_head(l) INIT_LIST_HEAD(&(l)->sleepers) +#define wake_up(l) do { int a; a++; } while (0) +#define wait_event(l,m) do { int a; a++; } while (0) +#define TASK_INTERRUPTIBLE 0 +#define TASK_UNINTERRUPTIBLE 1 +#define TASK_RUNNING 2 + + +#define schedule() do { int a; a++; } while (0) +static inline int schedule_timeout(t) +{ + return 0; +} + +#define lock_kernel() do { int a; a++; } while (0) +#define daemonize(l) do { int a; a++; } while (0) +#define sigfillset(l) do { int a; a++; } while (0) +#define recalc_sigpending(l) do { int a; a++; } while (0) +#define kernel_thread(l,m,n) + +static inline int call_usermodehelper(char *prog, char **argv, char **evnp) +{ + return 0; +} + + + +#define KERN_INFO + + + +struct timer_list { + struct list_head tl_list; + void (*function)(unsigned long unused); + void *data; + int expires; +}; + +static inline int timer_pending(struct timer_list *l) +{ + if (l->expires > jiffies) + return 1; + else + return 0; +} + +static inline int init_timer(struct timer_list *l) +{ + INIT_LIST_HEAD(&l->tl_list); + return 0; +} + +static inline void mod_timer(struct timer_list *l, int thetime) +{ + l->expires = thetime; +} + +static inline void del_timer(struct timer_list *l) +{ + free(l); +} + +typedef struct { volatile int counter; } atomic_t; + +#define atomic_read(a) ((a)->counter) +#define atomic_set(a,b) do {(a)->counter = b; } while (0) +#define atomic_dec_and_test(a) ((--((a)->counter)) == 0) +#define atomic_inc(a) (((a)->counter)++) +#define atomic_dec(a) do { (a)->counter--; } while (0) +#define atomic_add(b,a) do {(a)->counter += b;} while (0) +#define atomic_sub(b,a) do {(a)->counter -= b;} while (0) + +#define LBUG() do { sleep(1000000); } while (0) + +#include +#include +#include +#include +#include +#include + + +#endif + diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc index 881576c..dd2b1c8 100644 --- a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc +++ b/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc @@ -3,6 +3,7 @@ fs/namei.c fs/nfsd/vfs.c fs/open.c fs/stat.c +fs/exec.c include/linux/dcache.h include/linux/fs.h kernel/ksyms.c diff --git a/lustre/tests/acceptance-metadata-double.sh b/lustre/tests/acceptance-metadata-double.sh new file mode 100644 index 0000000..f647a55 --- /dev/null +++ b/lustre/tests/acceptance-metadata-double.sh @@ -0,0 +1,140 @@ +#!/bin/sh +set -e + +# +# Runs create.pl and rename.pl on two mountpoints with increasing load, varying +# debug levels. Assumes that the node is already setup with llmount2.sh +# + +SRCDIR="`dirname $0`" +CREATE=$SRCDIR/create.pl + +debug_client_on() +{ + echo -1 > /proc/sys/portals/debug +} + +debug_client_off() +{ + echo 0 > /proc/sys/portals/debug +} + +MNT=${MNT:-/mnt/lustre} + +debug_client_on +echo "create.pl, 2 mounts, 1 thread, 10 ops, debug on" +perl $CREATE -- $MNT 2 10 +echo "create.pl, 2 mounts, 1 thread, 100 ops, debug on" +perl $CREATE --silent -- $MNT 2 100 +echo "create.pl --mcreate=0, 2 mounts, 1 thread, 10 ops, debug on" +perl $CREATE --mcreate=0 -- $MNT 2 10 +echo "create.pl --mcreate=0, 2 mounts, 1 thread, 100 ops, debug on" +perl $CREATE --mcreate=0 --silent -- $MNT 2 100 +echo "rename.pl, 2 mounts, 1 thread, 10 ops, debug on" +perl rename.pl --count=2 $MNT 10 +echo "rename.pl, 2 mounts, 1 thread, 100 ops, debug on" +perl rename.pl --count=2 --silent $MNT 100 + +debug_client_off +echo "create.pl, 2 mounts, 1 thread, 1000 ops, debug off" +perl $CREATE --silent -- $MNT 2 1000 +echo "create.pl --mcreate=0, 2 mounts, 1 thread, 1000 ops, debug off" +perl $CREATE --silent --mcreate=0 -- $MNT 2 1000 +echo "rename.pl, 2 mounts, 1 thread, 1000 ops, debug off" +perl rename.pl --count=2 --silent $MNT 1000 + +debug_client_on +echo "create.pl, 2 mounts, 2 threads, 100 ops, debug on" +perl $CREATE --silent -- $MNT 2 100 & +perl $CREATE --silent -- $MNT 2 100 & +wait +echo "create.pl --mcreate=0, 2 mounts, 2 threads, 100 ops, debug on" +perl $CREATE --silent --mcreate=0 -- $MNT 2 100 & +perl $CREATE --silent --mcreate=0 -- $MNT 2 100 & +wait +echo "rename.pl, 2 mounts, 2 thread, 1000 ops, debug on" +perl rename.pl --count=2 --silent $MNT 1000 & +perl rename.pl --count=2 --silent $MNT 1000 & +wait + +debug_client_off +echo "create.pl, 2 mounts, 2 threads, 2000 ops, debug off" +perl $CREATE --silent -- $MNT 2 2000 & +perl $CREATE --silent -- $MNT 2 2000 & +wait +echo "create.pl --mcreate=0, 2 mounts, 2 threads, 2000 ops, debug off" +perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & +perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & +wait +echo "rename.pl, 2 mounts, 2 threads, 2000 ops, debug off" +perl rename.pl --count=2 --silent $MNT 2000 & +perl rename.pl --count=2 --silent $MNT 2000 & +wait + +debug_client_on +echo "create.pl, 2 mounts, 4 threads, 100 ops, debug on" +for i in `seq 1 4`; do + perl $CREATE --silent -- $MNT 2 100 & +done +wait +echo "create.pl --mcreate=0, 2 mounts, 4 threads, 100 ops, debug on" +for i in `seq 1 4`; do + perl $CREATE --silent --mcreate=0 -- $MNT 2 100 & +done +wait +echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug on" +for i in `seq 1 4`; do + perl rename.pl --count=2 --silent $MNT 2000 & +done +wait + +debug_client_off +echo "create.pl, 2 mounts, 4 threads, 2000 ops, debug off" +for i in `seq 1 4`; do + perl $CREATE --silent -- $MNT 2 2000 & +done +wait +echo "create.pl --mcreate=0, 2 mounts, 4 threads, 2000 ops, debug off" +for i in `seq 1 4`; do + perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & +done +wait +echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug off" +for i in `seq 1 4`; do + perl rename.pl --count=2 --silent $MNT 2000 & +done +wait + +debug_client_on +echo "create.pl, 2 mounts, 8 threads, 500 ops, debug on" +for i in `seq 1 8`; do + perl $CREATE --silent -- $MNT 2 500 & +done +wait +echo "create.pl --mcreate=0, 2 mounts, 8 threads, 500 ops, debug on" +for i in `seq 1 8`; do + perl $CREATE --silent --mcreate=0 -- $MNT 2 500 & +done +wait +echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug on" +for i in `seq 1 8`; do + perl rename.pl --count=2 --silent $MNT 2000 & +done +wait + +debug_client_off +echo "create.pl, 2 mounts, 8 threads, 2000 ops, debug off" +for i in `seq 1 8`; do + perl $CREATE --silent -- $MNT 2 2000 & +done +wait +echo "create.pl --mcreate=0, 2 mounts, 8 threads, 2000 ops, debug off" +for i in `seq 1 8`; do + perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & +done +wait +echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug off" +for i in `seq 1 8`; do + perl rename.pl --count=2 --silent $MNT 2000 & +done +wait diff --git a/lustre/tests/statone.c b/lustre/tests/statone.c new file mode 100644 index 0000000..5250984 --- /dev/null +++ b/lustre/tests/statone.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +int main(int argc, char **argv) +{ + struct obd_ioctl_data data; + char rawbuf[8192], parent[4096], *buf = rawbuf, *base, *t; + int max = sizeof(rawbuf), fd, offset, rc; + + if (argc != 2) { + printf("usage: %s filename\n", argv[0]); + return 1; + } + + base = argv[1]; + t = strrchr(base, '/'); + if (!t) { + strcpy(parent, "."); + offset = -1; + } else { + strncpy(parent, base, t - base); + offset = t - base - 1; + } + + fd = open(parent, O_RDONLY); + if (fd < 0) { + printf("open(%s) error: %s\n", parent, strerror(errno)); + exit(errno); + } + + memset(&data, 0, sizeof(data)); + data.ioc_version = OBD_IOCTL_VERSION; + data.ioc_len = sizeof(data); + if (offset >= 0) + data.ioc_inlbuf1 = base + offset + 2; + else + data.ioc_inlbuf1 = base; + data.ioc_inllen1 = strlen(data.ioc_inlbuf1) + 1; + + if (obd_ioctl_pack(&data, &buf, max)) { + printf("ioctl_pack failed.\n"); + exit(1); + } + + rc = ioctl(fd, IOC_MDC_LOOKUP, buf); + if (rc < 0) { + printf("ioctl(%s/%s) error: %s\n", parent, + data.ioc_inlbuf1, strerror(errno)); + exit(errno); + } + + return 0; +} -- 1.8.3.1