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
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 */
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");
14 if (EP_EVENT_FIRING (edev, rxdElan + offsetof (EP_RXD_ELAN, DataEvent), rxd->DataCookie, rxdMain->DataEvent)) /* PCI read */
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
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"
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
35 static unsigned long totalram_pages;
37 +struct page *check_get_page(unsigned long kaddr)
39 +#warning FIXME: Lustre team, is this solid?
40 + return virt_to_page(kaddr);
44 do_check_pgt_cache (int low, int high)
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
49 static unsigned long totalram_pages;
50 static unsigned long totalhigh_pages;
53 +struct page *check_get_page(unsigned long kaddr)
55 +#warning FIXME: Lustre team, is this solid enough?
56 + return virt_to_page(kaddr);
60 int do_check_pgt_cache(int low, int high)
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.
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)
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. */
82 + if (*(unsigned long *)(objp+cachep->objsize -
83 + BYTES_PER_WORD) != RED_MAGIC2)
84 + /* Either write past end, or a double free. */
89 + objnr = (objp-slabp->s_mem)/cachep->objsize;
90 + if (objnr >= cachep->num)
92 + if (objp != slabp->s_mem + objnr*cachep->objsize)
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]) {
104 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
106 + struct page *page = check_get_page((unsigned long)objp);
108 + if (!VALID_PAGE(page)) {
112 + if (!PageSlab(page)) {
116 + /* XXX check for freed slab objects ? */
117 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
120 + return (cachep == GET_PAGE_CACHE(page));
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
131 EXPORT_SYMBOL(blk_ioctl);
133 +#define NUM_DEV_NO_WRITE 16
134 +static int dev_no_write[NUM_DEV_NO_WRITE];
137 + * Debug code for turning block devices "read-only" (will discard writes
138 + * silently). This is for filesystem crash/recovery testing.
140 +void dev_set_rdonly(kdev_t dev, int no_write)
143 + printk(KERN_WARNING "Turning device %s read-only\n",
145 + dev_no_write[no_write] = 0xdead0000 + dev;
149 +int dev_check_rdonly(kdev_t dev) {
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))
160 +void dev_clear_rdonly(int no_write) {
161 + dev_no_write[no_write] = 0;
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
170 spin_unlock_irq(&lo->lo_lock);
173 +#ifdef CONFIG_DEV_RDONLY
174 + if (dev_check_rdonly(rbh->b_rdev))
178 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
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
185 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
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;
194 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
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
202 +export-objs := super.o
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
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);
214 +EXPORT_SYMBOL(ext3_bread);
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
221 transaction's t_log_list queue, and metadata buffers are on
222 the t_iobuf_list queue.
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.
231 jbd_debug(3, "JBD: commit phase 6\n");
233 - if (is_journal_aborted(journal))
234 + if (is_journal_aborted(journal)) {
235 + unlock_journal(journal);
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
242 descriptor = journal_get_descriptor_buffer(journal);
244 __journal_abort_hard(journal);
245 + unlock_journal(journal);
250 /* AKPM: buglet - add `i' to tmp! */
251 for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
252 journal_header_t *tmp =
254 put_bh(bh); /* One for getblk() */
255 journal_unlock_journal_head(descriptor);
257 - lock_journal(journal);
259 /* End of a transaction! Finally, we can do checkpoint
260 processing: any buffers committed as a result of this
265 + /* Call any callbacks that had been registered for handles in this
266 + * transaction. It is up to the callback to free any allocated
269 + if (!list_empty(&commit_transaction->t_jcb)) {
270 + struct list_head *p, *n;
271 + int error = is_journal_aborted(journal);
273 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
274 + struct journal_callback *jcb;
276 + jcb = list_entry(p, struct journal_callback, jcb_list);
278 + jcb->jcb_func(jcb, error);
282 + lock_journal(journal);
284 jbd_debug(3, "JBD: commit phase 7\n");
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
291 EXPORT_SYMBOL(journal_flush);
292 EXPORT_SYMBOL(journal_revoke);
293 +EXPORT_SYMBOL(journal_callback_set);
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
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);
305 /* Set up the commit timer for the new transaction. */
306 J_ASSERT (!journal->j_commit_timer_active);
311 +/* Allocate a new handle. This should probably be in a slab... */
312 +static handle_t *get_handle(int nblocks)
314 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
317 + memset(handle, 0, sizeof (handle_t));
318 + handle->h_buffer_credits = nblocks;
320 + INIT_LIST_HEAD(&handle->h_jcb);
326 * Obtain a new handle.
328 @@ -227,14 +242,11 @@
333 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
335 + handle = get_handle(nblocks);
337 return ERR_PTR(-ENOMEM);
338 - memset (handle, 0, sizeof (handle_t));
340 - handle->h_buffer_credits = nblocks;
342 current->journal_info = handle;
344 err = start_this_handle(journal, handle);
345 @@ -333,14 +345,11 @@
347 if (is_journal_aborted(journal))
348 return ERR_PTR(-EIO);
350 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
352 + handle = get_handle(nblocks);
354 return ERR_PTR(-ENOMEM);
355 - memset (handle, 0, sizeof (handle_t));
357 - handle->h_buffer_credits = nblocks;
359 current->journal_info = handle;
361 err = try_start_this_handle(journal, handle);
362 @@ -1319,6 +1328,29 @@
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.
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.
379 +void journal_callback_set(handle_t *handle, void (*func)(void *, int),
382 + struct journal_callback *jcb = cb_data;
384 + list_add(&jcb->jcb_list, &handle->h_jcb);
385 + jcb->jcb_func = func;
389 * All done for a particular handle.
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);
397 + /* Move callbacks from the handle to the transaction. */
398 + list_splice(&handle->h_jcb, &transaction->t_jcb);
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
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);
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
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);
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
429 return bh->b_private;
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 */
439 struct jbd_revoke_table_s;
441 /* The handle_t type represents a single atomic update being performed
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.
450 + struct list_head h_jcb;
453 unsigned int h_sync: 1; /* sync-on-close */
454 unsigned int h_jdata: 1; /* force data journaling */
457 /* How many handles used this transaction? */
460 + /* List of registered callback functions for this transaction.
461 + * Called when the transaction is committed. */
462 + struct list_head t_jcb;
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),
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
478 EXPORT_SYMBOL(lock_may_write);
479 EXPORT_SYMBOL(dcache_readdir);
482 +EXPORT_SYMBOL(panic_notifier_list);
483 +EXPORT_SYMBOL(pagecache_lock);
484 +EXPORT_SYMBOL(kmem_cache_validate);
485 +EXPORT_SYMBOL(do_kern_mount);
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
494 #include <asm/atomic.h>
495 #include <linux/mount.h>
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)
512 +struct lookup_intent {
515 + int it_disposition;
517 + struct iattr *it_iattr;
518 + __u64 it_lock_handle[2];
524 * linux/include/linux/dcache.h
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 */
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 *);
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
547 /* needed for tty driver, and maybe others */
549 + struct lookup_intent *f_intent;
551 /* preallocated helper kiobuf to speedup O_DIRECT */
552 struct kiobuf *f_iobuf;
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);
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 *);
579 #define kern_umount mntput
580 @@ -1360,6 +1365,7 @@
581 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
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)
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 @@
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
611 * XEmacs seems to be relying on it...
614 +void intent_release(struct dentry *de)
616 + if (de->d_op && de->d_op->d_intent_release)
617 + de->d_op->d_intent_release(de);
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.
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)
632 struct dentry * dentry = d_lookup(parent, name);
634 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
635 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) && !d_invalidate(dentry)) {
642 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
643 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
646 * make sure that nobody added the entry to the dcache in the meantime..
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)
652 struct dentry * result;
653 struct inode *dir = parent->d_inode;
655 result = ERR_PTR(-ENOMEM);
658 + if (dir->i_op->lookup2)
659 + result = dir->i_op->lookup2(dir, dentry, it);
661 result = dir->i_op->lookup(dir, dentry);
665 result = ERR_PTR(-ENOENT);
668 + if (result->d_op && result->d_op->d_revalidate2) {
669 + if (!result->d_op->d_revalidate2(result, flags, it) && !d_invalidate(result)) {
671 + result = ERR_PTR(-ENOENT);
679 * We expect 'base' to be positive and a directory.
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)
684 struct dentry *dentry;
686 @@ -524,12 +549,12 @@
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);
693 err = -EWOULDBLOCKIO;
696 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
697 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, it);
698 err = PTR_ERR(dentry);
705 - if (!inode->i_op->lookup)
706 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
709 /* here ends the main loop */
710 @@ -590,12 +615,12 @@
714 - dentry = cached_lookup(nd->dentry, &this, 0);
715 + dentry = cached_lookup(nd->dentry, &this, 0, it);
717 err = -EWOULDBLOCKIO;
720 - dentry = real_lookup(nd->dentry, &this, 0);
721 + dentry = real_lookup(nd->dentry, &this, 0, it);
722 err = PTR_ERR(dentry);
727 if (lookup_flags & LOOKUP_DIRECTORY) {
729 - if (!inode->i_op || !inode->i_op->lookup)
730 + if (!inode->i_op || (!inode->i_op->lookup &&
731 + !inode->i_op->lookup2))
736 else if (this.len == 2 && this.name[1] == '.')
737 nd->last_type = LAST_DOTDOT;
739 + nd->dentry->d_it = it;
743 @@ -645,15 +672,29 @@
748 + nd->dentry->d_it = it;
752 +int link_path_walk(const char * name, struct nameidata *nd)
754 + return link_path_walk_it(name, nd, NULL);
757 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
759 + current->total_link_count = 0;
760 + return link_path_walk_it(name, nd, it);
763 int path_walk(const char * name, struct nameidata *nd)
765 current->total_link_count = 0;
766 - return link_path_walk(name, nd);
767 + return link_path_walk_it(name, nd, NULL);
772 /* returns 1 if everything is done */
773 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
775 * needs parent already locked. Doesn't follow mounts.
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)
782 struct dentry * dentry;
784 @@ -777,13 +819,16 @@
788 - dentry = cached_lookup(base, name, 0);
789 + dentry = cached_lookup(base, name, 0, it);
791 struct dentry *new = d_alloc(base, name);
792 dentry = ERR_PTR(-ENOMEM);
796 + if (inode->i_op->lookup2)
797 + dentry = inode->i_op->lookup2(inode, new, it);
799 dentry = inode->i_op->lookup(inode, new);
806 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
808 + return lookup_hash_it(name, base, NULL);
813 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
817 this.hash = end_name_hash(hash);
819 - return lookup_hash(&this, base);
820 + return lookup_hash_it(&this, base, NULL);
822 return ERR_PTR(-EACCES);
828 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
833 + tmp = getname(name);
834 + err = PTR_ERR(tmp);
835 + if (!IS_ERR(tmp)) {
837 + if (path_init(tmp, flags, nd))
838 + err = path_walk_it(tmp, nd, it);
845 * It's inline, so penalty for filesystems that don't use sticky bit is
848 * for symlinks (where the permissions are checked later).
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)
855 int acc_mode, error = 0;
857 @@ -998,17 +1066,21 @@
858 * The simplest case - just a plain lookup.
860 if (!(flag & O_CREAT)) {
862 if (path_init(pathname, lookup_flags(flag), nd))
863 - error = path_walk(pathname, nd);
864 + error = path_walk_it(pathname, nd, it);
873 * Create - we need to know the parent.
876 + it->it_op |= IT_CREAT;
877 if (path_init(pathname, LOOKUP_PARENT, nd))
878 error = path_walk(pathname, nd);
880 @@ -1025,7 +1097,7 @@
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);
888 error = PTR_ERR(dentry);
889 @@ -1034,6 +1106,7 @@
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)
901 + intent_release(dentry);
905 + intent_release(dentry);
909 @@ -1195,13 +1270,20 @@
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);
919 +int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
921 + return open_namei_it(pathname, flag, mode, nd, NULL);
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)
930 struct dentry *dentry;
932 @@ -1209,7 +1291,7 @@
933 dentry = ERR_PTR(-EEXIST);
934 if (nd->last_type != LAST_NORM)
936 - dentry = lookup_hash(&nd->last, nd->dentry);
937 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
940 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
941 @@ -1255,6 +1337,7 @@
943 struct dentry * dentry;
945 + struct lookup_intent it = { IT_MKNOD , mode };
949 @@ -1266,11 +1349,12 @@
950 error = path_walk(tmp, &nd);
953 - dentry = lookup_create(&nd, 0);
954 + dentry = lookup_create(&nd, 0, &it);
955 error = PTR_ERR(dentry);
957 mode &= ~current->fs->umask;
958 if (!IS_ERR(dentry)) {
959 + dentry->d_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 @@
967 + intent_release(dentry);
970 up(&nd.dentry->d_inode->i_sem);
971 @@ -1324,6 +1409,7 @@
975 + struct lookup_intent it = { IT_MKDIR, mode };
977 tmp = getname(pathname);
978 error = PTR_ERR(tmp);
979 @@ -1335,11 +1421,13 @@
980 error = path_walk(tmp, &nd);
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 = ⁢
988 error = vfs_mkdir(nd.dentry->d_inode, dentry,
989 mode & ~current->fs->umask);
990 + intent_release(dentry);
993 up(&nd.dentry->d_inode->i_sem);
994 @@ -1421,6 +1509,7 @@
996 struct dentry *dentry;
998 + struct lookup_intent it = { IT_RMDIR, 0 };
1000 name = getname(pathname);
1002 @@ -1443,10 +1532,12 @@
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 = ⁢
1011 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1012 + intent_release(dentry);
1015 up(&nd.dentry->d_inode->i_sem);
1016 @@ -1490,6 +1581,7 @@
1018 struct dentry *dentry;
1019 struct nameidata nd;
1020 + struct lookup_intent it = { IT_UNLINK, 0 };
1022 name = getname(pathname);
1024 @@ -1503,14 +1595,16 @@
1025 if (nd.last_type != LAST_NORM)
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 = ⁢
1033 /* Why not before? Because we want correct error value */
1034 if (nd.last.name[nd.last.len])
1036 error = vfs_unlink(nd.dentry->d_inode, dentry);
1038 + intent_release(dentry);
1041 up(&nd.dentry->d_inode->i_sem);
1042 @@ -1557,6 +1651,7 @@
1046 + struct lookup_intent it = { IT_SYMLINK, 0 };
1048 from = getname(oldname);
1050 @@ -1571,11 +1666,13 @@
1051 error = path_walk(to, &nd);
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 = ⁢
1059 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1061 + intent_release(dentry);
1064 up(&nd.dentry->d_inode->i_sem);
1066 @@ -1640,6 +1737,7 @@
1070 + struct lookup_intent it = { IT_LINK, 0 };
1072 from = getname(oldname);
1074 @@ -1662,10 +1760,12 @@
1076 if (old_nd.mnt != nd.mnt)
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 = ⁢
1083 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1084 + intent_release(new_dentry);
1087 up(&nd.dentry->d_inode->i_sem);
1088 @@ -1708,7 +1808,8 @@
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)
1097 struct inode *target;
1098 @@ -1762,12 +1863,14 @@
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))
1105 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1108 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1109 + intent_release(new_dentry);
1112 target->i_flags |= S_DEAD;
1113 @@ -1789,7 +1892,8 @@
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)
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))
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);
1136 @@ -1831,13 +1937,14 @@
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)
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);
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);
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};
1160 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1161 error = path_walk(oldname, &oldnd);
1162 @@ -1882,7 +1990,9 @@
1164 double_lock(new_dir, old_dir);
1166 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1167 + it.it_op = IT_RENAME;
1169 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1170 error = PTR_ERR(old_dentry);
1171 if (IS_ERR(old_dentry))
1173 @@ -1898,14 +2008,15 @@
1174 if (newnd.last.name[newnd.last.len])
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))
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);
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
1194 #include <asm/uaccess.h>
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);
1200 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1203 struct nameidata nd;
1204 struct inode * inode;
1206 + struct lookup_intent it;
1208 + it.it_op = IT_SETATTR;
1212 if (length < 0) /* sorry, but loff_t says... */
1215 - error = user_path_walk(path, &nd);
1216 + error = user_path_walk_it(path, &nd, &it);
1219 + nd.dentry->d_it = ⁢
1220 inode = nd.dentry->d_inode;
1222 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1224 put_write_access(inode);
1227 + intent_release(nd.dentry);
1231 @@ -235,10 +243,14 @@
1232 struct nameidata nd;
1233 struct inode * inode;
1234 struct iattr newattrs;
1235 + struct lookup_intent it;
1237 + it.it_op = IT_SETATTR;
1239 - error = user_path_walk(filename, &nd);
1240 + error = user_path_walk_it(filename, &nd, &it);
1243 + nd.dentry->d_it = ⁢
1244 inode = nd.dentry->d_inode;
1249 error = notify_change(nd.dentry, &newattrs);
1251 + intent_release(nd.dentry);
1255 @@ -279,11 +292,15 @@
1256 struct nameidata nd;
1257 struct inode * inode;
1258 struct iattr newattrs;
1259 + struct lookup_intent it;
1261 + it.it_op = IT_SETATTR;
1263 - error = user_path_walk(filename, &nd);
1264 + error = user_path_walk_it(filename, &nd, &it);
1268 + nd.dentry->d_it = ⁢
1269 inode = nd.dentry->d_inode;
1274 error = notify_change(nd.dentry, &newattrs);
1276 + intent_release(nd.dentry);
1281 int old_fsuid, old_fsgid;
1282 kernel_cap_t old_cap;
1284 + struct lookup_intent it;
1286 + it.it_op = IT_GETATTR;
1288 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1290 @@ -339,13 +360,14 @@
1292 current->cap_effective = current->cap_permitted;
1294 - res = user_path_walk(filename, &nd);
1295 + res = user_path_walk_it(filename, &nd, &it);
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))
1302 + intent_release(nd.dentry);
1308 struct nameidata nd;
1310 + struct lookup_intent it;
1312 + it.it_op = IT_GETATTR;
1314 name = getname(filename);
1315 error = PTR_ERR(name);
1316 @@ -369,11 +394,12 @@
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);
1326 + nd.dentry->d_it = ⁢
1327 error = permission(nd.dentry->d_inode,MAY_EXEC);
1331 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1334 + intent_release(nd.dentry);
1340 struct nameidata nd;
1342 + struct lookup_intent it;
1344 + it.it_op = IT_GETATTR;
1346 name = getname(filename);
1347 error = PTR_ERR(name);
1348 @@ -429,11 +459,12 @@
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);
1358 + nd.dentry->d_it = ⁢
1359 error = permission(nd.dentry->d_inode,MAY_EXEC);
1366 + intent_release(nd.dentry);
1370 @@ -490,12 +522,15 @@
1371 struct inode * inode;
1373 struct iattr newattrs;
1374 + struct lookup_intent it;
1376 - error = user_path_walk(filename, &nd);
1377 + it.it_op = IT_SETATTR;
1378 + error = user_path_walk_it(filename, &nd, &it);
1381 inode = nd.dentry->d_inode;
1383 + nd.dentry->d_it = ⁢
1385 if (IS_RDONLY(inode))
1388 error = notify_change(nd.dentry, &newattrs);
1391 + intent_release(nd.dentry);
1395 @@ -580,10 +616,15 @@
1397 struct nameidata nd;
1399 + struct lookup_intent it;
1401 + it.it_op = IT_SETATTR;
1403 - error = user_path_walk(filename, &nd);
1404 + error = user_path_walk_it(filename, &nd, &it);
1406 + nd.dentry->d_it = ⁢
1407 error = chown_common(nd.dentry, user, group);
1408 + intent_release(nd.dentry);
1412 @@ -593,10 +634,15 @@
1414 struct nameidata nd;
1416 + struct lookup_intent it;
1418 - error = user_path_walk_link(filename, &nd);
1419 + it.it_op = IT_SETATTR;
1421 + error = user_path_walk_link_it(filename, &nd, &it);
1423 + nd.dentry->d_it = ⁢
1424 error = chown_common(nd.dentry, user, group);
1425 + intent_release(nd.dentry);
1429 @@ -630,10 +676,15 @@
1430 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
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);
1437 struct file *filp_open(const char * filename, int flags, int mode)
1439 int namei_flags, error;
1440 struct nameidata nd;
1441 + struct lookup_intent it = {IT_OPEN, 0};
1443 namei_flags = flags;
1444 if ((namei_flags+1) & O_ACCMODE)
1445 @@ -641,14 +692,14 @@
1446 if (namei_flags & O_TRUNC)
1449 - error = open_namei(filename, namei_flags, mode, &nd);
1450 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1452 - return dentry_open(nd.dentry, nd.mnt, flags);
1453 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1455 return ERR_PTR(error);
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)
1462 struct inode *inode;
1463 @@ -705,11 +756,19 @@
1467 + intent_release(dentry);
1470 return ERR_PTR(error);
1473 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1475 + return dentry_open_it(dentry, mnt, flags, NULL);
1481 * Find an empty file descriptor entry, and mark it busy.
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 @@
1487 struct nameidata nd;
1489 + struct lookup_intent it;
1490 + it.it_op = IT_GETATTR;
1492 - error = user_path_walk_link(name, &nd);
1494 + error = user_path_walk_link_it(name, &nd, &it);
1496 error = do_getattr(nd.mnt, nd.dentry, stat);
1497 + intent_release(nd.dentry);