1 --- linux-pristine/./include/linux/lustre_version.h Wed Dec 31 19:00:00 1969
2 +++ linux/./include/linux/lustre_version.h Tue Nov 26 07:02:14 2002
4 +#define LUSTRE_KERNEL_VERSION 5
5 --- linux-pristine/./arch/ia64/mm/init.c Thu Dec 5 10:47:25 2002
6 +++ linux/./arch/ia64/mm/init.c Fri Nov 29 18:06:20 2002
9 static struct page *vmem_map;
11 +struct page *check_get_page(unsigned long kaddr)
13 +#warning FIXME: Lustre team, is this solid?
14 + return virt_to_page(kaddr);
18 do_check_pgt_cache (int low, int high)
20 --- linux-pristine/./arch/i386/mm/init.c Thu Dec 5 10:47:24 2002
21 +++ linux/./arch/i386/mm/init.c Fri Nov 29 18:06:20 2002
23 static unsigned long totalram_pages;
24 static unsigned long totalhigh_pages;
26 +struct page *check_get_page(unsigned long kaddr)
28 +#warning FIXME: Lustre team, is this solid?
29 + return virt_to_page(kaddr);
32 int do_check_pgt_cache(int low, int high)
35 --- linux-pristine/./drivers/block/blkpg.c Thu Dec 5 10:47:36 2002
36 +++ linux/./drivers/block/blkpg.c Fri Nov 29 18:08:05 2002
39 EXPORT_SYMBOL(blk_ioctl);
41 +#define NUM_DEV_NO_WRITE 16
42 +static int dev_no_write[NUM_DEV_NO_WRITE];
45 + * Debug code for turning block devices "read-only" (will discard writes
46 + * silently). This is for filesystem crash/recovery testing.
48 +void dev_set_rdonly(kdev_t dev, int no_write)
51 + printk(KERN_WARNING "Turning device %s read-only\n",
53 + dev_no_write[no_write] = 0xdead0000 + dev;
57 +int dev_check_rdonly(kdev_t dev) {
60 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
61 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
62 + dev == (dev_no_write[i] & 0xffff))
68 +void dev_clear_rdonly(int no_write) {
69 + dev_no_write[no_write] = 0;
72 +EXPORT_SYMBOL(dev_set_rdonly);
73 +EXPORT_SYMBOL(dev_check_rdonly);
74 +EXPORT_SYMBOL(dev_clear_rdonly);
76 /*********************
79 --- linux-pristine/./drivers/block/loop.c Thu Dec 5 10:47:37 2002
80 +++ linux/./drivers/block/loop.c Fri Nov 29 18:06:20 2002
82 spin_unlock_irq(&lo->lo_lock);
85 +#ifdef CONFIG_DEV_RDONLY
86 + if (dev_check_rdonly(rbh->b_rdev))
90 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
92 } else if (rw == READA) {
93 --- linux-pristine/./drivers/ide/ide-disk.c Thu Dec 5 10:47:59 2002
94 +++ linux/./drivers/ide/ide-disk.c Fri Nov 29 18:06:20 2002
97 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
99 +#ifdef CONFIG_DEV_RDONLY
100 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
101 + ide_end_request(1, HWGROUP(drive));
102 + return ide_stopped;
106 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
107 OUT_BYTE(0x00, IDE_FEATURE_REG);
108 --- linux-pristine/./fs/ext3/Makefile Thu Dec 5 10:49:13 2002
109 +++ linux/./fs/ext3/Makefile Fri Nov 29 18:06:20 2002
114 +export-objs := super.o
116 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
117 ioctl.o namei.o super.o symlink.o
119 --- linux-pristine/./fs/ext3/super.c Thu Dec 5 10:49:13 2002
120 +++ linux/./fs/ext3/super.c Fri Nov 29 18:06:20 2002
121 @@ -1744,7 +1744,7 @@
122 unregister_filesystem(&ext3_fs_type);
126 +EXPORT_SYMBOL(ext3_bread);
128 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
129 MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
130 --- linux-pristine/./fs/jbd/commit.c Thu Dec 5 10:49:15 2002
131 +++ linux/./fs/jbd/commit.c Fri Nov 29 18:06:20 2002
133 transaction's t_log_list queue, and metadata buffers are on
134 the t_iobuf_list queue.
136 - Wait for the transactions in reverse order. That way we are
137 + Wait for the buffers in reverse order. That way we are
138 less likely to be woken up until all IOs have completed, and
139 so we incur less scheduling load.
143 jbd_debug(3, "JBD: commit phase 6\n");
145 - if (is_journal_aborted(journal))
146 + if (is_journal_aborted(journal)) {
147 + unlock_journal(journal);
151 /* Done it all: now write the commit record. We should have
152 * cleaned up our previous buffers by now, so if we are in abort
154 descriptor = journal_get_descriptor_buffer(journal);
156 __journal_abort_hard(journal);
157 + unlock_journal(journal);
162 put_bh(bh); /* One for getblk() */
163 journal_unlock_journal_head(descriptor);
165 - lock_journal(journal);
167 /* End of a transaction! Finally, we can do checkpoint
168 processing: any buffers committed as a result of this
173 + /* Call any callbacks that had been registered for handles in this
174 + * transaction. It is up to the callback to free any allocated
177 + if (!list_empty(&commit_transaction->t_jcb)) {
178 + struct list_head *p, *n;
179 + int error = is_journal_aborted(journal);
181 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
182 + struct journal_callback *jcb;
184 + jcb = list_entry(p, struct journal_callback, jcb_list);
186 + jcb->jcb_func(jcb, error);
190 + lock_journal(journal);
192 jbd_debug(3, "JBD: commit phase 7\n");
194 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
195 --- linux-pristine/./fs/jbd/journal.c Thu Dec 5 10:49:15 2002
196 +++ linux/./fs/jbd/journal.c Fri Nov 29 18:06:20 2002
199 EXPORT_SYMBOL(journal_flush);
200 EXPORT_SYMBOL(journal_revoke);
201 +EXPORT_SYMBOL(journal_callback_set);
203 EXPORT_SYMBOL(journal_init_dev);
204 EXPORT_SYMBOL(journal_init_inode);
205 --- linux-pristine/./fs/jbd/transaction.c Thu Dec 5 10:49:15 2002
206 +++ linux/./fs/jbd/transaction.c Fri Nov 29 18:06:20 2002
208 transaction->t_state = T_RUNNING;
209 transaction->t_tid = journal->j_transaction_sequence++;
210 transaction->t_expires = jiffies + journal->j_commit_interval;
211 + INIT_LIST_HEAD(&transaction->t_jcb);
213 /* Set up the commit timer for the new transaction. */
214 J_ASSERT (!journal->j_commit_timer_active);
219 +/* Allocate a new handle. This should probably be in a slab... */
220 +static handle_t *new_handle(int nblocks)
222 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
225 + memset(handle, 0, sizeof (handle_t));
226 + handle->h_buffer_credits = nblocks;
228 + INIT_LIST_HEAD(&handle->h_jcb);
234 * Obtain a new handle.
236 @@ -227,14 +242,11 @@
241 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
243 + handle = new_handle(nblocks);
245 return ERR_PTR(-ENOMEM);
246 - memset (handle, 0, sizeof (handle_t));
248 - handle->h_buffer_credits = nblocks;
250 current->journal_info = handle;
252 err = start_this_handle(journal, handle);
253 @@ -333,14 +345,11 @@
255 if (is_journal_aborted(journal))
256 return ERR_PTR(-EIO);
258 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
260 + handle = new_handle(nblocks);
262 return ERR_PTR(-ENOMEM);
263 - memset (handle, 0, sizeof (handle_t));
265 - handle->h_buffer_credits = nblocks;
267 current->journal_info = handle;
269 err = try_start_this_handle(journal, handle);
270 @@ -1328,6 +1337,28 @@
274 + * Register a callback function for this handle. The function will be
275 + * called when the transaction that this handle is part of has been
276 + * committed to disk with the original callback data struct and the
277 + * error status of the journal as parameters. There is no guarantee of
278 + * ordering between handles within a single transaction, nor between
279 + * callbacks registered on the same handle.
281 + * The caller is responsible for allocating the journal_callback struct.
282 + * This is to allow the caller to add as much extra data to the callback
283 + * as needed, but reduce the overhead of multiple allocations. The caller
284 + * allocated struct must start with a struct journal_callback at offset 0,
285 + * and has the caller-specific data afterwards.
287 +void journal_callback_set(handle_t *handle,
288 + void (*func)(struct journal_callback *jcb, int error),
289 + struct journal_callback *jcb)
291 + list_add(&jcb->jcb_list, &handle->h_jcb);
292 + jcb->jcb_func = func;
296 * All done for a particular handle.
298 * There is not much action needed here. We just return any remaining
299 @@ -1393,7 +1424,10 @@
300 wake_up(&journal->j_wait_transaction_locked);
304 + /* Move callbacks from the handle to the transaction. */
305 + list_splice(&handle->h_jcb, &transaction->t_jcb);
308 * If the handle is marked SYNC, we need to set another commit
309 * going! We also want to force a commit if the current
310 * transaction is occupying too much of the log, or if the
311 --- linux-pristine/./include/linux/blkdev.h Thu Dec 5 10:49:41 2002
312 +++ linux/./include/linux/blkdev.h Fri Nov 29 18:30:34 2002
317 +#define CONFIG_DEV_RDONLY
318 +void dev_set_rdonly(kdev_t, int);
319 +int dev_check_rdonly(kdev_t);
320 +void dev_clear_rdonly(int);
322 --- linux-pristine/./include/linux/slab.h Thu Dec 5 10:49:53 2002
323 +++ linux/./include/linux/slab.h Fri Nov 29 18:30:15 2002
325 extern void *kmem_cache_alloc(kmem_cache_t *, int);
326 extern void *kmem_cache_zalloc(kmem_cache_t *, int);
327 extern void kmem_cache_free(kmem_cache_t *, void *);
328 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
330 extern void *kmalloc(size_t, int);
331 extern void kfree(const void *);
332 --- linux-pristine/./include/linux/jbd.h Thu Dec 5 10:49:43 2002
333 +++ linux/./include/linux/jbd.h Fri Nov 29 18:50:01 2002
335 return bh->b_private;
338 +#define HAVE_JOURNAL_CALLBACK_STATUS
339 +struct journal_callback {
340 + struct list_head jcb_list;
341 + void (*jcb_func)(struct journal_callback *jcb, int error);
342 + /* user data goes here */
345 struct jbd_revoke_table_s;
347 /* The handle_t type represents a single atomic update being performed
352 + /* List of application registered callbacks for this handle.
353 + * The function(s) will be called after the transaction that
354 + * this handle is part of has been committed to disk.
356 + struct list_head h_jcb;
359 unsigned int h_sync: 1; /* sync-on-close */
360 unsigned int h_jdata: 1; /* force data journaling */
363 /* How many handles used this transaction? */
366 + /* List of registered callback functions for this transaction.
367 + * Called when the transaction is committed. */
368 + struct list_head t_jcb;
373 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
374 extern int journal_stop(handle_t *);
375 extern int journal_flush (journal_t *);
376 +extern void journal_callback_set(handle_t *handle,
377 + void (*fn)(struct journal_callback *,int),
378 + struct journal_callback *jcb);
380 extern void journal_lock_updates (journal_t *);
381 extern void journal_unlock_updates (journal_t *);
382 --- linux-pristine/./kernel/ksyms.c Thu Dec 5 10:50:01 2002
383 +++ linux/./kernel/ksyms.c Fri Nov 29 18:37:23 2002
385 EXPORT_SYMBOL(set_page_dirty);
386 EXPORT_SYMBOL(vfs_readlink);
387 EXPORT_SYMBOL(vfs_follow_link);
388 +EXPORT_SYMBOL(vfs_follow_link_it);
389 EXPORT_SYMBOL(page_readlink);
390 EXPORT_SYMBOL(page_follow_link);
391 EXPORT_SYMBOL(page_symlink_inode_operations);
393 EXPORT_SYMBOL(nr_free_pages);
394 EXPORT_SYMBOL(page_cache_size);
397 +EXPORT_SYMBOL(pagecache_lock);
398 +EXPORT_SYMBOL(do_kern_mount);
399 +EXPORT_SYMBOL(kmem_cache_validate);
401 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
402 EXPORT_SYMBOL(default_llseek);
403 EXPORT_SYMBOL(dentry_open);
404 --- linux-pristine/./include/linux/dcache.h Thu Dec 5 10:49:42 2002
405 +++ linux/./include/linux/dcache.h Fri Nov 29 18:30:11 2002
407 #include <asm/atomic.h>
408 #include <linux/mount.h>
411 +#define IT_CREAT (1<<1)
412 +#define IT_MKDIR (1<<2)
413 +#define IT_LINK (1<<3)
414 +#define IT_LINK2 (1<<4)
415 +#define IT_SYMLINK (1<<5)
416 +#define IT_UNLINK (1<<6)
417 +#define IT_RMDIR (1<<7)
418 +#define IT_RENAME (1<<8)
419 +#define IT_RENAME2 (1<<9)
420 +#define IT_READDIR (1<<10)
421 +#define IT_GETATTR (1<<11)
422 +#define IT_SETATTR (1<<12)
423 +#define IT_READLINK (1<<13)
424 +#define IT_MKNOD (1<<14)
425 +#define IT_LOOKUP (1<<15)
427 +struct lookup_intent {
430 + int it_disposition;
432 + struct iattr *it_iattr;
433 + __u64 it_lock_handle[2];
439 * linux/include/linux/dcache.h
442 unsigned long d_time; /* used by d_revalidate */
443 struct dentry_operations *d_op;
444 struct super_block * d_sb; /* The root of the dentry tree */
445 + struct lookup_intent *d_it;
446 unsigned long d_vfs_flags;
447 void * d_fsdata; /* fs-specific data */
448 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
450 int (*d_delete)(struct dentry *);
451 void (*d_release)(struct dentry *);
452 void (*d_iput)(struct dentry *, struct inode *);
453 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
454 + void (*d_intent_release)(struct dentry *, struct lookup_intent *);
457 /* the dentry parameter passed to d_hash and d_compare is the parent
458 --- linux-pristine/./include/linux/fs.h Thu Dec 5 10:49:42 2002
459 +++ linux/./include/linux/fs.h Fri Nov 29 18:30:15 2002
462 /* needed for tty driver, and maybe others */
464 + struct lookup_intent *f_intent;
466 /* preallocated helper kiobuf to speedup O_DIRECT */
467 struct kiobuf *f_iobuf;
469 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
470 extern int vfs_rmdir(struct inode *, struct dentry *);
471 extern int vfs_unlink(struct inode *, struct dentry *);
472 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
473 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
474 + struct inode *new_dir, struct dentry *new_dentry,
475 + struct lookup_intent *it);
480 struct inode_operations {
481 int (*create) (struct inode *,struct dentry *,int);
482 struct dentry * (*lookup) (struct inode *,struct dentry *);
483 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
484 int (*link) (struct dentry *,struct inode *,struct dentry *);
485 int (*unlink) (struct inode *,struct dentry *);
486 int (*symlink) (struct inode *,struct dentry *,const char *);
488 struct inode *, struct dentry *);
489 int (*readlink) (struct dentry *, char *,int);
490 int (*follow_link) (struct dentry *, struct nameidata *);
491 + int (*follow_link2) (struct dentry *, struct nameidata *,
492 + struct lookup_intent *it);
493 void (*truncate) (struct inode *);
494 int (*permission) (struct inode *, int);
495 int (*revalidate) (struct dentry *);
496 @@ -1063,7 +1069,7 @@
497 extern struct vfsmount *kern_mount(struct file_system_type *);
498 extern int may_umount(struct vfsmount *);
499 extern long do_mount(char *, char *, char *, unsigned long, void *);
501 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
502 #define kern_umount mntput
504 extern int vfs_statfs(struct super_block *, struct statfs *);
505 @@ -1387,6 +1393,7 @@
506 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
508 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
509 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
510 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
511 extern int FASTCALL(path_walk(const char *, struct nameidata *));
512 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
513 @@ -1397,6 +1404,8 @@
514 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
515 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
516 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
517 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
518 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
520 extern void iput(struct inode *);
521 extern void force_delete(struct inode *);
522 @@ -1508,6 +1517,8 @@
524 extern int vfs_readlink(struct dentry *, char *, int, const char *);
525 extern int vfs_follow_link(struct nameidata *, const char *);
526 +extern int vfs_follow_link_it(struct nameidata *, const char *,
527 + struct lookup_intent *it);
528 extern int page_readlink(struct dentry *, char *, int);
529 extern int page_follow_link(struct dentry *, struct nameidata *);
530 extern struct inode_operations page_symlink_inode_operations;
531 --- linux-pristine/./fs/dcache.c Thu Dec 5 10:49:13 2002
532 +++ linux/./fs/dcache.c Fri Nov 29 18:06:20 2002
535 dentry->d_fsdata = NULL;
536 dentry->d_mounted = 0;
537 + dentry->d_it = NULL;
538 INIT_LIST_HEAD(&dentry->d_hash);
539 INIT_LIST_HEAD(&dentry->d_lru);
540 INIT_LIST_HEAD(&dentry->d_subdirs);
541 --- linux-pristine/./fs/nfsd/vfs.c Thu Dec 5 10:49:18 2002
542 +++ linux/./fs/nfsd/vfs.c Fri Nov 29 18:06:20 2002
543 @@ -1285,7 +1285,7 @@
547 - err = vfs_rename(fdir, odentry, tdir, ndentry);
548 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
549 if (!err && EX_ISSYNC(tfhp->fh_export)) {
550 nfsd_sync_dir(tdentry);
551 nfsd_sync_dir(fdentry);
552 --- linux-pristine/./fs/namei.c Thu Dec 5 10:49:16 2002
553 +++ linux/./fs/namei.c Fri Nov 29 18:11:18 2002
555 * XEmacs seems to be relying on it...
558 +void intent_release(struct dentry *de, struct lookup_intent *it)
560 + if (it && de->d_op && de->d_op->d_intent_release)
561 + de->d_op->d_intent_release(de, it);
564 /* In order to reduce some races, while at the same time doing additional
565 * checking and hopefully speeding things up, we copy filenames to the
566 * kernel data space before using them..
567 @@ -260,10 +266,19 @@
568 * Internal lookup() using the new generic dcache.
571 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
572 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
573 + int flags, struct lookup_intent *it)
575 struct dentry * dentry = d_lookup(parent, name);
577 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
578 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
579 + !d_invalidate(dentry)) {
585 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
586 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
589 * make sure that nobody added the entry to the dcache in the meantime..
592 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
593 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
594 + int flags, struct lookup_intent *it)
596 struct dentry * result;
597 struct inode *dir = parent->d_inode;
599 result = ERR_PTR(-ENOMEM);
602 + if (dir->i_op->lookup2)
603 + result = dir->i_op->lookup2(dir, dentry, it);
605 result = dir->i_op->lookup(dir, dentry);
610 result = ERR_PTR(-ENOENT);
612 + } else if (result->d_op && result->d_op->d_revalidate2) {
613 + if (!result->d_op->d_revalidate2(result, flags, it) &&
614 + !d_invalidate(result)) {
616 + result = ERR_PTR(-ENOENT);
622 * Without that kind of total limit, nasty chains of consecutive
623 * symlinks can cause almost arbitrarily long lookups.
625 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
626 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
627 + struct lookup_intent *it)
630 if (current->link_count >= 5)
631 @@ -346,10 +372,14 @@
632 current->link_count++;
633 current->total_link_count++;
634 UPDATE_ATIME(dentry->d_inode);
635 - err = dentry->d_inode->i_op->follow_link(dentry, nd);
636 + if (dentry->d_inode->i_op->follow_link2)
637 + err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
639 + err = dentry->d_inode->i_op->follow_link(dentry, nd);
640 current->link_count--;
643 + intent_release(dentry, it);
649 * We expect 'base' to be positive and a directory.
651 -int link_path_walk(const char * name, struct nameidata *nd)
652 +int link_path_walk_it(const char *name, struct nameidata *nd,
653 + struct lookup_intent *it)
655 struct dentry *dentry;
660 /* This does the actual lookups.. */
661 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
662 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
664 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
665 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
666 err = PTR_ERR(dentry);
673 - if (inode->i_op->follow_link) {
674 - err = do_follow_link(dentry, nd);
675 + if (inode->i_op->follow_link || inode->i_op->follow_link2) {
676 + err = do_follow_link(dentry, nd, NULL);
684 - if (!inode->i_op->lookup)
685 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
688 /* here ends the main loop */
693 - dentry = cached_lookup(nd->dentry, &this, 0);
694 + dentry = cached_lookup(nd->dentry, &this, 0, it);
696 - dentry = real_lookup(nd->dentry, &this, 0);
697 + dentry = real_lookup(nd->dentry, &this, 0, it);
698 err = PTR_ERR(dentry);
702 while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
704 inode = dentry->d_inode;
705 - if ((lookup_flags & LOOKUP_FOLLOW)
706 - && inode && inode->i_op && inode->i_op->follow_link) {
707 - err = do_follow_link(dentry, nd);
708 + if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op &&
709 + (inode->i_op->follow_link || inode->i_op->follow_link2)) {
710 + err = do_follow_link(dentry, nd, it);
716 if (lookup_flags & LOOKUP_DIRECTORY) {
718 - if (!inode->i_op || !inode->i_op->lookup)
719 + if (!inode->i_op ||
720 + (!inode->i_op->lookup && !inode->i_op->lookup2))
724 @@ -636,10 +668,21 @@
728 +int link_path_walk(const char * name, struct nameidata *nd)
730 + return link_path_walk_it(name, nd, NULL);
733 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
735 + current->total_link_count = 0;
736 + return link_path_walk_it(name, nd, it);
739 int path_walk(const char * name, struct nameidata *nd)
741 current->total_link_count = 0;
742 - return link_path_walk(name, nd);
743 + return link_path_walk_it(name, nd, NULL);
748 * needs parent already locked. Doesn't follow mounts.
751 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
752 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
753 + struct lookup_intent *it)
755 struct dentry * dentry;
757 @@ -765,13 +809,16 @@
761 - dentry = cached_lookup(base, name, 0);
762 + dentry = cached_lookup(base, name, 0, it);
764 struct dentry *new = d_alloc(base, name);
765 dentry = ERR_PTR(-ENOMEM);
769 + if (inode->i_op->lookup2)
770 + dentry = inode->i_op->lookup2(inode, new, it);
772 dentry = inode->i_op->lookup(inode, new);
779 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
781 + return lookup_hash_it(name, base, NULL);
786 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
790 this.hash = end_name_hash(hash);
792 - return lookup_hash(&this, base);
793 + return lookup_hash_it(&this, base, NULL);
795 return ERR_PTR(-EACCES);
801 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
802 + struct lookup_intent *it)
807 + tmp = getname(name);
808 + err = PTR_ERR(tmp);
809 + if (!IS_ERR(tmp)) {
811 + if (path_init(tmp, flags, nd))
812 + err = path_walk_it(tmp, nd, it);
819 * It's inline, so penalty for filesystems that don't use sticky bit is
822 * for symlinks (where the permissions are checked later).
825 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
826 +int open_namei_it(const char *pathname, int flag, int mode,
827 + struct nameidata *nd, struct lookup_intent *it)
829 int acc_mode, error = 0;
833 if (!(flag & O_CREAT)) {
834 if (path_init(pathname, lookup_flags(flag), nd))
835 - error = path_walk(pathname, nd);
836 + error = path_walk_it(pathname, nd, it);
840 @@ -995,6 +1066,10 @@
842 * Create - we need to know the parent.
845 + it->it_mode = mode;
846 + it->it_op |= IT_CREAT;
848 if (path_init(pathname, LOOKUP_PARENT, nd))
849 error = path_walk(pathname, nd);
851 @@ -1011,7 +1086,7 @@
854 down(&dir->d_inode->i_sem);
855 - dentry = lookup_hash(&nd->last, nd->dentry);
856 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
859 error = PTR_ERR(dentry);
860 @@ -1020,6 +1095,7 @@
864 + it->it_mode = mode;
865 /* Negative dentry, just create the file */
866 if (!dentry->d_inode) {
867 if (!IS_POSIX_ACL(dir->d_inode))
868 @@ -1054,7 +1130,8 @@
870 if (!dentry->d_inode)
872 - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
873 + if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
874 + dentry->d_inode->i_op->follow_link2))
878 @@ -1140,8 +1217,10 @@
882 + intent_release(dentry, it);
885 + intent_release(nd->dentry, it);
889 @@ -1160,7 +1239,12 @@
890 * are done. Procfs-like symlinks just set LAST_BIND.
892 UPDATE_ATIME(dentry->d_inode);
893 - error = dentry->d_inode->i_op->follow_link(dentry, nd);
894 + if (dentry->d_inode->i_op->follow_link2)
895 + error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
897 + error = dentry->d_inode->i_op->follow_link(dentry, nd);
899 + intent_release(dentry, it);
903 @@ -1182,13 +1266,20 @@
906 down(&dir->d_inode->i_sem);
907 - dentry = lookup_hash(&nd->last, nd->dentry);
908 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
909 putname(nd->last.name);
913 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
915 + return open_namei_it(pathname, flag, mode, nd, NULL);
920 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
921 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
922 + struct lookup_intent *it)
924 struct dentry *dentry;
926 @@ -1196,7 +1287,7 @@
927 dentry = ERR_PTR(-EEXIST);
928 if (nd->last_type != LAST_NORM)
930 - dentry = lookup_hash(&nd->last, nd->dentry);
931 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
934 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
935 @@ -1242,6 +1333,7 @@
937 struct dentry * dentry;
939 + struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
943 @@ -1253,7 +1345,7 @@
944 error = path_walk(tmp, &nd);
947 - dentry = lookup_create(&nd, 0);
948 + dentry = lookup_create(&nd, 0, &it);
949 error = PTR_ERR(dentry);
951 if (!IS_POSIX_ACL(nd.dentry->d_inode))
952 @@ -1272,6 +1364,7 @@
956 + intent_release(dentry, &it);
959 up(&nd.dentry->d_inode->i_sem);
960 @@ -1312,6 +1405,7 @@
964 + struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
966 tmp = getname(pathname);
967 error = PTR_ERR(tmp);
968 @@ -1323,12 +1417,13 @@
969 error = path_walk(tmp, &nd);
972 - dentry = lookup_create(&nd, 1);
973 + dentry = lookup_create(&nd, 1, &it);
974 error = PTR_ERR(dentry);
975 if (!IS_ERR(dentry)) {
976 if (!IS_POSIX_ACL(nd.dentry->d_inode))
977 mode &= ~current->fs->umask;
978 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
979 + intent_release(dentry, &it);
982 up(&nd.dentry->d_inode->i_sem);
983 @@ -1410,6 +1505,7 @@
985 struct dentry *dentry;
987 + struct lookup_intent it = { .it_op = IT_RMDIR };
989 name = getname(pathname);
991 @@ -1432,10 +1528,11 @@
994 down(&nd.dentry->d_inode->i_sem);
995 - dentry = lookup_hash(&nd.last, nd.dentry);
996 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
997 error = PTR_ERR(dentry);
998 if (!IS_ERR(dentry)) {
999 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1000 + intent_release(dentry, &it);
1003 up(&nd.dentry->d_inode->i_sem);
1004 @@ -1479,6 +1576,7 @@
1006 struct dentry *dentry;
1007 struct nameidata nd;
1008 + struct lookup_intent it = { .it_op = IT_UNLINK };
1010 name = getname(pathname);
1012 @@ -1492,7 +1590,7 @@
1013 if (nd.last_type != LAST_NORM)
1015 down(&nd.dentry->d_inode->i_sem);
1016 - dentry = lookup_hash(&nd.last, nd.dentry);
1017 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1018 error = PTR_ERR(dentry);
1019 if (!IS_ERR(dentry)) {
1020 /* Why not before? Because we want correct error value */
1021 @@ -1500,6 +1598,7 @@
1023 error = vfs_unlink(nd.dentry->d_inode, dentry);
1025 + intent_release(dentry, &it);
1028 up(&nd.dentry->d_inode->i_sem);
1029 @@ -1546,6 +1645,7 @@
1033 + struct lookup_intent it = { .it_op = IT_SYMLINK };
1035 from = getname(oldname);
1037 @@ -1560,10 +1660,12 @@
1038 error = path_walk(to, &nd);
1041 - dentry = lookup_create(&nd, 0);
1042 + it.it_data = from;
1043 + dentry = lookup_create(&nd, 0, &it);
1044 error = PTR_ERR(dentry);
1045 if (!IS_ERR(dentry)) {
1046 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1047 + intent_release(dentry, &it);
1050 up(&nd.dentry->d_inode->i_sem);
1051 @@ -1629,6 +1731,7 @@
1055 + struct lookup_intent it = { .it_op = IT_LINK };
1057 from = getname(oldname);
1059 @@ -1641,7 +1744,7 @@
1062 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
1063 - error = path_walk(from, &old_nd);
1064 + error = path_walk_it(from, &old_nd, &it);
1067 if (path_init(to, LOOKUP_PARENT, &nd))
1068 @@ -1651,10 +1754,12 @@
1070 if (old_nd.mnt != nd.mnt)
1072 - new_dentry = lookup_create(&nd, 0);
1073 + it.it_op = IT_LINK2;
1074 + new_dentry = lookup_create(&nd, 0, &it);
1075 error = PTR_ERR(new_dentry);
1076 if (!IS_ERR(new_dentry)) {
1077 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1078 + intent_release(new_dentry, &it);
1081 up(&nd.dentry->d_inode->i_sem);
1082 @@ -1697,7 +1802,8 @@
1085 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1086 - struct inode *new_dir, struct dentry *new_dentry)
1087 + struct inode *new_dir, struct dentry *new_dentry,
1088 + struct lookup_intent *it)
1091 struct inode *target;
1092 @@ -1757,6 +1863,7 @@
1095 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1096 + intent_release(new_dentry, it);
1099 target->i_flags |= S_DEAD;
1100 @@ -1778,7 +1885,8 @@
1103 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1104 - struct inode *new_dir, struct dentry *new_dentry)
1105 + struct inode *new_dir, struct dentry *new_dentry,
1106 + struct lookup_intent *it)
1110 @@ -1809,6 +1917,7 @@
1113 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1114 + intent_release(new_dentry, it);
1115 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1118 @@ -1820,13 +1929,14 @@
1121 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1122 - struct inode *new_dir, struct dentry *new_dentry)
1123 + struct inode *new_dir, struct dentry *new_dentry,
1124 + struct lookup_intent *it)
1127 if (S_ISDIR(old_dentry->d_inode->i_mode))
1128 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1129 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1131 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1132 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1134 if (old_dir == new_dir)
1135 inode_dir_notify(old_dir, DN_RENAME);
1136 @@ -1843,6 +1953,7 @@
1138 struct dentry * old_dir, * new_dir;
1139 struct dentry * old_dentry, *new_dentry;
1140 + struct lookup_intent it = { .it_op = IT_RENAME };
1141 struct nameidata oldnd, newnd;
1143 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1144 @@ -1871,7 +1982,7 @@
1146 double_lock(new_dir, old_dir);
1148 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1149 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1150 error = PTR_ERR(old_dentry);
1151 if (IS_ERR(old_dentry))
1153 @@ -1887,18 +1998,21 @@
1154 if (newnd.last.name[newnd.last.len])
1157 - new_dentry = lookup_hash(&newnd.last, new_dir);
1158 + it.it_op = IT_RENAME2;
1159 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1160 error = PTR_ERR(new_dentry);
1161 if (IS_ERR(new_dentry))
1165 error = vfs_rename(old_dir->d_inode, old_dentry,
1166 - new_dir->d_inode, new_dentry);
1167 + new_dir->d_inode, new_dentry, &it);
1170 + intent_release(new_dentry, &it);
1173 + intent_release(old_dentry, &it);
1176 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1177 @@ -1947,7 +2061,8 @@
1181 -__vfs_follow_link(struct nameidata *nd, const char *link)
1182 +__vfs_follow_link(struct nameidata *nd, const char *link,
1183 + struct lookup_intent *it)
1187 @@ -1960,7 +2075,7 @@
1188 /* weird __emul_prefix() stuff did it */
1191 - res = link_path_walk(link, nd);
1192 + res = link_path_walk_it(link, nd, it);
1194 if (current->link_count || res || nd->last_type!=LAST_NORM)
1196 @@ -1982,7 +2097,13 @@
1198 int vfs_follow_link(struct nameidata *nd, const char *link)
1200 - return __vfs_follow_link(nd, link);
1201 + return __vfs_follow_link(nd, link, NULL);
1204 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
1205 + struct lookup_intent *it)
1207 + return __vfs_follow_link(nd, link, it);
1210 /* get the link contents into pagecache */
1211 @@ -2024,7 +2145,7 @@
1213 struct page *page = NULL;
1214 char *s = page_getlink(dentry, &page);
1215 - int res = __vfs_follow_link(nd, s);
1216 + int res = __vfs_follow_link(nd, s, NULL);
1219 page_cache_release(page);
1220 --- linux-pristine/./fs/open.c Thu Dec 5 10:49:20 2002
1221 +++ linux/./fs/open.c Fri Nov 29 18:06:21 2002
1223 #include <asm/uaccess.h>
1225 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1226 +extern int path_walk_it(const char *name, struct nameidata *nd,
1227 + struct lookup_intent *it);
1228 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1230 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1233 struct nameidata nd;
1234 struct inode * inode;
1236 + struct lookup_intent it = { .it_op = IT_SETATTR };
1239 if (length < 0) /* sorry, but loff_t says... */
1242 - error = user_path_walk(path, &nd);
1243 + error = user_path_walk_it(path, &nd, &it);
1246 inode = nd.dentry->d_inode;
1248 put_write_access(inode);
1251 + intent_release(nd.dentry, &it);
1256 struct nameidata nd;
1257 struct inode * inode;
1258 struct iattr newattrs;
1259 + struct lookup_intent it = { .it_op = IT_SETATTR };
1261 - error = user_path_walk(filename, &nd);
1262 + error = user_path_walk_it(filename, &nd, &it);
1265 inode = nd.dentry->d_inode;
1268 error = notify_change(nd.dentry, &newattrs);
1270 + intent_release(nd.dentry, &it);
1275 struct nameidata nd;
1276 struct inode * inode;
1277 struct iattr newattrs;
1278 + struct lookup_intent it = { .it_op = IT_SETATTR };
1280 - error = user_path_walk(filename, &nd);
1281 + error = user_path_walk_it(filename, &nd, &it);
1287 error = notify_change(nd.dentry, &newattrs);
1289 + intent_release(nd.dentry, &it);
1294 int old_fsuid, old_fsgid;
1295 kernel_cap_t old_cap;
1297 + struct lookup_intent it = { .it_op = IT_GETATTR };
1299 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1301 @@ -340,13 +350,14 @@
1303 current->cap_effective = current->cap_permitted;
1305 - res = user_path_walk(filename, &nd);
1306 + res = user_path_walk_it(filename, &nd, &it);
1308 res = permission(nd.dentry->d_inode, mode);
1309 /* SuS v2 requires we report a read only fs too */
1310 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1311 && !special_file(nd.dentry->d_inode->i_mode))
1313 + intent_release(nd.dentry, &it);
1319 struct nameidata nd;
1321 + struct lookup_intent it = { .it_op = IT_GETATTR };
1323 name = getname(filename);
1324 error = PTR_ERR(name);
1328 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1329 - error = path_walk(name, &nd);
1330 + error = path_walk_it(name, &nd, &it);
1335 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1338 + intent_release(nd.dentry, &it);
1344 struct nameidata nd;
1346 + struct lookup_intent it = { .it_op = IT_GETATTR };
1348 name = getname(filename);
1349 error = PTR_ERR(name);
1352 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1353 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1354 - error = path_walk(name, &nd);
1355 + error = path_walk_it(name, &nd, &it);
1363 + intent_release(nd.dentry, &it);
1368 struct inode * inode;
1370 struct iattr newattrs;
1371 + struct lookup_intent it = { .it_op = IT_SETATTR };
1373 - error = user_path_walk(filename, &nd);
1374 + error = user_path_walk_it(filename, &nd, &it);
1377 inode = nd.dentry->d_inode;
1379 error = notify_change(nd.dentry, &newattrs);
1382 + intent_release(nd.dentry, &it);
1386 @@ -581,10 +598,12 @@
1388 struct nameidata nd;
1390 + struct lookup_intent it = { .it_op = IT_SETATTR };
1392 - error = user_path_walk(filename, &nd);
1393 + error = user_path_walk_it(filename, &nd, &it);
1395 error = chown_common(nd.dentry, user, group);
1396 + intent_release(nd.dentry, &it);
1400 @@ -594,10 +613,12 @@
1402 struct nameidata nd;
1404 + struct lookup_intent it = { .it_op = IT_SETATTR };
1406 - error = user_path_walk_link(filename, &nd);
1407 + error = user_path_walk_link_it(filename, &nd, &it);
1409 error = chown_common(nd.dentry, user, group);
1410 + intent_release(nd.dentry, &it);
1414 @@ -631,10 +652,16 @@
1415 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1418 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1419 + struct nameidata *nd, struct lookup_intent *it);
1420 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1421 + int flags, struct lookup_intent *it);
1423 struct file *filp_open(const char * filename, int flags, int mode)
1425 int namei_flags, error;
1426 struct nameidata nd;
1427 + struct lookup_intent it = { .it_op = IT_OPEN };
1429 namei_flags = flags;
1430 if ((namei_flags+1) & O_ACCMODE)
1431 @@ -642,14 +669,15 @@
1432 if (namei_flags & O_TRUNC)
1435 - error = open_namei(filename, namei_flags, mode, &nd);
1437 - return dentry_open(nd.dentry, nd.mnt, flags);
1438 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1440 + return ERR_PTR(error);
1442 - return ERR_PTR(error);
1443 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1446 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1447 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1448 + int flags, struct lookup_intent *it)
1451 struct inode *inode;
1454 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1456 + intent_release(dentry, it);
1460 @@ -706,11 +735,17 @@
1464 + intent_release(dentry, it);
1467 return ERR_PTR(error);
1470 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1472 + return dentry_open_it(dentry, mnt, flags, NULL);
1476 * Find an empty file descriptor entry, and mark it busy.
1478 --- linux-pristine/./fs/stat.c Thu Dec 5 10:49:22 2002
1479 +++ linux/./fs/stat.c Fri Nov 29 18:06:21 2002
1482 #include <asm/uaccess.h>
1484 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1486 * Revalidate the inode. This is required for proper NFS attribute caching.
1488 @@ -135,13 +136,15 @@
1489 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1491 struct nameidata nd;
1492 + struct lookup_intent it = { .it_op = IT_GETATTR };
1495 - error = user_path_walk(filename, &nd);
1496 + error = user_path_walk_it(filename, &nd, &it);
1498 error = do_revalidate(nd.dentry);
1500 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1501 + intent_release(nd.dentry, &it);
1505 @@ -151,13 +154,15 @@
1506 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1508 struct nameidata nd;
1509 + struct lookup_intent it = { .it_op = IT_GETATTR };
1512 - error = user_path_walk(filename, &nd);
1513 + error = user_path_walk_it(filename, &nd, &it);
1515 error = do_revalidate(nd.dentry);
1517 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1518 + intent_release(nd.dentry, &it);
1522 @@ -172,13 +177,15 @@
1523 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1525 struct nameidata nd;
1526 + struct lookup_intent it = { .it_op = IT_GETATTR };
1529 - error = user_path_walk_link(filename, &nd);
1530 + error = user_path_walk_link_it(filename, &nd, &it);
1532 error = do_revalidate(nd.dentry);
1534 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1535 + intent_release(nd.dentry, &it);
1539 @@ -189,13 +196,15 @@
1540 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1542 struct nameidata nd;
1543 + struct lookup_intent it = { .it_op = IT_GETATTR };
1546 - error = user_path_walk_link(filename, &nd);
1547 + error = user_path_walk_link_it(filename, &nd, &it);
1549 error = do_revalidate(nd.dentry);
1551 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1552 + intent_release(nd.dentry, &it);
1556 @@ -247,20 +256,21 @@
1558 struct nameidata nd;
1560 + struct lookup_intent it = { .it_op = IT_READLINK };
1565 - error = user_path_walk_link(path, &nd);
1566 + error = user_path_walk_link_it(path, &nd, &it);
1568 struct inode * inode = nd.dentry->d_inode;
1571 if (inode->i_op && inode->i_op->readlink &&
1572 !(error = do_revalidate(nd.dentry))) {
1573 UPDATE_ATIME(inode);
1574 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1576 + intent_release(nd.dentry, &it);
1580 @@ -333,12 +343,14 @@
1582 struct nameidata nd;
1584 + struct lookup_intent it = { .it_op = IT_GETATTR };
1586 - error = user_path_walk(filename, &nd);
1587 + error = user_path_walk_it(filename, &nd, &it);
1589 error = do_revalidate(nd.dentry);
1591 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1592 + intent_release(nd.dentry, &it);
1596 @@ -348,12 +360,14 @@
1598 struct nameidata nd;
1600 + struct lookup_intent it = { .it_op = IT_GETATTR };
1602 - error = user_path_walk_link(filename, &nd);
1603 + error = user_path_walk_link_it(filename, &nd, &it);
1605 error = do_revalidate(nd.dentry);
1607 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1608 + intent_release(nd.dentry, &it);
1612 --- linux-pristine/./mm/slab.c Thu Dec 5 10:50:02 2002
1613 +++ linux/./mm/slab.c Fri Nov 29 18:06:21 2002
1614 @@ -1187,6 +1187,59 @@
1615 * Called with the cache-lock held.
1618 +extern struct page *check_get_page(unsigned long kaddr);
1619 +struct page *page_mem_map(struct page *page);
1620 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1621 + slab_t *slabp, void * objp)
1624 + unsigned int objnr;
1627 + if (cachep->flags & SLAB_RED_ZONE) {
1628 + objp -= BYTES_PER_WORD;
1629 + if ( *(unsigned long *)objp != RED_MAGIC2)
1630 + /* Either write before start, or a double free. */
1632 + if (*(unsigned long *)(objp+cachep->objsize -
1633 + BYTES_PER_WORD) != RED_MAGIC2)
1634 + /* Either write past end, or a double free. */
1639 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1640 + if (objnr >= cachep->num)
1642 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1645 + /* Check slab's freelist to see if this obj is there. */
1646 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1654 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1656 + struct page *page = check_get_page((unsigned long)objp);
1658 + if (!VALID_PAGE(page))
1661 + if (!PageSlab(page))
1664 + /* XXX check for freed slab objects ? */
1665 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1668 + return (cachep == GET_PAGE_CACHE(page));
1672 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1673 slab_t *slabp, void * objp)