1 --- lum-pristine/arch/ia64/mm/init.c Fri Nov 9 17:26:17 2001
2 +++ lum/arch/ia64/mm/init.c Thu Aug 1 18:07:35 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/i386/mm/init.c Fri Dec 21 12:41:53 2001
17 +++ lum/arch/i386/mm/init.c Thu Aug 1 18:07:35 2002
19 static unsigned long totalram_pages;
20 static unsigned long totalhigh_pages;
22 +struct page *check_get_page(unsigned long kaddr)
24 +#warning FIXME: Lustre team, is this solid?
25 + return virt_to_page(kaddr);
28 int do_check_pgt_cache(int low, int high)
31 --- lum-pristine/drivers/block/blkpg.c Mon Feb 25 14:37:57 2002
32 +++ lum/drivers/block/blkpg.c Thu Aug 1 18:07:35 2002
36 EXPORT_SYMBOL(blk_ioctl);
38 +#define NUM_DEV_NO_WRITE 16
39 +static int dev_no_write[NUM_DEV_NO_WRITE];
42 + * Debug code for turning block devices "read-only" (will discard writes
43 + * silently). This is for filesystem crash/recovery testing.
45 +void dev_set_rdonly(kdev_t dev, int no_write)
48 + printk(KERN_WARNING "Turning device %s read-only\n",
50 + dev_no_write[no_write] = 0xdead0000 + dev;
54 +int dev_check_rdonly(kdev_t dev) {
57 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
58 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
59 + dev == (dev_no_write[i] & 0xffff))
65 +void dev_clear_rdonly(int no_write) {
66 + dev_no_write[no_write] = 0;
69 +EXPORT_SYMBOL(dev_set_rdonly);
70 +EXPORT_SYMBOL(dev_check_rdonly);
71 +EXPORT_SYMBOL(dev_clear_rdonly);
72 --- lum-pristine/drivers/block/loop.c Fri Dec 21 12:41:53 2001
73 +++ lum/drivers/block/loop.c Thu Aug 1 18:07:35 2002
75 spin_unlock_irq(&lo->lo_lock);
78 +#ifdef CONFIG_DEV_RDONLY
79 + if (dev_check_rdonly(rbh->b_rdev))
83 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
85 } else if (rw == READA) {
86 --- lum-pristine/drivers/ide/ide-disk.c Fri Dec 21 12:41:54 2001
87 +++ lum/drivers/ide/ide-disk.c Thu Aug 1 18:07:35 2002
90 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
92 +#ifdef CONFIG_DEV_RDONLY
93 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
94 + ide_end_request(1, HWGROUP(drive));
99 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
100 OUT_BYTE(0x00, IDE_FEATURE_REG);
101 --- lum-pristine/fs/ext3/Makefile Fri Dec 21 12:41:55 2001
102 +++ lum/fs/ext3/Makefile Thu Aug 1 18:07:35 2002
107 +export-objs := super.o
109 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
110 ioctl.o namei.o super.o symlink.o
112 --- lum-pristine/fs/ext3/super.c Mon Feb 25 14:38:08 2002
113 +++ lum/fs/ext3/super.c Thu Aug 1 18:07:35 2002
114 @@ -1744,7 +1744,7 @@
115 unregister_filesystem(&ext3_fs_type);
119 +EXPORT_SYMBOL(ext3_bread);
121 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
122 MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
123 --- lum-pristine/fs/jbd/commit.c Mon Feb 25 14:38:08 2002
124 +++ lum/fs/jbd/commit.c Thu Aug 1 18:07:35 2002
126 transaction's t_log_list queue, and metadata buffers are on
127 the t_iobuf_list queue.
129 - Wait for the transactions in reverse order. That way we are
130 + Wait for the buffers in reverse order. That way we are
131 less likely to be woken up until all IOs have completed, and
132 so we incur less scheduling load.
136 jbd_debug(3, "JBD: commit phase 6\n");
138 - if (is_journal_aborted(journal))
139 + if (is_journal_aborted(journal)) {
140 + unlock_journal(journal);
144 /* Done it all: now write the commit record. We should have
145 * cleaned up our previous buffers by now, so if we are in abort
147 descriptor = journal_get_descriptor_buffer(journal);
149 __journal_abort_hard(journal);
150 + unlock_journal(journal);
155 put_bh(bh); /* One for getblk() */
156 journal_unlock_journal_head(descriptor);
158 - lock_journal(journal);
160 /* End of a transaction! Finally, we can do checkpoint
161 processing: any buffers committed as a result of this
166 + /* Call any callbacks that had been registered for handles in this
167 + * transaction. It is up to the callback to free any allocated
170 + if (!list_empty(&commit_transaction->t_jcb)) {
171 + struct list_head *p, *n;
172 + int error = is_journal_aborted(journal);
174 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
175 + struct journal_callback *jcb;
177 + jcb = list_entry(p, struct journal_callback, jcb_list);
179 + jcb->jcb_func(jcb, error);
183 + lock_journal(journal);
185 jbd_debug(3, "JBD: commit phase 7\n");
187 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
188 --- lum-pristine/fs/jbd/journal.c Mon Feb 25 14:38:08 2002
189 +++ lum/fs/jbd/journal.c Thu Aug 1 18:07:35 2002
192 EXPORT_SYMBOL(journal_flush);
193 EXPORT_SYMBOL(journal_revoke);
194 +EXPORT_SYMBOL(journal_callback_set);
196 EXPORT_SYMBOL(journal_init_dev);
197 EXPORT_SYMBOL(journal_init_inode);
198 --- lum-pristine/fs/jbd/transaction.c Mon Feb 25 14:38:08 2002
199 +++ lum/fs/jbd/transaction.c Thu Aug 1 18:07:35 2002
201 transaction->t_state = T_RUNNING;
202 transaction->t_tid = journal->j_transaction_sequence++;
203 transaction->t_expires = jiffies + journal->j_commit_interval;
204 + INIT_LIST_HEAD(&transaction->t_jcb);
206 /* Set up the commit timer for the new transaction. */
207 J_ASSERT (!journal->j_commit_timer_active);
212 +/* Allocate a new handle. This should probably be in a slab... */
213 +static handle_t *get_handle(int nblocks)
215 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
218 + memset(handle, 0, sizeof (handle_t));
219 + handle->h_buffer_credits = nblocks;
221 + INIT_LIST_HEAD(&handle->h_jcb);
227 * Obtain a new handle.
229 @@ -227,14 +242,11 @@
234 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
236 + handle = get_handle(nblocks);
238 return ERR_PTR(-ENOMEM);
239 - memset (handle, 0, sizeof (handle_t));
241 - handle->h_buffer_credits = nblocks;
243 current->journal_info = handle;
245 err = start_this_handle(journal, handle);
246 @@ -333,14 +345,11 @@
248 if (is_journal_aborted(journal))
249 return ERR_PTR(-EIO);
251 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
253 + handle = get_handle(nblocks);
255 return ERR_PTR(-ENOMEM);
256 - memset (handle, 0, sizeof (handle_t));
258 - handle->h_buffer_credits = nblocks;
260 current->journal_info = handle;
262 err = try_start_this_handle(journal, handle);
263 @@ -1328,6 +1337,29 @@
267 + * Register a callback function for this handle. The function will be
268 + * called when the transaction that this handle is part of has been
269 + * committed to disk with the original callback data struct and the
270 + * error status of the journal as parameters. There is no guarantee of
271 + * ordering between handles within a single transaction, nor between
272 + * callbacks registered on the same handle.
274 + * The caller is responsible for allocating the journal_callback struct.
275 + * This is to allow the caller to add as much extra data to the callback
276 + * as needed, but reduce the overhead of multiple allocations. The caller
277 + * allocated struct must start with a struct journal_callback at offset 0,
278 + * and has the caller-specific data afterwards.
280 +void journal_callback_set(handle_t *handle, void (*func)(void *, int),
283 + struct journal_callback *jcb = cb_data;
285 + list_add(&jcb->jcb_list, &handle->h_jcb);
286 + jcb->jcb_func = func;
290 * All done for a particular handle.
292 * There is not much action needed here. We just return any remaining
293 @@ -1383,7 +1415,10 @@
294 wake_up(&journal->j_wait_transaction_locked);
298 + /* Move callbacks from the handle to the transaction. */
299 + list_splice(&handle->h_jcb, &transaction->t_jcb);
302 * If the handle is marked SYNC, we need to set another commit
303 * going! We also want to force a commit if the current
304 * transaction is occupying too much of the log, or if the
305 --- lum-pristine/include/linux/blkdev.h Mon Nov 26 08:29:17 2001
306 +++ lum/include/linux/blkdev.h Mon Aug 12 11:48:39 2002
311 +#define CONFIG_DEV_RDONLY
312 +void dev_set_rdonly(kdev_t, int);
313 +int dev_check_rdonly(kdev_t);
314 +void dev_clear_rdonly(int);
316 --- lum-pristine/include/linux/slab.h Fri Dec 21 12:42:04 2001
317 +++ lum/include/linux/slab.h Mon Aug 12 11:48:38 2002
319 extern int kmem_cache_shrink(kmem_cache_t *);
320 extern void *kmem_cache_alloc(kmem_cache_t *, int);
321 extern void kmem_cache_free(kmem_cache_t *, void *);
322 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
324 extern void *kmalloc(size_t, int);
325 extern void kfree(const void *);
326 --- lum-pristine/include/linux/jbd.h Mon Feb 25 14:38:13 2002
327 +++ lum/include/linux/jbd.h Mon Aug 12 11:50:09 2002
329 return bh->b_private;
332 +#define HAVE_JOURNAL_CALLBACK_STATUS
333 +struct journal_callback {
334 + struct list_head jcb_list;
335 + void (*jcb_func)(void *cb_data, int error);
336 + /* user data goes here */
339 struct jbd_revoke_table_s;
341 /* The handle_t type represents a single atomic update being performed
346 + /* List of application registered callbacks for this handle.
347 + * The function(s) will be called after the transaction that
348 + * this handle is part of has been committed to disk.
350 + struct list_head h_jcb;
353 unsigned int h_sync: 1; /* sync-on-close */
354 unsigned int h_jdata: 1; /* force data journaling */
357 /* How many handles used this transaction? */
360 + /* List of registered callback functions for this transaction.
361 + * Called when the transaction is committed. */
362 + struct list_head t_jcb;
367 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
368 extern int journal_stop(handle_t *);
369 extern int journal_flush (journal_t *);
370 +extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int),
373 extern void journal_lock_updates (journal_t *);
374 extern void journal_unlock_updates (journal_t *);
375 --- lum-pristine/kernel/ksyms.c Mon Feb 25 14:38:13 2002
376 +++ lum/kernel/ksyms.c Thu Aug 1 18:07:35 2002
378 EXPORT_SYMBOL(lock_may_write);
379 EXPORT_SYMBOL(dcache_readdir);
382 +EXPORT_SYMBOL(panic_notifier_list);
383 +EXPORT_SYMBOL(pagecache_lock);
384 +EXPORT_SYMBOL(do_kern_mount);
385 +EXPORT_SYMBOL(kmem_cache_validate);
387 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
388 EXPORT_SYMBOL(default_llseek);
389 EXPORT_SYMBOL(dentry_open);
390 --- lum-pristine/include/linux/dcache.h Thu Nov 22 14:46:18 2001
391 +++ lum/include/linux/dcache.h Mon Aug 12 00:02:29 2002
393 #include <asm/atomic.h>
394 #include <linux/mount.h>
397 +#define IT_CREAT (1<<1)
398 +#define IT_MKDIR (1<<2)
399 +#define IT_LINK (1<<3)
400 +#define IT_SYMLINK (1<<4)
401 +#define IT_UNLINK (1<<5)
402 +#define IT_RMDIR (1<<6)
403 +#define IT_RENAME (1<<7)
404 +#define IT_RENAME2 (1<<8)
405 +#define IT_READDIR (1<<9)
406 +#define IT_GETATTR (1<<10)
407 +#define IT_SETATTR (1<<11)
408 +#define IT_READLINK (1<<12)
409 +#define IT_MKNOD (1<<13)
410 +#define IT_LOOKUP (1<<14)
412 +struct lookup_intent {
415 + int it_disposition;
417 + struct iattr *it_iattr;
418 + __u64 it_lock_handle[2];
424 * linux/include/linux/dcache.h
427 unsigned long d_time; /* used by d_revalidate */
428 struct dentry_operations *d_op;
429 struct super_block * d_sb; /* The root of the dentry tree */
430 + struct lookup_intent *d_it;
431 unsigned long d_vfs_flags;
432 void * d_fsdata; /* fs-specific data */
433 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
435 int (*d_delete)(struct dentry *);
436 void (*d_release)(struct dentry *);
437 void (*d_iput)(struct dentry *, struct inode *);
438 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
439 + void (*d_intent_release)(struct dentry *);
442 /* the dentry parameter passed to d_hash and d_compare is the parent
443 --- lum-pristine/include/linux/fs.h Mon Aug 12 11:02:53 2002
444 +++ lum/include/linux/fs.h Mon Aug 12 11:48:38 2002
447 /* needed for tty driver, and maybe others */
449 + struct lookup_intent *f_intent;
451 /* preallocated helper kiobuf to speedup O_DIRECT */
452 struct kiobuf *f_iobuf;
454 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
455 extern int vfs_rmdir(struct inode *, struct dentry *);
456 extern int vfs_unlink(struct inode *, struct dentry *);
457 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
458 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
459 + struct inode *new_dir, struct dentry *new_dentry,
460 + struct lookup_intent *it);
465 struct inode_operations {
466 int (*create) (struct inode *,struct dentry *,int);
467 struct dentry * (*lookup) (struct inode *,struct dentry *);
468 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
469 int (*link) (struct dentry *,struct inode *,struct dentry *);
470 int (*unlink) (struct inode *,struct dentry *);
471 int (*symlink) (struct inode *,struct dentry *,const char *);
473 extern struct vfsmount *kern_mount(struct file_system_type *);
474 extern int may_umount(struct vfsmount *);
475 extern long do_mount(char *, char *, char *, unsigned long, void *);
477 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
478 #define kern_umount mntput
480 extern int vfs_statfs(struct super_block *, struct statfs *);
481 @@ -1307,6 +1311,7 @@
482 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
484 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
485 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
486 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
487 extern int FASTCALL(path_walk(const char *, struct nameidata *));
488 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
489 @@ -1317,6 +1322,8 @@
490 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
491 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
492 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
493 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
494 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
496 extern void iput(struct inode *);
497 extern void force_delete(struct inode *);
498 --- lum-pristine/fs/dcache.c Mon Feb 25 14:38:08 2002
499 +++ lum/fs/dcache.c Thu Aug 1 18:07:35 2002
502 dentry->d_fsdata = NULL;
503 dentry->d_mounted = 0;
504 + dentry->d_it = NULL;
505 INIT_LIST_HEAD(&dentry->d_hash);
506 INIT_LIST_HEAD(&dentry->d_lru);
507 INIT_LIST_HEAD(&dentry->d_subdirs);
508 --- lum-pristine/fs/nfsd/vfs.c Fri Dec 21 12:41:55 2001
509 +++ lum/fs/nfsd/vfs.c Thu Aug 1 18:07:35 2002
510 @@ -1285,7 +1285,7 @@
514 - err = vfs_rename(fdir, odentry, tdir, ndentry);
515 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
516 if (!err && EX_ISSYNC(tfhp->fh_export)) {
517 nfsd_sync_dir(tdentry);
518 nfsd_sync_dir(fdentry);
519 --- lum-pristine/fs/namei.c Mon Feb 25 14:38:09 2002
520 +++ lum/fs/namei.c Mon Aug 12 11:47:56 2002
522 * XEmacs seems to be relying on it...
525 +void intent_release(struct dentry *de)
527 + if (de->d_op && de->d_op->d_intent_release)
528 + de->d_op->d_intent_release(de);
533 /* In order to reduce some races, while at the same time doing additional
534 * checking and hopefully speeding things up, we copy filenames to the
535 * kernel data space before using them..
536 @@ -260,10 +268,19 @@
537 * Internal lookup() using the new generic dcache.
540 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
541 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
542 + int flags, struct lookup_intent *it)
544 struct dentry * dentry = d_lookup(parent, name);
546 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
547 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
548 + !d_invalidate(dentry)) {
554 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
555 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
558 * make sure that nobody added the entry to the dcache in the meantime..
561 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
562 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
563 + int flags, struct lookup_intent *it)
565 struct dentry * result;
566 struct inode *dir = parent->d_inode;
568 result = ERR_PTR(-ENOMEM);
571 + if (dir->i_op->lookup2)
572 + result = dir->i_op->lookup2(dir, dentry, it);
574 result = dir->i_op->lookup(dir, dentry);
579 result = ERR_PTR(-ENOENT);
581 + } else if (result->d_op && result->d_op->d_revalidate2) {
582 + if (!result->d_op->d_revalidate2(result, flags, it) &&
583 + !d_invalidate(result)) {
585 + result = ERR_PTR(-ENOENT);
592 * We expect 'base' to be positive and a directory.
594 -int link_path_walk(const char * name, struct nameidata *nd)
595 +int link_path_walk_it(const char *name, struct nameidata *nd,
596 + struct lookup_intent *it)
598 struct dentry *dentry;
603 /* This does the actual lookups.. */
604 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
605 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
607 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
608 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
609 err = PTR_ERR(dentry);
616 - if (!inode->i_op->lookup)
617 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
620 /* here ends the main loop */
625 - dentry = cached_lookup(nd->dentry, &this, 0);
626 + dentry = cached_lookup(nd->dentry, &this, 0, it);
628 - dentry = real_lookup(nd->dentry, &this, 0);
629 + dentry = real_lookup(nd->dentry, &this, 0, it);
630 err = PTR_ERR(dentry);
635 if (lookup_flags & LOOKUP_DIRECTORY) {
637 - if (!inode->i_op || !inode->i_op->lookup)
638 + if (!inode->i_op || (!inode->i_op->lookup &&
639 + !inode->i_op->lookup2))
644 else if (this.len == 2 && this.name[1] == '.')
645 nd->last_type = LAST_DOTDOT;
647 + nd->dentry->d_it = it;
651 @@ -633,15 +663,29 @@
656 + nd->dentry->d_it = it;
660 +int link_path_walk(const char * name, struct nameidata *nd)
662 + return link_path_walk_it(name, nd, NULL);
665 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
667 + current->total_link_count = 0;
668 + return link_path_walk_it(name, nd, it);
671 int path_walk(const char * name, struct nameidata *nd)
673 current->total_link_count = 0;
674 - return link_path_walk(name, nd);
675 + return link_path_walk_it(name, nd, NULL);
680 /* returns 1 if everything is done */
681 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
683 * needs parent already locked. Doesn't follow mounts.
686 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
687 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
688 + struct lookup_intent *it)
690 struct dentry * dentry;
692 @@ -765,13 +810,16 @@
696 - dentry = cached_lookup(base, name, 0);
697 + dentry = cached_lookup(base, name, 0, it);
699 struct dentry *new = d_alloc(base, name);
700 dentry = ERR_PTR(-ENOMEM);
704 + if (inode->i_op->lookup2)
705 + dentry = inode->i_op->lookup2(inode, new, it);
707 dentry = inode->i_op->lookup(inode, new);
714 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
716 + return lookup_hash_it(name, base, NULL);
721 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
725 this.hash = end_name_hash(hash);
727 - return lookup_hash(&this, base);
728 + return lookup_hash_it(&this, base, NULL);
730 return ERR_PTR(-EACCES);
736 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
737 + struct lookup_intent *it)
742 + tmp = getname(name);
743 + err = PTR_ERR(tmp);
744 + if (!IS_ERR(tmp)) {
746 + if (path_init(tmp, flags, nd))
747 + err = path_walk_it(tmp, nd, it);
754 * It's inline, so penalty for filesystems that don't use sticky bit is
757 * for symlinks (where the permissions are checked later).
760 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
761 +int open_namei_it(const char *pathname, int flag, int mode,
762 + struct nameidata *nd, struct lookup_intent *it)
764 int acc_mode, error = 0;
766 @@ -984,17 +1056,22 @@
767 * The simplest case - just a plain lookup.
769 if (!(flag & O_CREAT)) {
770 if (path_init(pathname, lookup_flags(flag), nd))
771 - error = path_walk(pathname, nd);
772 + error = path_walk_it(pathname, nd, it);
781 * Create - we need to know the parent.
784 + it->it_mode = mode;
785 + it->it_op |= IT_CREAT;
787 if (path_init(pathname, LOOKUP_PARENT, nd))
788 error = path_walk(pathname, nd);
790 @@ -1011,7 +1089,7 @@
793 down(&dir->d_inode->i_sem);
794 - dentry = lookup_hash(&nd->last, nd->dentry);
795 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
798 error = PTR_ERR(dentry);
799 @@ -1020,6 +1098,8 @@
804 + dentry->d_it->it_mode = mode;
805 /* Negative dentry, just create the file */
806 if (!dentry->d_inode) {
807 error = vfs_create(dir->d_inode, dentry,
808 @@ -1139,8 +1219,10 @@
812 + intent_release(dentry);
815 + intent_release(nd->dentry);
819 @@ -1160,6 +1242,8 @@
821 UPDATE_ATIME(dentry->d_inode);
822 error = dentry->d_inode->i_op->follow_link(dentry, nd);
824 + intent_release(dentry);
828 @@ -1181,13 +1265,20 @@
831 down(&dir->d_inode->i_sem);
832 - dentry = lookup_hash(&nd->last, nd->dentry);
833 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
834 putname(nd->last.name);
838 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
840 + return open_namei_it(pathname, flag, mode, nd, NULL);
845 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
846 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
847 + struct lookup_intent *it)
849 struct dentry *dentry;
851 @@ -1195,7 +1286,7 @@
852 dentry = ERR_PTR(-EEXIST);
853 if (nd->last_type != LAST_NORM)
855 - dentry = lookup_hash(&nd->last, nd->dentry);
856 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
859 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
860 @@ -1241,6 +1332,7 @@
862 struct dentry * dentry;
864 + struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
868 @@ -1252,11 +1344,12 @@
869 error = path_walk(tmp, &nd);
872 - dentry = lookup_create(&nd, 0);
873 + dentry = lookup_create(&nd, 0, &it);
874 error = PTR_ERR(dentry);
876 mode &= ~current->fs->umask;
877 if (!IS_ERR(dentry)) {
878 + dentry->d_it = ⁢
879 switch (mode & S_IFMT) {
880 case 0: case S_IFREG:
881 error = vfs_create(nd.dentry->d_inode,dentry,mode);
882 @@ -1270,6 +1363,7 @@
886 + intent_release(dentry);
889 up(&nd.dentry->d_inode->i_sem);
890 @@ -1310,6 +1404,7 @@
894 + struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
896 tmp = getname(pathname);
897 error = PTR_ERR(tmp);
898 @@ -1321,11 +1416,13 @@
899 error = path_walk(tmp, &nd);
902 - dentry = lookup_create(&nd, 1);
903 + dentry = lookup_create(&nd, 1, &it);
904 error = PTR_ERR(dentry);
905 if (!IS_ERR(dentry)) {
906 + dentry->d_it = ⁢
907 error = vfs_mkdir(nd.dentry->d_inode, dentry,
908 mode & ~current->fs->umask);
909 + intent_release(dentry);
912 up(&nd.dentry->d_inode->i_sem);
913 @@ -1407,6 +1504,7 @@
915 struct dentry *dentry;
917 + struct lookup_intent it = { .it_op = IT_RMDIR };
919 name = getname(pathname);
921 @@ -1429,10 +1527,12 @@
924 down(&nd.dentry->d_inode->i_sem);
925 - dentry = lookup_hash(&nd.last, nd.dentry);
926 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
927 error = PTR_ERR(dentry);
928 if (!IS_ERR(dentry)) {
929 + dentry->d_it = ⁢
930 error = vfs_rmdir(nd.dentry->d_inode, dentry);
931 + intent_release(dentry);
934 up(&nd.dentry->d_inode->i_sem);
935 @@ -1476,6 +1576,7 @@
937 struct dentry *dentry;
939 + struct lookup_intent it = { .it_op = IT_UNLINK };
941 name = getname(pathname);
943 @@ -1489,14 +1590,16 @@
944 if (nd.last_type != LAST_NORM)
946 down(&nd.dentry->d_inode->i_sem);
947 - dentry = lookup_hash(&nd.last, nd.dentry);
948 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
949 error = PTR_ERR(dentry);
950 if (!IS_ERR(dentry)) {
951 + dentry->d_it = ⁢
952 /* Why not before? Because we want correct error value */
953 if (nd.last.name[nd.last.len])
955 error = vfs_unlink(nd.dentry->d_inode, dentry);
957 + intent_release(dentry);
960 up(&nd.dentry->d_inode->i_sem);
961 @@ -1543,6 +1646,7 @@
965 + struct lookup_intent it = { .it_op = IT_SYMLINK };
967 from = getname(oldname);
969 @@ -1557,10 +1661,13 @@
970 error = path_walk(to, &nd);
973 - dentry = lookup_create(&nd, 0);
975 + dentry = lookup_create(&nd, 0, &it);
976 error = PTR_ERR(dentry);
977 if (!IS_ERR(dentry)) {
978 + dentry->d_it = ⁢
979 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
980 + intent_release(dentry);
983 up(&nd.dentry->d_inode->i_sem);
984 @@ -1626,6 +1732,7 @@
988 + struct lookup_intent it = { .it_op = IT_LINK };
990 from = getname(oldname);
992 @@ -1648,10 +1755,12 @@
994 if (old_nd.mnt != nd.mnt)
996 - new_dentry = lookup_create(&nd, 0);
997 + new_dentry = lookup_create(&nd, 0, &it);
998 error = PTR_ERR(new_dentry);
999 if (!IS_ERR(new_dentry)) {
1000 + new_dentry->d_it = ⁢
1001 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1002 + intent_release(new_dentry);
1005 up(&nd.dentry->d_inode->i_sem);
1006 @@ -1694,7 +1803,8 @@
1009 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1010 - struct inode *new_dir, struct dentry *new_dentry)
1011 + struct inode *new_dir, struct dentry *new_dentry,
1012 + struct lookup_intent *it)
1015 struct inode *target;
1016 @@ -1748,12 +1858,14 @@
1018 double_down(&old_dir->i_zombie,
1019 &new_dir->i_zombie);
1020 + new_dentry->d_it = it;
1021 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
1023 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1026 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1027 + intent_release(new_dentry);
1030 target->i_flags |= S_DEAD;
1031 @@ -1775,7 +1887,8 @@
1034 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1035 - struct inode *new_dir, struct dentry *new_dentry)
1036 + struct inode *new_dir, struct dentry *new_dentry,
1037 + struct lookup_intent *it)
1041 @@ -1802,10 +1915,12 @@
1042 DQUOT_INIT(old_dir);
1043 DQUOT_INIT(new_dir);
1044 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1045 + new_dentry->d_it = it;
1046 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1049 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1050 + intent_release(new_dentry);
1051 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1054 @@ -1817,13 +1932,14 @@
1057 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1058 - struct inode *new_dir, struct dentry *new_dentry)
1059 + struct inode *new_dir, struct dentry *new_dentry,
1060 + struct lookup_intent *it)
1063 if (S_ISDIR(old_dentry->d_inode->i_mode))
1064 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1065 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1067 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1068 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1070 if (old_dir == new_dir)
1071 inode_dir_notify(old_dir, DN_RENAME);
1072 @@ -1840,6 +1956,7 @@
1074 struct dentry * old_dir, * new_dir;
1075 struct dentry * old_dentry, *new_dentry;
1076 + struct lookup_intent it = { .it_op = IT_RENAME };
1077 struct nameidata oldnd, newnd;
1079 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1080 @@ -1868,7 +1985,7 @@
1082 double_lock(new_dir, old_dir);
1084 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1085 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1086 error = PTR_ERR(old_dentry);
1087 if (IS_ERR(old_dentry))
1089 @@ -1884,18 +2003,21 @@
1090 if (newnd.last.name[newnd.last.len])
1093 - new_dentry = lookup_hash(&newnd.last, new_dir);
1094 + it.it_op = IT_RENAME2;
1095 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1096 error = PTR_ERR(new_dentry);
1097 if (IS_ERR(new_dentry))
1101 error = vfs_rename(old_dir->d_inode, old_dentry,
1102 - new_dir->d_inode, new_dentry);
1103 + new_dir->d_inode, new_dentry, &it);
1106 + intent_release(new_dentry);
1109 + intent_release(old_dentry);
1112 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1113 --- lum-pristine/fs/open.c Fri Oct 12 16:48:42 2001
1114 +++ lum/fs/open.c Sun Aug 11 15:26:29 2002
1116 #include <asm/uaccess.h>
1118 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1119 +extern int path_walk_it(const char *name, struct nameidata *nd,
1120 + struct lookup_intent *it);
1121 +extern void intent_release(struct dentry *de);
1123 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1126 struct nameidata nd;
1127 struct inode * inode;
1129 + struct lookup_intent it = { .it_op = IT_SETATTR };
1132 if (length < 0) /* sorry, but loff_t says... */
1135 - error = user_path_walk(path, &nd);
1136 + error = user_path_walk_it(path, &nd, &it);
1139 + nd.dentry->d_it = ⁢
1140 inode = nd.dentry->d_inode;
1142 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1144 put_write_access(inode);
1147 + intent_release(nd.dentry);
1151 @@ -235,10 +241,12 @@
1152 struct nameidata nd;
1153 struct inode * inode;
1154 struct iattr newattrs;
1155 + struct lookup_intent it = { .it_op = IT_SETATTR };
1157 - error = user_path_walk(filename, &nd);
1158 + error = user_path_walk_it(filename, &nd, &it);
1161 + nd.dentry->d_it = ⁢
1162 inode = nd.dentry->d_inode;
1167 error = notify_change(nd.dentry, &newattrs);
1169 + intent_release(nd.dentry);
1173 @@ -279,11 +288,13 @@
1174 struct nameidata nd;
1175 struct inode * inode;
1176 struct iattr newattrs;
1177 + struct lookup_intent it = { .it_op = IT_SETATTR };
1179 - error = user_path_walk(filename, &nd);
1180 + error = user_path_walk_it(filename, &nd, &it);
1184 + nd.dentry->d_it = ⁢
1185 inode = nd.dentry->d_inode;
1190 error = notify_change(nd.dentry, &newattrs);
1192 + intent_release(nd.dentry);
1197 int old_fsuid, old_fsgid;
1198 kernel_cap_t old_cap;
1200 + struct lookup_intent it = { .it_op = IT_GETATTR };
1202 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1204 @@ -339,13 +352,14 @@
1206 current->cap_effective = current->cap_permitted;
1208 - res = user_path_walk(filename, &nd);
1209 + res = user_path_walk_it(filename, &nd, &it);
1211 res = permission(nd.dentry->d_inode, mode);
1212 /* SuS v2 requires we report a read only fs too */
1213 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1214 && !special_file(nd.dentry->d_inode->i_mode))
1216 + intent_release(nd.dentry);
1222 struct nameidata nd;
1224 + struct lookup_intent it = { .it_op = IT_GETATTR };
1226 name = getname(filename);
1227 error = PTR_ERR(name);
1228 @@ -369,11 +384,12 @@
1231 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1232 - error = path_walk(name, &nd);
1233 + error = path_walk_it(name, &nd, &it);
1238 + nd.dentry->d_it = ⁢
1239 error = permission(nd.dentry->d_inode,MAY_EXEC);
1243 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1246 + intent_release(nd.dentry);
1252 struct nameidata nd;
1254 + struct lookup_intent it = { .it_op = IT_GETATTR };
1256 name = getname(filename);
1257 error = PTR_ERR(name);
1258 @@ -429,11 +447,12 @@
1260 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1261 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1262 - error = path_walk(name, &nd);
1263 + error = path_walk_it(name, &nd, &it);
1268 + nd.dentry->d_it = ⁢
1269 error = permission(nd.dentry->d_inode,MAY_EXEC);
1276 + intent_release(nd.dentry);
1280 @@ -490,12 +510,14 @@
1281 struct inode * inode;
1283 struct iattr newattrs;
1284 + struct lookup_intent it = { .it_op = IT_SETATTR };
1286 - error = user_path_walk(filename, &nd);
1287 + error = user_path_walk_it(filename, &nd, &it);
1290 inode = nd.dentry->d_inode;
1292 + nd.dentry->d_it = ⁢
1294 if (IS_RDONLY(inode))
1297 error = notify_change(nd.dentry, &newattrs);
1300 + intent_release(nd.dentry);
1304 @@ -580,10 +602,13 @@
1306 struct nameidata nd;
1308 + struct lookup_intent it = { .it_op = IT_SETATTR };
1310 - error = user_path_walk(filename, &nd);
1311 + error = user_path_walk_it(filename, &nd, &it);
1313 + nd.dentry->d_it = ⁢
1314 error = chown_common(nd.dentry, user, group);
1315 + intent_release(nd.dentry);
1319 @@ -593,10 +618,13 @@
1321 struct nameidata nd;
1323 + struct lookup_intent it = { .it_op = IT_SETATTR };
1325 - error = user_path_walk_link(filename, &nd);
1326 + error = user_path_walk_link_it(filename, &nd, &it);
1328 + nd.dentry->d_it = ⁢
1329 error = chown_common(nd.dentry, user, group);
1330 + intent_release(nd.dentry);
1334 @@ -630,10 +658,16 @@
1335 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1338 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1339 + struct nameidata *nd, struct lookup_intent *it);
1340 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1341 + int flags, struct lookup_intent *it);
1343 struct file *filp_open(const char * filename, int flags, int mode)
1345 int namei_flags, error;
1346 struct nameidata nd;
1347 + struct lookup_intent it = { .it_op = IT_OPEN };
1349 namei_flags = flags;
1350 if ((namei_flags+1) & O_ACCMODE)
1351 @@ -641,14 +675,15 @@
1352 if (namei_flags & O_TRUNC)
1355 - error = open_namei(filename, namei_flags, mode, &nd);
1357 - return dentry_open(nd.dentry, nd.mnt, flags);
1358 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1360 + return ERR_PTR(error);
1362 - return ERR_PTR(error);
1363 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1366 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1367 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1368 + int flags, struct lookup_intent *it)
1371 struct inode *inode;
1374 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1376 + intent_release(dentry);
1380 @@ -705,11 +741,17 @@
1384 + intent_release(dentry);
1387 return ERR_PTR(error);
1390 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1392 + return dentry_open_it(dentry, mnt, flags, NULL);
1396 * Find an empty file descriptor entry, and mark it busy.
1398 --- lum-pristine/fs/stat.c Thu Sep 13 19:04:43 2001
1399 +++ lum/fs/stat.c Mon Aug 12 00:04:39 2002
1402 #include <asm/uaccess.h>
1404 +extern void intent_release(struct dentry *de);
1406 * Revalidate the inode. This is required for proper NFS attribute caching.
1408 @@ -135,13 +135,15 @@
1409 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1411 struct nameidata nd;
1412 + struct lookup_intent it = { .it_op = IT_GETATTR };
1415 - error = user_path_walk(filename, &nd);
1416 + error = user_path_walk_it(filename, &nd, &it);
1418 error = do_revalidate(nd.dentry);
1420 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1421 + intent_release(nd.dentry);
1425 @@ -151,13 +153,15 @@
1426 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1428 struct nameidata nd;
1429 + struct lookup_intent it = { .it_op = IT_GETATTR };
1432 - error = user_path_walk(filename, &nd);
1433 + error = user_path_walk_it(filename, &nd, &it);
1435 error = do_revalidate(nd.dentry);
1437 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1438 + intent_release(nd.dentry);
1442 @@ -172,13 +176,15 @@
1443 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1445 struct nameidata nd;
1446 + struct lookup_intent it = { .it_op = IT_GETATTR };
1449 - error = user_path_walk_link(filename, &nd);
1450 + error = user_path_walk_link_it(filename, &nd, &it);
1452 error = do_revalidate(nd.dentry);
1454 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1455 + intent_release(nd.dentry);
1459 @@ -189,13 +195,15 @@
1460 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1462 struct nameidata nd;
1463 + struct lookup_intent it = { .it_op = IT_GETATTR };
1466 - error = user_path_walk_link(filename, &nd);
1467 + error = user_path_walk_link_it(filename, &nd, &it);
1469 error = do_revalidate(nd.dentry);
1471 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1472 + intent_release(nd.dentry);
1476 @@ -247,20 +255,21 @@
1478 struct nameidata nd;
1480 + struct lookup_intent it = { .it_op = IT_READLINK };
1485 - error = user_path_walk_link(path, &nd);
1486 + error = user_path_walk_link_it(path, &nd, &it);
1488 struct inode * inode = nd.dentry->d_inode;
1491 if (inode->i_op && inode->i_op->readlink &&
1492 !(error = do_revalidate(nd.dentry))) {
1493 UPDATE_ATIME(inode);
1494 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1496 + intent_release(nd.dentry);
1500 @@ -333,12 +342,14 @@
1502 struct nameidata nd;
1504 + struct lookup_intent it = { .it_op = IT_GETATTR };
1506 - error = user_path_walk(filename, &nd);
1507 + error = user_path_walk_it(filename, &nd, &it);
1509 error = do_revalidate(nd.dentry);
1511 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1512 + intent_release(nd.dentry);
1516 @@ -348,12 +359,14 @@
1518 struct nameidata nd;
1520 + struct lookup_intent it = { .it_op = IT_GETATTR };
1522 - error = user_path_walk_link(filename, &nd);
1523 + error = user_path_walk_link_it(filename, &nd, &it);
1525 error = do_revalidate(nd.dentry);
1527 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1528 + intent_release(nd.dentry);
1536 + struct lookup_intent it = { .it_op = IT_GETATTR };
1540 --- lum-pristine/mm/slab.c Fri Dec 21 12:42:05 2001
1541 +++ lum/mm/slab.c Thu Aug 1 18:07:35 2002
1542 @@ -1187,6 +1187,59 @@
1543 * Called with the cache-lock held.
1546 +extern struct page *check_get_page(unsigned long kaddr);
1547 +struct page *page_mem_map(struct page *page);
1548 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1549 + slab_t *slabp, void * objp)
1552 + unsigned int objnr;
1555 + if (cachep->flags & SLAB_RED_ZONE) {
1556 + objp -= BYTES_PER_WORD;
1557 + if ( *(unsigned long *)objp != RED_MAGIC2)
1558 + /* Either write before start, or a double free. */
1560 + if (*(unsigned long *)(objp+cachep->objsize -
1561 + BYTES_PER_WORD) != RED_MAGIC2)
1562 + /* Either write past end, or a double free. */
1567 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1568 + if (objnr >= cachep->num)
1570 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1573 + /* Check slab's freelist to see if this obj is there. */
1574 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1582 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1584 + struct page *page = check_get_page((unsigned long)objp);
1586 + if (!VALID_PAGE(page))
1589 + if (!PageSlab(page))
1592 + /* XXX check for freed slab objects ? */
1593 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1596 + return (cachep == GET_PAGE_CACHE(page));
1600 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1601 slab_t *slabp, void * objp)