Whamcloud - gitweb
6dac00162c7fc32eaea200b192ef729158e60ba2
[fs/lustre-release.git] / lustre / patches / patch-2.4.18-chaos25
1 --- kernel-2.4.18-pristine/arch/ia64/mm/init.c  2002-10-14 13:47:20.000000000 -0600
2 +++ kernel-2.4.18/arch/ia64/mm/init.c   2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/arch/i386/mm/init.c  2002-10-14 13:47:20.000000000 -0600
17 +++ kernel-2.4.18/arch/i386/mm/init.c   2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/drivers/block/blkpg.c        2002-10-14 13:47:20.000000000 -0600
32 +++ kernel-2.4.18/drivers/block/blkpg.c 2002-10-14 14:08:23.000000000 -0600
33 @@ -295,3 +295,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 --- kernel-2.4.18-pristine/drivers/block/loop.c 2002-10-14 13:47:20.000000000 -0600
73 +++ kernel-2.4.18/drivers/block/loop.c  2002-10-14 14:08:23.000000000 -0600
74 @@ -503,6 +503,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 --- kernel-2.4.18-pristine/drivers/ide/ide-disk.c       2002-10-14 13:47:20.000000000 -0600
87 +++ kernel-2.4.18/drivers/ide/ide-disk.c        2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/fs/ext3/Makefile     2002-10-14 13:47:20.000000000 -0600
102 +++ kernel-2.4.18/fs/ext3/Makefile      2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/fs/ext3/super.c      2002-10-14 13:47:20.000000000 -0600
113 +++ kernel-2.4.18/fs/ext3/super.c       2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/include/linux/slab.h 2002-10-14 13:47:20.000000000 -0600
124 +++ kernel-2.4.18/include/linux/slab.h  2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/kernel/ksyms.c       2002-10-14 13:47:20.000000000 -0600
134 +++ kernel-2.4.18/kernel/ksyms.c        2002-10-14 14:08:23.000000000 -0600
135 @@ -306,6 +306,12 @@
136  EXPORT_SYMBOL(lock_may_write);
137  EXPORT_SYMBOL(dcache_readdir);
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 --- kernel-2.4.18-pristine/include/linux/dcache.h       2002-10-14 13:51:28.000000000 -0600
149 +++ kernel-2.4.18/include/linux/dcache.h        2002-10-14 14:08:23.000000000 -0600
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 @@ -79,6 +107,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 @@ -92,6 +121,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 --- kernel-2.4.18-pristine/include/linux/fs.h   2002-10-14 13:47:27.000000000 -0600
203 +++ kernel-2.4.18/include/linux/fs.h    2002-10-14 14:08:23.000000000 -0600
204 @@ -572,6 +572,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 @@ -829,7 +830,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 @@ -890,6 +893,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 @@ -1036,6 +1040,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 @@ -1370,6 +1375,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 @@ -1381,6 +1387,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 iput(struct inode *);
255  extern void force_delete(struct inode *);
256 --- kernel-2.4.18-pristine/fs/dcache.c  2002-10-14 13:47:27.000000000 -0600
257 +++ kernel-2.4.18/fs/dcache.c   2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/fs/nfsd/vfs.c        2002-10-14 13:47:27.000000000 -0600
267 +++ kernel-2.4.18/fs/nfsd/vfs.c 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/fs/namei.c   2002-10-14 13:56:44.000000000 -0600
278 +++ kernel-2.4.18/fs/namei.c    2002-10-14 14:08:23.000000000 -0600
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 @@ -447,7 +474,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 @@ -524,12 +552,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 @@ -563,7 +591,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 @@ -590,12 +618,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 @@ -619,7 +647,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 @@ -661,10 +690,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 @@ -749,6 +789,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 @@ -777,7 +828,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 @@ -800,13 +852,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 @@ -818,6 +873,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 @@ -839,7 +900,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 @@ -870,6 +931,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 @@ -1008,7 +1086,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 @@ -1022,7 +1101,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 @@ -1032,6 +1111,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 @@ -1047,7 +1130,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 @@ -1056,6 +1139,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 @@ -1175,8 +1259,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 @@ -1196,6 +1282,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 @@ -1217,13 +1305,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 @@ -1231,7 +1326,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 @@ -1277,6 +1372,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 @@ -1287,7 +1383,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 @@ -1305,6 +1401,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 @@ -1345,6 +1442,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 @@ -1355,11 +1453,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 @@ -1439,6 +1538,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 @@ -1460,10 +1560,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 @@ -1507,6 +1608,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 @@ -1519,7 +1621,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 @@ -1527,6 +1629,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 @@ -1573,6 +1676,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 @@ -1586,10 +1690,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 @@ -1654,6 +1760,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 @@ -1661,7 +1768,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 @@ -1670,10 +1778,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 @@ -1715,7 +1822,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 @@ -1773,6 +1881,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 @@ -1794,7 +1903,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 @@ -1825,6 +1935,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 @@ -1836,13 +1947,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 @@ -1859,6 +1971,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 @@ -1884,7 +1997,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 @@ -1900,18 +2013,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 --- kernel-2.4.18-pristine/fs/open.c    2002-10-14 13:47:27.000000000 -0600
863 +++ kernel-2.4.18/fs/open.c     2002-10-14 14:08:23.000000000 -0600
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 +172,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 +264,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 +292,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 +310,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 @@ -330,6 +338,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 @@ -346,6 +355,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 @@ -363,13 +373,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 @@ -384,8 +395,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 @@ -396,6 +410,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 @@ -435,9 +450,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 @@ -453,6 +469,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 @@ -497,8 +514,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 @@ -518,6 +536,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 @@ -587,10 +606,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 @@ -600,10 +621,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 @@ -637,10 +660,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 @@ -648,14 +677,15 @@
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 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1082 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1083 +                           int flags, struct lookup_intent *it)
1084  {
1085         struct file * f;
1086         struct inode *inode;
1087 @@ -698,6 +728,7 @@
1088         }
1089         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1090  
1091 +       intent_release(dentry, it);
1092         return f;
1093  
1094  cleanup_all:
1095 @@ -712,11 +743,17 @@
1096  cleanup_file:
1097         put_filp(f);
1098  cleanup_dentry:
1099 +       intent_release(dentry, it);
1100         dput(dentry);
1101         mntput(mnt);
1102         return ERR_PTR(error);
1103  }
1104  
1105 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1106 +{
1107 +       return dentry_open_it(dentry, mnt, flags, NULL);
1108 +}
1109 +
1110  /*
1111   * Find an empty file descriptor entry, and mark it busy.
1112   */
1113 --- kernel-2.4.18-pristine/fs/stat.c    2002-10-14 13:47:27.000000000 -0600
1114 +++ kernel-2.4.18/fs/stat.c     2002-10-14 14:08:23.000000000 -0600
1115 @@ -13,6 +13,7 @@
1116  
1117  #include <asm/uaccess.h>
1118  
1119 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1120  /*
1121   * Revalidate the inode. This is required for proper NFS attribute caching.
1122   */
1123 @@ -104,10 +105,12 @@
1124  {
1125         struct nameidata nd;
1126         int error;
1127 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1128  
1129 -       error = user_path_walk(name, &nd);
1130 +       error = user_path_walk_it(name, &nd, &it);
1131         if (!error) {
1132                 error = do_getattr(nd.mnt, nd.dentry, stat);
1133 +               intent_release(nd.dentry, &it);
1134                 path_release(&nd);
1135         }
1136         return error;
1137 @@ -117,10 +120,12 @@
1138  {
1139         struct nameidata nd;
1140         int error;
1141 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1142  
1143 -       error = user_path_walk_link(name, &nd);
1144 +       error = user_path_walk_link_it(name, &nd, &it);
1145         if (!error) {
1146                 error = do_getattr(nd.mnt, nd.dentry, stat);
1147 +               intent_release(nd.dentry, &it);
1148                 path_release(&nd);
1149         }
1150         return error;
1151 --- kernel-2.4.18-pristine/mm/slab.c    2002-10-14 13:47:27.000000000 -0600
1152 +++ kernel-2.4.18/mm/slab.c     2002-10-14 14:08:23.000000000 -0600
1153 @@ -1207,6 +1207,59 @@
1154   * Called with the cache-lock held.
1155   */
1156  
1157 +extern struct page *check_get_page(unsigned long kaddr);
1158 +struct page *page_mem_map(struct page *page);
1159 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1160 +                                slab_t *slabp, void * objp)
1161 +{
1162 +       int i;
1163 +       unsigned int objnr;
1164 +
1165 +#if DEBUG
1166 +       if (cachep->flags & SLAB_RED_ZONE) {
1167 +               objp -= BYTES_PER_WORD;
1168 +               if ( *(unsigned long *)objp != RED_MAGIC2)
1169 +                       /* Either write before start, or a double free. */
1170 +                       return 0;
1171 +               if (*(unsigned long *)(objp+cachep->objsize -
1172 +                               BYTES_PER_WORD) != RED_MAGIC2)
1173 +                       /* Either write past end, or a double free. */
1174 +                       return 0;
1175 +       }
1176 +#endif
1177 +
1178 +       objnr = (objp-slabp->s_mem)/cachep->objsize;
1179 +       if (objnr >= cachep->num)
1180 +               return 0;
1181 +       if (objp != slabp->s_mem + objnr*cachep->objsize)
1182 +               return 0;
1183 +
1184 +       /* Check slab's freelist to see if this obj is there. */
1185 +       for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1186 +               if (i == objnr)
1187 +                       return 0;
1188 +       }
1189 +       return 1;
1190 +}
1191 +
1192 +
1193 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1194 +{
1195 +       struct page *page = check_get_page((unsigned long)objp);
1196 +
1197 +       if (!VALID_PAGE(page))
1198 +               return 0;
1199 +
1200 +       if (!PageSlab(page))
1201 +               return 0;
1202 +
1203 +       /* XXX check for freed slab objects ? */
1204 +       if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1205 +               return 0;
1206 +
1207 +       return (cachep == GET_PAGE_CACHE(page));
1208 +}
1209 +
1210  #if DEBUG
1211  static int kmem_extra_free_checks (kmem_cache_t * cachep,
1212                         slab_t *slabp, void * objp)
1213 --- kernel-2.4.18-pristine/fs/jbd/commit.c      2002-10-14 13:47:20.000000000 -0600
1214 +++ kernel-2.4.18/fs/jbd/commit.c       2002-10-14 14:08:23.000000000 -0600
1215 @@ -482,7 +482,7 @@
1216             transaction's t_log_list queue, and metadata buffers are on
1217             the t_iobuf_list queue.
1218  
1219 -          Wait for the transactions in reverse order.  That way we are
1220 +          Wait for the buffers in reverse order.  That way we are
1221            less likely to be woken up until all IOs have completed, and
1222            so we incur less scheduling load.
1223         */
1224 @@ -575,8 +575,10 @@
1225  
1226         jbd_debug(3, "JBD: commit phase 6\n");
1227  
1228 -       if (is_journal_aborted(journal))
1229 +       if (is_journal_aborted(journal)) {
1230 +               unlock_journal(journal);
1231                 goto skip_commit;
1232 +       }
1233  
1234         /* Done it all: now write the commit record.  We should have
1235          * cleaned up our previous buffers by now, so if we are in abort
1236 @@ -586,6 +588,7 @@
1237         descriptor = journal_get_descriptor_buffer(journal);
1238         if (!descriptor) {
1239                 __journal_abort_hard(journal);
1240 +               unlock_journal(journal);
1241                 goto skip_commit;
1242         }
1243         
1244 @@ -609,7 +612,6 @@
1245                 put_bh(bh);             /* One for getblk() */
1246                 journal_unlock_journal_head(descriptor);
1247         }
1248 -       lock_journal(journal);
1249  
1250         /* End of a transaction!  Finally, we can do checkpoint
1251             processing: any buffers committed as a result of this
1252 @@ -618,6 +620,25 @@
1253  
1254  skip_commit:
1255  
1256 +       /* Call any callbacks that had been registered for handles in this
1257 +        * transaction.  It is up to the callback to free any allocated
1258 +        * memory.
1259 +        */
1260 +       if (!list_empty(&commit_transaction->t_jcb)) {
1261 +               struct list_head *p, *n;
1262 +               int error = is_journal_aborted(journal);
1263 +
1264 +               list_for_each_safe(p, n, &commit_transaction->t_jcb) {
1265 +                       struct journal_callback *jcb;
1266 +
1267 +                       jcb = list_entry(p, struct journal_callback, jcb_list);
1268 +                       list_del(p);
1269 +                       jcb->jcb_func(jcb, error);
1270 +               }
1271 +       }
1272 +
1273 +       lock_journal(journal);
1274 +
1275         jbd_debug(3, "JBD: commit phase 7\n");
1276  
1277         J_ASSERT(commit_transaction->t_sync_datalist == NULL);
1278 --- kernel-2.4.18-pristine/fs/jbd/journal.c     2002-10-14 13:47:20.000000000 -0600
1279 +++ kernel-2.4.18/fs/jbd/journal.c      2002-10-14 14:08:23.000000000 -0600
1280 @@ -58,6 +58,7 @@
1281  #endif
1282  EXPORT_SYMBOL(journal_flush);
1283  EXPORT_SYMBOL(journal_revoke);
1284 +EXPORT_SYMBOL(journal_callback_set);
1285  
1286  EXPORT_SYMBOL(journal_init_dev);
1287  EXPORT_SYMBOL(journal_init_inode);
1288 --- kernel-2.4.18-pristine/fs/jbd/transaction.c 2002-10-14 13:47:20.000000000 -0600
1289 +++ kernel-2.4.18/fs/jbd/transaction.c  2002-10-14 14:08:23.000000000 -0600
1290 @@ -57,6 +57,7 @@
1291         transaction->t_state = T_RUNNING;
1292         transaction->t_tid = journal->j_transaction_sequence++;
1293         transaction->t_expires = jiffies + journal->j_commit_interval;
1294 +       INIT_LIST_HEAD(&transaction->t_jcb);
1295  
1296         /* Set up the commit timer for the new transaction. */
1297         J_ASSERT (!journal->j_commit_timer_active);
1298 @@ -201,6 +202,20 @@
1299         return 0;
1300  }
1301  
1302 +/* Allocate a new handle.  This should probably be in a slab... */
1303 +static handle_t *new_handle(int nblocks)
1304 +{
1305 +       handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
1306 +       if (!handle)
1307 +               return NULL;
1308 +       memset(handle, 0, sizeof (handle_t));
1309 +       handle->h_buffer_credits = nblocks;
1310 +       handle->h_ref = 1;
1311 +       INIT_LIST_HEAD(&handle->h_jcb);
1312 +
1313 +       return handle;
1314 +}
1315 +
1316  /*
1317   * Obtain a new handle.  
1318   *
1319 @@ -227,14 +242,11 @@
1320                 handle->h_ref++;
1321                 return handle;
1322         }
1323 -       
1324 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
1325 +
1326 +       handle = new_handle(nblocks);
1327         if (!handle)
1328                 return ERR_PTR(-ENOMEM);
1329 -       memset (handle, 0, sizeof (handle_t));
1330  
1331 -       handle->h_buffer_credits = nblocks;
1332 -       handle->h_ref = 1;
1333         current->journal_info = handle;
1334  
1335         err = start_this_handle(journal, handle);
1336 @@ -333,14 +345,11 @@
1337         
1338         if (is_journal_aborted(journal))
1339                 return ERR_PTR(-EIO);
1340 -       
1341 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
1342 +
1343 +       handle = new_handle(nblocks);
1344         if (!handle)
1345                 return ERR_PTR(-ENOMEM);
1346 -       memset (handle, 0, sizeof (handle_t));
1347  
1348 -       handle->h_buffer_credits = nblocks;
1349 -       handle->h_ref = 1;
1350         current->journal_info = handle;
1351  
1352         err = try_start_this_handle(journal, handle);
1353 @@ -1319,6 +1328,28 @@
1354  #endif
1355  
1356  /*
1357 + * Register a callback function for this handle.  The function will be
1358 + * called when the transaction that this handle is part of has been
1359 + * committed to disk with the original callback data struct and the
1360 + * error status of the journal as parameters.  There is no guarantee of
1361 + * ordering between handles within a single transaction, nor between
1362 + * callbacks registered on the same handle.
1363 + *
1364 + * The caller is responsible for allocating the journal_callback struct.
1365 + * This is to allow the caller to add as much extra data to the callback
1366 + * as needed, but reduce the overhead of multiple allocations.  The caller
1367 + * allocated struct must start with a struct journal_callback at offset 0,
1368 + * and has the caller-specific data afterwards.
1369 + */
1370 +void journal_callback_set(handle_t *handle,
1371 +                         void (*func)(struct journal_callback *jcb, int error),
1372 +                         struct journal_callback *jcb)
1373 +{
1374 +       list_add(&jcb->jcb_list, &handle->h_jcb);
1375 +       jcb->jcb_func = func;
1376 +}
1377 +
1378 +/*
1379   * All done for a particular handle.
1380   *
1381   * There is not much action needed here.  We just return any remaining
1382 @@ -1383,7 +1414,10 @@
1383                         wake_up(&journal->j_wait_transaction_locked);
1384         }
1385  
1386 -       /* 
1387 +       /* Move callbacks from the handle to the transaction. */
1388 +       list_splice(&handle->h_jcb, &transaction->t_jcb);
1389 +
1390 +       /*
1391          * If the handle is marked SYNC, we need to set another commit
1392          * going!  We also want to force a commit if the current
1393          * transaction is occupying too much of the log, or if the
1394 --- kernel-2.4.18-pristine/include/linux/jbd.h  2002-10-14 13:47:20.000000000 -0600
1395 +++ kernel-2.4.18/include/linux/jbd.h   2002-10-14 14:08:23.000000000 -0600
1396 @@ -257,6 +257,13 @@
1397         return bh->b_private;
1398  }
1399  
1400 +#define HAVE_JOURNAL_CALLBACK_STATUS
1401 +struct journal_callback {
1402 +       struct list_head jcb_list;
1403 +       void (*jcb_func)(struct journal_callback *jcb, int error);
1404 +       /* user data goes here */
1405 +};
1406 +
1407  struct jbd_revoke_table_s;
1408  
1409  /* The handle_t type represents a single atomic update being performed
1410 @@ -287,6 +294,12 @@
1411            operations */
1412         int                     h_err;
1413  
1414 +       /* List of application registered callbacks for this handle.
1415 +        * The function(s) will be called after the transaction that
1416 +        * this handle is part of has been committed to disk.
1417 +        */
1418 +       struct list_head        h_jcb;
1419 +
1420         /* Flags */
1421         unsigned int    h_sync:         1;      /* sync-on-close */
1422         unsigned int    h_jdata:        1;      /* force data journaling */
1423 @@ -406,6 +419,10 @@
1424  
1425         /* How many handles used this transaction? */
1426         int t_handle_count;
1427 +
1428 +       /* List of registered callback functions for this transaction.
1429 +        * Called when the transaction is committed. */
1430 +       struct list_head        t_jcb;
1431  };
1432  
1433  
1434 @@ -654,6 +671,9 @@
1435  extern int      journal_try_to_free_buffers(journal_t *, struct page *, int);
1436  extern int      journal_stop(handle_t *);
1437  extern int      journal_flush (journal_t *);
1438 +extern void     journal_callback_set(handle_t *handle,
1439 +                                     void (*fn)(struct journal_callback *,int),
1440 +                                     struct journal_callback *jcb);
1441  
1442  extern void     journal_lock_updates (journal_t *);
1443  extern void     journal_unlock_updates (journal_t *);