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