Whamcloud - gitweb
- add more patch series files. We have now obsoleted most of the
[fs/lustre-release.git] / lustre / kernel_patches / patches / vanilla-2.4.19.patch
1  arch/i386/mm/init.c            |    6 +
2  arch/ia64/mm/init.c            |    6 +
3  drivers/block/blkpg.c          |   35 ++++++
4  drivers/block/loop.c           |    5 
5  drivers/ide/ide-disk.c         |    6 +
6  fs/dcache.c                    |    1 
7  fs/ext3/Makefile               |    2 
8  fs/ext3/super.c                |    2 
9  fs/jbd/commit.c                |   27 ++++-
10  fs/jbd/journal.c               |    1 
11  fs/jbd/transaction.c           |   56 ++++++++--
12  fs/namei.c                     |  215 ++++++++++++++++++++++++++++++++---------
13  fs/nfsd/vfs.c                  |    2 
14  fs/open.c                      |   63 +++++++++---
15  fs/stat.c                      |   30 ++++-
16  include/linux/blkdev.h         |    4 
17  include/linux/dcache.h         |   31 +++++
18  include/linux/fs.h             |   14 ++
19  include/linux/jbd.h            |   20 +++
20  include/linux/lustre_version.h |    1 
21  include/linux/slab.h           |    1 
22  kernel/ksyms.c                 |    7 +
23  mm/slab.c                      |   53 ++++++++++
24  23 files changed, 502 insertions(+), 86 deletions(-)
25
26 --- /dev/null   Fri Aug 30 17:31:37 2002
27 +++ linux-2.4.19-root/include/linux/lustre_version.h    Sun Dec 15 16:58:43 2002
28 @@ -0,0 +1 @@
29 +#define LUSTRE_KERNEL_VERSION 4
30 --- linux-2.4.19/arch/ia64/mm/init.c~vanilla-2.4.19     Sun Dec 15 16:58:43 2002
31 +++ linux-2.4.19-root/arch/ia64/mm/init.c       Sun Dec 15 16:58:43 2002
32 @@ -37,6 +37,12 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF
33  
34  static unsigned long totalram_pages;
35  
36 +struct page *check_get_page(unsigned long kaddr)
37 +{
38 +#warning FIXME: Lustre team, is this solid?
39 +       return virt_to_page(kaddr);
40 +}
41 +
42  int
43  do_check_pgt_cache (int low, int high)
44  {
45 --- linux-2.4.19/arch/i386/mm/init.c~vanilla-2.4.19     Sun Dec 15 16:58:43 2002
46 +++ linux-2.4.19-root/arch/i386/mm/init.c       Sun Dec 15 16:58:43 2002
47 @@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn
48  static unsigned long totalram_pages;
49  static unsigned long totalhigh_pages;
50  
51 +struct page *check_get_page(unsigned long kaddr)
52 +{
53 +#warning FIXME: Lustre team, is this solid?
54 +       return virt_to_page(kaddr);
55 +}
56 +
57  int do_check_pgt_cache(int low, int high)
58  {
59         int freed = 0;
60 --- linux-2.4.19/drivers/block/blkpg.c~vanilla-2.4.19   Sun Dec 15 16:58:43 2002
61 +++ linux-2.4.19-root/drivers/block/blkpg.c     Sun Dec 15 16:58:43 2002
62 @@ -296,3 +296,38 @@ int blk_ioctl(kdev_t dev, unsigned int c
63  }
64  
65  EXPORT_SYMBOL(blk_ioctl);
66 +
67 +#define NUM_DEV_NO_WRITE 16
68 +static int dev_no_write[NUM_DEV_NO_WRITE];
69 +
70 +/*
71 + * Debug code for turning block devices "read-only" (will discard writes
72 + * silently).  This is for filesystem crash/recovery testing.
73 + */
74 +void dev_set_rdonly(kdev_t dev, int no_write)
75 +{
76 +       if (dev) {
77 +               printk(KERN_WARNING "Turning device %s read-only\n",
78 +                      bdevname(dev));
79 +               dev_no_write[no_write] = 0xdead0000 + dev;
80 +       }
81 +}
82 +
83 +int dev_check_rdonly(kdev_t dev) {
84 +       int i;
85 +
86 +       for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
87 +               if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
88 +                   dev == (dev_no_write[i] & 0xffff))
89 +                       return 1;
90 +       }
91 +       return 0;
92 +}
93 +
94 +void dev_clear_rdonly(int no_write) {
95 +       dev_no_write[no_write] = 0;
96 +}
97 +
98 +EXPORT_SYMBOL(dev_set_rdonly);
99 +EXPORT_SYMBOL(dev_check_rdonly);
100 +EXPORT_SYMBOL(dev_clear_rdonly);
101 --- linux-2.4.19/drivers/block/loop.c~vanilla-2.4.19    Sun Dec 15 16:58:43 2002
102 +++ linux-2.4.19-root/drivers/block/loop.c      Sun Dec 15 16:58:43 2002
103 @@ -474,6 +474,11 @@ static int loop_make_request(request_que
104         spin_unlock_irq(&lo->lo_lock);
105  
106         if (rw == WRITE) {
107 +#ifdef CONFIG_DEV_RDONLY
108 +               if (dev_check_rdonly(rbh->b_rdev))
109 +                       goto err;
110 +#endif
111 +
112                 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
113                         goto err;
114         } else if (rw == READA) {
115 --- linux-2.4.19/drivers/ide/ide-disk.c~vanilla-2.4.19  Sun Dec 15 16:58:43 2002
116 +++ linux-2.4.19-root/drivers/ide/ide-disk.c    Sun Dec 15 16:58:43 2002
117 @@ -551,6 +551,12 @@ static ide_startstop_t lba_48_rw_disk (i
118   */
119  static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
120  {
121 +#ifdef CONFIG_DEV_RDONLY
122 +       if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
123 +               ide_end_request(1, HWGROUP(drive));
124 +               return ide_stopped;
125 +       }
126 +#endif
127         if (IDE_CONTROL_REG)
128                 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
129  
130 --- linux-2.4.19/fs/ext3/Makefile~vanilla-2.4.19        Sun Dec 15 16:58:43 2002
131 +++ linux-2.4.19-root/fs/ext3/Makefile  Sun Dec 15 16:58:43 2002
132 @@ -9,6 +9,8 @@
133  
134  O_TARGET := ext3.o
135  
136 +export-objs := super.o
137 +
138  obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
139                 ioctl.o namei.o super.o symlink.o
140  obj-m    := $(O_TARGET)
141 --- linux-2.4.19/fs/ext3/super.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
142 +++ linux-2.4.19-root/fs/ext3/super.c   Sun Dec 15 16:58:43 2002
143 @@ -1744,7 +1744,7 @@ static void __exit exit_ext3_fs(void)
144         unregister_filesystem(&ext3_fs_type);
145  }
146  
147 -EXPORT_NO_SYMBOLS;
148 +EXPORT_SYMBOL(ext3_bread);
149  
150  MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
151  MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
152 --- linux-2.4.19/fs/jbd/commit.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
153 +++ linux-2.4.19-root/fs/jbd/commit.c   Sun Dec 15 16:58:43 2002
154 @@ -475,7 +475,7 @@ start_journal_io:
155             transaction's t_log_list queue, and metadata buffers are on
156             the t_iobuf_list queue.
157  
158 -          Wait for the transactions in reverse order.  That way we are
159 +          Wait for the buffers in reverse order.  That way we are
160            less likely to be woken up until all IOs have completed, and
161            so we incur less scheduling load.
162         */
163 @@ -566,8 +566,10 @@ start_journal_io:
164  
165         jbd_debug(3, "JBD: commit phase 6\n");
166  
167 -       if (is_journal_aborted(journal))
168 +       if (is_journal_aborted(journal)) {
169 +               unlock_journal(journal);
170                 goto skip_commit;
171 +       }
172  
173         /* Done it all: now write the commit record.  We should have
174          * cleaned up our previous buffers by now, so if we are in abort
175 @@ -577,6 +579,7 @@ start_journal_io:
176         descriptor = journal_get_descriptor_buffer(journal);
177         if (!descriptor) {
178                 __journal_abort_hard(journal);
179 +               unlock_journal(journal);
180                 goto skip_commit;
181         }
182         
183 @@ -600,7 +603,6 @@ start_journal_io:
184                 put_bh(bh);             /* One for getblk() */
185                 journal_unlock_journal_head(descriptor);
186         }
187 -       lock_journal(journal);
188  
189         /* End of a transaction!  Finally, we can do checkpoint
190             processing: any buffers committed as a result of this
191 @@ -609,6 +611,25 @@ start_journal_io:
192  
193  skip_commit:
194  
195 +       /* Call any callbacks that had been registered for handles in this
196 +        * transaction.  It is up to the callback to free any allocated
197 +        * memory.
198 +        */
199 +       if (!list_empty(&commit_transaction->t_jcb)) {
200 +               struct list_head *p, *n;
201 +               int error = is_journal_aborted(journal);
202 +
203 +               list_for_each_safe(p, n, &commit_transaction->t_jcb) {
204 +                       struct journal_callback *jcb;
205 +
206 +                       jcb = list_entry(p, struct journal_callback, jcb_list);
207 +                       list_del(p);
208 +                       jcb->jcb_func(jcb, error);
209 +               }
210 +       }
211 +
212 +       lock_journal(journal);
213 +
214         jbd_debug(3, "JBD: commit phase 7\n");
215  
216         J_ASSERT(commit_transaction->t_sync_datalist == NULL);
217 --- linux-2.4.19/fs/jbd/journal.c~vanilla-2.4.19        Sun Dec 15 16:58:43 2002
218 +++ linux-2.4.19-root/fs/jbd/journal.c  Sun Dec 15 16:58:43 2002
219 @@ -58,6 +58,7 @@ EXPORT_SYMBOL(journal_sync_buffer);
220  #endif
221  EXPORT_SYMBOL(journal_flush);
222  EXPORT_SYMBOL(journal_revoke);
223 +EXPORT_SYMBOL(journal_callback_set);
224  
225  EXPORT_SYMBOL(journal_init_dev);
226  EXPORT_SYMBOL(journal_init_inode);
227 --- linux-2.4.19/fs/jbd/transaction.c~vanilla-2.4.19    Sun Dec 15 16:58:43 2002
228 +++ linux-2.4.19-root/fs/jbd/transaction.c      Sun Dec 15 16:58:43 2002
229 @@ -57,6 +57,7 @@ static transaction_t * get_transaction (
230         transaction->t_state = T_RUNNING;
231         transaction->t_tid = journal->j_transaction_sequence++;
232         transaction->t_expires = jiffies + journal->j_commit_interval;
233 +       INIT_LIST_HEAD(&transaction->t_jcb);
234  
235         /* Set up the commit timer for the new transaction. */
236         J_ASSERT (!journal->j_commit_timer_active);
237 @@ -201,6 +202,20 @@ repeat_locked:
238         return 0;
239  }
240  
241 +/* Allocate a new handle.  This should probably be in a slab... */
242 +static handle_t *new_handle(int nblocks)
243 +{
244 +       handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
245 +       if (!handle)
246 +               return NULL;
247 +       memset(handle, 0, sizeof (handle_t));
248 +       handle->h_buffer_credits = nblocks;
249 +       handle->h_ref = 1;
250 +       INIT_LIST_HEAD(&handle->h_jcb);
251 +
252 +       return handle;
253 +}
254 +
255  /*
256   * Obtain a new handle.  
257   *
258 @@ -227,14 +242,11 @@ handle_t *journal_start(journal_t *journ
259                 handle->h_ref++;
260                 return handle;
261         }
262 -       
263 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
264 +
265 +       handle = new_handle(nblocks);
266         if (!handle)
267                 return ERR_PTR(-ENOMEM);
268 -       memset (handle, 0, sizeof (handle_t));
269  
270 -       handle->h_buffer_credits = nblocks;
271 -       handle->h_ref = 1;
272         current->journal_info = handle;
273  
274         err = start_this_handle(journal, handle);
275 @@ -333,14 +345,11 @@ handle_t *journal_try_start(journal_t *j
276         
277         if (is_journal_aborted(journal))
278                 return ERR_PTR(-EIO);
279 -       
280 -       handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
281 +
282 +       handle = new_handle(nblocks);
283         if (!handle)
284                 return ERR_PTR(-ENOMEM);
285 -       memset (handle, 0, sizeof (handle_t));
286  
287 -       handle->h_buffer_credits = nblocks;
288 -       handle->h_ref = 1;
289         current->journal_info = handle;
290  
291         err = try_start_this_handle(journal, handle);
292 @@ -1328,6 +1337,28 @@ out:
293  #endif
294  
295  /*
296 + * Register a callback function for this handle.  The function will be
297 + * called when the transaction that this handle is part of has been
298 + * committed to disk with the original callback data struct and the
299 + * error status of the journal as parameters.  There is no guarantee of
300 + * ordering between handles within a single transaction, nor between
301 + * callbacks registered on the same handle.
302 + *
303 + * The caller is responsible for allocating the journal_callback struct.
304 + * This is to allow the caller to add as much extra data to the callback
305 + * as needed, but reduce the overhead of multiple allocations.  The caller
306 + * allocated struct must start with a struct journal_callback at offset 0,
307 + * and has the caller-specific data afterwards.
308 + */
309 +void journal_callback_set(handle_t *handle,
310 +                         void (*func)(struct journal_callback *jcb, int error),
311 +                         struct journal_callback *jcb)
312 +{
313 +       list_add(&jcb->jcb_list, &handle->h_jcb);
314 +       jcb->jcb_func = func;
315 +}
316 +
317 +/*
318   * All done for a particular handle.
319   *
320   * There is not much action needed here.  We just return any remaining
321 @@ -1393,7 +1424,10 @@ int journal_stop(handle_t *handle)
322                         wake_up(&journal->j_wait_transaction_locked);
323         }
324  
325 -       /* 
326 +       /* Move callbacks from the handle to the transaction. */
327 +       list_splice(&handle->h_jcb, &transaction->t_jcb);
328 +
329 +       /*
330          * If the handle is marked SYNC, we need to set another commit
331          * going!  We also want to force a commit if the current
332          * transaction is occupying too much of the log, or if the
333 --- linux-2.4.19/include/linux/blkdev.h~vanilla-2.4.19  Sun Dec 15 16:58:43 2002
334 +++ linux-2.4.19-root/include/linux/blkdev.h    Sun Dec 15 17:02:24 2002
335 @@ -240,4 +240,8 @@ static inline unsigned int block_size(kd
336         return retval;
337  }
338  
339 +#define CONFIG_DEV_RDONLY
340 +void dev_set_rdonly(kdev_t, int);
341 +int dev_check_rdonly(kdev_t);
342 +void dev_clear_rdonly(int);
343  #endif
344 --- linux-2.4.19/include/linux/slab.h~vanilla-2.4.19    Sun Dec 15 16:58:43 2002
345 +++ linux-2.4.19-root/include/linux/slab.h      Sun Dec 15 17:02:12 2002
346 @@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache
347  extern int kmem_cache_shrink(kmem_cache_t *);
348  extern void *kmem_cache_alloc(kmem_cache_t *, int);
349  extern void kmem_cache_free(kmem_cache_t *, void *);
350 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
351  
352  extern void *kmalloc(size_t, int);
353  extern void kfree(const void *);
354 --- linux-2.4.19/include/linux/jbd.h~vanilla-2.4.19     Sun Dec 15 16:58:43 2002
355 +++ linux-2.4.19-root/include/linux/jbd.h       Sun Dec 15 16:58:43 2002
356 @@ -249,6 +249,13 @@ static inline struct journal_head *bh2jh
357         return bh->b_private;
358  }
359  
360 +#define HAVE_JOURNAL_CALLBACK_STATUS
361 +struct journal_callback {
362 +       struct list_head jcb_list;
363 +       void (*jcb_func)(struct journal_callback *jcb, int error);
364 +       /* user data goes here */
365 +};
366 +
367  struct jbd_revoke_table_s;
368  
369  /* The handle_t type represents a single atomic update being performed
370 @@ -279,6 +286,12 @@ struct handle_s 
371            operations */
372         int                     h_err;
373  
374 +       /* List of application registered callbacks for this handle.
375 +        * The function(s) will be called after the transaction that
376 +        * this handle is part of has been committed to disk.
377 +        */
378 +       struct list_head        h_jcb;
379 +
380         /* Flags */
381         unsigned int    h_sync:         1;      /* sync-on-close */
382         unsigned int    h_jdata:        1;      /* force data journaling */
383 @@ -398,6 +411,10 @@ struct transaction_s 
384  
385         /* How many handles used this transaction? */
386         int t_handle_count;
387 +
388 +       /* List of registered callback functions for this transaction.
389 +        * Called when the transaction is committed. */
390 +       struct list_head        t_jcb;
391  };
392  
393  
394 @@ -646,6 +663,9 @@ extern int   journal_flushpage(journal_t 
395  extern int      journal_try_to_free_buffers(journal_t *, struct page *, int);
396  extern int      journal_stop(handle_t *);
397  extern int      journal_flush (journal_t *);
398 +extern void     journal_callback_set(handle_t *handle,
399 +                                     void (*fn)(struct journal_callback *,int),
400 +                                     struct journal_callback *jcb);
401  
402  extern void     journal_lock_updates (journal_t *);
403  extern void     journal_unlock_updates (journal_t *);
404 --- linux-2.4.19/kernel/ksyms.c~vanilla-2.4.19  Sun Dec 15 16:58:43 2002
405 +++ linux-2.4.19-root/kernel/ksyms.c    Sun Dec 15 17:03:55 2002
406 @@ -264,6 +264,7 @@ EXPORT_SYMBOL(read_cache_page);
407  EXPORT_SYMBOL(set_page_dirty);
408  EXPORT_SYMBOL(vfs_readlink);
409  EXPORT_SYMBOL(vfs_follow_link);
410 +EXPORT_SYMBOL(vfs_follow_link_it);
411  EXPORT_SYMBOL(page_readlink);
412  EXPORT_SYMBOL(page_follow_link);
413  EXPORT_SYMBOL(page_symlink_inode_operations);
414 @@ -280,6 +281,12 @@ EXPORT_SYMBOL(dcache_dir_fsync);
415  EXPORT_SYMBOL(dcache_readdir);
416  EXPORT_SYMBOL(dcache_dir_ops);
417  
418 +/* lustre */
419 +EXPORT_SYMBOL(panic_notifier_list);
420 +EXPORT_SYMBOL(pagecache_lock_cacheline);
421 +EXPORT_SYMBOL(do_kern_mount);
422 +EXPORT_SYMBOL(kmem_cache_validate);
423 +
424  /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
425  EXPORT_SYMBOL(default_llseek);
426  EXPORT_SYMBOL(dentry_open);
427 --- linux-2.4.19/include/linux/dcache.h~vanilla-2.4.19  Sun Dec 15 16:58:43 2002
428 +++ linux-2.4.19-root/include/linux/dcache.h    Sun Dec 15 17:02:11 2002
429 @@ -6,6 +6,34 @@
430  #include <asm/atomic.h>
431  #include <linux/mount.h>
432  
433 +#define IT_OPEN  (1)
434 +#define IT_CREAT  (1<<1)
435 +#define IT_MKDIR  (1<<2)
436 +#define IT_LINK  (1<<3)
437 +#define IT_LINK2  (1<<4)
438 +#define IT_SYMLINK  (1<<5)
439 +#define IT_UNLINK  (1<<6)
440 +#define IT_RMDIR  (1<<7)
441 +#define IT_RENAME  (1<<8)
442 +#define IT_RENAME2  (1<<9)
443 +#define IT_READDIR  (1<<10)
444 +#define IT_GETATTR  (1<<11)
445 +#define IT_SETATTR  (1<<12)
446 +#define IT_READLINK  (1<<13)
447 +#define IT_MKNOD  (1<<14)
448 +#define IT_LOOKUP  (1<<15)
449 +
450 +struct lookup_intent {
451 +       int it_op;
452 +       int it_mode;
453 +       int it_disposition;
454 +       int it_status;
455 +       struct iattr *it_iattr;
456 +       __u64 it_lock_handle[2];
457 +       int it_lock_mode;
458 +       void *it_data;
459 +};
460 +
461  /*
462   * linux/include/linux/dcache.h
463   *
464 @@ -78,6 +106,7 @@ struct dentry {
465         unsigned long d_time;           /* used by d_revalidate */
466         struct dentry_operations  *d_op;
467         struct super_block * d_sb;      /* The root of the dentry tree */
468 +       struct lookup_intent *d_it;
469         unsigned long d_vfs_flags;
470         void * d_fsdata;                /* fs-specific data */
471         unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
472 @@ -90,6 +119,8 @@ struct dentry_operations {
473         int (*d_delete)(struct dentry *);
474         void (*d_release)(struct dentry *);
475         void (*d_iput)(struct dentry *, struct inode *);
476 +       int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
477 +       void (*d_intent_release)(struct dentry *, struct lookup_intent *);
478  };
479  
480  /* the dentry parameter passed to d_hash and d_compare is the parent
481 --- linux-2.4.19/include/linux/fs.h~vanilla-2.4.19      Sun Dec 15 16:58:43 2002
482 +++ linux-2.4.19-root/include/linux/fs.h        Sun Dec 15 17:02:11 2002
483 @@ -541,6 +541,7 @@ struct file {
484  
485         /* needed for tty driver, and maybe others */
486         void                    *private_data;
487 +       struct lookup_intent    *f_intent;
488  
489         /* preallocated helper kiobuf to speedup O_DIRECT */
490         struct kiobuf           *f_iobuf;
491 @@ -792,7 +793,9 @@ extern int vfs_symlink(struct inode *, s
492  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
493  extern int vfs_rmdir(struct inode *, struct dentry *);
494  extern int vfs_unlink(struct inode *, struct dentry *);
495 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
496 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
497 +               struct inode *new_dir, struct dentry *new_dentry,
498 +               struct lookup_intent *it);
499  
500  /*
501   * File types
502 @@ -853,6 +856,7 @@ struct file_operations {
503  struct inode_operations {
504         int (*create) (struct inode *,struct dentry *,int);
505         struct dentry * (*lookup) (struct inode *,struct dentry *);
506 +       struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
507         int (*link) (struct dentry *,struct inode *,struct dentry *);
508         int (*unlink) (struct inode *,struct dentry *);
509         int (*symlink) (struct inode *,struct dentry *,const char *);
510 @@ -863,6 +867,8 @@ struct inode_operations {
511                         struct inode *, struct dentry *);
512         int (*readlink) (struct dentry *, char *,int);
513         int (*follow_link) (struct dentry *, struct nameidata *);
514 +       int (*follow_link2) (struct dentry *, struct nameidata *,
515 +                              struct lookup_intent *it);
516         void (*truncate) (struct inode *);
517         int (*permission) (struct inode *, int);
518         int (*revalidate) (struct dentry *);
519 @@ -999,6 +1005,7 @@ extern int unregister_filesystem(struct 
520  extern struct vfsmount *kern_mount(struct file_system_type *);
521  extern int may_umount(struct vfsmount *);
522  extern long do_mount(char *, char *, char *, unsigned long, void *);
523 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
524  extern void umount_tree(struct vfsmount *);
525  
526  #define kern_umount mntput
527 @@ -1329,6 +1336,7 @@ typedef int (*read_actor_t)(read_descrip
528  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
529  
530  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
531 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
532  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
533  extern int FASTCALL(path_walk(const char *, struct nameidata *));
534  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
535 @@ -1339,6 +1347,8 @@ extern struct dentry * lookup_one_len(co
536  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
537  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
538  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
539 +#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
540 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
541  
542  extern void iput(struct inode *);
543  extern void force_delete(struct inode *);
544 @@ -1448,6 +1458,8 @@ extern struct file_operations generic_ro
545  
546  extern int vfs_readlink(struct dentry *, char *, int, const char *);
547  extern int vfs_follow_link(struct nameidata *, const char *);
548 +extern int vfs_follow_link_it(struct nameidata *, const char *,
549 +                             struct lookup_intent *it);
550  extern int page_readlink(struct dentry *, char *, int);
551  extern int page_follow_link(struct dentry *, struct nameidata *);
552  extern struct inode_operations page_symlink_inode_operations;
553 --- linux-2.4.19/fs/dcache.c~vanilla-2.4.19     Sun Dec 15 16:58:43 2002
554 +++ linux-2.4.19-root/fs/dcache.c       Sun Dec 15 16:58:43 2002
555 @@ -616,6 +616,7 @@ struct dentry * d_alloc(struct dentry * 
556         dentry->d_op = NULL;
557         dentry->d_fsdata = NULL;
558         dentry->d_mounted = 0;
559 +       dentry->d_it = NULL;
560         INIT_LIST_HEAD(&dentry->d_hash);
561         INIT_LIST_HEAD(&dentry->d_lru);
562         INIT_LIST_HEAD(&dentry->d_subdirs);
563 --- linux-2.4.19/fs/nfsd/vfs.c~vanilla-2.4.19   Sun Dec 15 16:58:43 2002
564 +++ linux-2.4.19-root/fs/nfsd/vfs.c     Sun Dec 15 16:58:43 2002
565 @@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
566                         err = nfserr_perm;
567         } else
568  #endif
569 -       err = vfs_rename(fdir, odentry, tdir, ndentry);
570 +       err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
571         if (!err && EX_ISSYNC(tfhp->fh_export)) {
572                 nfsd_sync_dir(tdentry);
573                 nfsd_sync_dir(fdentry);
574 --- linux-2.4.19/fs/namei.c~vanilla-2.4.19      Sun Dec 15 16:58:43 2002
575 +++ linux-2.4.19-root/fs/namei.c        Sun Dec 15 16:58:43 2002
576 @@ -94,6 +94,12 @@
577   * XEmacs seems to be relying on it...
578   */
579  
580 +void intent_release(struct dentry *de, struct lookup_intent *it)
581 +{
582 +       if (it && de->d_op && de->d_op->d_intent_release)
583 +               de->d_op->d_intent_release(de, it);
584 +}
585 +
586  /* In order to reduce some races, while at the same time doing additional
587   * checking and hopefully speeding things up, we copy filenames to the
588   * kernel data space before using them..
589 @@ -260,10 +266,19 @@ void path_release(struct nameidata *nd)
590   * Internal lookup() using the new generic dcache.
591   * SMP-safe
592   */
593 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
594 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
595 +                                   int flags, struct lookup_intent *it)
596  {
597         struct dentry * dentry = d_lookup(parent, name);
598  
599 +       if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
600 +               if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
601 +                   !d_invalidate(dentry)) {
602 +                       dput(dentry);
603 +                       dentry = NULL;
604 +               }
605 +               return dentry;
606 +       } else
607         if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
608                 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
609                         dput(dentry);
610 @@ -281,7 +296,8 @@ static struct dentry * cached_lookup(str
611   * make sure that nobody added the entry to the dcache in the meantime..
612   * SMP-safe
613   */
614 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
615 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
616 +                                 int flags, struct lookup_intent *it)
617  {
618         struct dentry * result;
619         struct inode *dir = parent->d_inode;
620 @@ -300,6 +316,9 @@ static struct dentry * real_lookup(struc
621                 result = ERR_PTR(-ENOMEM);
622                 if (dentry) {
623                         lock_kernel();
624 +                       if (dir->i_op->lookup2)
625 +                               result = dir->i_op->lookup2(dir, dentry, it);
626 +                       else
627                         result = dir->i_op->lookup(dir, dentry);
628                         unlock_kernel();
629                         if (result)
630 @@ -321,6 +340,12 @@ static struct dentry * real_lookup(struc
631                         dput(result);
632                         result = ERR_PTR(-ENOENT);
633                 }
634 +       } else if (result->d_op && result->d_op->d_revalidate2) {
635 +               if (!result->d_op->d_revalidate2(result, flags, it) &&
636 +                   !d_invalidate(result)) {
637 +                       dput(result);
638 +                       result = ERR_PTR(-ENOENT);
639 +               }
640         }
641         return result;
642  }
643 @@ -332,7 +357,8 @@ static struct dentry * real_lookup(struc
644   * Without that kind of total limit, nasty chains of consecutive
645   * symlinks can cause almost arbitrarily long lookups. 
646   */
647 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
648 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
649 +                                struct lookup_intent *it)
650  {
651         int err;
652         if (current->link_count >= 5)
653 @@ -346,10 +372,14 @@ static inline int do_follow_link(struct 
654         current->link_count++;
655         current->total_link_count++;
656         UPDATE_ATIME(dentry->d_inode);
657 -       err = dentry->d_inode->i_op->follow_link(dentry, nd);
658 +       if (dentry->d_inode->i_op->follow_link2)
659 +               err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
660 +       else
661 +               err = dentry->d_inode->i_op->follow_link(dentry, nd);
662         current->link_count--;
663         return err;
664  loop:
665 +       intent_release(dentry, it);
666         path_release(nd);
667         return -ELOOP;
668  }
669 @@ -447,7 +477,8 @@ static inline void follow_dotdot(struct 
670   *
671   * We expect 'base' to be positive and a directory.
672   */
673 -int link_path_walk(const char * name, struct nameidata *nd)
674 +int link_path_walk_it(const char *name, struct nameidata *nd,
675 +                     struct lookup_intent *it)
676  {
677         struct dentry *dentry;
678         struct inode *inode;
679 @@ -520,9 +551,9 @@ int link_path_walk(const char * name, st
680                                 break;
681                 }
682                 /* This does the actual lookups.. */
683 -               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
684 +               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
685                 if (!dentry) {
686 -                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
687 +                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
688                         err = PTR_ERR(dentry);
689                         if (IS_ERR(dentry))
690                                 break;
691 @@ -539,8 +570,8 @@ int link_path_walk(const char * name, st
692                 if (!inode->i_op)
693                         goto out_dput;
694  
695 -               if (inode->i_op->follow_link) {
696 -                       err = do_follow_link(dentry, nd);
697 +               if (inode->i_op->follow_link || inode->i_op->follow_link2) {
698 +                       err = do_follow_link(dentry, nd, it);
699                         dput(dentry);
700                         if (err)
701                                 goto return_err;
702 @@ -556,7 +587,7 @@ int link_path_walk(const char * name, st
703                         nd->dentry = dentry;
704                 }
705                 err = -ENOTDIR; 
706 -               if (!inode->i_op->lookup)
707 +               if (!inode->i_op->lookup && !inode->i_op->lookup2)
708                         break;
709                 continue;
710                 /* here ends the main loop */
711 @@ -583,9 +614,9 @@ last_component:
712                         if (err < 0)
713                                 break;
714                 }
715 -               dentry = cached_lookup(nd->dentry, &this, 0);
716 +               dentry = cached_lookup(nd->dentry, &this, 0, it);
717                 if (!dentry) {
718 -                       dentry = real_lookup(nd->dentry, &this, 0);
719 +                       dentry = real_lookup(nd->dentry, &this, 0, it);
720                         err = PTR_ERR(dentry);
721                         if (IS_ERR(dentry))
722                                 break;
723 @@ -593,9 +624,9 @@ last_component:
724                 while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
725                         ;
726                 inode = dentry->d_inode;
727 -               if ((lookup_flags & LOOKUP_FOLLOW)
728 -                   && inode && inode->i_op && inode->i_op->follow_link) {
729 -                       err = do_follow_link(dentry, nd);
730 +               if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op &&
731 +                   (inode->i_op->follow_link || inode->i_op->follow_link2)) {
732 +                       err = do_follow_link(dentry, nd, it);
733                         dput(dentry);
734                         if (err)
735                                 goto return_err;
736 @@ -609,7 +640,8 @@ last_component:
737                         goto no_inode;
738                 if (lookup_flags & LOOKUP_DIRECTORY) {
739                         err = -ENOTDIR; 
740 -                       if (!inode->i_op || !inode->i_op->lookup)
741 +                       if (!inode->i_op ||
742 +                           (!inode->i_op->lookup && !inode->i_op->lookup2))
743                                 break;
744                 }
745                 goto return_base;
746 @@ -651,10 +683,21 @@ return_err:
747         return err;
748  }
749  
750 +int link_path_walk(const char * name, struct nameidata *nd)
751 +{
752 +       return link_path_walk_it(name, nd, NULL);
753 +}
754 +
755 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
756 +{
757 +       current->total_link_count = 0;
758 +       return link_path_walk_it(name, nd, it);
759 +}
760 +
761  int path_walk(const char * name, struct nameidata *nd)
762  {
763         current->total_link_count = 0;
764 -       return link_path_walk(name, nd);
765 +       return link_path_walk_it(name, nd, NULL);
766  }
767  
768  /* SMP-safe */
769 @@ -757,7 +800,8 @@ int path_init(const char *name, unsigned
770   * needs parent already locked. Doesn't follow mounts.
771   * SMP-safe.
772   */
773 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
774 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
775 +                              struct lookup_intent *it)
776  {
777         struct dentry * dentry;
778         struct inode *inode;
779 @@ -780,13 +824,16 @@ struct dentry * lookup_hash(struct qstr 
780                         goto out;
781         }
782  
783 -       dentry = cached_lookup(base, name, 0);
784 +       dentry = cached_lookup(base, name, 0, it);
785         if (!dentry) {
786                 struct dentry *new = d_alloc(base, name);
787                 dentry = ERR_PTR(-ENOMEM);
788                 if (!new)
789                         goto out;
790                 lock_kernel();
791 +               if (inode->i_op->lookup2)
792 +                       dentry = inode->i_op->lookup2(inode, new, it);
793 +               else
794                 dentry = inode->i_op->lookup(inode, new);
795                 unlock_kernel();
796                 if (!dentry)
797 @@ -798,6 +845,12 @@ out:
798         return dentry;
799  }
800  
801 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
802 +{
803 +       return lookup_hash_it(name, base, NULL);
804 +}
805 +
806 +
807  /* SMP-safe */
808  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
809  {
810 @@ -819,7 +872,7 @@ struct dentry * lookup_one_len(const cha
811         }
812         this.hash = end_name_hash(hash);
813  
814 -       return lookup_hash(&this, base);
815 +       return lookup_hash_it(&this, base, NULL);
816  access:
817         return ERR_PTR(-EACCES);
818  }
819 @@ -851,6 +904,23 @@ int __user_walk(const char *name, unsign
820         return err;
821  }
822  
823 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
824 +                  struct lookup_intent *it)
825 +{
826 +       char *tmp;
827 +       int err;
828 +
829 +       tmp = getname(name);
830 +       err = PTR_ERR(tmp);
831 +       if (!IS_ERR(tmp)) {
832 +               err = 0;
833 +               if (path_init(tmp, flags, nd))
834 +                       err = path_walk_it(tmp, nd, it);
835 +               putname(tmp);
836 +       }
837 +       return err;
838 +}
839 +
840  /*
841   * It's inline, so penalty for filesystems that don't use sticky bit is
842   * minimal.
843 @@ -987,7 +1057,8 @@ exit_lock:
844   * for symlinks (where the permissions are checked later).
845   * SMP-safe
846   */
847 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
848 +int open_namei_it(const char *pathname, int flag, int mode,
849 +                 struct nameidata *nd, struct lookup_intent *it)
850  {
851         int acc_mode, error = 0;
852         struct inode *inode;
853 @@ -1002,7 +1073,7 @@ int open_namei(const char * pathname, in
854          */
855         if (!(flag & O_CREAT)) {
856                 if (path_init(pathname, lookup_flags(flag), nd))
857 -                       error = path_walk(pathname, nd);
858 +                       error = path_walk_it(pathname, nd, it);
859                 if (error)
860                         return error;
861                 dentry = nd->dentry;
862 @@ -1012,6 +1083,10 @@ int open_namei(const char * pathname, in
863         /*
864          * Create - we need to know the parent.
865          */
866 +       if (it) {
867 +               it->it_mode = mode;
868 +               it->it_op |= IT_CREAT;
869 +       }
870         if (path_init(pathname, LOOKUP_PARENT, nd))
871                 error = path_walk(pathname, nd);
872         if (error)
873 @@ -1028,7 +1103,7 @@ int open_namei(const char * pathname, in
874  
875         dir = nd->dentry;
876         down(&dir->d_inode->i_sem);
877 -       dentry = lookup_hash(&nd->last, nd->dentry);
878 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
879  
880  do_last:
881         error = PTR_ERR(dentry);
882 @@ -1037,6 +1112,7 @@ do_last:
883                 goto exit;
884         }
885  
886 +       it->it_mode = mode;
887         /* Negative dentry, just create the file */
888         if (!dentry->d_inode) {
889                 error = vfs_create(dir->d_inode, dentry,
890 @@ -1070,7 +1146,8 @@ do_last:
891         error = -ENOENT;
892         if (!dentry->d_inode)
893                 goto exit_dput;
894 -       if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
895 +       if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
896 +                                     dentry->d_inode->i_op->follow_link2))
897                 goto do_link;
898  
899         dput(nd->dentry);
900 @@ -1156,8 +1233,10 @@ ok:
901         return 0;
902  
903  exit_dput:
904 +       intent_release(dentry, it);
905         dput(dentry);
906  exit:
907 +       intent_release(nd->dentry, it);
908         path_release(nd);
909         return error;
910  
911 @@ -1176,7 +1255,12 @@ do_link:
912          * are done. Procfs-like symlinks just set LAST_BIND.
913          */
914         UPDATE_ATIME(dentry->d_inode);
915 -       error = dentry->d_inode->i_op->follow_link(dentry, nd);
916 +       if (dentry->d_inode->i_op->follow_link2)
917 +               error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
918 +       else
919 +               error = dentry->d_inode->i_op->follow_link(dentry, nd);
920 +       if (error)
921 +               intent_release(dentry, it);
922         dput(dentry);
923         if (error)
924                 return error;
925 @@ -1198,13 +1282,20 @@ do_link:
926         }
927         dir = nd->dentry;
928         down(&dir->d_inode->i_sem);
929 -       dentry = lookup_hash(&nd->last, nd->dentry);
930 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
931         putname(nd->last.name);
932         goto do_last;
933  }
934  
935 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
936 +{
937 +       return open_namei_it(pathname, flag, mode, nd, NULL);
938 +}
939 +
940 +
941  /* SMP-safe */
942 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
943 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
944 +                                   struct lookup_intent *it)
945  {
946         struct dentry *dentry;
947  
948 @@ -1212,7 +1303,7 @@ static struct dentry *lookup_create(stru
949         dentry = ERR_PTR(-EEXIST);
950         if (nd->last_type != LAST_NORM)
951                 goto fail;
952 -       dentry = lookup_hash(&nd->last, nd->dentry);
953 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
954         if (IS_ERR(dentry))
955                 goto fail;
956         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
957 @@ -1258,6 +1349,7 @@ asmlinkage long sys_mknod(const char * f
958         char * tmp;
959         struct dentry * dentry;
960         struct nameidata nd;
961 +       struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
962  
963         if (S_ISDIR(mode))
964                 return -EPERM;
965 @@ -1269,7 +1361,7 @@ asmlinkage long sys_mknod(const char * f
966                 error = path_walk(tmp, &nd);
967         if (error)
968                 goto out;
969 -       dentry = lookup_create(&nd, 0);
970 +       dentry = lookup_create(&nd, 0, &it);
971         error = PTR_ERR(dentry);
972  
973         mode &= ~current->fs->umask;
974 @@ -1287,6 +1379,7 @@ asmlinkage long sys_mknod(const char * f
975                 default:
976                         error = -EINVAL;
977                 }
978 +               intent_release(dentry, &it);
979                 dput(dentry);
980         }
981         up(&nd.dentry->d_inode->i_sem);
982 @@ -1327,6 +1420,7 @@ asmlinkage long sys_mkdir(const char * p
983  {
984         int error = 0;
985         char * tmp;
986 +       struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
987  
988         tmp = getname(pathname);
989         error = PTR_ERR(tmp);
990 @@ -1338,11 +1432,12 @@ asmlinkage long sys_mkdir(const char * p
991                         error = path_walk(tmp, &nd);
992                 if (error)
993                         goto out;
994 -               dentry = lookup_create(&nd, 1);
995 +               dentry = lookup_create(&nd, 1, &it);
996                 error = PTR_ERR(dentry);
997                 if (!IS_ERR(dentry)) {
998                         error = vfs_mkdir(nd.dentry->d_inode, dentry,
999                                           mode & ~current->fs->umask);
1000 +                       intent_release(dentry, &it);
1001                         dput(dentry);
1002                 }
1003                 up(&nd.dentry->d_inode->i_sem);
1004 @@ -1426,6 +1521,7 @@ asmlinkage long sys_rmdir(const char * p
1005         char * name;
1006         struct dentry *dentry;
1007         struct nameidata nd;
1008 +       struct lookup_intent it = { .it_op = IT_RMDIR };
1009  
1010         name = getname(pathname);
1011         if(IS_ERR(name))
1012 @@ -1448,10 +1544,11 @@ asmlinkage long sys_rmdir(const char * p
1013                         goto exit1;
1014         }
1015         down(&nd.dentry->d_inode->i_sem);
1016 -       dentry = lookup_hash(&nd.last, nd.dentry);
1017 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1018         error = PTR_ERR(dentry);
1019         if (!IS_ERR(dentry)) {
1020                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1021 +               intent_release(dentry, &it);
1022                 dput(dentry);
1023         }
1024         up(&nd.dentry->d_inode->i_sem);
1025 @@ -1495,6 +1592,7 @@ asmlinkage long sys_unlink(const char * 
1026         char * name;
1027         struct dentry *dentry;
1028         struct nameidata nd;
1029 +       struct lookup_intent it = { .it_op = IT_UNLINK };
1030  
1031         name = getname(pathname);
1032         if(IS_ERR(name))
1033 @@ -1508,7 +1606,7 @@ asmlinkage long sys_unlink(const char * 
1034         if (nd.last_type != LAST_NORM)
1035                 goto exit1;
1036         down(&nd.dentry->d_inode->i_sem);
1037 -       dentry = lookup_hash(&nd.last, nd.dentry);
1038 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1039         error = PTR_ERR(dentry);
1040         if (!IS_ERR(dentry)) {
1041                 /* Why not before? Because we want correct error value */
1042 @@ -1516,6 +1614,7 @@ asmlinkage long sys_unlink(const char * 
1043                         goto slashes;
1044                 error = vfs_unlink(nd.dentry->d_inode, dentry);
1045         exit2:
1046 +               intent_release(dentry, &it);
1047                 dput(dentry);
1048         }
1049         up(&nd.dentry->d_inode->i_sem);
1050 @@ -1562,6 +1661,7 @@ asmlinkage long sys_symlink(const char *
1051         int error = 0;
1052         char * from;
1053         char * to;
1054 +       struct lookup_intent it = { .it_op = IT_SYMLINK };
1055  
1056         from = getname(oldname);
1057         if(IS_ERR(from))
1058 @@ -1576,10 +1676,12 @@ asmlinkage long sys_symlink(const char *
1059                         error = path_walk(to, &nd);
1060                 if (error)
1061                         goto out;
1062 -               dentry = lookup_create(&nd, 0);
1063 +               it.it_data = from;
1064 +               dentry = lookup_create(&nd, 0, &it);
1065                 error = PTR_ERR(dentry);
1066                 if (!IS_ERR(dentry)) {
1067                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1068 +                       intent_release(dentry, &it);
1069                         dput(dentry);
1070                 }
1071                 up(&nd.dentry->d_inode->i_sem);
1072 @@ -1645,6 +1747,7 @@ asmlinkage long sys_link(const char * ol
1073         int error;
1074         char * from;
1075         char * to;
1076 +       struct lookup_intent it = { .it_op = IT_LINK };
1077  
1078         from = getname(oldname);
1079         if(IS_ERR(from))
1080 @@ -1657,7 +1760,7 @@ asmlinkage long sys_link(const char * ol
1081  
1082                 error = 0;
1083                 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
1084 -                       error = path_walk(from, &old_nd);
1085 +                       error = path_walk_it(from, &old_nd, &it);
1086                 if (error)
1087                         goto exit;
1088                 if (path_init(to, LOOKUP_PARENT, &nd))
1089 @@ -1667,10 +1770,12 @@ asmlinkage long sys_link(const char * ol
1090                 error = -EXDEV;
1091                 if (old_nd.mnt != nd.mnt)
1092                         goto out_release;
1093 -               new_dentry = lookup_create(&nd, 0);
1094 +               it.it_op = IT_LINK2;
1095 +               new_dentry = lookup_create(&nd, 0, &it);
1096                 error = PTR_ERR(new_dentry);
1097                 if (!IS_ERR(new_dentry)) {
1098                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1099 +                       intent_release(new_dentry, &it);
1100                         dput(new_dentry);
1101                 }
1102                 up(&nd.dentry->d_inode->i_sem);
1103 @@ -1713,7 +1818,8 @@ exit:
1104   *        locking].
1105   */
1106  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1107 -              struct inode *new_dir, struct dentry *new_dentry)
1108 +                  struct inode *new_dir, struct dentry *new_dentry,
1109 +                  struct lookup_intent *it)
1110  {
1111         int error;
1112         struct inode *target;
1113 @@ -1771,6 +1877,7 @@ int vfs_rename_dir(struct inode *old_dir
1114                 error = -EBUSY;
1115         else 
1116                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1117 +       intent_release(new_dentry, it);
1118         if (target) {
1119                 if (!error)
1120                         target->i_flags |= S_DEAD;
1121 @@ -1792,7 +1899,8 @@ out_unlock:
1122  }
1123  
1124  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1125 -              struct inode *new_dir, struct dentry *new_dentry)
1126 +                    struct inode *new_dir, struct dentry *new_dentry,
1127 +                    struct lookup_intent *it)
1128  {
1129         int error;
1130  
1131 @@ -1823,6 +1931,7 @@ int vfs_rename_other(struct inode *old_d
1132                 error = -EBUSY;
1133         else
1134                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1135 +       intent_release(new_dentry, it);
1136         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1137         if (error)
1138                 return error;
1139 @@ -1834,13 +1943,14 @@ int vfs_rename_other(struct inode *old_d
1140  }
1141  
1142  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1143 -              struct inode *new_dir, struct dentry *new_dentry)
1144 +              struct inode *new_dir, struct dentry *new_dentry,
1145 +              struct lookup_intent *it)
1146  {
1147         int error;
1148         if (S_ISDIR(old_dentry->d_inode->i_mode))
1149 -               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1150 +               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1151         else
1152 -               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1153 +               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1154         if (!error) {
1155                 if (old_dir == new_dir)
1156                         inode_dir_notify(old_dir, DN_RENAME);
1157 @@ -1857,6 +1967,7 @@ static inline int do_rename(const char *
1158         int error = 0;
1159         struct dentry * old_dir, * new_dir;
1160         struct dentry * old_dentry, *new_dentry;
1161 +       struct lookup_intent it = { .it_op = IT_RENAME };
1162         struct nameidata oldnd, newnd;
1163  
1164         if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1165 @@ -1885,7 +1996,7 @@ static inline int do_rename(const char *
1166  
1167         double_lock(new_dir, old_dir);
1168  
1169 -       old_dentry = lookup_hash(&oldnd.last, old_dir);
1170 +       old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1171         error = PTR_ERR(old_dentry);
1172         if (IS_ERR(old_dentry))
1173                 goto exit3;
1174 @@ -1901,18 +2012,21 @@ static inline int do_rename(const char *
1175                 if (newnd.last.name[newnd.last.len])
1176                         goto exit4;
1177         }
1178 -       new_dentry = lookup_hash(&newnd.last, new_dir);
1179 +       it.it_op = IT_RENAME2;
1180 +       new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1181         error = PTR_ERR(new_dentry);
1182         if (IS_ERR(new_dentry))
1183                 goto exit4;
1184  
1185         lock_kernel();
1186         error = vfs_rename(old_dir->d_inode, old_dentry,
1187 -                                  new_dir->d_inode, new_dentry);
1188 +                                  new_dir->d_inode, new_dentry, &it);
1189         unlock_kernel();
1190  
1191 +       intent_release(new_dentry, &it);
1192         dput(new_dentry);
1193  exit4:
1194 +       intent_release(old_dentry, &it);
1195         dput(old_dentry);
1196  exit3:
1197         double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1198 @@ -1961,7 +2075,8 @@ out:
1199  }
1200  
1201  static inline int
1202 -__vfs_follow_link(struct nameidata *nd, const char *link)
1203 +__vfs_follow_link(struct nameidata *nd, const char *link,
1204 +                 struct lookup_intent *it)
1205  {
1206         int res = 0;
1207         char *name;
1208 @@ -1974,7 +2089,7 @@ __vfs_follow_link(struct nameidata *nd, 
1209                         /* weird __emul_prefix() stuff did it */
1210                         goto out;
1211         }
1212 -       res = link_path_walk(link, nd);
1213 +       res = link_path_walk_it(link, nd, it);
1214  out:
1215         if (current->link_count || res || nd->last_type!=LAST_NORM)
1216                 return res;
1217 @@ -1996,7 +2111,13 @@ fail:
1218  
1219  int vfs_follow_link(struct nameidata *nd, const char *link)
1220  {
1221 -       return __vfs_follow_link(nd, link);
1222 +       return __vfs_follow_link(nd, link, NULL);
1223 +}
1224 +
1225 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
1226 +                      struct lookup_intent *it)
1227 +{
1228 +       return __vfs_follow_link(nd, link, it);
1229  }
1230  
1231  /* get the link contents into pagecache */
1232 @@ -2038,7 +2159,7 @@ int page_follow_link(struct dentry *dent
1233  {
1234         struct page *page = NULL;
1235         char *s = page_getlink(dentry, &page);
1236 -       int res = __vfs_follow_link(nd, s);
1237 +       int res = __vfs_follow_link(nd, s, NULL);
1238         if (page) {
1239                 kunmap(page);
1240                 page_cache_release(page);
1241 --- linux-2.4.19/fs/open.c~vanilla-2.4.19       Sun Dec 15 16:58:43 2002
1242 +++ linux-2.4.19-root/fs/open.c Sun Dec 15 16:58:43 2002
1243 @@ -19,6 +19,9 @@
1244  #include <asm/uaccess.h>
1245  
1246  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1247 +extern int path_walk_it(const char *name, struct nameidata *nd,
1248 +                       struct lookup_intent *it);
1249 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1250  
1251  int vfs_statfs(struct super_block *sb, struct statfs *buf)
1252  {
1253 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
1254         struct nameidata nd;
1255         struct inode * inode;
1256         int error;
1257 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1258  
1259         error = -EINVAL;
1260         if (length < 0) /* sorry, but loff_t says... */
1261                 goto out;
1262  
1263 -       error = user_path_walk(path, &nd);
1264 +       error = user_path_walk_it(path, &nd, &it);
1265         if (error)
1266                 goto out;
1267         inode = nd.dentry->d_inode;
1268 @@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
1269         put_write_access(inode);
1270  
1271  dput_and_out:
1272 +       intent_release(nd.dentry, &it);
1273         path_release(&nd);
1274  out:
1275         return error;
1276 @@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
1277         struct nameidata nd;
1278         struct inode * inode;
1279         struct iattr newattrs;
1280 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1281  
1282 -       error = user_path_walk(filename, &nd);
1283 +       error = user_path_walk_it(filename, &nd, &it);
1284         if (error)
1285                 goto out;
1286         inode = nd.dentry->d_inode;
1287 @@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
1288         }
1289         error = notify_change(nd.dentry, &newattrs);
1290  dput_and_out:
1291 +       intent_release(nd.dentry, &it);
1292         path_release(&nd);
1293  out:
1294         return error;
1295 @@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
1296         struct nameidata nd;
1297         struct inode * inode;
1298         struct iattr newattrs;
1299 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1300  
1301 -       error = user_path_walk(filename, &nd);
1302 +       error = user_path_walk_it(filename, &nd, &it);
1303  
1304         if (error)
1305                 goto out;
1306 @@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
1307         }
1308         error = notify_change(nd.dentry, &newattrs);
1309  dput_and_out:
1310 +       intent_release(nd.dentry, &it);
1311         path_release(&nd);
1312  out:
1313         return error;
1314 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * 
1315         int old_fsuid, old_fsgid;
1316         kernel_cap_t old_cap;
1317         int res;
1318 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1319  
1320         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
1321                 return -EINVAL;
1322 @@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * 
1323         else
1324                 current->cap_effective = current->cap_permitted;
1325  
1326 -       res = user_path_walk(filename, &nd);
1327 +       res = user_path_walk_it(filename, &nd, &it);
1328         if (!res) {
1329                 res = permission(nd.dentry->d_inode, mode);
1330                 /* SuS v2 requires we report a read only fs too */
1331                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1332                    && !special_file(nd.dentry->d_inode->i_mode))
1333                         res = -EROFS;
1334 +               intent_release(nd.dentry, &it);
1335                 path_release(&nd);
1336         }
1337  
1338 @@ -386,6 +397,7 @@ asmlinkage long sys_chdir(const char * f
1339         int error;
1340         struct nameidata nd;
1341         char *name;
1342 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1343  
1344         name = getname(filename);
1345         error = PTR_ERR(name);
1346 @@ -394,7 +406,7 @@ asmlinkage long sys_chdir(const char * f
1347  
1348         error = 0;
1349         if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1350 -               error = path_walk(name, &nd);
1351 +               error = path_walk_it(name, &nd, &it);
1352         putname(name);
1353         if (error)
1354                 goto out;
1355 @@ -406,6 +418,7 @@ asmlinkage long sys_chdir(const char * f
1356         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1357  
1358  dput_and_out:
1359 +       intent_release(nd.dentry, &it);
1360         path_release(&nd);
1361  out:
1362         return error;
1363 @@ -446,6 +459,7 @@ asmlinkage long sys_chroot(const char * 
1364         int error;
1365         struct nameidata nd;
1366         char *name;
1367 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1368  
1369         name = getname(filename);
1370         error = PTR_ERR(name);
1371 @@ -454,7 +468,7 @@ asmlinkage long sys_chroot(const char * 
1372  
1373         path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1374                       LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1375 -       error = path_walk(name, &nd);   
1376 +       error = path_walk_it(name, &nd, &it);
1377         putname(name);
1378         if (error)
1379                 goto out;
1380 @@ -471,6 +485,7 @@ asmlinkage long sys_chroot(const char * 
1381         set_fs_altroot();
1382         error = 0;
1383  dput_and_out:
1384 +       intent_release(nd.dentry, &it);
1385         path_release(&nd);
1386  out:
1387         return error;
1388 @@ -515,8 +530,9 @@ asmlinkage long sys_chmod(const char * f
1389         struct inode * inode;
1390         int error;
1391         struct iattr newattrs;
1392 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1393  
1394 -       error = user_path_walk(filename, &nd);
1395 +       error = user_path_walk_it(filename, &nd, &it);
1396         if (error)
1397                 goto out;
1398         inode = nd.dentry->d_inode;
1399 @@ -536,6 +552,7 @@ asmlinkage long sys_chmod(const char * f
1400         error = notify_change(nd.dentry, &newattrs);
1401  
1402  dput_and_out:
1403 +       intent_release(nd.dentry, &it);
1404         path_release(&nd);
1405  out:
1406         return error;
1407 @@ -605,10 +622,12 @@ asmlinkage long sys_chown(const char * f
1408  {
1409         struct nameidata nd;
1410         int error;
1411 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1412  
1413 -       error = user_path_walk(filename, &nd);
1414 +       error = user_path_walk_it(filename, &nd, &it);
1415         if (!error) {
1416                 error = chown_common(nd.dentry, user, group);
1417 +               intent_release(nd.dentry, &it);
1418                 path_release(&nd);
1419         }
1420         return error;
1421 @@ -618,10 +637,12 @@ asmlinkage long sys_lchown(const char * 
1422  {
1423         struct nameidata nd;
1424         int error;
1425 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1426  
1427 -       error = user_path_walk_link(filename, &nd);
1428 +       error = user_path_walk_link_it(filename, &nd, &it);
1429         if (!error) {
1430                 error = chown_common(nd.dentry, user, group);
1431 +               intent_release(nd.dentry, &it);
1432                 path_release(&nd);
1433         }
1434         return error;
1435 @@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int 
1436   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1437   * used by symlinks.
1438   */
1439 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1440 +                        struct nameidata *nd, struct lookup_intent *it);
1441 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1442 +                           int flags, struct lookup_intent *it);
1443 +
1444  struct file *filp_open(const char * filename, int flags, int mode)
1445  {
1446         int namei_flags, error;
1447         struct nameidata nd;
1448 +       struct lookup_intent it = { .it_op = IT_OPEN };
1449  
1450         namei_flags = flags;
1451         if ((namei_flags+1) & O_ACCMODE)
1452 @@ -666,14 +693,15 @@ struct file *filp_open(const char * file
1453         if (namei_flags & O_TRUNC)
1454                 namei_flags |= 2;
1455  
1456 -       error = open_namei(filename, namei_flags, mode, &nd);
1457 -       if (!error)
1458 -               return dentry_open(nd.dentry, nd.mnt, flags);
1459 +       error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1460 +       if (error)
1461 +               return ERR_PTR(error);
1462  
1463 -       return ERR_PTR(error);
1464 +       return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1465  }
1466  
1467 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1468 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1469 +                           int flags, struct lookup_intent *it)
1470  {
1471         struct file * f;
1472         struct inode *inode;
1473 @@ -716,6 +744,7 @@ struct file *dentry_open(struct dentry *
1474         }
1475         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1476  
1477 +       intent_release(dentry, it);
1478         return f;
1479  
1480  cleanup_all:
1481 @@ -730,11 +759,17 @@ cleanup_all:
1482  cleanup_file:
1483         put_filp(f);
1484  cleanup_dentry:
1485 +       intent_release(dentry, it);
1486         dput(dentry);
1487         mntput(mnt);
1488         return ERR_PTR(error);
1489  }
1490  
1491 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1492 +{
1493 +       return dentry_open_it(dentry, mnt, flags, NULL);
1494 +}
1495 +
1496  /*
1497   * Find an empty file descriptor entry, and mark it busy.
1498   */
1499 --- linux-2.4.19/fs/stat.c~vanilla-2.4.19       Sun Dec 15 16:58:43 2002
1500 +++ linux-2.4.19-root/fs/stat.c Sun Dec 15 16:58:43 2002
1501 @@ -13,6 +13,7 @@
1502  
1503  #include <asm/uaccess.h>
1504  
1505 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1506  /*
1507   * Revalidate the inode. This is required for proper NFS attribute caching.
1508   */
1509 @@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in
1510  asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1511  {
1512         struct nameidata nd;
1513 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1514         int error;
1515  
1516 -       error = user_path_walk(filename, &nd);
1517 +       error = user_path_walk_it(filename, &nd, &it);
1518         if (!error) {
1519                 error = do_revalidate(nd.dentry);
1520                 if (!error)
1521                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1522 +               intent_release(nd.dentry, &it);
1523                 path_release(&nd);
1524         }
1525         return error;
1526 @@ -151,13 +154,15 @@ asmlinkage long sys_stat(char * filename
1527  asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1528  {
1529         struct nameidata nd;
1530 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1531         int error;
1532  
1533 -       error = user_path_walk(filename, &nd);
1534 +       error = user_path_walk_it(filename, &nd, &it);
1535         if (!error) {
1536                 error = do_revalidate(nd.dentry);
1537                 if (!error)
1538                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1539 +               intent_release(nd.dentry, &it);
1540                 path_release(&nd);
1541         }
1542         return error;
1543 @@ -172,13 +177,15 @@ asmlinkage long sys_newstat(char * filen
1544  asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1545  {
1546         struct nameidata nd;
1547 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1548         int error;
1549  
1550 -       error = user_path_walk_link(filename, &nd);
1551 +       error = user_path_walk_link_it(filename, &nd, &it);
1552         if (!error) {
1553                 error = do_revalidate(nd.dentry);
1554                 if (!error)
1555                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1556 +               intent_release(nd.dentry, &it);
1557                 path_release(&nd);
1558         }
1559         return error;
1560 @@ -189,13 +196,15 @@ asmlinkage long sys_lstat(char * filenam
1561  asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1562  {
1563         struct nameidata nd;
1564 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1565         int error;
1566  
1567 -       error = user_path_walk_link(filename, &nd);
1568 +       error = user_path_walk_link_it(filename, &nd, &it);
1569         if (!error) {
1570                 error = do_revalidate(nd.dentry);
1571                 if (!error)
1572                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1573 +               intent_release(nd.dentry, &it);
1574                 path_release(&nd);
1575         }
1576         return error;
1577 @@ -247,20 +256,21 @@ asmlinkage long sys_readlink(const char 
1578  {
1579         struct nameidata nd;
1580         int error;
1581 +       struct lookup_intent it = { .it_op = IT_READLINK };
1582  
1583         if (bufsiz <= 0)
1584                 return -EINVAL;
1585  
1586 -       error = user_path_walk_link(path, &nd);
1587 +       error = user_path_walk_link_it(path, &nd, &it);
1588         if (!error) {
1589                 struct inode * inode = nd.dentry->d_inode;
1590 -
1591                 error = -EINVAL;
1592                 if (inode->i_op && inode->i_op->readlink &&
1593                     !(error = do_revalidate(nd.dentry))) {
1594                         UPDATE_ATIME(inode);
1595                         error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1596                 }
1597 +               intent_release(nd.dentry, &it);
1598                 path_release(&nd);
1599         }
1600         return error;
1601 @@ -333,12 +343,14 @@ asmlinkage long sys_stat64(char * filena
1602  {
1603         struct nameidata nd;
1604         int error;
1605 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1606  
1607 -       error = user_path_walk(filename, &nd);
1608 +       error = user_path_walk_it(filename, &nd, &it);
1609         if (!error) {
1610                 error = do_revalidate(nd.dentry);
1611                 if (!error)
1612                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1613 +               intent_release(nd.dentry, &it);
1614                 path_release(&nd);
1615         }
1616         return error;
1617 @@ -348,12 +360,14 @@ asmlinkage long sys_lstat64(char * filen
1618  {
1619         struct nameidata nd;
1620         int error;
1621 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1622  
1623 -       error = user_path_walk_link(filename, &nd);
1624 +       error = user_path_walk_link_it(filename, &nd, &it);
1625         if (!error) {
1626                 error = do_revalidate(nd.dentry);
1627                 if (!error)
1628                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1629 +               intent_release(nd.dentry, &it);
1630                 path_release(&nd);
1631         }
1632         return error;
1633 --- linux-2.4.19/mm/slab.c~vanilla-2.4.19       Sun Dec 15 16:58:43 2002
1634 +++ linux-2.4.19-root/mm/slab.c Sun Dec 15 16:58:43 2002
1635 @@ -1207,6 +1207,59 @@ failed:
1636   * Called with the cache-lock held.
1637   */
1638  
1639 +extern struct page *check_get_page(unsigned long kaddr);
1640 +struct page *page_mem_map(struct page *page);
1641 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1642 +                                slab_t *slabp, void * objp)
1643 +{
1644 +       int i;
1645 +       unsigned int objnr;
1646 +
1647 +#if DEBUG
1648 +       if (cachep->flags & SLAB_RED_ZONE) {
1649 +               objp -= BYTES_PER_WORD;
1650 +               if ( *(unsigned long *)objp != RED_MAGIC2)
1651 +                       /* Either write before start, or a double free. */
1652 +                       return 0;
1653 +               if (*(unsigned long *)(objp+cachep->objsize -
1654 +                               BYTES_PER_WORD) != RED_MAGIC2)
1655 +                       /* Either write past end, or a double free. */
1656 +                       return 0;
1657 +       }
1658 +#endif
1659 +
1660 +       objnr = (objp-slabp->s_mem)/cachep->objsize;
1661 +       if (objnr >= cachep->num)
1662 +               return 0;
1663 +       if (objp != slabp->s_mem + objnr*cachep->objsize)
1664 +               return 0;
1665 +
1666 +       /* Check slab's freelist to see if this obj is there. */
1667 +       for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1668 +               if (i == objnr)
1669 +                       return 0;
1670 +       }
1671 +       return 1;
1672 +}
1673 +
1674 +
1675 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1676 +{
1677 +       struct page *page = check_get_page((unsigned long)objp);
1678 +
1679 +       if (!VALID_PAGE(page))
1680 +               return 0;
1681 +
1682 +       if (!PageSlab(page))
1683 +               return 0;
1684 +
1685 +       /* XXX check for freed slab objects ? */
1686 +       if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1687 +               return 0;
1688 +
1689 +       return (cachep == GET_PAGE_CACHE(page));
1690 +}
1691 +
1692  #if DEBUG
1693  static int kmem_extra_free_checks (kmem_cache_t * cachep,
1694                         slab_t *slabp, void * objp)
1695
1696 _