1 --- linux-2.4.18-chaos5-pristine/drivers/block/blkpg.c Sat Jun 29 23:07:36 2002
2 +++ linux-2.4.18-chaos5/drivers/block/blkpg.c Sat Jun 29 23:09:04 2002
6 EXPORT_SYMBOL(blk_ioctl);
8 +#define NUM_DEV_NO_WRITE 16
9 +static int dev_no_write[NUM_DEV_NO_WRITE];
12 + * Debug code for turning block devices "read-only" (will discard writes
13 + * silently). This is for filesystem crash/recovery testing.
15 +void dev_set_rdonly(kdev_t dev, int no_write)
18 + printk(KERN_WARNING "Turning device %s read-only\n",
20 + dev_no_write[no_write] = 0xdead0000 + dev;
24 +int dev_check_rdonly(kdev_t dev) {
27 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
28 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
29 + dev == (dev_no_write[i] & 0xffff))
35 +void dev_clear_rdonly(int no_write) {
36 + dev_no_write[no_write] = 0;
39 +EXPORT_SYMBOL(dev_set_rdonly);
40 +EXPORT_SYMBOL(dev_check_rdonly);
41 +EXPORT_SYMBOL(dev_clear_rdonly);
42 --- linux-2.4.18-chaos5-pristine/drivers/block/loop.c Sat Jun 29 23:07:36 2002
43 +++ linux-2.4.18-chaos5/drivers/block/loop.c Sat Jun 29 23:09:04 2002
45 spin_unlock_irq(&lo->lo_lock);
48 +#ifdef CONFIG_DEV_RDONLY
49 + if (dev_check_rdonly(rbh->b_rdev))
53 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
55 } else if (rw == READA) {
56 --- linux-2.4.18-chaos5-pristine/drivers/ide/ide-disk.c Sat Jun 29 23:07:36 2002
57 +++ linux-2.4.18-chaos5/drivers/ide/ide-disk.c Sat Jun 29 23:09:04 2002
60 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
62 +#ifdef CONFIG_DEV_RDONLY
63 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
64 + ide_end_request(1, HWGROUP(drive));
69 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
71 --- linux-2.4.18-chaos5-pristine/fs/ext3/Makefile Sat Jun 29 23:07:56 2002
72 +++ linux-2.4.18-chaos5/fs/ext3/Makefile Sat Jun 29 23:09:04 2002
77 +export-objs := super.o
79 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
80 ioctl.o namei.o super.o symlink.o
82 --- linux-2.4.18-chaos5-pristine/fs/ext3/super.c Sat Jun 29 23:07:56 2002
83 +++ linux-2.4.18-chaos5/fs/ext3/super.c Sat Jun 29 23:09:04 2002
85 unregister_filesystem(&ext3_fs_type);
89 +EXPORT_SYMBOL(ext3_bread);
91 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
92 MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
93 --- linux-2.4.18-chaos5-pristine/fs/jbd/commit.c Sat Jun 29 23:07:56 2002
94 +++ linux-2.4.18-chaos5/fs/jbd/commit.c Sat Jun 29 23:09:04 2002
96 transaction's t_log_list queue, and metadata buffers are on
97 the t_iobuf_list queue.
99 - Wait for the transactions in reverse order. That way we are
100 + Wait for the buffers in reverse order. That way we are
101 less likely to be woken up until all IOs have completed, and
102 so we incur less scheduling load.
106 jbd_debug(3, "JBD: commit phase 6\n");
108 - if (is_journal_aborted(journal))
109 + if (is_journal_aborted(journal)) {
110 + unlock_journal(journal);
114 /* Done it all: now write the commit record. We should have
115 * cleaned up our previous buffers by now, so if we are in abort
117 descriptor = journal_get_descriptor_buffer(journal);
119 __journal_abort_hard(journal);
120 + unlock_journal(journal);
125 /* AKPM: buglet - add `i' to tmp! */
126 for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
127 journal_header_t *tmp =
129 put_bh(bh); /* One for getblk() */
130 journal_unlock_journal_head(descriptor);
132 - lock_journal(journal);
134 /* End of a transaction! Finally, we can do checkpoint
135 processing: any buffers committed as a result of this
140 + /* Call any callbacks that had been registered for handles in this
141 + * transaction. It is up to the callback to free any allocated
144 + if (!list_empty(&commit_transaction->t_jcb)) {
145 + struct list_head *p, *n;
146 + int error = is_journal_aborted(journal);
148 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
149 + struct journal_callback *jcb;
151 + jcb = list_entry(p, struct journal_callback, jcb_list);
153 + jcb->jcb_func(jcb, error);
157 + lock_journal(journal);
159 jbd_debug(3, "JBD: commit phase 7\n");
161 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
162 --- linux-2.4.18-chaos5-pristine/fs/jbd/journal.c Sat Jun 29 23:07:56 2002
163 +++ linux-2.4.18-chaos5/fs/jbd/journal.c Sat Jun 29 23:09:04 2002
166 EXPORT_SYMBOL(journal_flush);
167 EXPORT_SYMBOL(journal_revoke);
168 +EXPORT_SYMBOL(journal_callback_set);
170 EXPORT_SYMBOL(journal_init_dev);
171 EXPORT_SYMBOL(journal_init_inode);
172 --- linux-2.4.18-chaos5-pristine/fs/jbd/transaction.c Sat Jun 29 23:07:56 2002
173 +++ linux-2.4.18-chaos5/fs/jbd/transaction.c Sat Jun 29 23:09:04 2002
175 transaction->t_state = T_RUNNING;
176 transaction->t_tid = journal->j_transaction_sequence++;
177 transaction->t_expires = jiffies + journal->j_commit_interval;
178 + INIT_LIST_HEAD(&transaction->t_jcb);
180 /* Set up the commit timer for the new transaction. */
181 J_ASSERT (!journal->j_commit_timer_active);
186 +/* Allocate a new handle. This should probably be in a slab... */
187 +static handle_t *get_handle(int nblocks)
189 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
192 + memset(handle, 0, sizeof (handle_t));
193 + handle->h_buffer_credits = nblocks;
195 + INIT_LIST_HEAD(&handle->h_jcb);
201 * Obtain a new handle.
203 @@ -227,14 +242,11 @@
208 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
210 + handle = get_handle(nblocks);
212 return ERR_PTR(-ENOMEM);
213 - memset (handle, 0, sizeof (handle_t));
215 - handle->h_buffer_credits = nblocks;
217 current->journal_info = handle;
219 err = start_this_handle(journal, handle);
220 @@ -333,14 +345,11 @@
222 if (is_journal_aborted(journal))
223 return ERR_PTR(-EIO);
225 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
227 + handle = get_handle(nblocks);
229 return ERR_PTR(-ENOMEM);
230 - memset (handle, 0, sizeof (handle_t));
232 - handle->h_buffer_credits = nblocks;
234 current->journal_info = handle;
236 err = try_start_this_handle(journal, handle);
237 @@ -1319,6 +1328,29 @@
241 + * Register a callback function for this handle. The function will be
242 + * called when the transaction that this handle is part of has been
243 + * committed to disk with the original callback data struct and the
244 + * error status of the journal as parameters. There is no guarantee of
245 + * ordering between handles within a single transaction, nor between
246 + * callbacks registered on the same handle.
248 + * The caller is responsible for allocating the journal_callback struct.
249 + * This is to allow the caller to add as much extra data to the callback
250 + * as needed, but reduce the overhead of multiple allocations. The caller
251 + * allocated struct must start with a struct journal_callback at offset 0,
252 + * and has the caller-specific data afterwards.
254 +void journal_callback_set(handle_t *handle, void (*func)(void *, int),
257 + struct journal_callback *jcb = cb_data;
259 + list_add(&jcb->jcb_list, &handle->h_jcb);
260 + jcb->jcb_func = func;
264 * All done for a particular handle.
266 * There is not much action needed here. We just return any remaining
267 @@ -1383,7 +1415,10 @@
268 wake_up(&journal->j_wait_transaction_locked);
272 + /* Move callbacks from the handle to the transaction. */
273 + list_splice(&handle->h_jcb, &transaction->t_jcb);
276 * If the handle is marked SYNC, we need to set another commit
277 * going! We also want to force a commit if the current
278 * transaction is occupying too much of the log, or if the
279 --- linux-2.4.18-chaos5-pristine/include/linux/blkdev.h Sat Jun 29 23:07:57 2002
280 +++ linux-2.4.18-chaos5/include/linux/blkdev.h Mon Jul 1 08:51:17 2002
286 +#define CONFIG_DEV_RDONLY
287 +void dev_set_rdonly(kdev_t, int);
288 +int dev_check_rdonly(kdev_t);
289 +void dev_clear_rdonly(int);
291 --- linux-2.4.18-chaos5-pristine/include/linux/jbd.h Sat Jun 29 23:07:57 2002
292 +++ linux-2.4.18-chaos5/include/linux/jbd.h Mon Jul 1 08:51:19 2002
294 return bh->b_private;
297 +#define HAVE_JOURNAL_CALLBACK_STATUS
298 +struct journal_callback {
299 + struct list_head jcb_list;
300 + void (*jcb_func)(void *cb_data, int error);
301 + /* user data goes here */
304 struct jbd_revoke_table_s;
306 /* The handle_t type represents a single atomic update being performed
311 + /* List of application registered callbacks for this handle.
312 + * The function(s) will be called after the transaction that
313 + * this handle is part of has been committed to disk.
315 + struct list_head h_jcb;
318 unsigned int h_sync: 1; /* sync-on-close */
319 unsigned int h_jdata: 1; /* force data journaling */
322 /* How many handles used this transaction? */
325 + /* List of registered callback functions for this transaction.
326 + * Called when the transaction is committed. */
327 + struct list_head t_jcb;
332 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
333 extern int journal_stop(handle_t *);
334 extern int journal_flush (journal_t *);
335 +extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int),
338 extern void journal_lock_updates (journal_t *);
339 extern void journal_unlock_updates (journal_t *);
340 --- linux-2.4.18-chaos5-pristine/kernel/ksyms.c Sat Jun 29 23:07:57 2002
341 +++ linux-2.4.18-chaos5/kernel/ksyms.c Sat Jun 29 23:09:04 2002
343 EXPORT_SYMBOL(lock_may_write);
344 EXPORT_SYMBOL(dcache_readdir);
347 +EXPORT_SYMBOL(panic_notifier_list);
348 +EXPORT_SYMBOL(pagecache_lock_cacheline);
349 +EXPORT_SYMBOL(kmem_cache_validate);
350 +EXPORT_SYMBOL(do_kern_mount);
353 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
354 EXPORT_SYMBOL(default_llseek);
355 EXPORT_SYMBOL(dentry_open);
356 --- linux-2.4.18-chaos5-pristine/include/linux/dcache.h Sat Jun 29 23:07:57 2002
357 +++ linux-2.4.18-chaos5/include/linux/dcache.h Mon Jul 1 08:51:12 2002
359 #include <asm/atomic.h>
360 #include <linux/mount.h>
363 +#define IT_CREAT (1<<1)
364 +#define IT_MKDIR (1<<2)
365 +#define IT_LINK (1<<3)
366 +#define IT_SYMLINK (1<<4)
367 +#define IT_UNLINK (1<<5)
368 +#define IT_RMDIR (1<<6)
369 +#define IT_RENAME (1<<7)
370 +#define IT_RENAME2 (1<<8)
371 +#define IT_READDIR (1<<9)
372 +#define IT_GETATTR (1<<10)
373 +#define IT_SETATTR (1<<11)
374 +#define IT_READLINK (1<<12)
375 +#define IT_MKNOD (1<<13)
376 +#define IT_LOOKUP (1<<14)
378 +struct lookup_intent {
381 + int it_disposition;
383 + struct iattr *it_iattr;
384 + __u64 it_lock_handle[2];
390 * linux/include/linux/dcache.h
393 unsigned long d_time; /* used by d_revalidate */
394 struct dentry_operations *d_op;
395 struct super_block * d_sb; /* The root of the dentry tree */
396 + struct lookup_intent *d_it;
397 unsigned long d_vfs_flags;
398 void * d_fsdata; /* fs-specific data */
399 void * d_extra_attributes; /* TUX-specific data */
401 int (*d_delete)(struct dentry *);
402 void (*d_release)(struct dentry *);
403 void (*d_iput)(struct dentry *, struct inode *);
404 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
405 + void (*d_intent_release)(struct dentry *);
408 /* the dentry parameter passed to d_hash and d_compare is the parent
409 --- linux-2.4.18-chaos5-pristine/include/linux/fs.h Sat Jun 29 23:07:57 2002
410 +++ linux-2.4.18-chaos5/include/linux/fs.h Mon Jul 1 08:51:12 2002
413 /* needed for tty driver, and maybe others */
415 + struct lookup_intent *f_intent;
417 /* preallocated helper kiobuf to speedup O_DIRECT */
418 struct kiobuf *f_iobuf;
420 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
421 extern int vfs_rmdir(struct inode *, struct dentry *);
422 extern int vfs_unlink(struct inode *, struct dentry *);
423 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
424 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
425 + struct inode *new_dir, struct dentry *new_dentry,
426 + struct lookup_intent *it);
431 struct inode_operations {
432 int (*create) (struct inode *,struct dentry *,int);
433 struct dentry * (*lookup) (struct inode *,struct dentry *);
434 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
435 int (*link) (struct dentry *,struct inode *,struct dentry *);
436 int (*unlink) (struct inode *,struct dentry *);
437 int (*symlink) (struct inode *,struct dentry *,const char *);
438 @@ -1036,6 +1040,7 @@
439 extern struct vfsmount *kern_mount(struct file_system_type *);
440 extern int may_umount(struct vfsmount *);
441 extern long do_mount(char *, char *, char *, unsigned long, void *);
442 +struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
443 extern void umount_tree(struct vfsmount *);
445 #define kern_umount mntput
446 @@ -1370,6 +1375,7 @@
447 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
449 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
450 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
451 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
452 extern int FASTCALL(path_walk(const char *, struct nameidata *));
453 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
454 @@ -1381,6 +1387,8 @@
455 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
456 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
457 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
458 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
459 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
461 extern void iput(struct inode *);
462 extern void force_delete(struct inode *);
463 --- linux-2.4.18-chaos5-pristine/fs/nfsd/vfs.c Sat Jun 29 23:07:56 2002
464 +++ linux-2.4.18-chaos5/fs/nfsd/vfs.c Sat Jun 29 23:09:04 2002
465 @@ -1298,7 +1298,7 @@
469 - err = vfs_rename(fdir, odentry, tdir, ndentry);
470 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
472 if (!err && EX_ISSYNC(tfhp->fh_export)) {
473 nfsd_sync_dir(tdentry);
474 --- linux-2.4.18-chaos5-pristine/fs/namei.c Sat Jun 29 23:07:56 2002
475 +++ linux-2.4.18-chaos5/fs/namei.c Tue Jul 2 16:06:05 2002
477 * XEmacs seems to be relying on it...
480 +void intent_release(struct dentry *de)
482 + if (de->d_op && de->d_op->d_intent_release)
483 + de->d_op->d_intent_release(de);
488 /* In order to reduce some races, while at the same time doing additional
489 * checking and hopefully speeding things up, we copy filenames to the
490 * kernel data space before using them..
491 @@ -260,10 +268,19 @@
492 * Internal lookup() using the new generic dcache.
495 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
496 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
497 + int flags, struct lookup_intent *it)
499 struct dentry * dentry = d_lookup(parent, name);
501 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
502 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
503 + !d_invalidate(dentry)) {
509 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
510 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
513 * make sure that nobody added the entry to the dcache in the meantime..
516 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
517 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
518 + int flags, struct lookup_intent *it)
520 struct dentry * result;
521 struct inode *dir = parent->d_inode;
523 result = ERR_PTR(-ENOMEM);
526 + if (dir->i_op->lookup2)
527 + result = dir->i_op->lookup2(dir, dentry, it);
529 result = dir->i_op->lookup(dir, dentry);
533 result = ERR_PTR(-ENOENT);
536 + else if (result->d_op && result->d_op->d_revalidate2) {
537 + if (!result->d_op->d_revalidate2(result, flags, it) &&
538 + !d_invalidate(result)) {
540 + result = ERR_PTR(-ENOENT);
548 * We expect 'base' to be positive and a directory.
550 -int link_path_walk(const char * name, struct nameidata *nd)
551 +int link_path_walk_it(const char *name, struct nameidata *nd,
552 + struct lookup_intent *it)
554 struct dentry *dentry;
556 @@ -524,12 +549,12 @@
559 /* This does the actual lookups.. */
560 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
561 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, it);
563 err = -EWOULDBLOCKIO;
566 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
567 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, it);
568 err = PTR_ERR(dentry);
575 - if (!inode->i_op->lookup)
576 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
579 /* here ends the main loop */
580 @@ -590,12 +615,12 @@
584 - dentry = cached_lookup(nd->dentry, &this, 0);
585 + dentry = cached_lookup(nd->dentry, &this, 0, it);
587 err = -EWOULDBLOCKIO;
590 - dentry = real_lookup(nd->dentry, &this, 0);
591 + dentry = real_lookup(nd->dentry, &this, 0, it);
592 err = PTR_ERR(dentry);
597 if (lookup_flags & LOOKUP_DIRECTORY) {
599 - if (!inode->i_op || !inode->i_op->lookup)
600 + if (!inode->i_op || (!inode->i_op->lookup &&
601 + !inode->i_op->lookup2))
609 + nd->dentry->d_it = it;
613 @@ -658,15 +685,29 @@
618 + nd->dentry->d_it = it;
622 +int link_path_walk(const char * name, struct nameidata *nd)
624 + return link_path_walk_it(name, nd, NULL);
627 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
629 + current->total_link_count = 0;
630 + return link_path_walk_it(name, nd, it);
633 int path_walk(const char * name, struct nameidata *nd)
635 current->total_link_count = 0;
636 - return link_path_walk(name, nd);
637 + return link_path_walk_it(name, nd, NULL);
642 /* returns 1 if everything is done */
643 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
648 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
649 + struct lookup_intent *it)
652 + if (path_init(path, flags, nd))
653 + error = path_walk_it(path, nd, it);
659 int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
663 * needs parent already locked. Doesn't follow mounts.
666 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
667 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
668 + struct lookup_intent *it)
670 struct dentry * dentry;
672 @@ -800,13 +853,16 @@
676 - dentry = cached_lookup(base, name, 0);
677 + dentry = cached_lookup(base, name, 0, it);
679 struct dentry *new = d_alloc(base, name);
680 dentry = ERR_PTR(-ENOMEM);
684 + if (inode->i_op->lookup2)
685 + dentry = inode->i_op->lookup2(inode, new, it);
687 dentry = inode->i_op->lookup(inode, new);
694 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
696 + return lookup_hash_it(name, base, NULL);
701 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
705 this.hash = end_name_hash(hash);
707 - return lookup_hash(&this, base);
708 + return lookup_hash_it(&this, base, NULL);
710 return ERR_PTR(-EACCES);
716 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
717 + struct lookup_intent *it)
722 + tmp = getname(name);
723 + err = PTR_ERR(tmp);
724 + if (!IS_ERR(tmp)) {
726 + if (path_init(tmp, flags, nd))
727 + err = path_walk_it(tmp, nd, it);
734 * It's inline, so penalty for filesystems that don't use sticky bit is
736 @@ -1008,7 +1086,8 @@
737 * for symlinks (where the permissions are checked later).
740 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
741 +int open_namei_it(const char *pathname, int flag, int mode,
742 + struct nameidata *nd, struct lookup_intent *it)
744 int acc_mode, error = 0;
746 @@ -1022,16 +1101,19 @@
747 * The simplest case - just a plain lookup.
749 if (!(flag & O_CREAT)) {
750 - error = path_lookup(pathname, lookup_flags(flag), nd);
751 + error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
760 * Create - we need to know the parent.
763 + it->it_op |= IT_CREAT;
764 error = path_lookup(pathname, LOOKUP_PARENT, nd);
767 @@ -1047,7 +1129,7 @@
770 down(&dir->d_inode->i_sem);
771 - dentry = lookup_hash(&nd->last, nd->dentry);
772 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
775 error = PTR_ERR(dentry);
776 @@ -1056,6 +1138,7 @@
781 /* Negative dentry, just create the file */
782 if (!dentry->d_inode) {
783 error = vfs_create(dir->d_inode, dentry,
784 @@ -1172,9 +1255,11 @@
785 if (flag & FMODE_WRITE)
788 + intent_release(dentry);
792 + intent_release(dentry);
796 @@ -1217,13 +1302,20 @@
799 down(&dir->d_inode->i_sem);
800 - dentry = lookup_hash(&nd->last, nd->dentry);
801 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
802 putname(nd->last.name);
806 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
808 + return open_namei_it(pathname, flag, mode, nd, NULL);
813 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
814 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
815 + struct lookup_intent *it)
817 struct dentry *dentry;
819 @@ -1231,7 +1323,7 @@
820 dentry = ERR_PTR(-EEXIST);
821 if (nd->last_type != LAST_NORM)
823 - dentry = lookup_hash(&nd->last, nd->dentry);
824 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
827 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
828 @@ -1277,6 +1369,7 @@
830 struct dentry * dentry;
832 + struct lookup_intent it = { IT_MKNOD , mode };
836 @@ -1287,11 +1380,12 @@
837 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
840 - dentry = lookup_create(&nd, 0);
841 + dentry = lookup_create(&nd, 0, &it);
842 error = PTR_ERR(dentry);
844 mode &= ~current->fs->umask;
845 if (!IS_ERR(dentry)) {
846 + dentry->d_it = ⁢
847 switch (mode & S_IFMT) {
848 case 0: case S_IFREG:
849 error = vfs_create(nd.dentry->d_inode,dentry,mode);
850 @@ -1305,6 +1399,7 @@
854 + intent_release(dentry);
857 up(&nd.dentry->d_inode->i_sem);
858 @@ -1345,6 +1440,7 @@
862 + struct lookup_intent it = { IT_MKDIR, mode };
864 tmp = getname(pathname);
865 error = PTR_ERR(tmp);
866 @@ -1355,11 +1451,13 @@
867 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
870 - dentry = lookup_create(&nd, 1);
871 + dentry = lookup_create(&nd, 1, &it);
872 error = PTR_ERR(dentry);
873 if (!IS_ERR(dentry)) {
874 + dentry->d_it = ⁢
875 error = vfs_mkdir(nd.dentry->d_inode, dentry,
876 mode & ~current->fs->umask);
877 + intent_release(dentry);
880 up(&nd.dentry->d_inode->i_sem);
881 @@ -1439,6 +1537,7 @@
883 struct dentry *dentry;
885 + struct lookup_intent it = { IT_RMDIR, 0 };
887 name = getname(pathname);
889 @@ -1460,10 +1559,12 @@
892 down(&nd.dentry->d_inode->i_sem);
893 - dentry = lookup_hash(&nd.last, nd.dentry);
894 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
895 error = PTR_ERR(dentry);
896 if (!IS_ERR(dentry)) {
897 + dentry->d_it = ⁢
898 error = vfs_rmdir(nd.dentry->d_inode, dentry);
899 + intent_release(dentry);
902 up(&nd.dentry->d_inode->i_sem);
903 @@ -1507,6 +1608,7 @@
905 struct dentry *dentry;
907 + struct lookup_intent it = { IT_UNLINK, 0 };
909 name = getname(pathname);
911 @@ -1519,14 +1621,16 @@
912 if (nd.last_type != LAST_NORM)
914 down(&nd.dentry->d_inode->i_sem);
915 - dentry = lookup_hash(&nd.last, nd.dentry);
916 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
917 error = PTR_ERR(dentry);
918 if (!IS_ERR(dentry)) {
919 + dentry->d_it = ⁢
920 /* Why not before? Because we want correct error value */
921 if (nd.last.name[nd.last.len])
923 error = vfs_unlink(nd.dentry->d_inode, dentry);
925 + intent_release(dentry);
928 up(&nd.dentry->d_inode->i_sem);
929 @@ -1573,6 +1677,7 @@
933 + struct lookup_intent it = { IT_SYMLINK, 0 };
935 from = getname(oldname);
937 @@ -1586,11 +1691,13 @@
938 error = path_lookup(to, LOOKUP_PARENT, &nd);
941 - dentry = lookup_create(&nd, 0);
942 + dentry = lookup_create(&nd, 0, &it);
943 error = PTR_ERR(dentry);
944 if (!IS_ERR(dentry)) {
945 + dentry->d_it = ⁢
946 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
948 + intent_release(dentry);
951 up(&nd.dentry->d_inode->i_sem);
953 @@ -1654,6 +1761,7 @@
957 + struct lookup_intent it = { IT_LINK, 0 };
959 to = getname(newname);
961 @@ -1670,10 +1778,12 @@
963 if (old_nd.mnt != nd.mnt)
965 - new_dentry = lookup_create(&nd, 0);
966 + new_dentry = lookup_create(&nd, 0, &it);
967 error = PTR_ERR(new_dentry);
968 if (!IS_ERR(new_dentry)) {
969 + new_dentry->d_it = ⁢
970 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
971 + intent_release(new_dentry);
974 up(&nd.dentry->d_inode->i_sem);
975 @@ -1714,7 +1824,8 @@
978 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
979 - struct inode *new_dir, struct dentry *new_dentry)
980 + struct inode *new_dir, struct dentry *new_dentry,
981 + struct lookup_intent *it)
984 struct inode *target;
985 @@ -1768,10 +1879,12 @@
987 double_down(&old_dir->i_zombie,
989 + new_dentry->d_it = it;
990 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
993 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
994 + intent_release(new_dentry);
997 target->i_flags |= S_DEAD;
998 @@ -1793,7 +1906,8 @@
1001 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1002 - struct inode *new_dir, struct dentry *new_dentry)
1003 + struct inode *new_dir, struct dentry *new_dentry,
1004 + struct lookup_intent *it)
1008 @@ -1820,10 +1934,12 @@
1009 DQUOT_INIT(old_dir);
1010 DQUOT_INIT(new_dir);
1011 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1012 + new_dentry->d_it = it;
1013 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1016 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1017 + intent_release(new_dentry);
1018 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1021 @@ -1835,13 +1951,14 @@
1024 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1025 - struct inode *new_dir, struct dentry *new_dentry)
1026 + struct inode *new_dir, struct dentry *new_dentry,
1027 + struct lookup_intent *it)
1030 if (S_ISDIR(old_dentry->d_inode->i_mode))
1031 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1032 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1034 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1035 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1037 if (old_dir == new_dir)
1038 inode_dir_notify(old_dir, DN_RENAME);
1039 @@ -1858,6 +1975,7 @@
1041 struct dentry * old_dir, * new_dir;
1042 struct dentry * old_dentry, *new_dentry;
1043 + struct lookup_intent it = {IT_RENAME, 0};
1044 struct nameidata oldnd, newnd;
1046 error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
1047 @@ -1883,7 +2001,7 @@
1049 double_lock(new_dir, old_dir);
1051 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1052 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1053 error = PTR_ERR(old_dentry);
1054 if (IS_ERR(old_dentry))
1056 @@ -1899,14 +2019,15 @@
1057 if (newnd.last.name[newnd.last.len])
1060 - new_dentry = lookup_hash(&newnd.last, new_dir);
1061 + it.it_op = IT_RENAME2;
1062 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1063 error = PTR_ERR(new_dentry);
1064 if (IS_ERR(new_dentry))
1068 error = vfs_rename(old_dir->d_inode, old_dentry,
1069 - new_dir->d_inode, new_dentry);
1070 + new_dir->d_inode, new_dentry, &it);
1074 --- linux-2.4.18-chaos5-pristine/fs/open.c Sat Jun 29 23:07:56 2002
1075 +++ linux-2.4.18-chaos5/fs/open.c Sat Jun 29 23:09:04 2002
1077 #include <asm/uaccess.h>
1079 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1080 +extern int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it);
1081 +extern void intent_release(struct dentry *de);
1083 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1085 @@ -118,14 +120,19 @@
1086 struct nameidata nd;
1087 struct inode * inode;
1089 + struct lookup_intent it;
1091 + it.it_op = IT_SETATTR;
1095 if (length < 0) /* sorry, but loff_t says... */
1098 - error = user_path_walk(path, &nd);
1099 + error = user_path_walk_it(path, &nd, &it);
1102 + nd.dentry->d_it = ⁢
1103 inode = nd.dentry->d_inode;
1105 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1107 put_write_access(inode);
1110 + intent_release(nd.dentry);
1114 @@ -259,10 +267,14 @@
1115 struct nameidata nd;
1116 struct inode * inode;
1117 struct iattr newattrs;
1118 + struct lookup_intent it;
1120 - error = user_path_walk(filename, &nd);
1121 + it.it_op = IT_SETATTR;
1123 + error = user_path_walk_it(filename, &nd, &it);
1126 + nd.dentry->d_it = ⁢
1127 inode = nd.dentry->d_inode;
1132 error = notify_change(nd.dentry, &newattrs);
1134 + intent_release(nd.dentry);
1138 @@ -303,11 +316,15 @@
1139 struct nameidata nd;
1140 struct inode * inode;
1141 struct iattr newattrs;
1142 + struct lookup_intent it;
1144 + it.it_op = IT_SETATTR;
1146 - error = user_path_walk(filename, &nd);
1147 + error = user_path_walk_it(filename, &nd, &it);
1151 + nd.dentry->d_it = ⁢
1152 inode = nd.dentry->d_inode;
1157 error = notify_change(nd.dentry, &newattrs);
1159 + intent_release(nd.dentry);
1164 int old_fsuid, old_fsgid;
1165 kernel_cap_t old_cap;
1167 + struct lookup_intent it;
1169 + it.it_op = IT_GETATTR;
1171 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1173 @@ -363,13 +384,14 @@
1175 current->cap_effective = current->cap_permitted;
1177 - res = user_path_walk(filename, &nd);
1178 + res = user_path_walk_it(filename, &nd, &it);
1180 res = permission(nd.dentry->d_inode, mode);
1181 /* SuS v2 requires we report a read only fs too */
1182 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1183 && !special_file(nd.dentry->d_inode->i_mode))
1185 + intent_release(nd.dentry);
1189 @@ -384,11 +406,13 @@
1192 struct nameidata nd;
1194 - error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
1195 + struct lookup_intent it = {IT_GETATTR};
1197 + error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
1201 + nd.dentry->d_it = ⁢
1202 error = permission(nd.dentry->d_inode,MAY_EXEC);
1206 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1209 + intent_release(nd.dentry);
1213 @@ -435,12 +460,14 @@
1216 struct nameidata nd;
1217 + struct lookup_intent it = {IT_GETATTR};
1219 - error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1220 - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1221 + error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1222 + LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
1226 + nd.dentry->d_it = ⁢
1227 error = permission(nd.dentry->d_inode,MAY_EXEC);
1234 + intent_release(nd.dentry);
1238 @@ -497,12 +525,15 @@
1239 struct inode * inode;
1241 struct iattr newattrs;
1242 + struct lookup_intent it;
1244 - error = user_path_walk(filename, &nd);
1245 + it.it_op = IT_SETATTR;
1246 + error = user_path_walk_it(filename, &nd, &it);
1249 inode = nd.dentry->d_inode;
1251 + nd.dentry->d_it = ⁢
1253 if (IS_RDONLY(inode))
1256 error = notify_change(nd.dentry, &newattrs);
1259 + intent_release(nd.dentry);
1263 @@ -587,10 +619,15 @@
1265 struct nameidata nd;
1267 + struct lookup_intent it;
1269 + it.it_op = IT_SETATTR;
1271 - error = user_path_walk(filename, &nd);
1272 + error = user_path_walk_it(filename, &nd, &it);
1274 + nd.dentry->d_it = ⁢
1275 error = chown_common(nd.dentry, user, group);
1276 + intent_release(nd.dentry);
1280 @@ -600,10 +637,15 @@
1282 struct nameidata nd;
1284 + struct lookup_intent it;
1286 - error = user_path_walk_link(filename, &nd);
1287 + it.it_op = IT_SETATTR;
1289 + error = user_path_walk_link_it(filename, &nd, &it);
1291 + nd.dentry->d_it = ⁢
1292 error = chown_common(nd.dentry, user, group);
1293 + intent_release(nd.dentry);
1297 @@ -637,10 +679,15 @@
1298 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1301 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1302 + struct nameidata *nd, struct lookup_intent *it);
1303 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it);
1305 struct file *filp_open(const char * filename, int flags, int mode)
1307 int namei_flags, error;
1308 struct nameidata nd;
1309 + struct lookup_intent it = {IT_OPEN, 0};
1311 namei_flags = flags;
1312 if ((namei_flags+1) & O_ACCMODE)
1313 @@ -648,14 +695,14 @@
1314 if (namei_flags & O_TRUNC)
1317 - error = open_namei(filename, namei_flags, mode, &nd);
1318 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1320 - return dentry_open(nd.dentry, nd.mnt, flags);
1321 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1323 return ERR_PTR(error);
1326 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1327 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it)
1330 struct inode *inode;
1331 @@ -712,11 +759,19 @@
1335 + intent_release(dentry);
1338 return ERR_PTR(error);
1341 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1343 + return dentry_open_it(dentry, mnt, flags, NULL);
1349 * Find an empty file descriptor entry, and mark it busy.
1351 --- linux-2.4.18-chaos5-pristine/fs/stat.c Sat Jun 29 23:07:56 2002
1352 +++ linux-2.4.18-chaos5/fs/stat.c Mon Jul 1 08:54:45 2002
1355 #include <asm/uaccess.h>
1358 +extern void intent_release(struct dentry *de);
1360 * Revalidate the inode. This is required for proper NFS attribute caching.
1362 @@ -104,10 +106,12 @@
1364 struct nameidata nd;
1366 + struct lookup_intent it = { IT_GETATTR};
1368 - error = user_path_walk(name, &nd);
1369 + error = user_path_walk_it(name, &nd, &it);
1371 error = do_getattr(nd.mnt, nd.dentry, stat);
1372 + intent_release(nd.dentry);
1376 @@ -117,10 +121,13 @@
1378 struct nameidata nd;
1380 + struct lookup_intent it = { IT_GETATTR};
1383 - error = user_path_walk_link(name, &nd);
1384 + error = user_path_walk_link_it(name, &nd, &it);
1386 error = do_getattr(nd.mnt, nd.dentry, stat);
1387 + intent_release(nd.dentry);
1391 --- linux-2.4.18-chaos5-pristine/mm/slab.c Sat Jun 29 23:07:57 2002
1392 +++ linux-2.4.18-chaos5/mm/slab.c Sat Jun 29 23:09:04 2002
1393 @@ -1207,6 +1207,58 @@
1394 * Called with the cache-lock held.
1397 +extern struct page *check_get_page(unsigned long kaddr);
1398 +struct page *page_mem_map(struct page *page);
1399 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1400 + slab_t *slabp, void * objp)
1403 + unsigned int objnr;
1405 + if (cachep->flags & SLAB_RED_ZONE) {
1406 + objp -= BYTES_PER_WORD;
1407 + if ( *(unsigned long *)objp != RED_MAGIC2)
1408 + /* Either write before start, or a double free. */
1410 + if (*(unsigned long *)(objp+cachep->objsize -
1411 + BYTES_PER_WORD) != RED_MAGIC2)
1412 + /* Either write past end, or a double free. */
1417 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1418 + if (objnr >= cachep->num)
1420 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1423 + /* Check slab's freelist to see if this obj is there. */
1424 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1432 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1434 + struct page *page = check_get_page((unsigned long)objp);
1436 + if (!VALID_PAGE(page))
1439 + if (!PageSlab(page))
1442 + /* XXX check for freed slab objects ? */
1443 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1446 + return (cachep == GET_PAGE_CACHE(page));
1450 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1451 slab_t *slabp, void * objp)
1452 --- linux-2.4.18-chaos5-pristine/arch/i386/mm/init.c Sat Jun 29 23:07:34 2002
1453 +++ linux-2.4.18-chaos5/arch/i386/mm/init.c Sat Jun 29 23:09:04 2002
1455 static unsigned long totalram_pages;
1456 static unsigned long totalhigh_pages;
1459 +struct page *check_get_page(unsigned long kaddr)
1461 +#warning FIXME: Lustre team, is this solid enough?
1462 + return virt_to_page(kaddr);
1466 int do_check_pgt_cache(int low, int high)
1469 --- linux-2.4.18-chaos5-pristine/include/linux/slab.h Sat Jun 29 23:07:57 2002
1470 +++ linux-2.4.18-chaos5/include/linux/slab.h Mon Jul 1 08:51:12 2002
1472 extern int kmem_cache_shrink(kmem_cache_t *);
1473 extern void *kmem_cache_alloc(kmem_cache_t *, int);
1474 extern void kmem_cache_free(kmem_cache_t *, void *);
1475 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
1477 extern void *kmalloc(size_t, int);
1478 extern void kfree(const void *);
1479 --- linux-2.4.18-chaos5-pristine/scripts/mkspec Sat Jun 29 23:07:58 2002
1480 +++ linux-2.4.18-chaos5/scripts/mkspec Sat Jun 29 23:09:04 2002
1483 # Back on track, again
1484 echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
1485 +echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
1486 echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"