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