Whamcloud - gitweb
34c8f3411b4486053be537ac50e3b0828e1e0de3
[fs/lustre-release.git] / lustre / patches / patch-2.4.18-14
1 --- linux-2.4.18-12-uml-pristine/arch/ia64/mm/init.c    Mon Sep  9 14:41:40 2002
2 +++ linux-2.4.18-12-uml/arch/ia64/mm/init.c     Mon Sep  9 16:08:12 2002
3 @@ -37,6 +37,12 @@
4  
5  static unsigned long totalram_pages;
6  
7 +struct page *check_get_page(unsigned long kaddr)
8 +{
9 +#warning FIXME: Lustre team, is this solid?
10 +       return virt_to_page(kaddr);
11 +}
12 +
13  int
14  do_check_pgt_cache (int low, int high)
15  {
16 --- linux-2.4.18-12-uml-pristine/arch/i386/mm/init.c    Mon Sep  9 14:41:54 2002
17 +++ linux-2.4.18-12-uml/arch/i386/mm/init.c     Mon Sep  9 16:08:12 2002
18 @@ -43,6 +43,12 @@
19  static unsigned long totalram_pages;
20  static unsigned long totalhigh_pages;
21  
22 +struct page *check_get_page(unsigned long kaddr)
23 +{
24 +#warning FIXME: Lustre team, is this solid?
25 +       return virt_to_page(kaddr);
26 +}
27 +
28  int do_check_pgt_cache(int low, int high)
29  {
30         int freed = 0;
31 --- linux-2.4.18-12-uml-pristine/drivers/block/blkpg.c  Mon Sep  9 14:41:58 2002
32 +++ linux-2.4.18-12-uml/drivers/block/blkpg.c   Mon Sep  9 16:08:12 2002
33 @@ -297,3 +297,38 @@
34  }
35  
36  EXPORT_SYMBOL(blk_ioctl);
37 +
38 +#define NUM_DEV_NO_WRITE 16
39 +static int dev_no_write[NUM_DEV_NO_WRITE];
40 +
41 +/*
42 + * Debug code for turning block devices "read-only" (will discard writes
43 + * silently).  This is for filesystem crash/recovery testing.
44 + */
45 +void dev_set_rdonly(kdev_t dev, int no_write)
46 +{
47 +       if (dev) {
48 +               printk(KERN_WARNING "Turning device %s read-only\n",
49 +                      bdevname(dev));
50 +               dev_no_write[no_write] = 0xdead0000 + dev;
51 +       }
52 +}
53 +
54 +int dev_check_rdonly(kdev_t dev) {
55 +       int i;
56 +
57 +       for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
58 +               if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
59 +                   dev == (dev_no_write[i] & 0xffff))
60 +                       return 1;
61 +       }
62 +       return 0;
63 +}
64 +
65 +void dev_clear_rdonly(int no_write) {
66 +       dev_no_write[no_write] = 0;
67 +}
68 +
69 +EXPORT_SYMBOL(dev_set_rdonly);
70 +EXPORT_SYMBOL(dev_check_rdonly);
71 +EXPORT_SYMBOL(dev_clear_rdonly);
72 --- linux-2.4.18-12-uml-pristine/drivers/block/loop.c   Mon Sep  9 14:41:58 2002
73 +++ linux-2.4.18-12-uml/drivers/block/loop.c    Mon Sep  9 16:08:12 2002
74 @@ -491,6 +491,11 @@
75         spin_unlock_irq(&lo->lo_lock);
76  
77         if (rw == WRITE) {
78 +#ifdef CONFIG_DEV_RDONLY
79 +               if (dev_check_rdonly(rbh->b_rdev))
80 +                       goto err;
81 +#endif
82 +
83                 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
84                         goto err;
85         } else if (rw == READA) {
86 --- linux-2.4.18-12-uml-pristine/drivers/ide/ide-disk.c Mon Sep  9 14:41:57 2002
87 +++ linux-2.4.18-12-uml/drivers/ide/ide-disk.c  Mon Sep  9 16:08:12 2002
88 @@ -557,6 +557,12 @@
89   */
90  static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
91  {
92 +#ifdef CONFIG_DEV_RDONLY
93 +       if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
94 +               ide_end_request(1, HWGROUP(drive));
95 +               return ide_stopped;
96 +       }
97 +#endif
98         if (IDE_CONTROL_REG)
99                 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
100  
101 --- linux-2.4.18-12-uml-pristine/fs/ext3/Makefile       Fri Dec 21 10:41:55 2001
102 +++ linux-2.4.18-12-uml/fs/ext3/Makefile        Mon Sep  9 16:08:12 2002
103 @@ -9,6 +9,8 @@
104  
105  O_TARGET := ext3.o
106  
107 +export-objs := super.o
108 +
109  obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
110                 ioctl.o namei.o super.o symlink.o
111  obj-m    := $(O_TARGET)
112 --- linux-2.4.18-12-uml-pristine/fs/ext3/super.c        Mon Sep  9 14:41:50 2002
113 +++ linux-2.4.18-12-uml/fs/ext3/super.c Mon Sep  9 16:08:12 2002
114 @@ -1746,7 +1746,7 @@
115         unregister_filesystem(&ext3_fs_type);
116  }
117  
118 -EXPORT_NO_SYMBOLS;
119 +EXPORT_SYMBOL(ext3_bread);
120  
121  MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
122  MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
123 --- linux-2.4.18-12-uml-pristine/include/linux/slab.h   Wed Sep 11 12:32:08 2002
124 +++ linux-2.4.18-12-uml/include/linux/slab.h    Wed Sep 18 15:52:16 2002
125 @@ -57,6 +57,7 @@
126  extern int kmem_cache_shrink(kmem_cache_t *);
127  extern void *kmem_cache_alloc(kmem_cache_t *, int);
128  extern void kmem_cache_free(kmem_cache_t *, void *);
129 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
130  
131  extern void *kmalloc(size_t, int);
132  extern void kfree(const void *);
133 --- linux-2.4.18-12-uml-pristine/kernel/ksyms.c Mon Sep  9 14:41:58 2002
134 +++ linux-2.4.18-12-uml/kernel/ksyms.c  Mon Sep  9 16:08:12 2002
135 @@ -306,6 +306,12 @@
136  EXPORT_SYMBOL_GPL(nr_free_pages);
137  EXPORT_SYMBOL_GPL(page_cache_size);
138  
139 +/* lustre */
140 +EXPORT_SYMBOL(panic_notifier_list);
141 +EXPORT_SYMBOL(pagecache_lock_cacheline);
142 +EXPORT_SYMBOL(do_kern_mount);
143 +EXPORT_SYMBOL(kmem_cache_validate);
144 +
145  /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
146  EXPORT_SYMBOL(default_llseek);
147  EXPORT_SYMBOL(dentry_open);
148 --- linux-2.4.18-12-uml-pristine/include/linux/dcache.h Wed Sep 11 12:32:08 2002
149 +++ linux-2.4.18-12-uml/include/linux/dcache.h  Wed Sep 18 14:21:14 2002
150 @@ -6,6 +6,34 @@
151  #include <asm/atomic.h>
152  #include <linux/mount.h>
153  
154 +#define IT_OPEN  (1)
155 +#define IT_CREAT  (1<<1)
156 +#define IT_MKDIR  (1<<2)
157 +#define IT_LINK  (1<<3)
158 +#define IT_LINK2  (1<<4)
159 +#define IT_SYMLINK  (1<<5)
160 +#define IT_UNLINK  (1<<6)
161 +#define IT_RMDIR  (1<<7)
162 +#define IT_RENAME  (1<<8)
163 +#define IT_RENAME2  (1<<9)
164 +#define IT_READDIR  (1<<10)
165 +#define IT_GETATTR  (1<<11)
166 +#define IT_SETATTR  (1<<12)
167 +#define IT_READLINK  (1<<13)
168 +#define IT_MKNOD  (1<<14)
169 +#define IT_LOOKUP  (1<<15)
170 +
171 +struct lookup_intent {
172 +       int it_op;
173 +       int it_mode;
174 +       int it_disposition;
175 +       int it_status;
176 +       struct iattr *it_iattr;
177 +       __u64 it_lock_handle[2];
178 +       int it_lock_mode;
179 +       void *it_data;
180 +};
181 +
182  /*
183   * linux/include/linux/dcache.h
184   *
185 @@ -78,6 +106,7 @@
186         unsigned long d_time;           /* used by d_revalidate */
187         struct dentry_operations  *d_op;
188         struct super_block * d_sb;      /* The root of the dentry tree */
189 +       struct lookup_intent *d_it;
190         unsigned long d_vfs_flags;
191         void * d_fsdata;                /* fs-specific data */
192         void * d_extra_attributes;      /* TUX-specific data */
193 @@ -91,6 +120,8 @@
194         int (*d_delete)(struct dentry *);
195         void (*d_release)(struct dentry *);
196         void (*d_iput)(struct dentry *, struct inode *);
197 +       int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
198 +       void (*d_intent_release)(struct dentry *, struct lookup_intent *);
199  };
200  
201  /* the dentry parameter passed to d_hash and d_compare is the parent
202 --- linux-2.4.18-12-uml-pristine/include/linux/fs.h     Wed Sep 11 12:32:08 2002
203 +++ linux-2.4.18-12-uml/include/linux/fs.h      Wed Sep 18 15:52:16 2002
204 @@ -576,6 +576,7 @@
205  
206         /* needed for tty driver, and maybe others */
207         void                    *private_data;
208 +       struct lookup_intent    *f_intent;
209  
210         /* preallocated helper kiobuf to speedup O_DIRECT */
211         struct kiobuf           *f_iobuf;
212 @@ -836,7 +837,9 @@
213  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
214  extern int vfs_rmdir(struct inode *, struct dentry *);
215  extern int vfs_unlink(struct inode *, struct dentry *);
216 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
217 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
218 +               struct inode *new_dir, struct dentry *new_dentry,
219 +               struct lookup_intent *it);
220  
221  /*
222   * File types
223 @@ -897,6 +900,7 @@
224  struct inode_operations {
225         int (*create) (struct inode *,struct dentry *,int);
226         struct dentry * (*lookup) (struct inode *,struct dentry *);
227 +       struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
228         int (*link) (struct dentry *,struct inode *,struct dentry *);
229         int (*unlink) (struct inode *,struct dentry *);
230         int (*symlink) (struct inode *,struct dentry *,const char *);
231 @@ -1046,6 +1050,7 @@
232  extern struct vfsmount *kern_mount(struct file_system_type *);
233  extern int may_umount(struct vfsmount *);
234  extern long do_mount(char *, char *, char *, unsigned long, void *);
235 +struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
236  extern void umount_tree(struct vfsmount *);
237  
238  #define kern_umount mntput
239 @@ -1380,6 +1385,7 @@
240  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
241  
242  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
243 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
244  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
245  extern int FASTCALL(path_walk(const char *, struct nameidata *));
246  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
247 @@ -1391,6 +1397,8 @@
248  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
249  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
250  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
251 +#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
252 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
253  
254  extern void inode_init_once(struct inode *);
255  extern void iput(struct inode *);
256 --- linux-2.4.18-12-uml-pristine/fs/dcache.c    Mon Sep  9 14:41:54 2002
257 +++ linux-2.4.18-12-uml/fs/dcache.c     Mon Sep  9 16:08:12 2002
258 @@ -645,6 +645,7 @@
259         dentry->d_fsdata = NULL;
260         dentry->d_extra_attributes = NULL;
261         dentry->d_mounted = 0;
262 +       dentry->d_it = NULL;
263         INIT_LIST_HEAD(&dentry->d_hash);
264         INIT_LIST_HEAD(&dentry->d_lru);
265         INIT_LIST_HEAD(&dentry->d_subdirs);
266 --- linux-2.4.18-12-uml-pristine/fs/nfsd/vfs.c  Mon Sep  9 14:41:50 2002
267 +++ linux-2.4.18-12-uml/fs/nfsd/vfs.c   Mon Sep  9 16:08:12 2002
268 @@ -1298,7 +1298,7 @@
269                         err = nfserr_perm;
270         } else
271  #endif
272 -       err = vfs_rename(fdir, odentry, tdir, ndentry);
273 +       err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
274         unlock_kernel();
275         if (!err && EX_ISSYNC(tfhp->fh_export)) {
276                 nfsd_sync_dir(tdentry);
277 --- linux-2.4.18-12-uml-pristine/fs/namei.c     Mon Sep  9 14:41:56 2002
278 +++ linux-2.4.18-12-uml/fs/namei.c      Wed Sep 18 16:59:58 2002
279 @@ -94,6 +94,14 @@
280   * XEmacs seems to be relying on it...
281   */
282  
283 +void intent_release(struct dentry *de, struct lookup_intent *it)
284 +{
285 +       if (de->d_op && de->d_op->d_intent_release)
286 +               de->d_op->d_intent_release(de, it);
287 +       de->d_it = NULL;
288 +}
289 +
290 +
291  /* In order to reduce some races, while at the same time doing additional
292   * checking and hopefully speeding things up, we copy filenames to the
293   * kernel data space before using them..
294 @@ -260,10 +268,19 @@
295   * Internal lookup() using the new generic dcache.
296   * SMP-safe
297   */
298 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
299 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
300 +                                   int flags, struct lookup_intent *it)
301  {
302         struct dentry * dentry = d_lookup(parent, name);
303  
304 +       if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
305 +               if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
306 +                   !d_invalidate(dentry)) {
307 +                       dput(dentry);
308 +                       dentry = NULL;
309 +               }
310 +               return dentry;
311 +       } else
312         if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
313                 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
314                         dput(dentry);
315 @@ -281,7 +298,8 @@
316   * make sure that nobody added the entry to the dcache in the meantime..
317   * SMP-safe
318   */
319 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
320 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
321 +                                 int flags, struct lookup_intent *it)
322  {
323         struct dentry * result;
324         struct inode *dir = parent->d_inode;
325 @@ -300,6 +318,9 @@
326                 result = ERR_PTR(-ENOMEM);
327                 if (dentry) {
328                         lock_kernel();
329 +                       if (dir->i_op->lookup2)
330 +                               result = dir->i_op->lookup2(dir, dentry, it);
331 +                       else
332                         result = dir->i_op->lookup(dir, dentry);
333                         unlock_kernel();
334                         if (result)
335 @@ -321,6 +342,12 @@
336                         dput(result);
337                         result = ERR_PTR(-ENOENT);
338                 }
339 +       } else if (result->d_op && result->d_op->d_revalidate2) {
340 +               if (!result->d_op->d_revalidate2(result, flags, it) &&
341 +                   !d_invalidate(result)) {
342 +                       dput(result);
343 +                       result = ERR_PTR(-ENOENT);
344 +               }
345         }
346         return result;
347  }
348 @@ -449,7 +476,8 @@
349   *
350   * We expect 'base' to be positive and a directory.
351   */
352 -int link_path_walk(const char * name, struct nameidata *nd)
353 +int link_path_walk_it(const char *name, struct nameidata *nd,
354 +                     struct lookup_intent *it)
355  {
356         struct dentry *dentry;
357         struct inode *inode;
358 @@ -526,12 +554,12 @@
359                                 break;
360                 }
361                 /* This does the actual lookups.. */
362 -               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
363 +               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
364                 if (!dentry) {
365                         err = -EWOULDBLOCKIO;
366                         if (atomic)
367                                 break;
368 -                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
369 +                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
370                         err = PTR_ERR(dentry);
371                         if (IS_ERR(dentry))
372                                 break;
373 @@ -565,7 +593,7 @@
374                         nd->dentry = dentry;
375                 }
376                 err = -ENOTDIR; 
377 -               if (!inode->i_op->lookup)
378 +               if (!inode->i_op->lookup && !inode->i_op->lookup2)
379                         break;
380                 continue;
381                 /* here ends the main loop */
382 @@ -592,12 +620,12 @@
383                         if (err < 0)
384                                 break;
385                 }
386 -               dentry = cached_lookup(nd->dentry, &this, 0);
387 +               dentry = cached_lookup(nd->dentry, &this, 0, it);
388                 if (!dentry) {
389                         err = -EWOULDBLOCKIO;
390                         if (atomic)
391                                 break;
392 -                       dentry = real_lookup(nd->dentry, &this, 0);
393 +                       dentry = real_lookup(nd->dentry, &this, 0, it);
394                         err = PTR_ERR(dentry);
395                         if (IS_ERR(dentry))
396                                 break;
397 @@ -621,7 +649,8 @@
398                         goto no_inode;
399                 if (lookup_flags & LOOKUP_DIRECTORY) {
400                         err = -ENOTDIR; 
401 -                       if (!inode->i_op || !inode->i_op->lookup)
402 +                       if (!inode->i_op || (!inode->i_op->lookup &&
403 +                                            !inode->i_op->lookup2))
404                                 break;
405                 }
406                 goto return_base;
407 @@ -663,10 +693,21 @@
408         return err;
409  }
410  
411 +int link_path_walk(const char * name, struct nameidata *nd)
412 +{
413 +       return link_path_walk_it(name, nd, NULL);
414 +}
415 +
416 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
417 +{
418 +       current->total_link_count = 0;
419 +       return link_path_walk_it(name, nd, it);
420 +}
421 +
422  int path_walk(const char * name, struct nameidata *nd)
423  {
424         current->total_link_count = 0;
425 -       return link_path_walk(name, nd);
426 +       return link_path_walk_it(name, nd, NULL);
427  }
428  
429  /* SMP-safe */
430 @@ -751,6 +795,17 @@
431  }
432  
433  /* SMP-safe */
434 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
435 +                  struct lookup_intent *it)
436 +{
437 +       int error = 0;
438 +       if (path_init(path, flags, nd))
439 +               error = path_walk_it(path, nd, it);
440 +       return error;
441 +}
442 +
443 +
444 +/* SMP-safe */
445  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
446  {
447         int error = 0;
448 @@ -779,7 +834,8 @@
449   * needs parent already locked. Doesn't follow mounts.
450   * SMP-safe.
451   */
452 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
453 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
454 +                              struct lookup_intent *it)
455  {
456         struct dentry * dentry;
457         struct inode *inode;
458 @@ -802,13 +858,16 @@
459                         goto out;
460         }
461  
462 -       dentry = cached_lookup(base, name, 0);
463 +       dentry = cached_lookup(base, name, 0, it);
464         if (!dentry) {
465                 struct dentry *new = d_alloc(base, name);
466                 dentry = ERR_PTR(-ENOMEM);
467                 if (!new)
468                         goto out;
469                 lock_kernel();
470 +               if (inode->i_op->lookup2)
471 +                       dentry = inode->i_op->lookup2(inode, new, it);
472 +               else
473                 dentry = inode->i_op->lookup(inode, new);
474                 unlock_kernel();
475                 if (!dentry)
476 @@ -820,6 +879,12 @@
477         return dentry;
478  }
479  
480 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
481 +{
482 +       return lookup_hash_it(name, base, NULL);
483 +}
484 +
485 +
486  /* SMP-safe */
487  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
488  {
489 @@ -841,7 +906,7 @@
490         }
491         this.hash = end_name_hash(hash);
492  
493 -       return lookup_hash(&this, base);
494 +       return lookup_hash_it(&this, base, NULL);
495  access:
496         return ERR_PTR(-EACCES);
497  }
498 @@ -872,6 +937,23 @@
499         return err;
500  }
501  
502 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
503 +                  struct lookup_intent *it)
504 +{
505 +       char *tmp;
506 +       int err;
507 +
508 +       tmp = getname(name);
509 +       err = PTR_ERR(tmp);
510 +       if (!IS_ERR(tmp)) {
511 +               err = 0;
512 +               if (path_init(tmp, flags, nd))
513 +                       err = path_walk_it(tmp, nd, it);
514 +               putname(tmp);
515 +       }
516 +       return err;
517 +}
518 +
519  /*
520   * It's inline, so penalty for filesystems that don't use sticky bit is
521   * minimal.
522 @@ -1010,7 +1092,8 @@
523   * for symlinks (where the permissions are checked later).
524   * SMP-safe
525   */
526 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
527 +int open_namei_it(const char *pathname, int flag, int mode,
528 +                 struct nameidata *nd, struct lookup_intent *it)
529  {
530         int acc_mode, error = 0;
531         struct inode *inode;
532 @@ -1024,7 +1107,7 @@
533          * The simplest case - just a plain lookup.
534          */
535         if (!(flag & O_CREAT)) {
536 -               error = path_lookup(pathname, lookup_flags(flag), nd);
537 +               error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
538                 if (error)
539                         return error;
540                 dentry = nd->dentry;
541 @@ -1034,6 +1117,10 @@
542         /*
543          * Create - we need to know the parent.
544          */
545 +       if (it) {
546 +               it->it_mode = mode;
547 +               it->it_op |= IT_CREAT;
548 +       }
549         error = path_lookup(pathname, LOOKUP_PARENT, nd);
550         if (error)
551                 return error;
552 @@ -1049,7 +1137,7 @@
553  
554         dir = nd->dentry;
555         down(&dir->d_inode->i_sem);
556 -       dentry = lookup_hash(&nd->last, nd->dentry);
557 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
558  
559  do_last:
560         error = PTR_ERR(dentry);
561 @@ -1058,6 +1146,7 @@
562                 goto exit;
563         }
564  
565 +       it->it_mode = mode;
566         /* Negative dentry, just create the file */
567         if (!dentry->d_inode) {
568                 error = vfs_create(dir->d_inode, dentry,
569 @@ -1177,8 +1267,10 @@
570         return 0;
571  
572  exit_dput:
573 +       intent_release(dentry, it);
574         dput(dentry);
575  exit:
576 +       intent_release(nd->dentry, it);
577         path_release(nd);
578         return error;
579  
580 @@ -1198,6 +1290,8 @@
581          */
582         UPDATE_ATIME(dentry->d_inode);
583         error = dentry->d_inode->i_op->follow_link(dentry, nd);
584 +       if (error)
585 +               intent_release(dentry, it);
586         dput(dentry);
587         if (error)
588                 return error;
589 @@ -1219,13 +1313,20 @@
590         }
591         dir = nd->dentry;
592         down(&dir->d_inode->i_sem);
593 -       dentry = lookup_hash(&nd->last, nd->dentry);
594 +       dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
595         putname(nd->last.name);
596         goto do_last;
597  }
598  
599 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
600 +{
601 +       return open_namei_it(pathname, flag, mode, nd, NULL);
602 +}
603 +
604 +
605  /* SMP-safe */
606 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
607 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
608 +                                   struct lookup_intent *it)
609  {
610         struct dentry *dentry;
611  
612 @@ -1233,7 +1334,7 @@
613         dentry = ERR_PTR(-EEXIST);
614         if (nd->last_type != LAST_NORM)
615                 goto fail;
616 -       dentry = lookup_hash(&nd->last, nd->dentry);
617 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
618         if (IS_ERR(dentry))
619                 goto fail;
620         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
621 @@ -1279,6 +1380,7 @@
622         char * tmp;
623         struct dentry * dentry;
624         struct nameidata nd;
625 +       struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
626  
627         if (S_ISDIR(mode))
628                 return -EPERM;
629 @@ -1289,7 +1391,7 @@
630         error = path_lookup(tmp, LOOKUP_PARENT, &nd);
631         if (error)
632                 goto out;
633 -       dentry = lookup_create(&nd, 0);
634 +       dentry = lookup_create(&nd, 0, &it);
635         error = PTR_ERR(dentry);
636  
637         mode &= ~current->fs->umask;
638 @@ -1307,6 +1410,7 @@
639                 default:
640                         error = -EINVAL;
641                 }
642 +               intent_release(dentry, &it);
643                 dput(dentry);
644         }
645         up(&nd.dentry->d_inode->i_sem);
646 @@ -1347,6 +1451,7 @@
647  {
648         int error = 0;
649         char * tmp;
650 +       struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
651  
652         tmp = getname(pathname);
653         error = PTR_ERR(tmp);
654 @@ -1357,11 +1462,12 @@
655                 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
656                 if (error)
657                         goto out;
658 -               dentry = lookup_create(&nd, 1);
659 +               dentry = lookup_create(&nd, 1, &it);
660                 error = PTR_ERR(dentry);
661                 if (!IS_ERR(dentry)) {
662                         error = vfs_mkdir(nd.dentry->d_inode, dentry,
663                                           mode & ~current->fs->umask);
664 +                       intent_release(dentry, &it);
665                         dput(dentry);
666                 }
667                 up(&nd.dentry->d_inode->i_sem);
668 @@ -1445,6 +1552,7 @@
669         char * name;
670         struct dentry *dentry;
671         struct nameidata nd;
672 +       struct lookup_intent it = { .it_op = IT_RMDIR };
673  
674         name = getname(pathname);
675         if(IS_ERR(name))
676 @@ -1466,10 +1574,11 @@
677                         goto exit1;
678         }
679         down(&nd.dentry->d_inode->i_sem);
680 -       dentry = lookup_hash(&nd.last, nd.dentry);
681 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
682         error = PTR_ERR(dentry);
683         if (!IS_ERR(dentry)) {
684                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
685 +               intent_release(dentry, &it);
686                 dput(dentry);
687         }
688         up(&nd.dentry->d_inode->i_sem);
689 @@ -1513,6 +1623,7 @@
690         char * name;
691         struct dentry *dentry;
692         struct nameidata nd;
693 +       struct lookup_intent it = { .it_op = IT_UNLINK };
694  
695         name = getname(pathname);
696         if(IS_ERR(name))
697 @@ -1525,7 +1636,7 @@
698         if (nd.last_type != LAST_NORM)
699                 goto exit1;
700         down(&nd.dentry->d_inode->i_sem);
701 -       dentry = lookup_hash(&nd.last, nd.dentry);
702 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
703         error = PTR_ERR(dentry);
704         if (!IS_ERR(dentry)) {
705                 /* Why not before? Because we want correct error value */
706 @@ -1533,6 +1644,7 @@
707                         goto slashes;
708                 error = vfs_unlink(nd.dentry->d_inode, dentry);
709         exit2:
710 +               intent_release(dentry, &it);
711                 dput(dentry);
712         }
713         up(&nd.dentry->d_inode->i_sem);
714 @@ -1579,6 +1692,7 @@
715         int error = 0;
716         char * from;
717         char * to;
718 +       struct lookup_intent it = { .it_op = IT_SYMLINK };
719  
720         from = getname(oldname);
721         if(IS_ERR(from))
722 @@ -1592,10 +1706,12 @@
723                 error = path_lookup(to, LOOKUP_PARENT, &nd);
724                 if (error)
725                         goto out;
726 -               dentry = lookup_create(&nd, 0);
727 +               it.it_data = from;
728 +               dentry = lookup_create(&nd, 0, &it);
729                 error = PTR_ERR(dentry);
730                 if (!IS_ERR(dentry)) {
731                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
732 +                       intent_release(dentry, &it);
733                         dput(dentry);
734                 }
735                 up(&nd.dentry->d_inode->i_sem);
736 @@ -1660,6 +1777,7 @@
737  {
738         int error;
739         char * to;
740 +       struct lookup_intent it = { .it_op = IT_LINK };
741  
742         to = getname(newname);
743         error = PTR_ERR(to);
744 @@ -1667,7 +1785,7 @@
745                 struct dentry *new_dentry;
746                 struct nameidata nd, old_nd;
747  
748 -               error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd);
749 +               error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it);
750                 if (error)
751                         goto exit;
752                 error = path_lookup(to, LOOKUP_PARENT, &nd);
753 @@ -1676,10 +1794,12 @@
754                 error = -EXDEV;
755                 if (old_nd.mnt != nd.mnt)
756                         goto out_release;
757 -               new_dentry = lookup_create(&nd, 0);
758 +               it.it_op = IT_LINK2;
759 +               new_dentry = lookup_create(&nd, 0, &it);
760                 error = PTR_ERR(new_dentry);
761                 if (!IS_ERR(new_dentry)) {
762                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
763 +                       intent_release(new_dentry, &it);
764                         dput(new_dentry);
765                 }
766                 up(&nd.dentry->d_inode->i_sem);
767 @@ -1720,7 +1841,8 @@
768   *        locking].
769   */
770  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
771 -              struct inode *new_dir, struct dentry *new_dentry)
772 +                  struct inode *new_dir, struct dentry *new_dentry,
773 +                  struct lookup_intent *it)
774  {
775         int error;
776         struct inode *target;
777 @@ -1778,6 +1900,7 @@
778                 error = -EBUSY;
779         else 
780                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
781 +       intent_release(new_dentry, it);
782         if (target) {
783                 if (!error)
784                         target->i_flags |= S_DEAD;
785 @@ -1799,7 +1923,8 @@
786  }
787  
788  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
789 -              struct inode *new_dir, struct dentry *new_dentry)
790 +                    struct inode *new_dir, struct dentry *new_dentry,
791 +                    struct lookup_intent *it)
792  {
793         int error;
794  
795 @@ -1830,6 +1951,7 @@
796                 error = -EBUSY;
797         else
798                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
799 +       intent_release(new_dentry, it);
800         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
801         if (error)
802                 return error;
803 @@ -1841,13 +1968,14 @@
804  }
805  
806  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
807 -              struct inode *new_dir, struct dentry *new_dentry)
808 +              struct inode *new_dir, struct dentry *new_dentry,
809 +              struct lookup_intent *it)
810  {
811         int error;
812         if (S_ISDIR(old_dentry->d_inode->i_mode))
813 -               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
814 +               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
815         else
816 -               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
817 +               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
818         if (!error) {
819                 if (old_dir == new_dir)
820                         inode_dir_notify(old_dir, DN_RENAME);
821 @@ -1864,6 +1992,7 @@
822         int error = 0;
823         struct dentry * old_dir, * new_dir;
824         struct dentry * old_dentry, *new_dentry;
825 +       struct lookup_intent it = { .it_op = IT_RENAME };
826         struct nameidata oldnd, newnd;
827  
828         error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
829 @@ -1889,7 +2018,7 @@
830  
831         double_lock(new_dir, old_dir);
832  
833 -       old_dentry = lookup_hash(&oldnd.last, old_dir);
834 +       old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
835         error = PTR_ERR(old_dentry);
836         if (IS_ERR(old_dentry))
837                 goto exit3;
838 @@ -1905,18 +2034,21 @@
839                 if (newnd.last.name[newnd.last.len])
840                         goto exit4;
841         }
842 -       new_dentry = lookup_hash(&newnd.last, new_dir);
843 +       it.it_op = IT_RENAME2;
844 +       new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
845         error = PTR_ERR(new_dentry);
846         if (IS_ERR(new_dentry))
847                 goto exit4;
848  
849         lock_kernel();
850         error = vfs_rename(old_dir->d_inode, old_dentry,
851 -                                  new_dir->d_inode, new_dentry);
852 +                                  new_dir->d_inode, new_dentry, &it);
853         unlock_kernel();
854  
855 +       intent_release(new_dentry, &it);
856         dput(new_dentry);
857  exit4:
858 +       intent_release(old_dentry, &it); // FIXME: release same intent twice!!!
859         dput(old_dentry);
860  exit3:
861         double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
862 --- linux-2.4.18-12-uml-pristine/fs/open.c      Mon Sep  9 14:41:56 2002
863 +++ linux-2.4.18-12-uml/fs/open.c       Mon Sep  9 16:11:20 2002
864 @@ -19,6 +19,9 @@
865  #include <asm/uaccess.h>
866  
867  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
868 +extern int path_walk_it(const char *name, struct nameidata *nd,
869 +                       struct lookup_intent *it);
870 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
871  
872  int vfs_statfs(struct super_block *sb, struct statfs *buf)
873  {
874 @@ -118,12 +121,13 @@
875         struct nameidata nd;
876         struct inode * inode;
877         int error;
878 +       struct lookup_intent it = { .it_op = IT_SETATTR };
879  
880         error = -EINVAL;
881         if (length < 0) /* sorry, but loff_t says... */
882                 goto out;
883  
884 -       error = user_path_walk(path, &nd);
885 +       error = user_path_walk_it(path, &nd, &it);
886         if (error)
887                 goto out;
888         inode = nd.dentry->d_inode;
889 @@ -168,6 +173,7 @@
890         put_write_access(inode);
891  
892  dput_and_out:
893 +       intent_release(nd.dentry, &it);
894         path_release(&nd);
895  out:
896         return error;
897 @@ -259,8 +265,9 @@
898         struct nameidata nd;
899         struct inode * inode;
900         struct iattr newattrs;
901 +       struct lookup_intent it = { .it_op = IT_SETATTR };
902  
903 -       error = user_path_walk(filename, &nd);
904 +       error = user_path_walk_it(filename, &nd, &it);
905         if (error)
906                 goto out;
907         inode = nd.dentry->d_inode;
908 @@ -286,6 +294,7 @@
909         }
910         error = notify_change(nd.dentry, &newattrs);
911  dput_and_out:
912 +       intent_release(nd.dentry, &it);
913         path_release(&nd);
914  out:
915         return error;
916 @@ -303,8 +312,9 @@
917         struct nameidata nd;
918         struct inode * inode;
919         struct iattr newattrs;
920 +       struct lookup_intent it = { .it_op = IT_SETATTR };
921  
922 -       error = user_path_walk(filename, &nd);
923 +       error = user_path_walk_it(filename, &nd, &it);
924  
925         if (error)
926                 goto out;
927 @@ -331,6 +342,7 @@
928         }
929         error = notify_change(nd.dentry, &newattrs);
930  dput_and_out:
931 +       intent_release(nd.dentry, &it);
932         path_release(&nd);
933  out:
934         return error;
935 @@ -347,6 +359,7 @@
936         int old_fsuid, old_fsgid;
937         kernel_cap_t old_cap;
938         int res;
939 +       struct lookup_intent it = { .it_op = IT_GETATTR };
940  
941         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
942                 return -EINVAL;
943 @@ -364,13 +377,14 @@
944         else
945                 current->cap_effective = current->cap_permitted;
946  
947 -       res = user_path_walk(filename, &nd);
948 +       res = user_path_walk_it(filename, &nd, &it);
949         if (!res) {
950                 res = permission(nd.dentry->d_inode, mode);
951                 /* SuS v2 requires we report a read only fs too */
952                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
953                    && !special_file(nd.dentry->d_inode->i_mode))
954                         res = -EROFS;
955 +               intent_release(nd.dentry, &it);
956                 path_release(&nd);
957         }
958  
959 @@ -385,8 +399,11 @@
960  {
961         int error;
962         struct nameidata nd;
963 +       struct lookup_intent it = { .it_op = IT_GETATTR };
964  
965 -       error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
966 +       error = __user_walk_it(filename,
967 +                              LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
968 +                              &nd, &it);
969         if (error)
970                 goto out;
971  
972 @@ -397,6 +415,7 @@
973         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
974  
975  dput_and_out:
976 +       intent_release(nd.dentry, &it);
977         path_release(&nd);
978  out:
979         return error;
980 @@ -436,9 +455,10 @@
981  {
982         int error;
983         struct nameidata nd;
984 +       struct lookup_intent it = { .it_op = IT_GETATTR };
985  
986 -       error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
987 -                     LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
988 +       error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
989 +                              LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
990         if (error)
991                 goto out;
992  
993 @@ -454,6 +475,7 @@
994         set_fs_altroot();
995         error = 0;
996  dput_and_out:
997 +       intent_release(nd.dentry, &it);
998         path_release(&nd);
999  out:
1000         return error;
1001 @@ -498,8 +520,9 @@
1002         struct inode * inode;
1003         int error;
1004         struct iattr newattrs;
1005 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1006  
1007 -       error = user_path_walk(filename, &nd);
1008 +       error = user_path_walk_it(filename, &nd, &it);
1009         if (error)
1010                 goto out;
1011         inode = nd.dentry->d_inode;
1012 @@ -519,6 +543,7 @@
1013         error = notify_change(nd.dentry, &newattrs);
1014  
1015  dput_and_out:
1016 +       intent_release(nd.dentry, &it);
1017         path_release(&nd);
1018  out:
1019         return error;
1020 @@ -588,10 +613,12 @@
1021  {
1022         struct nameidata nd;
1023         int error;
1024 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1025  
1026 -       error = user_path_walk(filename, &nd);
1027 +       error = user_path_walk_it(filename, &nd, &it);
1028         if (!error) {
1029                 error = chown_common(nd.dentry, user, group);
1030 +               intent_release(nd.dentry, &it);
1031                 path_release(&nd);
1032         }
1033         return error;
1034 @@ -601,10 +629,12 @@
1035  {
1036         struct nameidata nd;
1037         int error;
1038 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1039  
1040 -       error = user_path_walk_link(filename, &nd);
1041 +       error = user_path_walk_link_it(filename, &nd, &it);
1042         if (!error) {
1043                 error = chown_common(nd.dentry, user, group);
1044 +               intent_release(nd.dentry, &it);
1045                 path_release(&nd);
1046         }
1047         return error;
1048 @@ -638,10 +669,16 @@
1049   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1050   * used by symlinks.
1051   */
1052 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1053 +                        struct nameidata *nd, struct lookup_intent *it);
1054 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1055 +                           int flags, struct lookup_intent *it);
1056 +
1057  struct file *filp_open(const char * filename, int flags, int mode)
1058  {
1059         int namei_flags, error;
1060         struct nameidata nd;
1061 +       struct lookup_intent it = { .it_op = IT_OPEN };
1062  
1063         namei_flags = flags;
1064         if ((namei_flags+1) & O_ACCMODE)
1065 @@ -649,18 +686,19 @@
1066         if (namei_flags & O_TRUNC)
1067                 namei_flags |= 2;
1068  
1069 -       error = open_namei(filename, namei_flags, mode, &nd);
1070 -       if (!error)
1071 -               return dentry_open(nd.dentry, nd.mnt, flags);
1072 -
1073 -       return ERR_PTR(error);
1074 +       error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1075 +       if (error)
1076 +               return ERR_PTR(error);
1077 +
1078 +       return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1079  }
1080  
1081  extern ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr);
1082  /* for files over a certains size it doesn't pay to do readahead on open */
1083  #define READAHEAD_CUTOFF 48000
1084  
1085 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1086 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1087 +                           int flags, struct lookup_intent *it)
1088  {
1089         struct file * f;
1090         struct inode *inode;
1091 @@ -711,6 +749,7 @@
1092                 do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT);
1093         
1094  
1095 +       intent_release(dentry, it);
1096         return f;
1097  
1098  cleanup_all:
1099 @@ -725,11 +764,17 @@
1100  cleanup_file:
1101         put_filp(f);
1102  cleanup_dentry:
1103 +       intent_release(dentry, it);
1104         dput(dentry);
1105         mntput(mnt);
1106         return ERR_PTR(error);
1107  }
1108  
1109 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1110 +{
1111 +       return dentry_open_it(dentry, mnt, flags, NULL);
1112 +}
1113 +
1114  /*
1115   * Find an empty file descriptor entry, and mark it busy.
1116   */
1117 --- linux-2.4.18-12-uml-pristine/fs/stat.c      Mon Sep  9 14:41:56 2002
1118 +++ linux-2.4.18-12-uml/fs/stat.c       Mon Sep  9 16:08:12 2002
1119 @@ -13,6 +13,7 @@
1120  
1121  #include <asm/uaccess.h>
1122  
1123 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1124  /*
1125   * Revalidate the inode. This is required for proper NFS attribute caching.
1126   */
1127 @@ -104,10 +105,12 @@
1128  {
1129         struct nameidata nd;
1130         int error;
1131 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1132  
1133 -       error = user_path_walk(name, &nd);
1134 +       error = user_path_walk_it(name, &nd, &it);
1135         if (!error) {
1136                 error = do_getattr(nd.mnt, nd.dentry, stat);
1137 +               intent_release(nd.dentry, &it);
1138                 path_release(&nd);
1139         }
1140         return error;
1141 @@ -117,10 +120,12 @@
1142  {
1143         struct nameidata nd;
1144         int error;
1145 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1146  
1147 -       error = user_path_walk_link(name, &nd);
1148 +       error = user_path_walk_link_it(name, &nd, &it);
1149         if (!error) {
1150                 error = do_getattr(nd.mnt, nd.dentry, stat);
1151 +               intent_release(nd.dentry, &it);
1152                 path_release(&nd);
1153         }
1154         return error;
1155 --- linux-2.4.18-12-uml-pristine/mm/slab.c      Mon Sep  9 14:41:53 2002
1156 +++ linux-2.4.18-12-uml/mm/slab.c       Mon Sep  9 16:08:12 2002
1157 @@ -1208,6 +1208,59 @@
1158   * Called with the cache-lock held.
1159   */
1160  
1161 +extern struct page *check_get_page(unsigned long kaddr);
1162 +struct page *page_mem_map(struct page *page);
1163 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1164 +                                slab_t *slabp, void * objp)
1165 +{
1166 +       int i;
1167 +       unsigned int objnr;
1168 +
1169 +#if DEBUG
1170 +       if (cachep->flags & SLAB_RED_ZONE) {
1171 +               objp -= BYTES_PER_WORD;
1172 +               if ( *(unsigned long *)objp != RED_MAGIC2)
1173 +                       /* Either write before start, or a double free. */
1174 +                       return 0;
1175 +               if (*(unsigned long *)(objp+cachep->objsize -
1176 +                               BYTES_PER_WORD) != RED_MAGIC2)
1177 +                       /* Either write past end, or a double free. */
1178 +                       return 0;
1179 +       }
1180 +#endif
1181 +
1182 +       objnr = (objp-slabp->s_mem)/cachep->objsize;
1183 +       if (objnr >= cachep->num)
1184 +               return 0;
1185 +       if (objp != slabp->s_mem + objnr*cachep->objsize)
1186 +               return 0;
1187 +
1188 +       /* Check slab's freelist to see if this obj is there. */
1189 +       for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1190 +               if (i == objnr)
1191 +                       return 0;
1192 +       }
1193 +       return 1;
1194 +}
1195 +
1196 +
1197 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1198 +{
1199 +       struct page *page = check_get_page((unsigned long)objp);
1200 +
1201 +       if (!VALID_PAGE(page))
1202 +               return 0;
1203 +
1204 +       if (!PageSlab(page))
1205 +               return 0;
1206 +
1207 +       /* XXX check for freed slab objects ? */
1208 +       if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1209 +               return 0;
1210 +
1211 +       return (cachep == GET_PAGE_CACHE(page));
1212 +}
1213 +
1214  #if DEBUG
1215  static int kmem_extra_free_checks (kmem_cache_t * cachep,
1216                         slab_t *slabp, void * objp)
1217 Cheers, Andreas
1218 --
1219 Andreas Dilger
1220 http://sourceforge.net/projects/ext2resize/
1221 http://www-mddsp.enel.ucalgary.ca/People/adilger/