1 --- lum-pristine/arch/ia64/mm/init.c Fri Nov 9 15:26:17 2001
2 +++ lum/arch/ia64/mm/init.c Thu Jul 4 10:04:25 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 Sat Jul 13 13:20:13 2002
17 +++ lum/arch/um/kernel/mem.c Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Thu Jul 4 10:04:25 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 Jul 13 13:06:04 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 Jul 13 13:06:04 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 Jul 13 13:09:28 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 Thu Jul 4 10:47:09 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 Jul 13 13:05:41 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)
507 +#define IT_LOOKUP (1<<14)
509 +struct lookup_intent {
512 + int it_disposition;
514 + struct iattr *it_iattr;
515 + __u64 it_lock_handle[2];
521 * linux/include/linux/dcache.h
524 struct dentry_operations *d_op;
525 struct super_block * d_sb; /* The root of the dentry tree */
526 unsigned long d_vfs_flags;
527 + struct lookup_intent *d_it;
528 void * d_fsdata; /* fs-specific data */
529 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
532 struct dentry_operations {
533 int (*d_revalidate)(struct dentry *, int);
534 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
535 int (*d_hash) (struct dentry *, struct qstr *);
536 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
537 int (*d_delete)(struct dentry *);
538 void (*d_release)(struct dentry *);
539 void (*d_iput)(struct dentry *, struct inode *);
540 + void (*d_intent_release)(struct dentry *);
543 /* the dentry parameter passed to d_hash and d_compare is the parent
544 --- lum-pristine/include/linux/fs.h Sat Jul 13 13:20:13 2002
545 +++ lum/include/linux/fs.h Sat Jul 13 13:06:04 2002
548 /* needed for tty driver, and maybe others */
550 + struct lookup_intent *f_intent;
552 /* preallocated helper kiobuf to speedup O_DIRECT */
553 struct kiobuf *f_iobuf;
555 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
556 extern int vfs_rmdir(struct inode *, struct dentry *);
557 extern int vfs_unlink(struct inode *, struct dentry *);
558 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
559 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
560 + struct inode *new_dir, struct dentry *new_dentry,
561 + struct lookup_intent *it);
566 struct inode_operations {
567 int (*create) (struct inode *,struct dentry *,int);
568 struct dentry * (*lookup) (struct inode *,struct dentry *);
569 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
570 int (*link) (struct dentry *,struct inode *,struct dentry *);
571 int (*unlink) (struct inode *,struct dentry *);
572 int (*symlink) (struct inode *,struct dentry *,const char *);
574 extern struct vfsmount *kern_mount(struct file_system_type *);
575 extern int may_umount(struct vfsmount *);
576 extern long do_mount(char *, char *, char *, unsigned long, void *);
578 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
579 #define kern_umount mntput
581 extern int vfs_statfs(struct super_block *, struct statfs *);
582 @@ -1307,6 +1311,7 @@
583 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
585 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
586 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
587 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
588 extern int FASTCALL(path_walk(const char *, struct nameidata *));
589 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
590 @@ -1317,6 +1322,8 @@
591 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
592 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
593 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
594 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
595 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
597 extern void iput(struct inode *);
598 extern void force_delete(struct inode *);
599 --- lum-pristine/fs/nfsd/vfs.c Fri Dec 21 10:41:55 2001
600 +++ lum/fs/nfsd/vfs.c Thu Jul 4 10:04:25 2002
601 @@ -1285,7 +1285,7 @@
605 - err = vfs_rename(fdir, odentry, tdir, ndentry);
606 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
607 if (!err && EX_ISSYNC(tfhp->fh_export)) {
608 nfsd_sync_dir(tdentry);
609 nfsd_sync_dir(fdentry);
610 --- lum-pristine/fs/namei.c Mon Feb 25 12:38:09 2002
611 +++ lum/fs/namei.c Sun Jul 14 21:06:07 2002
613 * XEmacs seems to be relying on it...
616 +void intent_release(struct dentry *de)
618 + if (de->d_op && de->d_op->d_intent_release)
619 + de->d_op->d_intent_release(de);
624 /* In order to reduce some races, while at the same time doing additional
625 * checking and hopefully speeding things up, we copy filenames to the
626 * kernel data space before using them..
627 @@ -260,10 +268,17 @@
628 * Internal lookup() using the new generic dcache.
631 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
632 +static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
634 struct dentry * dentry = d_lookup(parent, name);
636 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
637 + 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);
667 result = ERR_PTR(-ENOENT);
669 + } else 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);
679 * We expect 'base' to be positive and a directory.
681 -int link_path_walk(const char * name, struct nameidata *nd)
682 +int link_path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
684 struct dentry *dentry;
689 /* This does the actual lookups.. */
690 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
691 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
693 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
694 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
695 err = PTR_ERR(dentry);
702 - if (!inode->i_op->lookup)
703 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
706 /* here ends the main loop */
711 - dentry = cached_lookup(nd->dentry, &this, 0);
712 + dentry = cached_lookup(nd->dentry, &this, 0, it);
714 - dentry = real_lookup(nd->dentry, &this, 0);
715 + dentry = real_lookup(nd->dentry, &this, 0, it);
716 err = PTR_ERR(dentry);
721 if (lookup_flags & LOOKUP_DIRECTORY) {
723 - if (!inode->i_op || !inode->i_op->lookup)
724 + if (!inode->i_op || (!inode->i_op->lookup &&
725 + !inode->i_op->lookup2))
730 else if (this.len == 2 && this.name[1] == '.')
731 nd->last_type = LAST_DOTDOT;
733 + nd->dentry->d_it = it;
737 @@ -633,15 +658,29 @@
742 + nd->dentry->d_it = it;
746 +int link_path_walk(const char * name, struct nameidata *nd)
748 + return link_path_walk_it(name, nd, NULL);
751 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
753 + current->total_link_count = 0;
754 + return link_path_walk_it(name, nd, it);
757 int path_walk(const char * name, struct nameidata *nd)
759 current->total_link_count = 0;
760 - return link_path_walk(name, nd);
761 + return link_path_walk_it(name, nd, NULL);
766 /* returns 1 if everything is done */
767 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
769 * needs parent already locked. Doesn't follow mounts.
772 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
773 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
774 + struct lookup_intent *it)
776 struct dentry * dentry;
778 @@ -765,13 +805,16 @@
782 - dentry = cached_lookup(base, name, 0);
783 + dentry = cached_lookup(base, name, 0, it);
785 struct dentry *new = d_alloc(base, name);
786 dentry = ERR_PTR(-ENOMEM);
790 + if (inode->i_op->lookup2)
791 + dentry = inode->i_op->lookup2(inode, new, it);
793 dentry = inode->i_op->lookup(inode, new);
800 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
802 + return lookup_hash_it(name, base, NULL);
807 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
811 this.hash = end_name_hash(hash);
813 - return lookup_hash(&this, base);
814 + return lookup_hash_it(&this, base, NULL);
816 return ERR_PTR(-EACCES);
822 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
827 + tmp = getname(name);
828 + err = PTR_ERR(tmp);
829 + if (!IS_ERR(tmp)) {
831 + if (path_init(tmp, flags, nd))
832 + err = path_walk_it(tmp, nd, it);
839 * It's inline, so penalty for filesystems that don't use sticky bit is
842 * for symlinks (where the permissions are checked later).
845 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
846 +int open_namei_it(const char * pathname, int flag, int mode, struct nameidata *nd,
847 + struct lookup_intent *it)
849 int acc_mode, error = 0;
851 @@ -984,17 +1050,23 @@
852 * The simplest case - just a plain lookup.
854 if (!(flag & O_CREAT)) {
856 if (path_init(pathname, lookup_flags(flag), nd))
857 - error = path_walk(pathname, nd);
858 + error = path_walk_it(pathname, nd, it);
867 * Create - we need to know the parent.
870 + it->it_mode = mode;
871 + it->it_op |= IT_CREAT;
873 if (path_init(pathname, LOOKUP_PARENT, nd))
874 error = path_walk(pathname, nd);
876 @@ -1011,7 +1083,7 @@
879 down(&dir->d_inode->i_sem);
880 - dentry = lookup_hash(&nd->last, nd->dentry);
881 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
884 error = PTR_ERR(dentry);
885 @@ -1020,6 +1092,8 @@
890 + dentry->d_it->it_mode = mode;
891 /* Negative dentry, just create the file */
892 if (!dentry->d_inode) {
893 error = vfs_create(dir->d_inode, dentry,
894 @@ -1136,9 +1210,11 @@
895 if (flag & FMODE_WRITE)
898 + intent_release(dentry);
902 + intent_release(dentry);
906 @@ -1181,13 +1257,20 @@
909 down(&dir->d_inode->i_sem);
910 - dentry = lookup_hash(&nd->last, nd->dentry);
911 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
912 putname(nd->last.name);
916 +int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
918 + return open_namei_it(pathname, flag, mode, nd, NULL);
923 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
924 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
925 + struct lookup_intent *it)
927 struct dentry *dentry;
929 @@ -1195,7 +1278,7 @@
930 dentry = ERR_PTR(-EEXIST);
931 if (nd->last_type != LAST_NORM)
933 - dentry = lookup_hash(&nd->last, nd->dentry);
934 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
937 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
938 @@ -1241,6 +1324,7 @@
940 struct dentry * dentry;
942 + struct lookup_intent it = { IT_MKNOD , mode };
946 @@ -1252,11 +1336,12 @@
947 error = path_walk(tmp, &nd);
950 - dentry = lookup_create(&nd, 0);
951 + dentry = lookup_create(&nd, 0, &it);
952 error = PTR_ERR(dentry);
954 mode &= ~current->fs->umask;
955 if (!IS_ERR(dentry)) {
956 + dentry->d_it = ⁢
957 switch (mode & S_IFMT) {
958 case 0: case S_IFREG:
959 error = vfs_create(nd.dentry->d_inode,dentry,mode);
960 @@ -1270,6 +1355,7 @@
964 + intent_release(dentry);
967 up(&nd.dentry->d_inode->i_sem);
968 @@ -1310,6 +1396,7 @@
972 + struct lookup_intent it = { IT_MKDIR, mode };
974 tmp = getname(pathname);
975 error = PTR_ERR(tmp);
976 @@ -1321,11 +1408,13 @@
977 error = path_walk(tmp, &nd);
980 - dentry = lookup_create(&nd, 1);
981 + dentry = lookup_create(&nd, 1, &it);
982 error = PTR_ERR(dentry);
983 if (!IS_ERR(dentry)) {
984 + dentry->d_it = ⁢
985 error = vfs_mkdir(nd.dentry->d_inode, dentry,
986 mode & ~current->fs->umask);
987 + intent_release(dentry);
990 up(&nd.dentry->d_inode->i_sem);
991 @@ -1407,6 +1496,7 @@
993 struct dentry *dentry;
995 + struct lookup_intent it = { IT_RMDIR, 0 };
997 name = getname(pathname);
999 @@ -1429,10 +1519,12 @@
1002 down(&nd.dentry->d_inode->i_sem);
1003 - dentry = lookup_hash(&nd.last, nd.dentry);
1004 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1005 error = PTR_ERR(dentry);
1006 if (!IS_ERR(dentry)) {
1007 + dentry->d_it = ⁢
1008 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1009 + intent_release(dentry);
1012 up(&nd.dentry->d_inode->i_sem);
1013 @@ -1476,6 +1568,7 @@
1015 struct dentry *dentry;
1016 struct nameidata nd;
1017 + struct lookup_intent it = { IT_UNLINK, 0 };
1019 name = getname(pathname);
1021 @@ -1489,14 +1582,16 @@
1022 if (nd.last_type != LAST_NORM)
1024 down(&nd.dentry->d_inode->i_sem);
1025 - dentry = lookup_hash(&nd.last, nd.dentry);
1026 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1027 error = PTR_ERR(dentry);
1028 if (!IS_ERR(dentry)) {
1029 + dentry->d_it = ⁢
1030 /* Why not before? Because we want correct error value */
1031 if (nd.last.name[nd.last.len])
1033 error = vfs_unlink(nd.dentry->d_inode, dentry);
1035 + intent_release(dentry);
1038 up(&nd.dentry->d_inode->i_sem);
1039 @@ -1543,6 +1638,7 @@
1043 + struct lookup_intent it = { IT_SYMLINK, 0 };
1045 from = getname(oldname);
1047 @@ -1557,10 +1653,12 @@
1048 error = path_walk(to, &nd);
1051 - dentry = lookup_create(&nd, 0);
1052 + dentry = lookup_create(&nd, 0, &it);
1053 error = PTR_ERR(dentry);
1054 if (!IS_ERR(dentry)) {
1055 + dentry->d_it = ⁢
1056 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1057 + intent_release(dentry);
1060 up(&nd.dentry->d_inode->i_sem);
1061 @@ -1626,6 +1724,7 @@
1065 + struct lookup_intent it = { IT_LINK, 0 };
1067 from = getname(oldname);
1069 @@ -1648,10 +1747,12 @@
1071 if (old_nd.mnt != nd.mnt)
1073 - new_dentry = lookup_create(&nd, 0);
1074 + new_dentry = lookup_create(&nd, 0, &it);
1075 error = PTR_ERR(new_dentry);
1076 if (!IS_ERR(new_dentry)) {
1077 + new_dentry->d_it = ⁢
1078 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1079 + intent_release(new_dentry);
1082 up(&nd.dentry->d_inode->i_sem);
1083 @@ -1694,7 +1795,8 @@
1086 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1087 - struct inode *new_dir, struct dentry *new_dentry)
1088 + struct inode *new_dir, struct dentry *new_dentry,
1089 + struct lookup_intent *it)
1092 struct inode *target;
1093 @@ -1748,12 +1850,14 @@
1095 double_down(&old_dir->i_zombie,
1096 &new_dir->i_zombie);
1097 + new_dentry->d_it = it;
1098 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
1100 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1103 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1104 + intent_release(new_dentry);
1107 target->i_flags |= S_DEAD;
1108 @@ -1775,7 +1879,8 @@
1111 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1112 - struct inode *new_dir, struct dentry *new_dentry)
1113 + struct inode *new_dir, struct dentry *new_dentry,
1114 + struct lookup_intent *it)
1118 @@ -1802,10 +1907,12 @@
1119 DQUOT_INIT(old_dir);
1120 DQUOT_INIT(new_dir);
1121 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1122 + new_dentry->d_it = it;
1123 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1126 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1127 + intent_release(new_dentry);
1128 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1131 @@ -1817,13 +1924,14 @@
1134 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1135 - struct inode *new_dir, struct dentry *new_dentry)
1136 + struct inode *new_dir, struct dentry *new_dentry,
1137 + struct lookup_intent *it)
1140 if (S_ISDIR(old_dentry->d_inode->i_mode))
1141 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1142 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it);
1144 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1145 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it);
1147 if (old_dir == new_dir)
1148 inode_dir_notify(old_dir, DN_RENAME);
1149 @@ -1841,6 +1949,7 @@
1150 struct dentry * old_dir, * new_dir;
1151 struct dentry * old_dentry, *new_dentry;
1152 struct nameidata oldnd, newnd;
1153 + struct lookup_intent it = {IT_RENAME, 0};
1155 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1156 error = path_walk(oldname, &oldnd);
1157 @@ -1868,7 +1977,9 @@
1159 double_lock(new_dir, old_dir);
1161 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1162 + it.it_op = IT_RENAME;
1164 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1165 error = PTR_ERR(old_dentry);
1166 if (IS_ERR(old_dentry))
1168 @@ -1884,18 +1995,21 @@
1169 if (newnd.last.name[newnd.last.len])
1172 - new_dentry = lookup_hash(&newnd.last, new_dir);
1173 + it.it_op = IT_RENAME2;
1174 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1175 error = PTR_ERR(new_dentry);
1176 if (IS_ERR(new_dentry))
1180 error = vfs_rename(old_dir->d_inode, old_dentry,
1181 - new_dir->d_inode, new_dentry);
1182 + new_dir->d_inode, new_dentry, &it);
1185 + intent_release(new_dentry);
1188 + intent_release(old_dentry);
1191 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1192 --- lum-pristine/fs/open.c Fri Oct 12 14:48:42 2001
1193 +++ lum/fs/open.c Thu Jul 4 10:04:25 2002
1195 #include <asm/uaccess.h>
1197 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1198 +extern int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it);
1199 +extern void intent_release(struct dentry *de);
1201 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1204 struct nameidata nd;
1205 struct inode * inode;
1207 + struct lookup_intent it = { IT_SETATTR };
1210 if (length < 0) /* sorry, but loff_t says... */
1213 - error = user_path_walk(path, &nd);
1214 + error = user_path_walk_it(path, &nd, &it);
1217 + nd.dentry->d_it = ⁢
1218 inode = nd.dentry->d_inode;
1220 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1222 put_write_access(inode);
1225 + intent_release(nd.dentry);
1229 @@ -235,10 +240,14 @@
1230 struct nameidata nd;
1231 struct inode * inode;
1232 struct iattr newattrs;
1233 + struct lookup_intent it;
1235 + it.it_op = IT_SETATTR;
1237 - error = user_path_walk(filename, &nd);
1238 + error = user_path_walk_it(filename, &nd, &it);
1241 + nd.dentry->d_it = ⁢
1242 inode = nd.dentry->d_inode;
1247 error = notify_change(nd.dentry, &newattrs);
1249 + intent_release(nd.dentry);
1253 @@ -279,11 +289,15 @@
1254 struct nameidata nd;
1255 struct inode * inode;
1256 struct iattr newattrs;
1257 + struct lookup_intent it;
1259 + it.it_op = IT_SETATTR;
1261 - error = user_path_walk(filename, &nd);
1262 + error = user_path_walk_it(filename, &nd, &it);
1266 + nd.dentry->d_it = ⁢
1267 inode = nd.dentry->d_inode;
1272 error = notify_change(nd.dentry, &newattrs);
1274 + intent_release(nd.dentry);
1279 int old_fsuid, old_fsgid;
1280 kernel_cap_t old_cap;
1282 + struct lookup_intent it;
1284 + it.it_op = IT_GETATTR;
1286 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1288 @@ -339,13 +357,14 @@
1290 current->cap_effective = current->cap_permitted;
1292 - res = user_path_walk(filename, &nd);
1293 + res = user_path_walk_it(filename, &nd, &it);
1295 res = permission(nd.dentry->d_inode, mode);
1296 /* SuS v2 requires we report a read only fs too */
1297 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1298 && !special_file(nd.dentry->d_inode->i_mode))
1300 + intent_release(nd.dentry);
1306 struct nameidata nd;
1308 + struct lookup_intent it;
1310 + it.it_op = IT_GETATTR;
1312 name = getname(filename);
1313 error = PTR_ERR(name);
1314 @@ -369,11 +391,12 @@
1317 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1318 - error = path_walk(name, &nd);
1319 + error = path_walk_it(name, &nd, &it);
1324 + nd.dentry->d_it = ⁢
1325 error = permission(nd.dentry->d_inode,MAY_EXEC);
1329 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1332 + intent_release(nd.dentry);
1338 struct nameidata nd;
1340 + struct lookup_intent it;
1342 + it.it_op = IT_GETATTR;
1344 name = getname(filename);
1345 error = PTR_ERR(name);
1346 @@ -429,11 +456,12 @@
1348 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1349 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1350 - error = path_walk(name, &nd);
1351 + error = path_walk_it(name, &nd, &it);
1356 + nd.dentry->d_it = ⁢
1357 error = permission(nd.dentry->d_inode,MAY_EXEC);
1364 + intent_release(nd.dentry);
1368 @@ -490,12 +519,15 @@
1369 struct inode * inode;
1371 struct iattr newattrs;
1372 + struct lookup_intent it;
1374 - error = user_path_walk(filename, &nd);
1375 + it.it_op = IT_SETATTR;
1376 + error = user_path_walk_it(filename, &nd, &it);
1379 inode = nd.dentry->d_inode;
1381 + nd.dentry->d_it = ⁢
1383 if (IS_RDONLY(inode))
1386 error = notify_change(nd.dentry, &newattrs);
1389 + intent_release(nd.dentry);
1393 @@ -580,10 +613,15 @@
1395 struct nameidata nd;
1397 + struct lookup_intent it;
1399 + it.it_op = IT_SETATTR;
1401 - error = user_path_walk(filename, &nd);
1402 + error = user_path_walk_it(filename, &nd, &it);
1404 + nd.dentry->d_it = ⁢
1405 error = chown_common(nd.dentry, user, group);
1406 + intent_release(nd.dentry);
1410 @@ -593,10 +631,15 @@
1412 struct nameidata nd;
1414 + struct lookup_intent it;
1416 + it.it_op = IT_SETATTR;
1418 - error = user_path_walk_link(filename, &nd);
1419 + error = user_path_walk_link_it(filename, &nd, &it);
1421 + nd.dentry->d_it = ⁢
1422 error = chown_common(nd.dentry, user, group);
1423 + intent_release(nd.dentry);
1427 @@ -630,10 +673,15 @@
1428 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1431 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1432 + struct nameidata *nd, struct lookup_intent *it);
1433 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it);
1435 struct file *filp_open(const char * filename, int flags, int mode)
1437 int namei_flags, error;
1438 struct nameidata nd;
1439 + struct lookup_intent it = {IT_OPEN, 0};
1441 namei_flags = flags;
1442 if ((namei_flags+1) & O_ACCMODE)
1443 @@ -641,14 +689,14 @@
1444 if (namei_flags & O_TRUNC)
1447 - error = open_namei(filename, namei_flags, mode, &nd);
1448 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1450 - return dentry_open(nd.dentry, nd.mnt, flags);
1451 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1453 return ERR_PTR(error);
1456 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1457 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it)
1460 struct inode *inode;
1461 @@ -705,11 +753,19 @@
1465 + intent_release(dentry);
1468 return ERR_PTR(error);
1471 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1473 + return dentry_open_it(dentry, mnt, flags, NULL);
1479 * Find an empty file descriptor entry, and mark it busy.
1481 --- lum-pristine/fs/stat.c Thu Sep 13 17:04:43 2001
1482 +++ lum/fs/stat.c Thu Jul 4 10:04:25 2002
1483 @@ -135,13 +135,15 @@
1484 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1486 struct nameidata nd;
1487 + struct lookup_intent it = {IT_GETATTR, 0};
1490 - error = user_path_walk(filename, &nd);
1491 + error = user_path_walk_it(filename, &nd, &it);
1493 error = do_revalidate(nd.dentry);
1495 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1496 + intent_release(nd.dentry);
1500 @@ -151,13 +153,15 @@
1501 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1503 struct nameidata nd;
1504 + struct lookup_intent it = {IT_GETATTR, 0};
1507 - error = user_path_walk(filename, &nd);
1508 + error = user_path_walk_it(filename, &nd, &it);
1510 error = do_revalidate(nd.dentry);
1512 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1513 + intent_release(nd.dentry);
1517 @@ -172,13 +176,15 @@
1518 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1520 struct nameidata nd;
1521 + struct lookup_intent it = {IT_GETATTR, 0};
1524 - error = user_path_walk_link(filename, &nd);
1525 + error = user_path_walk_link_it(filename, &nd, &it);
1527 error = do_revalidate(nd.dentry);
1529 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1530 + intent_release(nd.dentry);
1534 @@ -189,13 +195,15 @@
1535 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1537 struct nameidata nd;
1538 + struct lookup_intent it = {IT_GETATTR, 0};
1541 - error = user_path_walk_link(filename, &nd);
1542 + error = user_path_walk_link_it(filename, &nd, &it);
1544 error = do_revalidate(nd.dentry);
1546 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1547 + intent_release(nd.dentry);
1551 @@ -247,20 +255,21 @@
1553 struct nameidata nd;
1555 + struct lookup_intent it = { IT_READLINK };
1560 - error = user_path_walk_link(path, &nd);
1561 + error = user_path_walk_link_it(path, &nd, &it);
1563 struct inode * inode = nd.dentry->d_inode;
1566 if (inode->i_op && inode->i_op->readlink &&
1567 !(error = do_revalidate(nd.dentry))) {
1568 UPDATE_ATIME(inode);
1569 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1571 + intent_release(nd.dentry);
1575 @@ -333,12 +342,14 @@
1577 struct nameidata nd;
1579 + struct lookup_intent it = {IT_GETATTR};
1581 - error = user_path_walk(filename, &nd);
1582 + error = user_path_walk_it(filename, &nd, &it);
1584 error = do_revalidate(nd.dentry);
1586 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1587 + intent_release(nd.dentry);
1591 @@ -348,12 +359,14 @@
1593 struct nameidata nd;
1595 + struct lookup_intent it = { IT_GETATTR};
1597 - error = user_path_walk_link(filename, &nd);
1598 + error = user_path_walk_link_it(filename, &nd, &it);
1600 error = do_revalidate(nd.dentry);
1602 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1603 + intent_release(nd.dentry);
1607 @@ -363,6 +376,10 @@
1611 + struct lookup_intent it;
1613 + memset(&it, 0, sizeof(it));
1614 + it.it_op = IT_GETATTR;