Whamcloud - gitweb
f0ab311885b4a93a9dde923a73b59a38f150d185
[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 Jul  4 10:04:25 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   Sat Jul 13 13:20:13 2002
17 +++ lum/arch/um/kernel/mem.c    Thu Jul  4 10:04:25 2002
18 @@ -527,6 +527,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 @@ -542,12 +558,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     Thu Jul  4 10:04:25 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       Thu Jul  4 10:04:25 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   Thu Jul  4 10:04:25 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    Thu Jul  4 10:04:25 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  Thu Jul  4 10:04:25 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        Thu Jul  4 10:04:25 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 Thu Jul  4 10:04:25 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 Thu Jul  4 10:04:25 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        Thu Jul  4 10:04:25 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    Thu Jul  4 10:04:25 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 Jul 13 13:06:04 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 Jul 13 13:06:04 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 Jul 13 13:09:28 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  Thu Jul  4 10:47:09 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 Jul 13 13:05:41 2002
489 @@ -6,6 +6,33 @@
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 +#define IT_LOOKUP   (1<<14)
508 +
509 +struct lookup_intent { 
510 +       int it_op;
511 +       int it_mode;
512 +       int it_disposition;
513 +       int it_status; 
514 +       struct iattr *it_iattr;
515 +        __u64 it_lock_handle[2];
516 +        int it_lock_mode;
517 +       void *it_data;
518 +};
519 +
520  /*
521   * linux/include/linux/dcache.h
522   *
523 @@ -79,17 +106,20 @@
524         struct dentry_operations  *d_op;
525         struct super_block * d_sb;      /* The root of the dentry tree */
526         unsigned long d_vfs_flags;
527 +       struct lookup_intent *d_it;
528         void * d_fsdata;                /* fs-specific data */
529         unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
530  };
531  
532  struct dentry_operations {
533         int (*d_revalidate)(struct dentry *, int);
534 +       int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
535         int (*d_hash) (struct dentry *, struct qstr *);
536         int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
537         int (*d_delete)(struct dentry *);
538         void (*d_release)(struct dentry *);
539         void (*d_iput)(struct dentry *, struct inode *);
540 +       void (*d_intent_release)(struct dentry *);
541  };
542  
543  /* the dentry parameter passed to d_hash and d_compare is the parent
544 --- lum-pristine/include/linux/fs.h     Sat Jul 13 13:20:13 2002
545 +++ lum/include/linux/fs.h      Sat Jul 13 13:06:04 2002
546 @@ -536,6 +536,7 @@
547  
548         /* needed for tty driver, and maybe others */
549         void                    *private_data;
550 +        struct lookup_intent    *f_intent;
551  
552         /* preallocated helper kiobuf to speedup O_DIRECT */
553         struct kiobuf           *f_iobuf;
554 @@ -779,7 +780,9 @@
555  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
556  extern int vfs_rmdir(struct inode *, struct dentry *);
557  extern int vfs_unlink(struct inode *, struct dentry *);
558 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
559 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
560 +               struct inode *new_dir, struct dentry *new_dentry, 
561 +               struct lookup_intent *it);
562  
563  /*
564   * File types
565 @@ -840,6 +843,7 @@
566  struct inode_operations {
567         int (*create) (struct inode *,struct dentry *,int);
568         struct dentry * (*lookup) (struct inode *,struct dentry *);
569 +        struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
570         int (*link) (struct dentry *,struct inode *,struct dentry *);
571         int (*unlink) (struct inode *,struct dentry *);
572         int (*symlink) (struct inode *,struct dentry *,const char *);
573 @@ -986,7 +990,7 @@
574  extern struct vfsmount *kern_mount(struct file_system_type *);
575  extern int may_umount(struct vfsmount *);
576  extern long do_mount(char *, char *, char *, unsigned long, void *);
577 -
578 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
579  #define kern_umount mntput
580  
581  extern int vfs_statfs(struct super_block *, struct statfs *);
582 @@ -1307,6 +1311,7 @@
583  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
584  
585  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
586 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
587  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
588  extern int FASTCALL(path_walk(const char *, struct nameidata *));
589  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
590 @@ -1317,6 +1322,8 @@
591  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
592  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
593  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
594 +#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
595 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
596  
597  extern void iput(struct inode *);
598  extern void force_delete(struct inode *);
599 --- lum-pristine/fs/nfsd/vfs.c  Fri Dec 21 10:41:55 2001
600 +++ lum/fs/nfsd/vfs.c   Thu Jul  4 10:04:25 2002
601 @@ -1285,7 +1285,7 @@
602                         err = nfserr_perm;
603         } else
604  #endif
605 -       err = vfs_rename(fdir, odentry, tdir, ndentry);
606 +       err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
607         if (!err && EX_ISSYNC(tfhp->fh_export)) {
608                 nfsd_sync_dir(tdentry);
609                 nfsd_sync_dir(fdentry);
610 --- lum-pristine/fs/namei.c     Mon Feb 25 12:38:09 2002
611 +++ lum/fs/namei.c      Sun Jul 14 21:06:07 2002
612 @@ -94,6 +94,14 @@
613   * XEmacs seems to be relying on it...
614   */
615  
616 +void intent_release(struct dentry *de) 
617 +{
618 +       if (de->d_op && de->d_op->d_intent_release)
619 +               de->d_op->d_intent_release(de);
620 +       de->d_it = NULL;
621 +}
622 +
623 +
624  /* In order to reduce some races, while at the same time doing additional
625   * checking and hopefully speeding things up, we copy filenames to the
626   * kernel data space before using them..
627 @@ -260,10 +268,17 @@
628   * Internal lookup() using the new generic dcache.
629   * SMP-safe
630   */
631 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
632 +static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
633  {
634         struct dentry * dentry = d_lookup(parent, name);
635  
636 +       if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
637 +               if (!dentry->d_op->d_revalidate2(dentry, flags, it) && !d_invalidate(dentry)) {
638 +                       dput(dentry);
639 +                       dentry = NULL;
640 +               }
641 +               return dentry; 
642 +       } else 
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 +296,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 +315,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 @@ -321,6 +339,11 @@
666                         dput(result);
667                         result = ERR_PTR(-ENOENT);
668                 }
669 +       } else 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 @@ -445,7 +468,7 @@
678   *
679   * We expect 'base' to be positive and a directory.
680   */
681 -int link_path_walk(const char * name, struct nameidata *nd)
682 +int link_path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
683  {
684         struct dentry *dentry;
685         struct inode *inode;
686 @@ -518,9 +541,9 @@
687                                 break;
688                 }
689                 /* This does the actual lookups.. */
690 -               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
691 +               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
692                 if (!dentry) {
693 -                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
694 +                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
695                         err = PTR_ERR(dentry);
696                         if (IS_ERR(dentry))
697                                 break;
698 @@ -554,7 +577,7 @@
699                         nd->dentry = dentry;
700                 }
701                 err = -ENOTDIR; 
702 -               if (!inode->i_op->lookup)
703 +               if (!inode->i_op->lookup && !inode->i_op->lookup2)
704                         break;
705                 continue;
706                 /* here ends the main loop */
707 @@ -581,9 +604,9 @@
708                         if (err < 0)
709                                 break;
710                 }
711 -               dentry = cached_lookup(nd->dentry, &this, 0);
712 +               dentry = cached_lookup(nd->dentry, &this, 0, it);
713                 if (!dentry) {
714 -                       dentry = real_lookup(nd->dentry, &this, 0);
715 +                       dentry = real_lookup(nd->dentry, &this, 0, it);
716                         err = PTR_ERR(dentry);
717                         if (IS_ERR(dentry))
718                                 break;
719 @@ -607,7 +630,8 @@
720                         goto no_inode;
721                 if (lookup_flags & LOOKUP_DIRECTORY) {
722                         err = -ENOTDIR; 
723 -                       if (!inode->i_op || !inode->i_op->lookup)
724 +                       if (!inode->i_op || (!inode->i_op->lookup && 
725 +                                            !inode->i_op->lookup2))
726                                 break;
727                 }
728                 goto return_base;
729 @@ -626,6 +650,7 @@
730                 else if (this.len == 2 && this.name[1] == '.')
731                         nd->last_type = LAST_DOTDOT;
732  return_base:
733 +                nd->dentry->d_it = it;
734                 return 0;
735  out_dput:
736                 dput(dentry);
737 @@ -633,15 +658,29 @@
738         }
739         path_release(nd);
740  return_err:
741 +        if (!err)
742 +                nd->dentry->d_it = it;
743         return err;
744  }
745  
746 +int link_path_walk(const char * name, struct nameidata *nd)
747 +{
748 +       return link_path_walk_it(name, nd, NULL);
749 +}
750 +
751 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
752 +{
753 +       current->total_link_count = 0;
754 +       return link_path_walk_it(name, nd, it);
755 +}
756 +
757  int path_walk(const char * name, struct nameidata *nd)
758  {
759         current->total_link_count = 0;
760 -       return link_path_walk(name, nd);
761 +       return link_path_walk_it(name, nd, NULL);
762  }
763  
764 +
765  /* SMP-safe */
766  /* returns 1 if everything is done */
767  static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
768 @@ -742,7 +781,8 @@
769   * needs parent already locked. Doesn't follow mounts.
770   * SMP-safe.
771   */
772 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
773 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, 
774 +                           struct lookup_intent *it)
775  {
776         struct dentry * dentry;
777         struct inode *inode;
778 @@ -765,13 +805,16 @@
779                         goto out;
780         }
781  
782 -       dentry = cached_lookup(base, name, 0);
783 +       dentry = cached_lookup(base, name, 0, it);
784         if (!dentry) {
785                 struct dentry *new = d_alloc(base, name);
786                 dentry = ERR_PTR(-ENOMEM);
787                 if (!new)
788                         goto out;
789                 lock_kernel();
790 +               if (inode->i_op->lookup2) 
791 +                       dentry = inode->i_op->lookup2(inode, new, it);
792 +               else 
793                 dentry = inode->i_op->lookup(inode, new);
794                 unlock_kernel();
795                 if (!dentry)
796 @@ -783,6 +826,12 @@
797         return dentry;
798  }
799  
800 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
801 +{
802 +       return lookup_hash_it(name, base, NULL);
803 +}
804 +
805 +
806  /* SMP-safe */
807  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
808  {
809 @@ -804,7 +853,7 @@
810         }
811         this.hash = end_name_hash(hash);
812  
813 -       return lookup_hash(&this, base);
814 +       return lookup_hash_it(&this, base, NULL);
815  access:
816         return ERR_PTR(-EACCES);
817  }
818 @@ -836,6 +885,22 @@
819         return err;
820  }
821  
822 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
823 +{
824 +       char *tmp;
825 +       int err;
826 +
827 +       tmp = getname(name);
828 +       err = PTR_ERR(tmp);
829 +       if (!IS_ERR(tmp)) {
830 +               err = 0;
831 +               if (path_init(tmp, flags, nd))
832 +                       err = path_walk_it(tmp, nd, it);
833 +               putname(tmp);
834 +       }
835 +       return err;
836 +}
837 +
838  /*
839   * It's inline, so penalty for filesystems that don't use sticky bit is
840   * minimal.
841 @@ -970,7 +1035,8 @@
842   * for symlinks (where the permissions are checked later).
843   * SMP-safe
844   */
845 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
846 +int open_namei_it(const char * pathname, int flag, int mode, struct nameidata *nd, 
847 +               struct lookup_intent *it)
848  {
849         int acc_mode, error = 0;
850         struct inode *inode;
851 @@ -984,17 +1050,23 @@
852          * The simplest case - just a plain lookup.
853          */
854         if (!(flag & O_CREAT)) {
855 +
856                 if (path_init(pathname, lookup_flags(flag), nd))
857 -                       error = path_walk(pathname, nd);
858 +                       error = path_walk_it(pathname, nd, it);
859                 if (error)
860                         return error;
861                 dentry = nd->dentry;
862 +                dentry->d_it = it;
863                 goto ok;
864         }
865  
866         /*
867          * Create - we need to know the parent.
868          */
869 +       if (it) {
870 +                it->it_mode = mode;
871 +               it->it_op |= IT_CREAT;
872 +        }
873         if (path_init(pathname, LOOKUP_PARENT, nd))
874                 error = path_walk(pathname, nd);
875         if (error)
876 @@ -1011,7 +1083,7 @@
877  
878         dir = nd->dentry;
879         down(&dir->d_inode->i_sem);
880 -       dentry = lookup_hash(&nd->last, nd->dentry);
881 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
882  
883  do_last:
884         error = PTR_ERR(dentry);
885 @@ -1020,6 +1092,8 @@
886                 goto exit;
887         }
888  
889 +        dentry->d_it = it;
890 +        dentry->d_it->it_mode = mode;
891         /* Negative dentry, just create the file */
892         if (!dentry->d_inode) {
893                 error = vfs_create(dir->d_inode, dentry,
894 @@ -1136,9 +1210,11 @@
895                 if (flag & FMODE_WRITE)
896                         DQUOT_INIT(inode);
897  
898 +        intent_release(dentry);
899         return 0;
900  
901  exit_dput:
902 +        intent_release(dentry);
903         dput(dentry);
904  exit:
905         path_release(nd);
906 @@ -1181,13 +1257,20 @@
907         }
908         dir = nd->dentry;
909         down(&dir->d_inode->i_sem);
910 -       dentry = lookup_hash(&nd->last, nd->dentry);
911 +       dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
912         putname(nd->last.name);
913         goto do_last;
914  }
915  
916 +int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
917 +{
918 +       return open_namei_it(pathname, flag, mode, nd, NULL); 
919 +}
920 +
921 +
922  /* SMP-safe */
923 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
924 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir, 
925 +                                   struct lookup_intent *it)
926  {
927         struct dentry *dentry;
928  
929 @@ -1195,7 +1278,7 @@
930         dentry = ERR_PTR(-EEXIST);
931         if (nd->last_type != LAST_NORM)
932                 goto fail;
933 -       dentry = lookup_hash(&nd->last, nd->dentry);
934 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
935         if (IS_ERR(dentry))
936                 goto fail;
937         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
938 @@ -1241,6 +1324,7 @@
939         char * tmp;
940         struct dentry * dentry;
941         struct nameidata nd;
942 +       struct lookup_intent it = { IT_MKNOD , mode };
943  
944         if (S_ISDIR(mode))
945                 return -EPERM;
946 @@ -1252,11 +1336,12 @@
947                 error = path_walk(tmp, &nd);
948         if (error)
949                 goto out;
950 -       dentry = lookup_create(&nd, 0);
951 +       dentry = lookup_create(&nd, 0, &it);
952         error = PTR_ERR(dentry);
953  
954         mode &= ~current->fs->umask;
955         if (!IS_ERR(dentry)) {
956 +               dentry->d_it = &it;
957                 switch (mode & S_IFMT) {
958                 case 0: case S_IFREG:
959                         error = vfs_create(nd.dentry->d_inode,dentry,mode);
960 @@ -1270,6 +1355,7 @@
961                 default:
962                         error = -EINVAL;
963                 }
964 +                intent_release(dentry); 
965                 dput(dentry);
966         }
967         up(&nd.dentry->d_inode->i_sem);
968 @@ -1310,6 +1396,7 @@
969  {
970         int error = 0;
971         char * tmp;
972 +       struct lookup_intent it = { IT_MKDIR, mode };
973  
974         tmp = getname(pathname);
975         error = PTR_ERR(tmp);
976 @@ -1321,11 +1408,13 @@
977                         error = path_walk(tmp, &nd);
978                 if (error)
979                         goto out;
980 -               dentry = lookup_create(&nd, 1);
981 +               dentry = lookup_create(&nd, 1, &it);
982                 error = PTR_ERR(dentry);
983                 if (!IS_ERR(dentry)) {
984 +                       dentry->d_it = &it;
985                         error = vfs_mkdir(nd.dentry->d_inode, dentry,
986                                           mode & ~current->fs->umask);
987 +                        intent_release(dentry); 
988                         dput(dentry);
989                 }
990                 up(&nd.dentry->d_inode->i_sem);
991 @@ -1407,6 +1496,7 @@
992         char * name;
993         struct dentry *dentry;
994         struct nameidata nd;
995 +       struct lookup_intent it = { IT_RMDIR, 0 };
996  
997         name = getname(pathname);
998         if(IS_ERR(name))
999 @@ -1429,10 +1519,12 @@
1000                         goto exit1;
1001         }
1002         down(&nd.dentry->d_inode->i_sem);
1003 -       dentry = lookup_hash(&nd.last, nd.dentry);
1004 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1005         error = PTR_ERR(dentry);
1006         if (!IS_ERR(dentry)) {
1007 +               dentry->d_it = &it; 
1008                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1009 +               intent_release(dentry); 
1010                 dput(dentry);
1011         }
1012         up(&nd.dentry->d_inode->i_sem);
1013 @@ -1476,6 +1568,7 @@
1014         char * name;
1015         struct dentry *dentry;
1016         struct nameidata nd;
1017 +       struct lookup_intent it = { IT_UNLINK, 0 };
1018  
1019         name = getname(pathname);
1020         if(IS_ERR(name))
1021 @@ -1489,14 +1582,16 @@
1022         if (nd.last_type != LAST_NORM)
1023                 goto exit1;
1024         down(&nd.dentry->d_inode->i_sem);
1025 -       dentry = lookup_hash(&nd.last, nd.dentry);
1026 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1027         error = PTR_ERR(dentry);
1028         if (!IS_ERR(dentry)) {
1029 +               dentry->d_it = &it;
1030                 /* Why not before? Because we want correct error value */
1031                 if (nd.last.name[nd.last.len])
1032                         goto slashes;
1033                 error = vfs_unlink(nd.dentry->d_inode, dentry);
1034         exit2:
1035 +               intent_release(dentry); 
1036                 dput(dentry);
1037         }
1038         up(&nd.dentry->d_inode->i_sem);
1039 @@ -1543,6 +1638,7 @@
1040         int error = 0;
1041         char * from;
1042         char * to;
1043 +       struct lookup_intent it = { IT_SYMLINK, 0 };
1044  
1045         from = getname(oldname);
1046         if(IS_ERR(from))
1047 @@ -1557,10 +1653,12 @@
1048                         error = path_walk(to, &nd);
1049                 if (error)
1050                         goto out;
1051 -               dentry = lookup_create(&nd, 0);
1052 +               dentry = lookup_create(&nd, 0, &it);
1053                 error = PTR_ERR(dentry);
1054                 if (!IS_ERR(dentry)) {
1055 +                       dentry->d_it = &it;
1056                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1057 +                        intent_release(dentry); 
1058                         dput(dentry);
1059                 }
1060                 up(&nd.dentry->d_inode->i_sem);
1061 @@ -1626,6 +1724,7 @@
1062         int error;
1063         char * from;
1064         char * to;
1065 +       struct lookup_intent it = { IT_LINK, 0 };
1066  
1067         from = getname(oldname);
1068         if(IS_ERR(from))
1069 @@ -1648,10 +1747,12 @@
1070                 error = -EXDEV;
1071                 if (old_nd.mnt != nd.mnt)
1072                         goto out_release;
1073 -               new_dentry = lookup_create(&nd, 0);
1074 +               new_dentry = lookup_create(&nd, 0, &it);
1075                 error = PTR_ERR(new_dentry);
1076                 if (!IS_ERR(new_dentry)) {
1077 +                       new_dentry->d_it = &it;
1078                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1079 +                        intent_release(new_dentry); 
1080                         dput(new_dentry);
1081                 }
1082                 up(&nd.dentry->d_inode->i_sem);
1083 @@ -1694,7 +1795,8 @@
1084   *        locking].
1085   */
1086  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1087 -              struct inode *new_dir, struct dentry *new_dentry)
1088 +                  struct inode *new_dir, struct dentry *new_dentry,
1089 +                  struct lookup_intent *it)
1090  {
1091         int error;
1092         struct inode *target;
1093 @@ -1748,12 +1850,14 @@
1094         } else
1095                 double_down(&old_dir->i_zombie,
1096                             &new_dir->i_zombie);
1097 +       new_dentry->d_it = it;
1098         if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
1099                 error = -ENOENT;
1100         else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1101                 error = -EBUSY;
1102         else 
1103                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1104 +       intent_release(new_dentry); 
1105         if (target) {
1106                 if (!error)
1107                         target->i_flags |= S_DEAD;
1108 @@ -1775,7 +1879,8 @@
1109  }
1110  
1111  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1112 -              struct inode *new_dir, struct dentry *new_dentry)
1113 +               struct inode *new_dir, struct dentry *new_dentry, 
1114 +                    struct lookup_intent *it)
1115  {
1116         int error;
1117  
1118 @@ -1802,10 +1907,12 @@
1119         DQUOT_INIT(old_dir);
1120         DQUOT_INIT(new_dir);
1121         double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1122 +       new_dentry->d_it = it;
1123         if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1124                 error = -EBUSY;
1125         else
1126                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1127 +       intent_release(new_dentry); 
1128         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1129         if (error)
1130                 return error;
1131 @@ -1817,13 +1924,14 @@
1132  }
1133  
1134  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1135 -              struct inode *new_dir, struct dentry *new_dentry)
1136 +               struct inode *new_dir, struct dentry *new_dentry, 
1137 +               struct lookup_intent *it)
1138  {
1139         int error;
1140         if (S_ISDIR(old_dentry->d_inode->i_mode))
1141 -               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1142 +               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it);
1143         else
1144 -               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1145 +               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it);
1146         if (!error) {
1147                 if (old_dir == new_dir)
1148                         inode_dir_notify(old_dir, DN_RENAME);
1149 @@ -1841,6 +1949,7 @@
1150         struct dentry * old_dir, * new_dir;
1151         struct dentry * old_dentry, *new_dentry;
1152         struct nameidata oldnd, newnd;
1153 +       struct lookup_intent it = {IT_RENAME, 0};
1154  
1155         if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1156                 error = path_walk(oldname, &oldnd);
1157 @@ -1868,7 +1977,9 @@
1158  
1159         double_lock(new_dir, old_dir);
1160  
1161 -       old_dentry = lookup_hash(&oldnd.last, old_dir);
1162 +       it.it_op = IT_RENAME;
1163 +       it.it_mode = 0;
1164 +       old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1165         error = PTR_ERR(old_dentry);
1166         if (IS_ERR(old_dentry))
1167                 goto exit3;
1168 @@ -1884,18 +1995,21 @@
1169                 if (newnd.last.name[newnd.last.len])
1170                         goto exit4;
1171         }
1172 -       new_dentry = lookup_hash(&newnd.last, new_dir);
1173 +       it.it_op = IT_RENAME2;
1174 +       new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1175         error = PTR_ERR(new_dentry);
1176         if (IS_ERR(new_dentry))
1177                 goto exit4;
1178  
1179         lock_kernel();
1180         error = vfs_rename(old_dir->d_inode, old_dentry,
1181 -                                  new_dir->d_inode, new_dentry);
1182 +                                  new_dir->d_inode, new_dentry, &it);
1183         unlock_kernel();
1184  
1185 +        intent_release(new_dentry);
1186         dput(new_dentry);
1187  exit4:
1188 +        intent_release(old_dentry);
1189         dput(old_dentry);
1190  exit3:
1191         double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1192 --- lum-pristine/fs/open.c      Fri Oct 12 14:48:42 2001
1193 +++ lum/fs/open.c       Thu Jul  4 10:04:25 2002
1194 @@ -19,6 +19,8 @@
1195  #include <asm/uaccess.h>
1196  
1197  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1198 +extern int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it);
1199 +extern void intent_release(struct dentry *de);
1200  
1201  int vfs_statfs(struct super_block *sb, struct statfs *buf)
1202  {
1203 @@ -94,14 +96,16 @@
1204         struct nameidata nd;
1205         struct inode * inode;
1206         int error;
1207 +       struct lookup_intent it = { IT_SETATTR };
1208  
1209         error = -EINVAL;
1210         if (length < 0) /* sorry, but loff_t says... */
1211                 goto out;
1212  
1213 -       error = user_path_walk(path, &nd);
1214 +       error = user_path_walk_it(path, &nd, &it);
1215         if (error)
1216                 goto out;
1217 +       nd.dentry->d_it = &it;
1218         inode = nd.dentry->d_inode;
1219  
1220         /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1221 @@ -144,6 +148,7 @@
1222         put_write_access(inode);
1223  
1224  dput_and_out:
1225 +       intent_release(nd.dentry);
1226         path_release(&nd);
1227  out:
1228         return error;
1229 @@ -235,10 +240,14 @@
1230         struct nameidata nd;
1231         struct inode * inode;
1232         struct iattr newattrs;
1233 +       struct lookup_intent it;
1234 +
1235 +       it.it_op = IT_SETATTR;
1236  
1237 -       error = user_path_walk(filename, &nd);
1238 +       error = user_path_walk_it(filename, &nd, &it);
1239         if (error)
1240                 goto out;
1241 +       nd.dentry->d_it = &it;
1242         inode = nd.dentry->d_inode;
1243  
1244         error = -EROFS;
1245 @@ -262,6 +271,7 @@
1246         }
1247         error = notify_change(nd.dentry, &newattrs);
1248  dput_and_out:
1249 +       intent_release(nd.dentry);
1250         path_release(&nd);
1251  out:
1252         return error;
1253 @@ -279,11 +289,15 @@
1254         struct nameidata nd;
1255         struct inode * inode;
1256         struct iattr newattrs;
1257 +       struct lookup_intent it;
1258 +       
1259 +       it.it_op = IT_SETATTR;
1260  
1261 -       error = user_path_walk(filename, &nd);
1262 +       error = user_path_walk_it(filename, &nd, &it);
1263  
1264         if (error)
1265                 goto out;
1266 +       nd.dentry->d_it = &it;
1267         inode = nd.dentry->d_inode;
1268  
1269         error = -EROFS;
1270 @@ -306,6 +320,7 @@
1271         }
1272         error = notify_change(nd.dentry, &newattrs);
1273  dput_and_out:
1274 +       intent_release(nd.dentry);
1275         path_release(&nd);
1276  out:
1277         return error;
1278 @@ -322,6 +337,9 @@
1279         int old_fsuid, old_fsgid;
1280         kernel_cap_t old_cap;
1281         int res;
1282 +       struct lookup_intent it;
1283 +       
1284 +       it.it_op = IT_GETATTR;
1285  
1286         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
1287                 return -EINVAL;
1288 @@ -339,13 +357,14 @@
1289         else
1290                 current->cap_effective = current->cap_permitted;
1291  
1292 -       res = user_path_walk(filename, &nd);
1293 +       res = user_path_walk_it(filename, &nd, &it);
1294         if (!res) {
1295                 res = permission(nd.dentry->d_inode, mode);
1296                 /* SuS v2 requires we report a read only fs too */
1297                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1298                    && !special_file(nd.dentry->d_inode->i_mode))
1299                         res = -EROFS;
1300 +                intent_release(nd.dentry);
1301                 path_release(&nd);
1302         }
1303  
1304 @@ -361,6 +380,9 @@
1305         int error;
1306         struct nameidata nd;
1307         char *name;
1308 +       struct lookup_intent it;
1309 +       
1310 +       it.it_op = IT_GETATTR;
1311  
1312         name = getname(filename);
1313         error = PTR_ERR(name);
1314 @@ -369,11 +391,12 @@
1315  
1316         error = 0;
1317         if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1318 -               error = path_walk(name, &nd);
1319 +               error = path_walk_it(name, &nd, &it);
1320         putname(name);
1321         if (error)
1322                 goto out;
1323  
1324 +       nd.dentry->d_it = &it;
1325         error = permission(nd.dentry->d_inode,MAY_EXEC);
1326         if (error)
1327                 goto dput_and_out;
1328 @@ -381,6 +404,7 @@
1329         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1330  
1331  dput_and_out:
1332 +       intent_release(nd.dentry);
1333         path_release(&nd);
1334  out:
1335         return error;
1336 @@ -421,6 +445,9 @@
1337         int error;
1338         struct nameidata nd;
1339         char *name;
1340 +       struct lookup_intent it;
1341
1342 +       it.it_op = IT_GETATTR;
1343  
1344         name = getname(filename);
1345         error = PTR_ERR(name);
1346 @@ -429,11 +456,12 @@
1347  
1348         path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1349                       LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1350 -       error = path_walk(name, &nd);   
1351 +       error = path_walk_it(name, &nd, &it);   
1352         putname(name);
1353         if (error)
1354                 goto out;
1355  
1356 +       nd.dentry->d_it = &it;
1357         error = permission(nd.dentry->d_inode,MAY_EXEC);
1358         if (error)
1359                 goto dput_and_out;
1360 @@ -446,6 +474,7 @@
1361         set_fs_altroot();
1362         error = 0;
1363  dput_and_out:
1364 +       intent_release(nd.dentry);
1365         path_release(&nd);
1366  out:
1367         return error;
1368 @@ -490,12 +519,15 @@
1369         struct inode * inode;
1370         int error;
1371         struct iattr newattrs;
1372 +       struct lookup_intent it;
1373  
1374 -       error = user_path_walk(filename, &nd);
1375 +       it.it_op = IT_SETATTR;
1376 +       error = user_path_walk_it(filename, &nd, &it);
1377         if (error)
1378                 goto out;
1379         inode = nd.dentry->d_inode;
1380  
1381 +       nd.dentry->d_it = &it;
1382         error = -EROFS;
1383         if (IS_RDONLY(inode))
1384                 goto dput_and_out;
1385 @@ -511,6 +543,7 @@
1386         error = notify_change(nd.dentry, &newattrs);
1387  
1388  dput_and_out:
1389 +       intent_release(nd.dentry);
1390         path_release(&nd);
1391  out:
1392         return error;
1393 @@ -580,10 +613,15 @@
1394  {
1395         struct nameidata nd;
1396         int error;
1397 +       struct lookup_intent it;
1398 +       
1399 +       it.it_op = IT_SETATTR;
1400  
1401 -       error = user_path_walk(filename, &nd);
1402 +       error = user_path_walk_it(filename, &nd, &it);
1403         if (!error) {
1404 +               nd.dentry->d_it = &it;
1405                 error = chown_common(nd.dentry, user, group);
1406 +               intent_release(nd.dentry);
1407                 path_release(&nd);
1408         }
1409         return error;
1410 @@ -593,10 +631,15 @@
1411  {
1412         struct nameidata nd;
1413         int error;
1414 +       struct lookup_intent it;
1415 +
1416 +       it.it_op = IT_SETATTR;
1417  
1418 -       error = user_path_walk_link(filename, &nd);
1419 +       error = user_path_walk_link_it(filename, &nd, &it);
1420         if (!error) {
1421 +               nd.dentry->d_it = &it;
1422                 error = chown_common(nd.dentry, user, group);
1423 +               intent_release(nd.dentry);
1424                 path_release(&nd);
1425         }
1426         return error;
1427 @@ -630,10 +673,15 @@
1428   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1429   * used by symlinks.
1430   */
1431 +extern int open_namei_it(const char *filename, int namei_flags, int mode, 
1432 +                        struct nameidata *nd, struct lookup_intent *it);
1433 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it);
1434 +
1435  struct file *filp_open(const char * filename, int flags, int mode)
1436  {
1437         int namei_flags, error;
1438         struct nameidata nd;
1439 +       struct lookup_intent it = {IT_OPEN, 0};
1440  
1441         namei_flags = flags;
1442         if ((namei_flags+1) & O_ACCMODE)
1443 @@ -641,14 +689,14 @@
1444         if (namei_flags & O_TRUNC)
1445                 namei_flags |= 2;
1446  
1447 -       error = open_namei(filename, namei_flags, mode, &nd);
1448 +       error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1449         if (!error)
1450 -               return dentry_open(nd.dentry, nd.mnt, flags);
1451 +               return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1452  
1453         return ERR_PTR(error);
1454  }
1455  
1456 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1457 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it)
1458  {
1459         struct file * f;
1460         struct inode *inode;
1461 @@ -705,11 +753,19 @@
1462  cleanup_file:
1463         put_filp(f);
1464  cleanup_dentry:
1465 +        intent_release(dentry);
1466         dput(dentry);
1467         mntput(mnt);
1468         return ERR_PTR(error);
1469  }
1470  
1471 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1472 +{
1473 +       return dentry_open_it(dentry, mnt, flags, NULL);
1474 +
1475 +}
1476 +
1477 +
1478  /*
1479   * Find an empty file descriptor entry, and mark it busy.
1480   */
1481 --- lum-pristine/fs/stat.c      Thu Sep 13 17:04:43 2001
1482 +++ lum/fs/stat.c       Thu Jul  4 10:04:25 2002
1483 @@ -135,13 +135,15 @@
1484  asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1485  {
1486         struct nameidata nd;
1487 +        struct lookup_intent it = {IT_GETATTR, 0};
1488         int error;
1489  
1490 -       error = user_path_walk(filename, &nd);
1491 +       error = user_path_walk_it(filename, &nd, &it);
1492         if (!error) {
1493                 error = do_revalidate(nd.dentry);
1494                 if (!error)
1495                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1496 +                intent_release(nd.dentry);
1497                 path_release(&nd);
1498         }
1499         return error;
1500 @@ -151,13 +153,15 @@
1501  asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1502  {
1503         struct nameidata nd;
1504 +        struct lookup_intent it = {IT_GETATTR, 0};
1505         int error;
1506  
1507 -       error = user_path_walk(filename, &nd);
1508 +       error = user_path_walk_it(filename, &nd, &it);
1509         if (!error) {
1510                 error = do_revalidate(nd.dentry);
1511                 if (!error)
1512                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1513 +                intent_release(nd.dentry);
1514                 path_release(&nd);
1515         }
1516         return error;
1517 @@ -172,13 +176,15 @@
1518  asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1519  {
1520         struct nameidata nd;
1521 +        struct lookup_intent it = {IT_GETATTR, 0};
1522         int error;
1523  
1524 -       error = user_path_walk_link(filename, &nd);
1525 +       error = user_path_walk_link_it(filename, &nd, &it);
1526         if (!error) {
1527                 error = do_revalidate(nd.dentry);
1528                 if (!error)
1529                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1530 +                intent_release(nd.dentry);
1531                 path_release(&nd);
1532         }
1533         return error;
1534 @@ -189,13 +195,15 @@
1535  asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1536  {
1537         struct nameidata nd;
1538 +        struct lookup_intent it = {IT_GETATTR, 0};
1539         int error;
1540  
1541 -       error = user_path_walk_link(filename, &nd);
1542 +       error = user_path_walk_link_it(filename, &nd, &it);
1543         if (!error) {
1544                 error = do_revalidate(nd.dentry);
1545                 if (!error)
1546                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1547 +                intent_release(nd.dentry);
1548                 path_release(&nd);
1549         }
1550         return error;
1551 @@ -247,20 +255,21 @@
1552  {
1553         struct nameidata nd;
1554         int error;
1555 +       struct lookup_intent it = { IT_READLINK };
1556  
1557         if (bufsiz <= 0)
1558                 return -EINVAL;
1559  
1560 -       error = user_path_walk_link(path, &nd);
1561 +       error = user_path_walk_link_it(path, &nd, &it);
1562         if (!error) {
1563                 struct inode * inode = nd.dentry->d_inode;
1564 -
1565                 error = -EINVAL;
1566                 if (inode->i_op && inode->i_op->readlink &&
1567                     !(error = do_revalidate(nd.dentry))) {
1568                         UPDATE_ATIME(inode);
1569                         error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1570                 }
1571 +                intent_release(nd.dentry);
1572                 path_release(&nd);
1573         }
1574         return error;
1575 @@ -333,12 +342,14 @@
1576  {
1577         struct nameidata nd;
1578         int error;
1579 +       struct lookup_intent it = {IT_GETATTR};
1580  
1581 -       error = user_path_walk(filename, &nd);
1582 +       error = user_path_walk_it(filename, &nd, &it);
1583         if (!error) {
1584                 error = do_revalidate(nd.dentry);
1585                 if (!error)
1586                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1587 +                intent_release(nd.dentry); 
1588                 path_release(&nd);
1589         }
1590         return error;
1591 @@ -348,12 +359,14 @@
1592  {
1593         struct nameidata nd;
1594         int error;
1595 +       struct lookup_intent it = { IT_GETATTR};
1596  
1597 -       error = user_path_walk_link(filename, &nd);
1598 +       error = user_path_walk_link_it(filename, &nd, &it);
1599         if (!error) {
1600                 error = do_revalidate(nd.dentry);
1601                 if (!error)
1602                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1603 +                intent_release(nd.dentry); 
1604                 path_release(&nd);
1605         }
1606         return error;
1607 @@ -363,6 +376,10 @@
1608  {
1609         struct file * f;
1610         int err = -EBADF;
1611 +       struct lookup_intent it;
1612 +
1613 +       memset(&it, 0, sizeof(it));
1614 +       it.it_op = IT_GETATTR;
1615  
1616         f = fget(fd);
1617         if (f) {