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