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