1 --- lum-pristine/include/linux/lustre_version.h Wed Dec 31 19:00:00 1969
2 +++ lum/include/linux/lustre_version.h Tue Nov 26 07:02:14 2002
4 +#define LUSTRE_KERNEL_VERSION 4
5 --- lum-pristine/arch/ia64/mm/init.c Fri Nov 9 17:26:17 2001
6 +++ lum/arch/ia64/mm/init.c Thu Aug 1 18:07:35 2002
9 static unsigned long totalram_pages;
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 --- lum-pristine/arch/i386/mm/init.c Fri Dec 21 12:41:53 2001
21 +++ lum/arch/i386/mm/init.c Thu Aug 1 18:07:35 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 --- lum-pristine/drivers/block/blkpg.c Mon Feb 25 14:37:57 2002
36 +++ lum/drivers/block/blkpg.c Thu Aug 1 18:07:35 2002
40 EXPORT_SYMBOL(blk_ioctl);
42 +#define NUM_DEV_NO_WRITE 16
43 +static int dev_no_write[NUM_DEV_NO_WRITE];
46 + * Debug code for turning block devices "read-only" (will discard writes
47 + * silently). This is for filesystem crash/recovery testing.
49 +void dev_set_rdonly(kdev_t dev, int no_write)
52 + printk(KERN_WARNING "Turning device %s read-only\n",
54 + dev_no_write[no_write] = 0xdead0000 + dev;
58 +int dev_check_rdonly(kdev_t dev) {
61 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
62 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
63 + dev == (dev_no_write[i] & 0xffff))
69 +void dev_clear_rdonly(int no_write) {
70 + dev_no_write[no_write] = 0;
73 +EXPORT_SYMBOL(dev_set_rdonly);
74 +EXPORT_SYMBOL(dev_check_rdonly);
75 +EXPORT_SYMBOL(dev_clear_rdonly);
76 --- lum-pristine/drivers/block/loop.c Fri Dec 21 12:41:53 2001
77 +++ lum/drivers/block/loop.c Thu Aug 1 18:07:35 2002
79 spin_unlock_irq(&lo->lo_lock);
82 +#ifdef CONFIG_DEV_RDONLY
83 + if (dev_check_rdonly(rbh->b_rdev))
87 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
89 } else if (rw == READA) {
90 --- lum-pristine/drivers/ide/ide-disk.c Fri Dec 21 12:41:54 2001
91 +++ lum/drivers/ide/ide-disk.c Thu Aug 1 18:07:35 2002
94 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
96 +#ifdef CONFIG_DEV_RDONLY
97 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
98 + ide_end_request(1, HWGROUP(drive));
103 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
104 OUT_BYTE(0x00, IDE_FEATURE_REG);
105 --- lum-pristine/fs/ext3/Makefile Fri Dec 21 12:41:55 2001
106 +++ lum/fs/ext3/Makefile Thu Aug 1 18:07:35 2002
111 +export-objs := super.o
113 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
114 ioctl.o namei.o super.o symlink.o
116 --- lum-pristine/fs/ext3/super.c Mon Feb 25 14:38:08 2002
117 +++ lum/fs/ext3/super.c Thu Aug 1 18:07:35 2002
118 @@ -1744,7 +1744,7 @@
119 unregister_filesystem(&ext3_fs_type);
123 +EXPORT_SYMBOL(ext3_bread);
125 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
126 MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
127 --- lum-pristine/fs/jbd/commit.c Mon Feb 25 14:38:08 2002
128 +++ lum/fs/jbd/commit.c Thu Aug 1 18:07:35 2002
130 transaction's t_log_list queue, and metadata buffers are on
131 the t_iobuf_list queue.
133 - Wait for the transactions in reverse order. That way we are
134 + Wait for the buffers in reverse order. That way we are
135 less likely to be woken up until all IOs have completed, and
136 so we incur less scheduling load.
140 jbd_debug(3, "JBD: commit phase 6\n");
142 - if (is_journal_aborted(journal))
143 + if (is_journal_aborted(journal)) {
144 + unlock_journal(journal);
148 /* Done it all: now write the commit record. We should have
149 * cleaned up our previous buffers by now, so if we are in abort
151 descriptor = journal_get_descriptor_buffer(journal);
153 __journal_abort_hard(journal);
154 + unlock_journal(journal);
159 put_bh(bh); /* One for getblk() */
160 journal_unlock_journal_head(descriptor);
162 - lock_journal(journal);
164 /* End of a transaction! Finally, we can do checkpoint
165 processing: any buffers committed as a result of this
170 + /* Call any callbacks that had been registered for handles in this
171 + * transaction. It is up to the callback to free any allocated
174 + if (!list_empty(&commit_transaction->t_jcb)) {
175 + struct list_head *p, *n;
176 + int error = is_journal_aborted(journal);
178 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
179 + struct journal_callback *jcb;
181 + jcb = list_entry(p, struct journal_callback, jcb_list);
183 + jcb->jcb_func(jcb, error);
187 + lock_journal(journal);
189 jbd_debug(3, "JBD: commit phase 7\n");
191 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
192 --- lum-pristine/fs/jbd/journal.c Mon Feb 25 14:38:08 2002
193 +++ lum/fs/jbd/journal.c Thu Aug 1 18:07:35 2002
196 EXPORT_SYMBOL(journal_flush);
197 EXPORT_SYMBOL(journal_revoke);
198 +EXPORT_SYMBOL(journal_callback_set);
200 EXPORT_SYMBOL(journal_init_dev);
201 EXPORT_SYMBOL(journal_init_inode);
202 --- lum-pristine/fs/jbd/transaction.c Mon Feb 25 14:38:08 2002
203 +++ lum/fs/jbd/transaction.c Thu Aug 1 18:07:35 2002
205 transaction->t_state = T_RUNNING;
206 transaction->t_tid = journal->j_transaction_sequence++;
207 transaction->t_expires = jiffies + journal->j_commit_interval;
208 + INIT_LIST_HEAD(&transaction->t_jcb);
210 /* Set up the commit timer for the new transaction. */
211 J_ASSERT (!journal->j_commit_timer_active);
216 +/* Allocate a new handle. This should probably be in a slab... */
217 +static handle_t *new_handle(int nblocks)
219 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
222 + memset(handle, 0, sizeof (handle_t));
223 + handle->h_buffer_credits = nblocks;
225 + INIT_LIST_HEAD(&handle->h_jcb);
231 * Obtain a new handle.
233 @@ -227,14 +242,11 @@
238 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
240 + handle = new_handle(nblocks);
242 return ERR_PTR(-ENOMEM);
243 - memset (handle, 0, sizeof (handle_t));
245 - handle->h_buffer_credits = nblocks;
247 current->journal_info = handle;
249 err = start_this_handle(journal, handle);
250 @@ -333,14 +345,11 @@
252 if (is_journal_aborted(journal))
253 return ERR_PTR(-EIO);
255 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
257 + handle = new_handle(nblocks);
259 return ERR_PTR(-ENOMEM);
260 - memset (handle, 0, sizeof (handle_t));
262 - handle->h_buffer_credits = nblocks;
264 current->journal_info = handle;
266 err = try_start_this_handle(journal, handle);
267 @@ -1328,6 +1337,28 @@
271 + * Register a callback function for this handle. The function will be
272 + * called when the transaction that this handle is part of has been
273 + * committed to disk with the original callback data struct and the
274 + * error status of the journal as parameters. There is no guarantee of
275 + * ordering between handles within a single transaction, nor between
276 + * callbacks registered on the same handle.
278 + * The caller is responsible for allocating the journal_callback struct.
279 + * This is to allow the caller to add as much extra data to the callback
280 + * as needed, but reduce the overhead of multiple allocations. The caller
281 + * allocated struct must start with a struct journal_callback at offset 0,
282 + * and has the caller-specific data afterwards.
284 +void journal_callback_set(handle_t *handle,
285 + void (*func)(struct journal_callback *jcb, int error),
286 + struct journal_callback *jcb)
288 + list_add(&jcb->jcb_list, &handle->h_jcb);
289 + jcb->jcb_func = func;
293 * All done for a particular handle.
295 * There is not much action needed here. We just return any remaining
296 @@ -1383,7 +1415,10 @@
297 wake_up(&journal->j_wait_transaction_locked);
301 + /* Move callbacks from the handle to the transaction. */
302 + list_splice(&handle->h_jcb, &transaction->t_jcb);
305 * If the handle is marked SYNC, we need to set another commit
306 * going! We also want to force a commit if the current
307 * transaction is occupying too much of the log, or if the
308 --- lum-pristine/include/linux/blkdev.h Mon Nov 26 08:29:17 2001
309 +++ lum/include/linux/blkdev.h Mon Aug 12 11:48:39 2002
314 +#define CONFIG_DEV_RDONLY
315 +void dev_set_rdonly(kdev_t, int);
316 +int dev_check_rdonly(kdev_t);
317 +void dev_clear_rdonly(int);
319 --- lum-pristine/include/linux/slab.h Fri Dec 21 12:42:04 2001
320 +++ lum/include/linux/slab.h Mon Aug 12 11:48:38 2002
322 extern int kmem_cache_shrink(kmem_cache_t *);
323 extern void *kmem_cache_alloc(kmem_cache_t *, int);
324 extern void kmem_cache_free(kmem_cache_t *, void *);
325 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
327 extern void *kmalloc(size_t, int);
328 extern void kfree(const void *);
329 --- lum-pristine/include/linux/jbd.h Mon Feb 25 14:38:13 2002
330 +++ lum/include/linux/jbd.h Mon Aug 12 11:50:09 2002
332 return bh->b_private;
335 +#define HAVE_JOURNAL_CALLBACK_STATUS
336 +struct journal_callback {
337 + struct list_head jcb_list;
338 + void (*jcb_func)(struct journal_callback *jcb, int error);
339 + /* user data goes here */
342 struct jbd_revoke_table_s;
344 /* The handle_t type represents a single atomic update being performed
349 + /* List of application registered callbacks for this handle.
350 + * The function(s) will be called after the transaction that
351 + * this handle is part of has been committed to disk.
353 + struct list_head h_jcb;
356 unsigned int h_sync: 1; /* sync-on-close */
357 unsigned int h_jdata: 1; /* force data journaling */
360 /* How many handles used this transaction? */
363 + /* List of registered callback functions for this transaction.
364 + * Called when the transaction is committed. */
365 + struct list_head t_jcb;
370 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
371 extern int journal_stop(handle_t *);
372 extern int journal_flush (journal_t *);
373 +extern void journal_callback_set(handle_t *handle,
374 + void (*fn)(struct journal_callback *,int),
375 + struct journal_callback *jcb);
377 extern void journal_lock_updates (journal_t *);
378 extern void journal_unlock_updates (journal_t *);
379 --- lum-pristine/kernel/ksyms.c Mon Feb 25 14:38:13 2002
380 +++ lum/kernel/ksyms.c Thu Aug 1 18:07:35 2002
382 EXPORT_SYMBOL(set_page_dirty);
383 EXPORT_SYMBOL(vfs_readlink);
384 EXPORT_SYMBOL(vfs_follow_link);
385 +EXPORT_SYMBOL(vfs_follow_link_it);
386 EXPORT_SYMBOL(page_readlink);
387 EXPORT_SYMBOL(page_follow_link);
388 EXPORT_SYMBOL(page_symlink_inode_operations);
390 EXPORT_SYMBOL(lock_may_write);
391 EXPORT_SYMBOL(dcache_readdir);
394 +EXPORT_SYMBOL(panic_notifier_list);
395 +EXPORT_SYMBOL(pagecache_lock);
396 +EXPORT_SYMBOL(do_kern_mount);
397 +EXPORT_SYMBOL(kmem_cache_validate);
399 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
400 EXPORT_SYMBOL(default_llseek);
401 EXPORT_SYMBOL(dentry_open);
402 --- lum-pristine/include/linux/dcache.h Thu Nov 22 14:46:18 2001
403 +++ lum/include/linux/dcache.h Mon Aug 12 00:02:29 2002
405 #include <asm/atomic.h>
406 #include <linux/mount.h>
409 +#define IT_CREAT (1<<1)
410 +#define IT_MKDIR (1<<2)
411 +#define IT_LINK (1<<3)
412 +#define IT_LINK2 (1<<4)
413 +#define IT_SYMLINK (1<<5)
414 +#define IT_UNLINK (1<<6)
415 +#define IT_RMDIR (1<<7)
416 +#define IT_RENAME (1<<8)
417 +#define IT_RENAME2 (1<<9)
418 +#define IT_READDIR (1<<10)
419 +#define IT_GETATTR (1<<11)
420 +#define IT_SETATTR (1<<12)
421 +#define IT_READLINK (1<<13)
422 +#define IT_MKNOD (1<<14)
423 +#define IT_LOOKUP (1<<15)
425 +struct lookup_intent {
428 + int it_disposition;
430 + struct iattr *it_iattr;
431 + __u64 it_lock_handle[2];
437 * linux/include/linux/dcache.h
440 unsigned long d_time; /* used by d_revalidate */
441 struct dentry_operations *d_op;
442 struct super_block * d_sb; /* The root of the dentry tree */
443 + struct lookup_intent *d_it;
444 unsigned long d_vfs_flags;
445 void * d_fsdata; /* fs-specific data */
446 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
448 int (*d_delete)(struct dentry *);
449 void (*d_release)(struct dentry *);
450 void (*d_iput)(struct dentry *, struct inode *);
451 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
452 + void (*d_intent_release)(struct dentry *, struct lookup_intent *);
455 /* the dentry parameter passed to d_hash and d_compare is the parent
456 --- lum-pristine/include/linux/fs.h Mon Aug 12 11:02:53 2002
457 +++ lum/include/linux/fs.h Mon Aug 12 11:48:38 2002
460 /* needed for tty driver, and maybe others */
462 + struct lookup_intent *f_intent;
464 /* preallocated helper kiobuf to speedup O_DIRECT */
465 struct kiobuf *f_iobuf;
467 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
468 extern int vfs_rmdir(struct inode *, struct dentry *);
469 extern int vfs_unlink(struct inode *, struct dentry *);
470 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
471 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
472 + struct inode *new_dir, struct dentry *new_dentry,
473 + struct lookup_intent *it);
478 struct inode_operations {
479 int (*create) (struct inode *,struct dentry *,int);
480 struct dentry * (*lookup) (struct inode *,struct dentry *);
481 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
482 int (*link) (struct dentry *,struct inode *,struct dentry *);
483 int (*unlink) (struct inode *,struct dentry *);
484 int (*symlink) (struct inode *,struct dentry *,const char *);
486 struct inode *, struct dentry *);
487 int (*readlink) (struct dentry *, char *,int);
488 int (*follow_link) (struct dentry *, struct nameidata *);
489 + int (*follow_link2) (struct dentry *, struct nameidata *,
490 + struct lookup_intent *it);
491 void (*truncate) (struct inode *);
492 int (*permission) (struct inode *, int);
493 int (*revalidate) (struct dentry *);
495 extern struct vfsmount *kern_mount(struct file_system_type *);
496 extern int may_umount(struct vfsmount *);
497 extern long do_mount(char *, char *, char *, unsigned long, void *);
499 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
500 #define kern_umount mntput
502 extern int vfs_statfs(struct super_block *, struct statfs *);
503 @@ -1307,6 +1311,7 @@
504 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
506 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
507 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
508 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
509 extern int FASTCALL(path_walk(const char *, struct nameidata *));
510 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
511 @@ -1317,6 +1322,8 @@
512 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
513 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
514 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
515 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
516 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
518 extern void iput(struct inode *);
519 extern void force_delete(struct inode *);
520 @@ -1422,6 +1428,8 @@
522 extern int vfs_readlink(struct dentry *, char *, int, const char *);
523 extern int vfs_follow_link(struct nameidata *, const char *);
524 +extern int vfs_follow_link_it(struct nameidata *, const char *,
525 + struct lookup_intent *it);
526 extern int page_readlink(struct dentry *, char *, int);
527 extern int page_follow_link(struct dentry *, struct nameidata *);
528 extern struct inode_operations page_symlink_inode_operations;
529 --- lum-pristine/fs/dcache.c Mon Feb 25 14:38:08 2002
530 +++ lum/fs/dcache.c Thu Aug 1 18:07:35 2002
533 dentry->d_fsdata = NULL;
534 dentry->d_mounted = 0;
535 + dentry->d_it = NULL;
536 INIT_LIST_HEAD(&dentry->d_hash);
537 INIT_LIST_HEAD(&dentry->d_lru);
538 INIT_LIST_HEAD(&dentry->d_subdirs);
539 --- lum-pristine/fs/nfsd/vfs.c Fri Dec 21 12:41:55 2001
540 +++ lum/fs/nfsd/vfs.c Thu Aug 1 18:07:35 2002
541 @@ -1285,7 +1285,7 @@
545 - err = vfs_rename(fdir, odentry, tdir, ndentry);
546 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
547 if (!err && EX_ISSYNC(tfhp->fh_export)) {
548 nfsd_sync_dir(tdentry);
549 nfsd_sync_dir(fdentry);
550 --- lum-pristine/fs/namei.c Mon Feb 25 14:38:09 2002
551 +++ lum/fs/namei.c Mon Aug 12 11:47:56 2002
553 * XEmacs seems to be relying on it...
556 +void intent_release(struct dentry *de, struct lookup_intent *it)
558 + if (it && de->d_op && de->d_op->d_intent_release)
559 + de->d_op->d_intent_release(de, it);
562 /* In order to reduce some races, while at the same time doing additional
563 * checking and hopefully speeding things up, we copy filenames to the
564 * kernel data space before using them..
565 @@ -260,10 +268,19 @@
566 * Internal lookup() using the new generic dcache.
569 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
570 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
571 + int flags, struct lookup_intent *it)
573 struct dentry * dentry = d_lookup(parent, name);
575 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
576 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
577 + !d_invalidate(dentry)) {
583 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
584 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
587 * make sure that nobody added the entry to the dcache in the meantime..
590 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
591 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
592 + int flags, struct lookup_intent *it)
594 struct dentry * result;
595 struct inode *dir = parent->d_inode;
597 result = ERR_PTR(-ENOMEM);
600 + if (dir->i_op->lookup2)
601 + result = dir->i_op->lookup2(dir, dentry, it);
603 result = dir->i_op->lookup(dir, dentry);
608 result = ERR_PTR(-ENOENT);
610 + } else if (result->d_op && result->d_op->d_revalidate2) {
611 + if (!result->d_op->d_revalidate2(result, flags, it) &&
612 + !d_invalidate(result)) {
614 + result = ERR_PTR(-ENOENT);
620 * Without that kind of total limit, nasty chains of consecutive
621 * symlinks can cause almost arbitrarily long lookups.
623 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
624 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
625 + struct lookup_intent *it)
628 if (current->link_count >= max_recursive_link)
629 @@ -348,10 +376,14 @@
630 current->link_count++;
631 current->total_link_count++;
632 UPDATE_ATIME(dentry->d_inode);
633 - err = dentry->d_inode->i_op->follow_link(dentry, nd);
634 + if (dentry->d_inode->i_op->follow_link2)
635 + err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
637 + err = dentry->d_inode->i_op->follow_link(dentry, nd);
638 current->link_count--;
641 + intent_release(dentry, it);
647 * We expect 'base' to be positive and a directory.
649 -int link_path_walk(const char * name, struct nameidata *nd)
650 +int link_path_walk_it(const char *name, struct nameidata *nd,
651 + struct lookup_intent *it)
653 struct dentry *dentry;
658 /* This does the actual lookups.. */
659 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
660 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
662 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
663 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
664 err = PTR_ERR(dentry);
671 - if (inode->i_op->follow_link) {
672 - err = do_follow_link(dentry, nd);
673 + if (inode->i_op->follow_link || inode->i_op->follow_link2) {
674 + err = do_follow_link(dentry, nd, it);
682 - if (!inode->i_op->lookup)
683 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
686 /* here ends the main loop */
691 - dentry = cached_lookup(nd->dentry, &this, 0);
692 + dentry = cached_lookup(nd->dentry, &this, 0, it);
694 - dentry = real_lookup(nd->dentry, &this, 0);
695 + dentry = real_lookup(nd->dentry, &this, 0, it);
696 err = PTR_ERR(dentry);
700 while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
702 inode = dentry->d_inode;
703 - if ((lookup_flags & LOOKUP_FOLLOW)
704 - && inode && inode->i_op && inode->i_op->follow_link) {
705 - err = do_follow_link(dentry, nd);
706 + if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op &&
707 + (inode->i_op->follow_link || inode->i_op->follow_link2)) {
708 + err = do_follow_link(dentry, nd, it);
714 if (lookup_flags & LOOKUP_DIRECTORY) {
716 - if (!inode->i_op || !inode->i_op->lookup)
717 + if (!inode->i_op ||
718 + (!inode->i_op->lookup && !inode->i_op->lookup2))
722 @@ -630,12 +660,23 @@
726 +int link_path_walk(const char * name, struct nameidata *nd)
728 + return link_path_walk_it(name, nd, NULL);
731 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
733 + current->total_link_count = 0;
734 + return link_path_walk_it(name, nd, it);
737 int path_walk(const char * name, struct nameidata *nd)
739 current->total_link_count = 0;
740 - return link_path_walk(name, nd);
741 + return link_path_walk_it(name, nd, NULL);
745 /* returns 1 if everything is done */
746 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
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 +810,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 @@ -994,6 +1067,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 +1089,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 +1098,7 @@
864 + it->it_mode = mode;
865 /* Negative dentry, just create the file */
866 if (!dentry->d_inode) {
867 error = vfs_create(dir->d_inode, dentry,
868 @@ -1053,7 +1134,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 @@ -1139,8 +1219,10 @@
882 + intent_release(dentry, it);
885 + intent_release(nd->dentry, it);
889 @@ -1160,7 +1242,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 @@ -1181,13 +1265,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 @@ -1195,7 +1286,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 @@ -1241,6 +1332,7 @@
937 struct dentry * dentry;
939 + struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
943 @@ -1252,7 +1344,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 mode &= ~current->fs->umask;
952 @@ -1270,6 +1363,7 @@
956 + intent_release(dentry, &it);
959 up(&nd.dentry->d_inode->i_sem);
960 @@ -1310,6 +1404,7 @@
964 + struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
966 tmp = getname(pathname);
967 error = PTR_ERR(tmp);
968 @@ -1321,11 +1416,12 @@
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 error = vfs_mkdir(nd.dentry->d_inode, dentry,
977 mode & ~current->fs->umask);
978 + intent_release(dentry, &it);
981 up(&nd.dentry->d_inode->i_sem);
982 @@ -1407,6 +1504,7 @@
984 struct dentry *dentry;
986 + struct lookup_intent it = { .it_op = IT_RMDIR };
988 name = getname(pathname);
990 @@ -1429,10 +1527,11 @@
993 down(&nd.dentry->d_inode->i_sem);
994 - dentry = lookup_hash(&nd.last, nd.dentry);
995 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
996 error = PTR_ERR(dentry);
997 if (!IS_ERR(dentry)) {
998 error = vfs_rmdir(nd.dentry->d_inode, dentry);
999 + intent_release(dentry, &it);
1002 up(&nd.dentry->d_inode->i_sem);
1003 @@ -1476,6 +1576,7 @@
1005 struct dentry *dentry;
1006 struct nameidata nd;
1007 + struct lookup_intent it = { .it_op = IT_UNLINK };
1009 name = getname(pathname);
1011 @@ -1489,14 +1590,15 @@
1012 if (nd.last_type != LAST_NORM)
1014 down(&nd.dentry->d_inode->i_sem);
1015 - dentry = lookup_hash(&nd.last, nd.dentry);
1016 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1017 error = PTR_ERR(dentry);
1018 if (!IS_ERR(dentry)) {
1019 /* Why not before? Because we want correct error value */
1020 if (nd.last.name[nd.last.len])
1022 error = vfs_unlink(nd.dentry->d_inode, dentry);
1024 + intent_release(dentry, &it);
1027 up(&nd.dentry->d_inode->i_sem);
1028 @@ -1543,6 +1646,7 @@
1032 + struct lookup_intent it = { .it_op = IT_SYMLINK };
1034 from = getname(oldname);
1036 @@ -1557,10 +1661,12 @@
1037 error = path_walk(to, &nd);
1040 - dentry = lookup_create(&nd, 0);
1041 + it.it_data = from;
1042 + dentry = lookup_create(&nd, 0, &it);
1043 error = PTR_ERR(dentry);
1044 if (!IS_ERR(dentry)) {
1045 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1046 + intent_release(dentry, &it);
1049 up(&nd.dentry->d_inode->i_sem);
1050 @@ -1626,6 +1732,7 @@
1054 + struct lookup_intent it = { .it_op = IT_LINK };
1056 from = getname(oldname);
1058 @@ -1639,7 +1745,7 @@
1061 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
1062 - error = path_walk(from, &old_nd);
1063 + error = path_walk_it(from, &old_nd, &it);
1066 if (path_init(to, LOOKUP_PARENT, &nd))
1067 @@ -1648,10 +1755,12 @@
1069 if (old_nd.mnt != nd.mnt)
1071 - new_dentry = lookup_create(&nd, 0);
1072 + it.it_op = IT_LINK2;
1073 + new_dentry = lookup_create(&nd, 0, &it);
1074 error = PTR_ERR(new_dentry);
1075 if (!IS_ERR(new_dentry)) {
1076 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1077 + intent_release(new_dentry, &it);
1080 up(&nd.dentry->d_inode->i_sem);
1081 @@ -1694,7 +1803,8 @@
1084 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1085 - struct inode *new_dir, struct dentry *new_dentry)
1086 + struct inode *new_dir, struct dentry *new_dentry,
1087 + struct lookup_intent *it)
1090 struct inode *target;
1091 @@ -1754,6 +1864,7 @@
1094 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1095 + intent_release(new_dentry, it);
1098 target->i_flags |= S_DEAD;
1099 @@ -1775,7 +1887,8 @@
1102 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1103 - struct inode *new_dir, struct dentry *new_dentry)
1104 + struct inode *new_dir, struct dentry *new_dentry,
1105 + struct lookup_intent *it)
1109 @@ -1806,6 +1919,7 @@
1112 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1113 + intent_release(new_dentry, it);
1114 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1117 @@ -1817,13 +1932,14 @@
1120 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1121 - struct inode *new_dir, struct dentry *new_dentry)
1122 + struct inode *new_dir, struct dentry *new_dentry,
1123 + struct lookup_intent *it)
1126 if (S_ISDIR(old_dentry->d_inode->i_mode))
1127 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1128 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1130 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1131 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1133 if (old_dir == new_dir)
1134 inode_dir_notify(old_dir, DN_RENAME);
1135 @@ -1840,6 +1956,7 @@
1137 struct dentry * old_dir, * new_dir;
1138 struct dentry * old_dentry, *new_dentry;
1139 + struct lookup_intent it = { .it_op = IT_RENAME };
1140 struct nameidata oldnd, newnd;
1142 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1143 @@ -1868,7 +1985,7 @@
1145 double_lock(new_dir, old_dir);
1147 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1148 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1149 error = PTR_ERR(old_dentry);
1150 if (IS_ERR(old_dentry))
1152 @@ -1884,18 +2003,21 @@
1153 if (newnd.last.name[newnd.last.len])
1156 - new_dentry = lookup_hash(&newnd.last, new_dir);
1157 + it.it_op = IT_RENAME2;
1158 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1159 error = PTR_ERR(new_dentry);
1160 if (IS_ERR(new_dentry))
1164 error = vfs_rename(old_dir->d_inode, old_dentry,
1165 - new_dir->d_inode, new_dentry);
1166 + new_dir->d_inode, new_dentry, &it);
1169 + intent_release(new_dentry, &it);
1172 + intent_release(old_dentry, &it);
1175 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1176 @@ -1965,7 +2094,8 @@
1180 -__vfs_follow_link(struct nameidata *nd, const char *link)
1181 +__vfs_follow_link(struct nameidata *nd, const char *link,
1182 + struct lookup_intent *it)
1186 @@ -1978,7 +2108,7 @@
1187 /* weird __emul_prefix() stuff did it */
1190 - res = link_path_walk(link, nd);
1191 + res = link_path_walk_it(link, nd, it);
1193 if (current->link_count || res || nd->last_type!=LAST_NORM)
1195 @@ -2000,7 +2130,13 @@
1197 int vfs_follow_link(struct nameidata *nd, const char *link)
1199 - return __vfs_follow_link(nd, link);
1200 + return __vfs_follow_link(nd, link, NULL);
1203 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
1204 + struct lookup_intent *it)
1206 + return __vfs_follow_link(nd, link, it);
1209 /* get the link contents into pagecache */
1210 @@ -2042,7 +2178,7 @@
1212 struct page *page = NULL;
1213 char *s = page_getlink(dentry, &page);
1214 - int res = __vfs_follow_link(nd, s);
1215 + int res = __vfs_follow_link(nd, s, NULL);
1218 page_cache_release(page);
1219 --- lum-pristine/fs/open.c Fri Oct 12 16:48:42 2001
1220 +++ lum/fs/open.c Sun Aug 11 15:26:29 2002
1222 #include <asm/uaccess.h>
1224 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1225 +extern int path_walk_it(const char *name, struct nameidata *nd,
1226 + struct lookup_intent *it);
1227 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1229 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1232 struct nameidata nd;
1233 struct inode * inode;
1235 + struct lookup_intent it = { .it_op = IT_SETATTR };
1238 if (length < 0) /* sorry, but loff_t says... */
1241 - error = user_path_walk(path, &nd);
1242 + error = user_path_walk_it(path, &nd, &it);
1245 inode = nd.dentry->d_inode;
1247 put_write_access(inode);
1250 + intent_release(nd.dentry, &it);
1255 struct nameidata nd;
1256 struct inode * inode;
1257 struct iattr newattrs;
1258 + struct lookup_intent it = { .it_op = IT_SETATTR };
1260 - error = user_path_walk(filename, &nd);
1261 + error = user_path_walk_it(filename, &nd, &it);
1264 inode = nd.dentry->d_inode;
1267 error = notify_change(nd.dentry, &newattrs);
1269 + intent_release(nd.dentry, &it);
1274 struct nameidata nd;
1275 struct inode * inode;
1276 struct iattr newattrs;
1277 + struct lookup_intent it = { .it_op = IT_SETATTR };
1279 - error = user_path_walk(filename, &nd);
1280 + error = user_path_walk_it(filename, &nd, &it);
1286 error = notify_change(nd.dentry, &newattrs);
1288 + intent_release(nd.dentry, &it);
1293 int old_fsuid, old_fsgid;
1294 kernel_cap_t old_cap;
1296 + struct lookup_intent it = { .it_op = IT_GETATTR };
1298 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1300 @@ -339,13 +352,14 @@
1302 current->cap_effective = current->cap_permitted;
1304 - res = user_path_walk(filename, &nd);
1305 + res = user_path_walk_it(filename, &nd, &it);
1307 res = permission(nd.dentry->d_inode, mode);
1308 /* SuS v2 requires we report a read only fs too */
1309 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1310 && !special_file(nd.dentry->d_inode->i_mode))
1312 + intent_release(nd.dentry, &it);
1318 struct nameidata nd;
1320 + struct lookup_intent it = { .it_op = IT_GETATTR };
1322 name = getname(filename);
1323 error = PTR_ERR(name);
1327 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1328 - error = path_walk(name, &nd);
1329 + error = path_walk_it(name, &nd, &it);
1334 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1337 + intent_release(nd.dentry, &it);
1343 struct nameidata nd;
1345 + struct lookup_intent it = { .it_op = IT_GETATTR };
1347 name = getname(filename);
1348 error = PTR_ERR(name);
1351 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1352 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1353 - error = path_walk(name, &nd);
1354 + error = path_walk_it(name, &nd, &it);
1362 + intent_release(nd.dentry, &it);
1367 struct inode * inode;
1369 struct iattr newattrs;
1370 + struct lookup_intent it = { .it_op = IT_SETATTR };
1372 - error = user_path_walk(filename, &nd);
1373 + error = user_path_walk_it(filename, &nd, &it);
1376 inode = nd.dentry->d_inode;
1378 error = notify_change(nd.dentry, &newattrs);
1381 + intent_release(nd.dentry, &it);
1385 @@ -580,10 +602,12 @@
1387 struct nameidata nd;
1389 + struct lookup_intent it = { .it_op = IT_SETATTR };
1391 - error = user_path_walk(filename, &nd);
1392 + error = user_path_walk_it(filename, &nd, &it);
1394 error = chown_common(nd.dentry, user, group);
1395 + intent_release(nd.dentry, &it);
1399 @@ -593,10 +618,12 @@
1401 struct nameidata nd;
1403 + struct lookup_intent it = { .it_op = IT_SETATTR };
1405 - error = user_path_walk_link(filename, &nd);
1406 + error = user_path_walk_link_it(filename, &nd, &it);
1408 error = chown_common(nd.dentry, user, group);
1409 + intent_release(nd.dentry, &it);
1413 @@ -630,10 +658,16 @@
1414 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1417 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1418 + struct nameidata *nd, struct lookup_intent *it);
1419 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1420 + int flags, struct lookup_intent *it);
1422 struct file *filp_open(const char * filename, int flags, int mode)
1424 int namei_flags, error;
1425 struct nameidata nd;
1426 + struct lookup_intent it = { .it_op = IT_OPEN };
1428 namei_flags = flags;
1429 if ((namei_flags+1) & O_ACCMODE)
1430 @@ -641,14 +675,15 @@
1431 if (namei_flags & O_TRUNC)
1434 - error = open_namei(filename, namei_flags, mode, &nd);
1436 - return dentry_open(nd.dentry, nd.mnt, flags);
1437 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1439 + return ERR_PTR(error);
1441 - return ERR_PTR(error);
1442 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1445 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1446 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1447 + int flags, struct lookup_intent *it)
1450 struct inode *inode;
1453 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1455 + intent_release(dentry, it);
1459 @@ -705,11 +741,17 @@
1463 + intent_release(dentry, it);
1466 return ERR_PTR(error);
1469 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1471 + return dentry_open_it(dentry, mnt, flags, NULL);
1475 * Find an empty file descriptor entry, and mark it busy.
1477 --- lum-pristine/fs/stat.c Thu Sep 13 19:04:43 2001
1478 +++ lum/fs/stat.c Mon Aug 12 00:04:39 2002
1481 #include <asm/uaccess.h>
1483 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1485 * Revalidate the inode. This is required for proper NFS attribute caching.
1487 @@ -135,13 +135,15 @@
1488 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1490 struct nameidata nd;
1491 + struct lookup_intent it = { .it_op = IT_GETATTR };
1494 - error = user_path_walk(filename, &nd);
1495 + error = user_path_walk_it(filename, &nd, &it);
1497 error = do_revalidate(nd.dentry);
1499 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1500 + intent_release(nd.dentry, &it);
1504 @@ -151,13 +153,15 @@
1505 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1507 struct nameidata nd;
1508 + struct lookup_intent it = { .it_op = IT_GETATTR };
1511 - error = user_path_walk(filename, &nd);
1512 + error = user_path_walk_it(filename, &nd, &it);
1514 error = do_revalidate(nd.dentry);
1516 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1517 + intent_release(nd.dentry, &it);
1521 @@ -172,13 +176,15 @@
1522 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1524 struct nameidata nd;
1525 + struct lookup_intent it = { .it_op = IT_GETATTR };
1528 - error = user_path_walk_link(filename, &nd);
1529 + error = user_path_walk_link_it(filename, &nd, &it);
1531 error = do_revalidate(nd.dentry);
1533 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1534 + intent_release(nd.dentry, &it);
1538 @@ -189,13 +195,15 @@
1539 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1541 struct nameidata nd;
1542 + struct lookup_intent it = { .it_op = IT_GETATTR };
1545 - error = user_path_walk_link(filename, &nd);
1546 + error = user_path_walk_link_it(filename, &nd, &it);
1548 error = do_revalidate(nd.dentry);
1550 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1551 + intent_release(nd.dentry, &it);
1555 @@ -247,20 +255,21 @@
1557 struct nameidata nd;
1559 + struct lookup_intent it = { .it_op = IT_READLINK };
1564 - error = user_path_walk_link(path, &nd);
1565 + error = user_path_walk_link_it(path, &nd, &it);
1567 struct inode * inode = nd.dentry->d_inode;
1570 if (inode->i_op && inode->i_op->readlink &&
1571 !(error = do_revalidate(nd.dentry))) {
1572 UPDATE_ATIME(inode);
1573 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1575 + intent_release(nd.dentry, &it);
1579 @@ -333,12 +342,14 @@
1581 struct nameidata nd;
1583 + struct lookup_intent it = { .it_op = IT_GETATTR };
1585 - error = user_path_walk(filename, &nd);
1586 + error = user_path_walk_it(filename, &nd, &it);
1588 error = do_revalidate(nd.dentry);
1590 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1591 + intent_release(nd.dentry, &it);
1595 @@ -348,12 +359,14 @@
1597 struct nameidata nd;
1599 + struct lookup_intent it = { .it_op = IT_GETATTR };
1601 - error = user_path_walk_link(filename, &nd);
1602 + error = user_path_walk_link_it(filename, &nd, &it);
1604 error = do_revalidate(nd.dentry);
1606 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1607 + intent_release(nd.dentry, &it);
1611 --- lum-pristine/mm/slab.c Fri Dec 21 12:42:05 2001
1612 +++ lum/mm/slab.c Thu Aug 1 18:07:35 2002
1613 @@ -1187,6 +1187,59 @@
1614 * Called with the cache-lock held.
1617 +extern struct page *check_get_page(unsigned long kaddr);
1618 +struct page *page_mem_map(struct page *page);
1619 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1620 + slab_t *slabp, void * objp)
1623 + unsigned int objnr;
1626 + if (cachep->flags & SLAB_RED_ZONE) {
1627 + objp -= BYTES_PER_WORD;
1628 + if ( *(unsigned long *)objp != RED_MAGIC2)
1629 + /* Either write before start, or a double free. */
1631 + if (*(unsigned long *)(objp+cachep->objsize -
1632 + BYTES_PER_WORD) != RED_MAGIC2)
1633 + /* Either write past end, or a double free. */
1638 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1639 + if (objnr >= cachep->num)
1641 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1644 + /* Check slab's freelist to see if this obj is there. */
1645 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1653 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1655 + struct page *page = check_get_page((unsigned long)objp);
1657 + if (!VALID_PAGE(page))
1660 + if (!PageSlab(page))
1663 + /* XXX check for freed slab objects ? */
1664 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1667 + return (cachep == GET_PAGE_CACHE(page));
1671 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1672 slab_t *slabp, void * objp)