Whamcloud - gitweb
- bring b_devel changes into b_io in preparation for file size fixes
authorzab <zab>
Tue, 25 Feb 2003 01:09:40 +0000 (01:09 +0000)
committerzab <zab>
Tue, 25 Feb 2003 01:09:40 +0000 (01:09 +0000)
lustre/extN/extN-san.diff [new file with mode: 0644]
lustre/include/liblustre.h [new file with mode: 0644]
lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc
lustre/tests/acceptance-metadata-double.sh [new file with mode: 0644]
lustre/tests/statone.c [new file with mode: 0644]

diff --git a/lustre/extN/extN-san.diff b/lustre/extN/extN-san.diff
new file mode 100644 (file)
index 0000000..c961c3f
--- /dev/null
@@ -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 (file)
index 0000000..a27abb9
--- /dev/null
@@ -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. <info@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.
+ *
+ * User-space Lustre headers.
+ *
+ */
+#ifndef LIBLUSTRE_H__
+#define LIBLUSTRE_H__
+
+#include <sys/mman.h>
+#include <asm/page.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+
+#include <portals/list.h>
+#include <portals/p30.h>
+
+/* 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 <linux/obd_support.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_import.h>
+#include <linux/lustre_export.h>
+#include <linux/lustre_net.h>
+
+
+#endif
+
index 881576c..dd2b1c8 100644 (file)
@@ -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 (file)
index 0000000..f647a55
--- /dev/null
@@ -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 (file)
index 0000000..5250984
--- /dev/null
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <liblustre.h>
+#include <linux/lustre_lib.h>
+#include <linux/obd.h>
+
+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;
+}