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