1 --- lum-pristine/arch/ia64/mm/init.c Fri Nov 9 15:26:17 2001
2 +++ lum/arch/ia64/mm/init.c Thu Jun 20 14:46:05 2002
5 static unsigned long totalram_pages;
7 +struct page *check_get_page(unsigned long kaddr)
9 +#warning FIXME: Lustre team, is this solid?
10 + return virt_to_page(kaddr);
14 do_check_pgt_cache (int low, int high)
16 --- lum-pristine/arch/um/kernel/mem.c Thu Jun 13 14:07:26 2002
17 +++ lum/arch/um/kernel/mem.c Fri Jun 14 17:00:21 2002
19 return(phys_mem_map(pte_val(pte)));
22 +struct page *check_get_page(unsigned long kaddr)
25 + struct mem_region *mr;
26 + unsigned long phys = __pa(kaddr);
27 + unsigned int n = phys_region_index(phys);
29 + if(regions[n] == NULL)
33 + page = (struct page *) mr->mem_map;
34 + return page + ((phys_addr(phys)) >> PAGE_SHIFT);
38 struct mem_region *page_region(struct page *page, int *index_out)
45 - panic("No region found for page");
46 +//panic("No region found for page");
50 struct page *page_mem_map(struct page *page)
52 + if (!page_region(page, NULL))
54 return((struct page *) page_region(page, NULL)->mem_map);
57 --- lum-pristine/arch/i386/mm/init.c Fri Dec 21 10:41:53 2001
58 +++ lum/arch/i386/mm/init.c Sat Jun 15 00:31:15 2002
60 static unsigned long totalram_pages;
61 static unsigned long totalhigh_pages;
63 +struct page *check_get_page(unsigned long kaddr)
65 +#warning FIXME: Lustre team, is this solid?
66 + return virt_to_page(kaddr);
69 int do_check_pgt_cache(int low, int high)
72 --- lum-pristine/mm/slab.c Fri Dec 21 10:42:05 2001
73 +++ lum/mm/slab.c Fri Jun 14 23:57:09 2002
74 @@ -1187,6 +1187,59 @@
75 * Called with the cache-lock held.
78 +extern struct page *check_get_page(unsigned long kaddr);
79 +struct page *page_mem_map(struct page *page);
80 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
81 + slab_t *slabp, void * objp)
86 + if (cachep->flags & SLAB_RED_ZONE) {
87 + objp -= BYTES_PER_WORD;
88 + if ( *(unsigned long *)objp != RED_MAGIC2)
89 + /* Either write before start, or a double free. */
91 + if (*(unsigned long *)(objp+cachep->objsize -
92 + BYTES_PER_WORD) != RED_MAGIC2)
93 + /* Either write past end, or a double free. */
97 + objnr = (objp-slabp->s_mem)/cachep->objsize;
98 + if (objnr >= cachep->num)
100 + if (objp != slabp->s_mem + objnr*cachep->objsize)
103 + /* Check slab's freelist to see if this obj is there. */
104 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
112 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
114 + struct page *page = check_get_page((unsigned long)objp);
116 + if (!VALID_PAGE(page)) {
120 + if (!PageSlab(page)) {
124 + /* XXX check for freed slab objects ? */
125 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
128 + return (cachep == GET_PAGE_CACHE(page));
132 static int kmem_extra_free_checks (kmem_cache_t * cachep,
133 slab_t *slabp, void * objp)
134 --- lum-pristine/drivers/block/blkpg.c Mon Feb 25 12:37:57 2002
135 +++ lum/drivers/block/blkpg.c Fri Jun 7 12:49:14 2002
139 EXPORT_SYMBOL(blk_ioctl);
141 +#define NUM_DEV_NO_WRITE 16
142 +static int dev_no_write[NUM_DEV_NO_WRITE];
145 + * Debug code for turning block devices "read-only" (will discard writes
146 + * silently). This is for filesystem crash/recovery testing.
148 +void dev_set_rdonly(kdev_t dev, int no_write)
151 + printk(KERN_WARNING "Turning device %s read-only\n",
153 + dev_no_write[no_write] = 0xdead0000 + dev;
157 +int dev_check_rdonly(kdev_t dev) {
160 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
161 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
162 + dev == (dev_no_write[i] & 0xffff))
168 +void dev_clear_rdonly(int no_write) {
169 + dev_no_write[no_write] = 0;
172 +EXPORT_SYMBOL(dev_set_rdonly);
173 +EXPORT_SYMBOL(dev_check_rdonly);
174 +EXPORT_SYMBOL(dev_clear_rdonly);
175 --- lum-pristine/drivers/block/loop.c Fri Dec 21 10:41:53 2001
176 +++ lum/drivers/block/loop.c Fri Jun 7 12:49:14 2002
178 spin_unlock_irq(&lo->lo_lock);
181 +#ifdef CONFIG_DEV_RDONLY
182 + if (dev_check_rdonly(rbh->b_rdev))
186 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
188 } else if (rw == READA) {
189 --- lum-pristine/drivers/ide/ide-disk.c Fri Dec 21 10:41:54 2001
190 +++ lum/drivers/ide/ide-disk.c Fri Jun 7 12:49:14 2002
193 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
195 +#ifdef CONFIG_DEV_RDONLY
196 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
197 + ide_end_request(1, HWGROUP(drive));
198 + return ide_stopped;
202 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
203 OUT_BYTE(0x00, IDE_FEATURE_REG);
204 --- lum-pristine/fs/ext3/Makefile Fri Dec 21 10:41:55 2001
205 +++ lum/fs/ext3/Makefile Fri Jun 7 12:49:13 2002
210 +export-objs := super.o
212 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
213 ioctl.o namei.o super.o symlink.o
215 --- lum-pristine/fs/ext3/super.c Mon Feb 25 12:38:08 2002
216 +++ lum/fs/ext3/super.c Fri Jun 7 12:49:14 2002
217 @@ -1744,7 +1744,7 @@
218 unregister_filesystem(&ext3_fs_type);
222 +EXPORT_SYMBOL(ext3_bread);
224 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
225 MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
226 --- lum-pristine/fs/jbd/commit.c Mon Feb 25 12:38:08 2002
227 +++ lum/fs/jbd/commit.c Fri Jun 7 12:49:14 2002
229 transaction's t_log_list queue, and metadata buffers are on
230 the t_iobuf_list queue.
232 - Wait for the transactions in reverse order. That way we are
233 + Wait for the buffers in reverse order. That way we are
234 less likely to be woken up until all IOs have completed, and
235 so we incur less scheduling load.
239 jbd_debug(3, "JBD: commit phase 6\n");
241 - if (is_journal_aborted(journal))
242 + if (is_journal_aborted(journal)) {
243 + unlock_journal(journal);
247 /* Done it all: now write the commit record. We should have
248 * cleaned up our previous buffers by now, so if we are in abort
250 descriptor = journal_get_descriptor_buffer(journal);
252 __journal_abort_hard(journal);
253 + unlock_journal(journal);
258 put_bh(bh); /* One for getblk() */
259 journal_unlock_journal_head(descriptor);
261 - lock_journal(journal);
263 /* End of a transaction! Finally, we can do checkpoint
264 processing: any buffers committed as a result of this
269 + /* Call any callbacks that had been registered for handles in this
270 + * transaction. It is up to the callback to free any allocated
273 + if (!list_empty(&commit_transaction->t_jcb)) {
274 + struct list_head *p, *n;
275 + int error = is_journal_aborted(journal);
277 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
278 + struct journal_callback *jcb;
280 + jcb = list_entry(p, struct journal_callback, jcb_list);
282 + jcb->jcb_func(jcb, error);
286 + lock_journal(journal);
288 jbd_debug(3, "JBD: commit phase 7\n");
290 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
291 --- lum-pristine/fs/jbd/journal.c Mon Feb 25 12:38:08 2002
292 +++ lum/fs/jbd/journal.c Fri Jun 7 12:49:14 2002
295 EXPORT_SYMBOL(journal_flush);
296 EXPORT_SYMBOL(journal_revoke);
297 +EXPORT_SYMBOL(journal_callback_set);
299 EXPORT_SYMBOL(journal_init_dev);
300 EXPORT_SYMBOL(journal_init_inode);
301 --- lum-pristine/fs/jbd/transaction.c Mon Feb 25 12:38:08 2002
302 +++ lum/fs/jbd/transaction.c Fri Jun 7 12:49:14 2002
304 transaction->t_state = T_RUNNING;
305 transaction->t_tid = journal->j_transaction_sequence++;
306 transaction->t_expires = jiffies + journal->j_commit_interval;
307 + INIT_LIST_HEAD(&transaction->t_jcb);
309 /* Set up the commit timer for the new transaction. */
310 J_ASSERT (!journal->j_commit_timer_active);
315 +/* Allocate a new handle. This should probably be in a slab... */
316 +static handle_t *get_handle(int nblocks)
318 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
321 + memset(handle, 0, sizeof (handle_t));
322 + handle->h_buffer_credits = nblocks;
324 + INIT_LIST_HEAD(&handle->h_jcb);
330 * Obtain a new handle.
332 @@ -228,13 +243,10 @@
336 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
337 + handle = get_handle(nblocks);
339 return ERR_PTR(-ENOMEM);
340 - memset (handle, 0, sizeof (handle_t));
342 - handle->h_buffer_credits = nblocks;
344 current->journal_info = handle;
346 err = start_this_handle(journal, handle);
347 @@ -334,13 +346,10 @@
348 if (is_journal_aborted(journal))
349 return ERR_PTR(-EIO);
351 - 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 @@ -1328,6 +1337,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 @@ -1393,6 +1425,9 @@
393 wake_up(&journal->j_wait_transaction_locked);
396 + /* Move callbacks from the handle to the transaction. */
397 + list_splice(&handle->h_jcb, &transaction->t_jcb);
400 * If the handle is marked SYNC, we need to set another commit
401 * going! We also want to force a commit if the current
402 --- lum-pristine/include/linux/blkdev.h Mon Nov 26 06:29:17 2001
403 +++ lum/include/linux/blkdev.h Sat Jun 22 12:23:55 2002
408 +#define CONFIG_DEV_RDONLY
409 +void dev_set_rdonly(kdev_t, int);
410 +int dev_check_rdonly(kdev_t);
411 +void dev_clear_rdonly(int);
413 --- lum-pristine/include/linux/slab.h Fri Dec 21 10:42:04 2001
414 +++ lum/include/linux/slab.h Sat Jun 22 12:23:50 2002
416 extern int kmem_cache_shrink(kmem_cache_t *);
417 extern void *kmem_cache_alloc(kmem_cache_t *, int);
418 extern void kmem_cache_free(kmem_cache_t *, void *);
419 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
421 extern void *kmalloc(size_t, int);
422 extern void kfree(const void *);
423 --- lum-pristine/include/linux/jbd.h Mon Feb 25 12:38:13 2002
424 +++ lum/include/linux/jbd.h Sat Jun 22 12:24:17 2002
426 return bh->b_private;
429 +#define HAVE_JOURNAL_CALLBACK_STATUS
430 +struct journal_callback {
431 + struct list_head jcb_list;
432 + void (*jcb_func)(void *cb_data, int error);
433 + /* user data goes here */
436 struct jbd_revoke_table_s;
438 /* The handle_t type represents a single atomic update being performed
443 + /* List of application registered callbacks for this handle.
444 + * The function(s) will be called after the transaction that
445 + * this handle is part of has been committed to disk.
447 + struct list_head h_jcb;
450 unsigned int h_sync: 1; /* sync-on-close */
451 unsigned int h_jdata: 1; /* force data journaling */
454 /* How many handles used this transaction? */
457 + /* List of registered callback functions for this transaction.
458 + * Called when the transaction is committed. */
459 + struct list_head t_jcb;
464 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
465 extern int journal_stop(handle_t *);
466 extern int journal_flush (journal_t *);
467 +extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int),
470 extern void journal_lock_updates (journal_t *);
471 extern void journal_unlock_updates (journal_t *);
472 --- lum-pristine/kernel/ksyms.c Mon Feb 25 12:38:13 2002
473 +++ lum/kernel/ksyms.c Sat Jun 22 12:20:01 2002
475 EXPORT_SYMBOL(lock_may_write);
476 EXPORT_SYMBOL(dcache_readdir);
479 +EXPORT_SYMBOL(panic_notifier_list);
480 +EXPORT_SYMBOL(pagecache_lock);
481 +EXPORT_SYMBOL(do_kern_mount);
482 +EXPORT_SYMBOL(kmem_cache_validate);
484 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
485 EXPORT_SYMBOL(default_llseek);
486 EXPORT_SYMBOL(dentry_open);
487 --- lum-pristine/include/linux/dcache.h Thu Nov 22 12:46:18 2001
488 +++ lum/include/linux/dcache.h Sat Jun 22 12:23:50 2002
490 #include <asm/atomic.h>
491 #include <linux/mount.h>
494 +#define IT_CREAT (1<<1)
495 +#define IT_MKDIR (1<<2)
496 +#define IT_LINK (1<<3)
497 +#define IT_SYMLINK (1<<4)
498 +#define IT_UNLINK (1<<5)
499 +#define IT_RMDIR (1<<6)
500 +#define IT_RENAME (1<<7)
501 +#define IT_RENAME2 (1<<8)
502 +#define IT_READDIR (1<<9)
503 +#define IT_GETATTR (1<<10)
504 +#define IT_SETATTR (1<<11)
505 +#define IT_READLINK (1<<12)
506 +#define IT_MKNOD (1<<13)
508 +struct lookup_intent {
511 + int it_disposition;
513 + struct iattr *it_iattr;
514 + __u64 it_lock_handle[2];
520 * linux/include/linux/dcache.h
523 struct dentry_operations *d_op;
524 struct super_block * d_sb; /* The root of the dentry tree */
525 unsigned long d_vfs_flags;
526 + struct lookup_intent *d_it;
527 void * d_fsdata; /* fs-specific data */
528 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
531 struct dentry_operations {
532 int (*d_revalidate)(struct dentry *, int);
533 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
534 int (*d_hash) (struct dentry *, struct qstr *);
535 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
536 int (*d_delete)(struct dentry *);
537 void (*d_release)(struct dentry *);
538 void (*d_iput)(struct dentry *, struct inode *);
539 + void (*d_intent_release)(struct dentry *);
542 /* the dentry parameter passed to d_hash and d_compare is the parent
543 --- lum-pristine/include/linux/fs.h Thu Jun 13 14:07:26 2002
544 +++ lum/include/linux/fs.h Sat Jun 22 12:23:50 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 *);
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 *);
577 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
578 #define kern_umount mntput
580 extern int vfs_statfs(struct super_block *, struct statfs *);
581 @@ -1307,6 +1311,7 @@
582 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
584 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
585 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
586 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
587 extern int FASTCALL(path_walk(const char *, struct nameidata *));
588 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
589 @@ -1317,6 +1322,8 @@
590 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
591 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
592 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
593 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
594 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
596 extern void iput(struct inode *);
597 extern void force_delete(struct inode *);
598 --- lum-pristine/fs/nfsd/vfs.c Fri Dec 21 10:41:55 2001
599 +++ lum/fs/nfsd/vfs.c Thu Jun 20 10:37:05 2002
600 @@ -1285,7 +1285,7 @@
604 - err = vfs_rename(fdir, odentry, tdir, ndentry);
605 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
606 if (!err && EX_ISSYNC(tfhp->fh_export)) {
607 nfsd_sync_dir(tdentry);
608 nfsd_sync_dir(fdentry);
609 --- lum-pristine/fs/namei.c Mon Feb 25 12:38:09 2002
610 +++ lum/fs/namei.c Sat Jun 22 18:37:55 2002
612 * XEmacs seems to be relying on it...
615 +void intent_release(struct dentry *de)
617 + if (de->d_op && de->d_op->d_intent_release)
618 + de->d_op->d_intent_release(de);
623 /* In order to reduce some races, while at the same time doing additional
624 * checking and hopefully speeding things up, we copy filenames to the
625 * kernel data space before using them..
626 @@ -260,10 +268,18 @@
627 * Internal lookup() using the new generic dcache.
630 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
631 +static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
633 struct dentry * dentry = d_lookup(parent, name);
635 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
636 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) && !d_invalidate(dentry)) {
643 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
644 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
647 * make sure that nobody added the entry to the dcache in the meantime..
650 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
651 +static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
653 struct dentry * result;
654 struct inode *dir = parent->d_inode;
656 result = ERR_PTR(-ENOMEM);
659 + if (dir->i_op->lookup2)
660 + result = dir->i_op->lookup2(dir, dentry, it);
662 result = dir->i_op->lookup(dir, dentry);
666 result = ERR_PTR(-ENOENT);
669 + if (result->d_op && result->d_op->d_revalidate2) {
670 + if (!result->d_op->d_revalidate2(result, flags, it) && !d_invalidate(result)) {
672 + result = ERR_PTR(-ENOENT);
680 * We expect 'base' to be positive and a directory.
682 -int link_path_walk(const char * name, struct nameidata *nd)
683 +int link_path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
685 struct dentry *dentry;
690 /* This does the actual lookups.. */
691 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
692 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
694 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
695 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
696 err = PTR_ERR(dentry);
703 - if (!inode->i_op->lookup)
704 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
707 /* here ends the main loop */
712 - dentry = cached_lookup(nd->dentry, &this, 0);
713 + dentry = cached_lookup(nd->dentry, &this, 0, it);
715 - dentry = real_lookup(nd->dentry, &this, 0);
716 + dentry = real_lookup(nd->dentry, &this, 0, it);
717 err = PTR_ERR(dentry);
722 if (lookup_flags & LOOKUP_DIRECTORY) {
724 - if (!inode->i_op || !inode->i_op->lookup)
725 + if (!inode->i_op || (!inode->i_op->lookup &&
726 + !inode->i_op->lookup2))
731 else if (this.len == 2 && this.name[1] == '.')
732 nd->last_type = LAST_DOTDOT;
734 + nd->dentry->d_it = it;
738 @@ -633,15 +660,29 @@
743 + nd->dentry->d_it = it;
747 +int link_path_walk(const char * name, struct nameidata *nd)
749 + return link_path_walk_it(name, nd, NULL);
752 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
754 + current->total_link_count = 0;
755 + return link_path_walk_it(name, nd, it);
758 int path_walk(const char * name, struct nameidata *nd)
760 current->total_link_count = 0;
761 - return link_path_walk(name, nd);
762 + return link_path_walk_it(name, nd, NULL);
767 /* returns 1 if everything is done */
768 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
770 * needs parent already locked. Doesn't follow mounts.
773 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
774 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
775 + struct lookup_intent *it)
777 struct dentry * dentry;
779 @@ -765,13 +807,16 @@
783 - dentry = cached_lookup(base, name, 0);
784 + dentry = cached_lookup(base, name, 0, it);
786 struct dentry *new = d_alloc(base, name);
787 dentry = ERR_PTR(-ENOMEM);
791 + if (inode->i_op->lookup2)
792 + dentry = inode->i_op->lookup2(inode, new, it);
794 dentry = inode->i_op->lookup(inode, new);
801 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
803 + return lookup_hash_it(name, base, NULL);
808 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
812 this.hash = end_name_hash(hash);
814 - return lookup_hash(&this, base);
815 + return lookup_hash_it(&this, base, NULL);
817 return ERR_PTR(-EACCES);
823 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
828 + tmp = getname(name);
829 + err = PTR_ERR(tmp);
830 + if (!IS_ERR(tmp)) {
832 + if (path_init(tmp, flags, nd))
833 + err = path_walk_it(tmp, nd, it);
840 * It's inline, so penalty for filesystems that don't use sticky bit is
843 * for symlinks (where the permissions are checked later).
846 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
847 +int open_namei_it(const char * pathname, int flag, int mode, struct nameidata *nd,
848 + struct lookup_intent *it)
850 int acc_mode, error = 0;
852 @@ -984,17 +1052,23 @@
853 * The simplest case - just a plain lookup.
855 if (!(flag & O_CREAT)) {
857 if (path_init(pathname, lookup_flags(flag), nd))
858 - error = path_walk(pathname, nd);
859 + error = path_walk_it(pathname, nd, it);
868 * Create - we need to know the parent.
871 + it->it_mode = mode;
872 + it->it_op |= IT_CREAT;
874 if (path_init(pathname, LOOKUP_PARENT, nd))
875 error = path_walk(pathname, nd);
877 @@ -1011,7 +1085,7 @@
880 down(&dir->d_inode->i_sem);
881 - dentry = lookup_hash(&nd->last, nd->dentry);
882 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
885 error = PTR_ERR(dentry);
886 @@ -1020,6 +1094,8 @@
891 + dentry->d_it->it_mode = mode;
892 /* Negative dentry, just create the file */
893 if (!dentry->d_inode) {
894 error = vfs_create(dir->d_inode, dentry,
895 @@ -1136,9 +1212,11 @@
896 if (flag & FMODE_WRITE)
899 + intent_release(dentry);
903 + intent_release(dentry);
907 @@ -1181,13 +1259,20 @@
910 down(&dir->d_inode->i_sem);
911 - dentry = lookup_hash(&nd->last, nd->dentry);
912 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
913 putname(nd->last.name);
917 +int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
919 + return open_namei_it(pathname, flag, mode, nd, NULL);
924 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
925 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
926 + struct lookup_intent *it)
928 struct dentry *dentry;
930 @@ -1195,7 +1280,7 @@
931 dentry = ERR_PTR(-EEXIST);
932 if (nd->last_type != LAST_NORM)
934 - dentry = lookup_hash(&nd->last, nd->dentry);
935 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
938 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
939 @@ -1241,6 +1326,7 @@
941 struct dentry * dentry;
943 + struct lookup_intent it = { IT_MKNOD , mode };
947 @@ -1252,11 +1338,12 @@
948 error = path_walk(tmp, &nd);
951 - dentry = lookup_create(&nd, 0);
952 + dentry = lookup_create(&nd, 0, &it);
953 error = PTR_ERR(dentry);
955 mode &= ~current->fs->umask;
956 if (!IS_ERR(dentry)) {
957 + dentry->d_it = ⁢
958 switch (mode & S_IFMT) {
959 case 0: case S_IFREG:
960 error = vfs_create(nd.dentry->d_inode,dentry,mode);
961 @@ -1270,6 +1357,7 @@
965 + intent_release(dentry);
968 up(&nd.dentry->d_inode->i_sem);
969 @@ -1310,6 +1398,7 @@
973 + struct lookup_intent it = { IT_MKDIR, mode };
975 tmp = getname(pathname);
976 error = PTR_ERR(tmp);
977 @@ -1321,11 +1410,13 @@
978 error = path_walk(tmp, &nd);
981 - dentry = lookup_create(&nd, 1);
982 + dentry = lookup_create(&nd, 1, &it);
983 error = PTR_ERR(dentry);
984 if (!IS_ERR(dentry)) {
985 + dentry->d_it = ⁢
986 error = vfs_mkdir(nd.dentry->d_inode, dentry,
987 mode & ~current->fs->umask);
988 + intent_release(dentry);
991 up(&nd.dentry->d_inode->i_sem);
992 @@ -1407,6 +1498,7 @@
994 struct dentry *dentry;
996 + struct lookup_intent it = { IT_RMDIR, 0 };
998 name = getname(pathname);
1000 @@ -1429,10 +1521,12 @@
1003 down(&nd.dentry->d_inode->i_sem);
1004 - dentry = lookup_hash(&nd.last, nd.dentry);
1005 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1006 error = PTR_ERR(dentry);
1007 if (!IS_ERR(dentry)) {
1008 + dentry->d_it = ⁢
1009 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1010 + intent_release(dentry);
1013 up(&nd.dentry->d_inode->i_sem);
1014 @@ -1476,6 +1570,7 @@
1016 struct dentry *dentry;
1017 struct nameidata nd;
1018 + struct lookup_intent it = { IT_UNLINK, 0 };
1020 name = getname(pathname);
1022 @@ -1489,14 +1584,16 @@
1023 if (nd.last_type != LAST_NORM)
1025 down(&nd.dentry->d_inode->i_sem);
1026 - dentry = lookup_hash(&nd.last, nd.dentry);
1027 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1028 error = PTR_ERR(dentry);
1029 if (!IS_ERR(dentry)) {
1030 + dentry->d_it = ⁢
1031 /* Why not before? Because we want correct error value */
1032 if (nd.last.name[nd.last.len])
1034 error = vfs_unlink(nd.dentry->d_inode, dentry);
1036 + intent_release(dentry);
1039 up(&nd.dentry->d_inode->i_sem);
1040 @@ -1543,6 +1640,7 @@
1044 + struct lookup_intent it = { IT_SYMLINK, 0 };
1046 from = getname(oldname);
1048 @@ -1557,10 +1655,12 @@
1049 error = path_walk(to, &nd);
1052 - dentry = lookup_create(&nd, 0);
1053 + dentry = lookup_create(&nd, 0, &it);
1054 error = PTR_ERR(dentry);
1055 if (!IS_ERR(dentry)) {
1056 + dentry->d_it = ⁢
1057 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1058 + intent_release(dentry);
1061 up(&nd.dentry->d_inode->i_sem);
1062 @@ -1626,6 +1726,7 @@
1066 + struct lookup_intent it = { IT_LINK, 0 };
1068 from = getname(oldname);
1070 @@ -1648,10 +1749,12 @@
1072 if (old_nd.mnt != nd.mnt)
1074 - new_dentry = lookup_create(&nd, 0);
1075 + new_dentry = lookup_create(&nd, 0, &it);
1076 error = PTR_ERR(new_dentry);
1077 if (!IS_ERR(new_dentry)) {
1078 + new_dentry->d_it = ⁢
1079 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1080 + intent_release(new_dentry);
1083 up(&nd.dentry->d_inode->i_sem);
1084 @@ -1694,7 +1797,8 @@
1087 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1088 - struct inode *new_dir, struct dentry *new_dentry)
1089 + struct inode *new_dir, struct dentry *new_dentry,
1090 + struct lookup_intent *it)
1093 struct inode *target;
1094 @@ -1748,12 +1852,14 @@
1096 double_down(&old_dir->i_zombie,
1097 &new_dir->i_zombie);
1098 + new_dentry->d_it = it;
1099 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
1101 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1104 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1105 + intent_release(new_dentry);
1108 target->i_flags |= S_DEAD;
1109 @@ -1775,7 +1881,8 @@
1112 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1113 - struct inode *new_dir, struct dentry *new_dentry)
1114 + struct inode *new_dir, struct dentry *new_dentry,
1115 + struct lookup_intent *it)
1119 @@ -1802,10 +1909,12 @@
1120 DQUOT_INIT(old_dir);
1121 DQUOT_INIT(new_dir);
1122 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1123 + new_dentry->d_it = it;
1124 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1127 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1128 + intent_release(new_dentry);
1129 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1132 @@ -1817,13 +1926,14 @@
1135 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1136 - struct inode *new_dir, struct dentry *new_dentry)
1137 + struct inode *new_dir, struct dentry *new_dentry,
1138 + struct lookup_intent *it)
1141 if (S_ISDIR(old_dentry->d_inode->i_mode))
1142 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1143 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it);
1145 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1146 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it);
1148 if (old_dir == new_dir)
1149 inode_dir_notify(old_dir, DN_RENAME);
1150 @@ -1841,6 +1951,7 @@
1151 struct dentry * old_dir, * new_dir;
1152 struct dentry * old_dentry, *new_dentry;
1153 struct nameidata oldnd, newnd;
1154 + struct lookup_intent it = {IT_RENAME, 0};
1156 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1157 error = path_walk(oldname, &oldnd);
1158 @@ -1868,7 +1979,9 @@
1160 double_lock(new_dir, old_dir);
1162 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1163 + it.it_op = IT_RENAME;
1165 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1166 error = PTR_ERR(old_dentry);
1167 if (IS_ERR(old_dentry))
1169 @@ -1884,14 +1997,15 @@
1170 if (newnd.last.name[newnd.last.len])
1173 - new_dentry = lookup_hash(&newnd.last, new_dir);
1174 + it.it_op = IT_RENAME2;
1175 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1176 error = PTR_ERR(new_dentry);
1177 if (IS_ERR(new_dentry))
1181 error = vfs_rename(old_dir->d_inode, old_dentry,
1182 - new_dir->d_inode, new_dentry);
1183 + new_dir->d_inode, new_dentry, &it);
1187 --- lum-pristine/fs/open.c Fri Oct 12 14:48:42 2001
1188 +++ lum/fs/open.c Sat Jun 22 16:44:30 2002
1190 #include <asm/uaccess.h>
1192 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1193 +extern int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it);
1194 +extern void intent_release(struct dentry *de);
1196 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1199 struct nameidata nd;
1200 struct inode * inode;
1202 + struct lookup_intent it = { IT_SETATTR };
1205 if (length < 0) /* sorry, but loff_t says... */
1208 - error = user_path_walk(path, &nd);
1209 + error = user_path_walk_it(path, &nd, &it);
1212 + nd.dentry->d_it = ⁢
1213 inode = nd.dentry->d_inode;
1215 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1217 put_write_access(inode);
1220 + intent_release(nd.dentry);
1224 @@ -235,10 +240,14 @@
1225 struct nameidata nd;
1226 struct inode * inode;
1227 struct iattr newattrs;
1228 + struct lookup_intent it;
1230 + it.it_op = IT_SETATTR;
1232 - error = user_path_walk(filename, &nd);
1233 + error = user_path_walk_it(filename, &nd, &it);
1236 + nd.dentry->d_it = ⁢
1237 inode = nd.dentry->d_inode;
1242 error = notify_change(nd.dentry, &newattrs);
1244 + intent_release(nd.dentry);
1248 @@ -279,11 +289,15 @@
1249 struct nameidata nd;
1250 struct inode * inode;
1251 struct iattr newattrs;
1252 + struct lookup_intent it;
1254 + it.it_op = IT_SETATTR;
1256 - error = user_path_walk(filename, &nd);
1257 + error = user_path_walk_it(filename, &nd, &it);
1261 + nd.dentry->d_it = ⁢
1262 inode = nd.dentry->d_inode;
1267 error = notify_change(nd.dentry, &newattrs);
1269 + intent_release(nd.dentry);
1274 int old_fsuid, old_fsgid;
1275 kernel_cap_t old_cap;
1277 + struct lookup_intent it;
1279 + it.it_op = IT_GETATTR;
1281 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1283 @@ -339,13 +357,14 @@
1285 current->cap_effective = current->cap_permitted;
1287 - res = user_path_walk(filename, &nd);
1288 + res = user_path_walk_it(filename, &nd, &it);
1290 res = permission(nd.dentry->d_inode, mode);
1291 /* SuS v2 requires we report a read only fs too */
1292 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1293 && !special_file(nd.dentry->d_inode->i_mode))
1295 + intent_release(nd.dentry);
1301 struct nameidata nd;
1303 + struct lookup_intent it;
1305 + it.it_op = IT_GETATTR;
1307 name = getname(filename);
1308 error = PTR_ERR(name);
1309 @@ -369,11 +391,12 @@
1312 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1313 - error = path_walk(name, &nd);
1314 + error = path_walk_it(name, &nd, &it);
1319 + nd.dentry->d_it = ⁢
1320 error = permission(nd.dentry->d_inode,MAY_EXEC);
1324 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1327 + intent_release(nd.dentry);
1333 struct nameidata nd;
1335 + struct lookup_intent it;
1337 + it.it_op = IT_GETATTR;
1339 name = getname(filename);
1340 error = PTR_ERR(name);
1341 @@ -429,11 +456,12 @@
1343 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1344 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1345 - error = path_walk(name, &nd);
1346 + error = path_walk_it(name, &nd, &it);
1351 + nd.dentry->d_it = ⁢
1352 error = permission(nd.dentry->d_inode,MAY_EXEC);
1359 + intent_release(nd.dentry);
1363 @@ -490,12 +519,15 @@
1364 struct inode * inode;
1366 struct iattr newattrs;
1367 + struct lookup_intent it;
1369 - error = user_path_walk(filename, &nd);
1370 + it.it_op = IT_SETATTR;
1371 + error = user_path_walk_it(filename, &nd, &it);
1374 inode = nd.dentry->d_inode;
1376 + nd.dentry->d_it = ⁢
1378 if (IS_RDONLY(inode))
1381 error = notify_change(nd.dentry, &newattrs);
1384 + intent_release(nd.dentry);
1388 @@ -580,10 +613,15 @@
1390 struct nameidata nd;
1392 + struct lookup_intent it;
1394 + it.it_op = IT_SETATTR;
1396 - error = user_path_walk(filename, &nd);
1397 + error = user_path_walk_it(filename, &nd, &it);
1399 + nd.dentry->d_it = ⁢
1400 error = chown_common(nd.dentry, user, group);
1401 + intent_release(nd.dentry);
1405 @@ -593,10 +631,15 @@
1407 struct nameidata nd;
1409 + struct lookup_intent it;
1411 + it.it_op = IT_SETATTR;
1413 - error = user_path_walk_link(filename, &nd);
1414 + error = user_path_walk_link_it(filename, &nd, &it);
1416 + nd.dentry->d_it = ⁢
1417 error = chown_common(nd.dentry, user, group);
1418 + intent_release(nd.dentry);
1422 @@ -630,10 +673,15 @@
1423 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1426 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1427 + struct nameidata *nd, struct lookup_intent *it);
1428 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it);
1430 struct file *filp_open(const char * filename, int flags, int mode)
1432 int namei_flags, error;
1433 struct nameidata nd;
1434 + struct lookup_intent it = {IT_OPEN, 0};
1436 namei_flags = flags;
1437 if ((namei_flags+1) & O_ACCMODE)
1438 @@ -641,14 +689,14 @@
1439 if (namei_flags & O_TRUNC)
1442 - error = open_namei(filename, namei_flags, mode, &nd);
1443 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1445 - return dentry_open(nd.dentry, nd.mnt, flags);
1446 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1448 return ERR_PTR(error);
1451 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1452 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it)
1455 struct inode *inode;
1456 @@ -705,11 +753,19 @@
1460 + intent_release(dentry);
1463 return ERR_PTR(error);
1466 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1468 + return dentry_open_it(dentry, mnt, flags, NULL);
1474 * Find an empty file descriptor entry, and mark it busy.
1476 --- lum-pristine/fs/stat.c Thu Sep 13 17:04:43 2001
1477 +++ lum/fs/stat.c Sat Jun 22 18:39:04 2002
1478 @@ -135,13 +135,15 @@
1479 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1481 struct nameidata nd;
1482 + struct lookup_intent it = {IT_GETATTR, 0};
1485 - error = user_path_walk(filename, &nd);
1486 + error = user_path_walk_it(filename, &nd, &it);
1488 error = do_revalidate(nd.dentry);
1490 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1491 + intent_release(nd.dentry);
1495 @@ -151,13 +153,15 @@
1496 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1498 struct nameidata nd;
1499 + struct lookup_intent it = {IT_GETATTR, 0};
1502 - error = user_path_walk(filename, &nd);
1503 + error = user_path_walk_it(filename, &nd, &it);
1505 error = do_revalidate(nd.dentry);
1507 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1508 + intent_release(nd.dentry);
1512 @@ -172,13 +176,15 @@
1513 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1515 struct nameidata nd;
1516 + struct lookup_intent it = {IT_GETATTR, 0};
1519 - error = user_path_walk_link(filename, &nd);
1520 + error = user_path_walk_link_it(filename, &nd, &it);
1522 error = do_revalidate(nd.dentry);
1524 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1525 + intent_release(nd.dentry);
1529 @@ -189,13 +195,15 @@
1530 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1532 struct nameidata nd;
1533 + struct lookup_intent it = {IT_GETATTR, 0};
1536 - error = user_path_walk_link(filename, &nd);
1537 + error = user_path_walk_link_it(filename, &nd, &it);
1539 error = do_revalidate(nd.dentry);
1541 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1542 + intent_release(nd.dentry);
1546 @@ -247,20 +255,21 @@
1548 struct nameidata nd;
1550 + struct lookup_intent it = { IT_READLINK };
1555 - error = user_path_walk_link(path, &nd);
1556 + error = user_path_walk_link_it(path, &nd, &it);
1558 struct inode * inode = nd.dentry->d_inode;
1561 if (inode->i_op && inode->i_op->readlink &&
1562 !(error = do_revalidate(nd.dentry))) {
1563 UPDATE_ATIME(inode);
1564 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1566 + intent_release(nd.dentry);
1570 @@ -333,12 +342,14 @@
1572 struct nameidata nd;
1574 + struct lookup_intent it = {IT_GETATTR};
1576 - error = user_path_walk(filename, &nd);
1577 + error = user_path_walk_it(filename, &nd, &it);
1579 error = do_revalidate(nd.dentry);
1581 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1582 + intent_release(nd.dentry);
1586 @@ -348,12 +359,14 @@
1588 struct nameidata nd;
1590 + struct lookup_intent it = { IT_GETATTR};
1592 - error = user_path_walk_link(filename, &nd);
1593 + error = user_path_walk_link_it(filename, &nd, &it);
1595 error = do_revalidate(nd.dentry);
1597 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1598 + intent_release(nd.dentry);
1602 @@ -363,6 +376,10 @@
1606 + struct lookup_intent it;
1608 + memset(&it, 0, sizeof(it));
1609 + it.it_op = IT_GETATTR;