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