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