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