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