1 --- linux-2.4.18-lustre12-pristine/arch/ia64/mm/init.c Wed Jun 26 00:15:21 2002
2 +++ linux-2.4.18-lustre12/arch/ia64/mm/init.c Tue Aug 13 11:13:09 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 --- linux-2.4.18-lustre12-pristine/arch/i386/mm/init.c Wed Jun 26 00:15:21 2002
17 +++ linux-2.4.18-lustre12/arch/i386/mm/init.c Tue Aug 13 11:13:09 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 --- linux-2.4.18-lustre12-pristine/drivers/block/blkpg.c Tue May 7 20:33:10 2002
32 +++ linux-2.4.18-lustre12/drivers/block/blkpg.c Tue Aug 13 11:13:08 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 --- linux-2.4.18-lustre12-pristine/drivers/block/loop.c Tue May 7 19:48:59 2002
73 +++ linux-2.4.18-lustre12/drivers/block/loop.c Tue Aug 13 11:13:08 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 --- linux-2.4.18-lustre12-pristine/drivers/ide/ide-disk.c Tue May 7 18:43:35 2002
87 +++ linux-2.4.18-lustre12/drivers/ide/ide-disk.c Tue Aug 13 11:13:08 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);
101 --- linux-2.4.18-lustre12-pristine/fs/ext3/Makefile Tue May 7 17:53:46 2002
102 +++ linux-2.4.18-lustre12/fs/ext3/Makefile Tue Aug 13 11:13:08 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 --- linux-2.4.18-lustre12-pristine/fs/ext3/super.c Tue May 7 19:43:17 2002
113 +++ linux-2.4.18-lustre12/fs/ext3/super.c Tue Aug 13 11:13:08 2002
114 @@ -1746,7 +1746,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 --- linux-2.4.18-lustre12-pristine/fs/jbd/commit.c Tue May 7 18:39:35 2002
124 +++ linux-2.4.18-lustre12/fs/jbd/commit.c Tue Aug 13 11:13:08 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 /* AKPM: buglet - add `i' to tmp! */
156 for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
157 journal_header_t *tmp =
159 put_bh(bh); /* One for getblk() */
160 journal_unlock_journal_head(descriptor);
162 - lock_journal(journal);
164 /* End of a transaction! Finally, we can do checkpoint
165 processing: any buffers committed as a result of this
170 + /* Call any callbacks that had been registered for handles in this
171 + * transaction. It is up to the callback to free any allocated
174 + if (!list_empty(&commit_transaction->t_jcb)) {
175 + struct list_head *p, *n;
176 + int error = is_journal_aborted(journal);
178 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
179 + struct journal_callback *jcb;
181 + jcb = list_entry(p, struct journal_callback, jcb_list);
183 + jcb->jcb_func(jcb, error);
187 + lock_journal(journal);
189 jbd_debug(3, "JBD: commit phase 7\n");
191 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
192 --- linux-2.4.18-lustre12-pristine/fs/jbd/journal.c Wed Jun 26 00:16:17 2002
193 +++ linux-2.4.18-lustre12/fs/jbd/journal.c Tue Aug 13 11:13:08 2002
196 EXPORT_SYMBOL(journal_flush);
197 EXPORT_SYMBOL(journal_revoke);
198 +EXPORT_SYMBOL(journal_callback_set);
200 EXPORT_SYMBOL(journal_init_dev);
201 EXPORT_SYMBOL(journal_init_inode);
202 --- linux-2.4.18-lustre12-pristine/fs/jbd/transaction.c Tue Jun 18 15:53:27 2002
203 +++ linux-2.4.18-lustre12/fs/jbd/transaction.c Tue Aug 13 11:13:08 2002
205 transaction->t_state = T_RUNNING;
206 transaction->t_tid = journal->j_transaction_sequence++;
207 transaction->t_expires = jiffies + journal->j_commit_interval;
208 + INIT_LIST_HEAD(&transaction->t_jcb);
210 /* Set up the commit timer for the new transaction. */
211 J_ASSERT (!journal->j_commit_timer_active);
216 +/* Allocate a new handle. This should probably be in a slab... */
217 +static handle_t *get_handle(int nblocks)
219 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
222 + memset(handle, 0, sizeof (handle_t));
223 + handle->h_buffer_credits = nblocks;
225 + INIT_LIST_HEAD(&handle->h_jcb);
231 * Obtain a new handle.
233 @@ -227,14 +242,11 @@
238 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
240 + handle = get_handle(nblocks);
242 return ERR_PTR(-ENOMEM);
243 - memset (handle, 0, sizeof (handle_t));
245 - handle->h_buffer_credits = nblocks;
247 current->journal_info = handle;
249 err = start_this_handle(journal, handle);
250 @@ -333,14 +345,11 @@
252 if (is_journal_aborted(journal))
253 return ERR_PTR(-EIO);
255 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
257 + handle = get_handle(nblocks);
259 return ERR_PTR(-ENOMEM);
260 - memset (handle, 0, sizeof (handle_t));
262 - handle->h_buffer_credits = nblocks;
264 current->journal_info = handle;
266 err = try_start_this_handle(journal, handle);
267 @@ -1319,6 +1328,29 @@
271 + * Register a callback function for this handle. The function will be
272 + * called when the transaction that this handle is part of has been
273 + * committed to disk with the original callback data struct and the
274 + * error status of the journal as parameters. There is no guarantee of
275 + * ordering between handles within a single transaction, nor between
276 + * callbacks registered on the same handle.
278 + * The caller is responsible for allocating the journal_callback struct.
279 + * This is to allow the caller to add as much extra data to the callback
280 + * as needed, but reduce the overhead of multiple allocations. The caller
281 + * allocated struct must start with a struct journal_callback at offset 0,
282 + * and has the caller-specific data afterwards.
284 +void journal_callback_set(handle_t *handle, void (*func)(void *, int),
287 + struct journal_callback *jcb = cb_data;
289 + list_add(&jcb->jcb_list, &handle->h_jcb);
290 + jcb->jcb_func = func;
294 * All done for a particular handle.
296 * There is not much action needed here. We just return any remaining
297 @@ -1383,7 +1415,10 @@
298 wake_up(&journal->j_wait_transaction_locked);
302 + /* Move callbacks from the handle to the transaction. */
303 + list_splice(&handle->h_jcb, &transaction->t_jcb);
306 * If the handle is marked SYNC, we need to set another commit
307 * going! We also want to force a commit if the current
308 * transaction is occupying too much of the log, or if the
309 --- linux-2.4.18-lustre12-pristine/include/linux/blkdev.h Wed Jun 26 00:16:30 2002
310 +++ linux-2.4.18-lustre12/include/linux/blkdev.h Tue Aug 13 11:13:08 2002
315 +#define CONFIG_DEV_RDONLY
316 +void dev_set_rdonly(kdev_t, int);
317 +int dev_check_rdonly(kdev_t);
318 +void dev_clear_rdonly(int);
320 --- linux-2.4.18-lustre12-pristine/include/linux/slab.h Wed Jun 26 00:16:34 2002
321 +++ linux-2.4.18-lustre12/include/linux/slab.h Tue Aug 13 11:13:09 2002
323 extern int kmem_cache_shrink(kmem_cache_t *);
324 extern void *kmem_cache_alloc(kmem_cache_t *, int);
325 extern void kmem_cache_free(kmem_cache_t *, void *);
326 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
328 extern void *kmalloc(size_t, int);
329 extern void kfree(const void *);
330 --- linux-2.4.18-lustre12-pristine/include/linux/jbd.h Tue May 7 19:43:17 2002
331 +++ linux-2.4.18-lustre12/include/linux/jbd.h Tue Aug 13 11:13:08 2002
333 return bh->b_private;
336 +#define HAVE_JOURNAL_CALLBACK_STATUS
337 +struct journal_callback {
338 + struct list_head jcb_list;
339 + void (*jcb_func)(void *cb_data, int error);
340 + /* user data goes here */
343 struct jbd_revoke_table_s;
345 /* The handle_t type represents a single atomic update being performed
350 + /* List of application registered callbacks for this handle.
351 + * The function(s) will be called after the transaction that
352 + * this handle is part of has been committed to disk.
354 + struct list_head h_jcb;
357 unsigned int h_sync: 1; /* sync-on-close */
358 unsigned int h_jdata: 1; /* force data journaling */
361 /* How many handles used this transaction? */
364 + /* List of registered callback functions for this transaction.
365 + * Called when the transaction is committed. */
366 + struct list_head t_jcb;
371 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
372 extern int journal_stop(handle_t *);
373 extern int journal_flush (journal_t *);
374 +extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int),
377 extern void journal_lock_updates (journal_t *);
378 extern void journal_unlock_updates (journal_t *);
379 --- linux-2.4.18-lustre12-pristine/kernel/ksyms.c Wed Jun 26 00:16:38 2002
380 +++ linux-2.4.18-lustre12/kernel/ksyms.c Tue Aug 13 11:13:08 2002
382 EXPORT_SYMBOL(lock_may_write);
383 EXPORT_SYMBOL(dcache_readdir);
386 +EXPORT_SYMBOL(panic_notifier_list);
387 +EXPORT_SYMBOL(pagecache_lock_cacheline);
388 +EXPORT_SYMBOL(do_kern_mount);
389 +EXPORT_SYMBOL(kmem_cache_validate);
391 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
392 EXPORT_SYMBOL(default_llseek);
393 EXPORT_SYMBOL(dentry_open);
394 --- linux-2.4.18-lustre12-pristine/include/linux/dcache.h Tue May 7 18:22:37 2002
395 +++ linux-2.4.18-lustre12/include/linux/dcache.h Tue Aug 13 11:13:09 2002
397 #include <asm/atomic.h>
398 #include <linux/mount.h>
401 +#define IT_CREAT (1<<1)
402 +#define IT_MKDIR (1<<2)
403 +#define IT_LINK (1<<3)
404 +#define IT_SYMLINK (1<<4)
405 +#define IT_UNLINK (1<<5)
406 +#define IT_RMDIR (1<<6)
407 +#define IT_RENAME (1<<7)
408 +#define IT_RENAME2 (1<<8)
409 +#define IT_READDIR (1<<9)
410 +#define IT_GETATTR (1<<10)
411 +#define IT_SETATTR (1<<11)
412 +#define IT_READLINK (1<<12)
413 +#define IT_MKNOD (1<<13)
414 +#define IT_LOOKUP (1<<14)
416 +struct lookup_intent {
419 + int it_disposition;
421 + struct iattr *it_iattr;
422 + __u64 it_lock_handle[2];
428 * linux/include/linux/dcache.h
431 unsigned long d_time; /* used by d_revalidate */
432 struct dentry_operations *d_op;
433 struct super_block * d_sb; /* The root of the dentry tree */
434 + struct lookup_intent *d_it;
435 unsigned long d_vfs_flags;
436 void * d_fsdata; /* fs-specific data */
437 void * d_extra_attributes; /* TUX-specific data */
439 int (*d_delete)(struct dentry *);
440 void (*d_release)(struct dentry *);
441 void (*d_iput)(struct dentry *, struct inode *);
442 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
443 + void (*d_intent_release)(struct dentry *);
446 /* the dentry parameter passed to d_hash and d_compare is the parent
447 --- linux-2.4.18-lustre12-pristine/include/linux/fs.h Wed Jun 26 00:16:31 2002
448 +++ linux-2.4.18-lustre12/include/linux/fs.h Tue Aug 13 11:13:09 2002
451 /* needed for tty driver, and maybe others */
453 + struct lookup_intent *f_intent;
455 /* preallocated helper kiobuf to speedup O_DIRECT */
456 struct kiobuf *f_iobuf;
458 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
459 extern int vfs_rmdir(struct inode *, struct dentry *);
460 extern int vfs_unlink(struct inode *, struct dentry *);
461 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
462 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
463 + struct inode *new_dir, struct dentry *new_dentry,
464 + struct lookup_intent *it);
469 struct inode_operations {
470 int (*create) (struct inode *,struct dentry *,int);
471 struct dentry * (*lookup) (struct inode *,struct dentry *);
472 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
473 int (*link) (struct dentry *,struct inode *,struct dentry *);
474 int (*unlink) (struct inode *,struct dentry *);
475 int (*symlink) (struct inode *,struct dentry *,const char *);
476 @@ -1036,6 +1040,7 @@
477 extern struct vfsmount *kern_mount(struct file_system_type *);
478 extern int may_umount(struct vfsmount *);
479 extern long do_mount(char *, char *, char *, unsigned long, void *);
480 +struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
481 extern void umount_tree(struct vfsmount *);
483 #define kern_umount mntput
484 @@ -1370,6 +1375,7 @@
485 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
487 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
488 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
489 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
490 extern int FASTCALL(path_walk(const char *, struct nameidata *));
491 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
492 @@ -1381,6 +1387,8 @@
493 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
494 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
495 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
496 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
497 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
499 extern void iput(struct inode *);
500 extern void force_delete(struct inode *);
501 --- linux-2.4.18-lustre12-pristine/fs/dcache.c Wed Jun 26 00:16:14 2002
502 +++ linux-2.4.18-lustre12/fs/dcache.c Tue Aug 13 11:13:09 2002
504 dentry->d_fsdata = NULL;
505 dentry->d_extra_attributes = NULL;
506 dentry->d_mounted = 0;
507 + dentry->d_it = NULL;
508 INIT_LIST_HEAD(&dentry->d_hash);
509 INIT_LIST_HEAD(&dentry->d_lru);
510 INIT_LIST_HEAD(&dentry->d_subdirs);
511 --- linux-2.4.18-lustre12-pristine/fs/nfsd/vfs.c Wed Jun 26 00:16:24 2002
512 +++ linux-2.4.18-lustre12/fs/nfsd/vfs.c Tue Aug 13 11:13:09 2002
513 @@ -1298,7 +1298,7 @@
517 - err = vfs_rename(fdir, odentry, tdir, ndentry);
518 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
520 if (!err && EX_ISSYNC(tfhp->fh_export)) {
521 nfsd_sync_dir(tdentry);
522 --- linux-2.4.18-lustre12-pristine/fs/namei.c Wed Jun 26 00:16:14 2002
523 +++ linux-2.4.18-lustre12/fs/namei.c Tue Aug 13 11:18:48 2002
525 * XEmacs seems to be relying on it...
528 +void intent_release(struct dentry *de)
530 + if (de->d_op && de->d_op->d_intent_release)
531 + de->d_op->d_intent_release(de);
536 /* In order to reduce some races, while at the same time doing additional
537 * checking and hopefully speeding things up, we copy filenames to the
538 * kernel data space before using them..
539 @@ -260,10 +268,19 @@
540 * Internal lookup() using the new generic dcache.
543 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
544 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
545 + int flags, struct lookup_intent *it)
547 struct dentry * dentry = d_lookup(parent, name);
549 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
550 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
551 + !d_invalidate(dentry)) {
557 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
558 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
561 * make sure that nobody added the entry to the dcache in the meantime..
564 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
565 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
566 + int flags, struct lookup_intent *it)
568 struct dentry * result;
569 struct inode *dir = parent->d_inode;
571 result = ERR_PTR(-ENOMEM);
574 + if (dir->i_op->lookup2)
575 + result = dir->i_op->lookup2(dir, dentry, it);
577 result = dir->i_op->lookup(dir, dentry);
582 result = ERR_PTR(-ENOENT);
584 + } else if (result->d_op && result->d_op->d_revalidate2) {
585 + if (!result->d_op->d_revalidate2(result, flags, it) &&
586 + !d_invalidate(result)) {
588 + result = ERR_PTR(-ENOENT);
595 * We expect 'base' to be positive and a directory.
597 -int link_path_walk(const char * name, struct nameidata *nd)
598 +int link_path_walk_it(const char *name, struct nameidata *nd,
599 + struct lookup_intent *it)
601 struct dentry *dentry;
603 @@ -524,12 +553,12 @@
606 /* This does the actual lookups.. */
607 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
608 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
610 err = -EWOULDBLOCKIO;
613 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
614 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
615 err = PTR_ERR(dentry);
622 - if (!inode->i_op->lookup)
623 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
626 /* here ends the main loop */
627 @@ -590,12 +619,12 @@
631 - dentry = cached_lookup(nd->dentry, &this, 0);
632 + dentry = cached_lookup(nd->dentry, &this, 0, it);
634 err = -EWOULDBLOCKIO;
637 - dentry = real_lookup(nd->dentry, &this, 0);
638 + dentry = real_lookup(nd->dentry, &this, 0, it);
639 err = PTR_ERR(dentry);
644 if (lookup_flags & LOOKUP_DIRECTORY) {
646 - if (!inode->i_op || !inode->i_op->lookup)
647 + if (!inode->i_op || (!inode->i_op->lookup &&
648 + !inode->i_op->lookup2))
656 + nd->dentry->d_it = it;
660 @@ -658,15 +689,29 @@
665 + nd->dentry->d_it = it;
669 +int link_path_walk(const char * name, struct nameidata *nd)
671 + return link_path_walk_it(name, nd, NULL);
674 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
676 + current->total_link_count = 0;
677 + return link_path_walk_it(name, nd, it);
680 int path_walk(const char * name, struct nameidata *nd)
682 current->total_link_count = 0;
683 - return link_path_walk(name, nd);
684 + return link_path_walk_it(name, nd, NULL);
689 /* returns 1 if everything is done */
690 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
695 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
696 + struct lookup_intent *it)
699 + if (path_init(path, flags, nd))
700 + error = path_walk_it(path, nd, it);
706 int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
710 * needs parent already locked. Doesn't follow mounts.
713 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
714 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
715 + struct lookup_intent *it)
717 struct dentry * dentry;
719 @@ -800,13 +857,16 @@
723 - dentry = cached_lookup(base, name, 0);
724 + dentry = cached_lookup(base, name, 0, it);
726 struct dentry *new = d_alloc(base, name);
727 dentry = ERR_PTR(-ENOMEM);
731 + if (inode->i_op->lookup2)
732 + dentry = inode->i_op->lookup2(inode, new, it);
734 dentry = inode->i_op->lookup(inode, new);
741 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
743 + return lookup_hash_it(name, base, NULL);
748 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
752 this.hash = end_name_hash(hash);
754 - return lookup_hash(&this, base);
755 + return lookup_hash_it(&this, base, NULL);
757 return ERR_PTR(-EACCES);
763 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
764 + struct lookup_intent *it)
769 + tmp = getname(name);
770 + err = PTR_ERR(tmp);
771 + if (!IS_ERR(tmp)) {
773 + if (path_init(tmp, flags, nd))
774 + err = path_walk_it(tmp, nd, it);
781 * It's inline, so penalty for filesystems that don't use sticky bit is
783 @@ -1008,7 +1091,8 @@
784 * for symlinks (where the permissions are checked later).
787 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
788 +int open_namei_it(const char *pathname, int flag, int mode,
789 + struct nameidata *nd, struct lookup_intent *it)
791 int acc_mode, error = 0;
793 @@ -1022,16 +1106,21 @@
794 * The simplest case - just a plain lookup.
796 if (!(flag & O_CREAT)) {
797 - error = path_lookup(pathname, lookup_flags(flag), nd);
798 + error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
807 * Create - we need to know the parent.
810 + it->it_mode = mode;
811 + it->it_op |= IT_CREAT;
813 error = path_lookup(pathname, LOOKUP_PARENT, nd);
816 @@ -1047,7 +1136,7 @@
819 down(&dir->d_inode->i_sem);
820 - dentry = lookup_hash(&nd->last, nd->dentry);
821 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
824 error = PTR_ERR(dentry);
825 @@ -1056,6 +1145,8 @@
830 + dentry->d_it->it_mode = mode;
831 /* Negative dentry, just create the file */
832 if (!dentry->d_inode) {
833 error = vfs_create(dir->d_inode, dentry,
834 @@ -1175,8 +1266,10 @@
838 + intent_release(dentry);
841 + intent_release(nd->dentry);
845 @@ -1196,6 +1289,8 @@
847 UPDATE_ATIME(dentry->d_inode);
848 error = dentry->d_inode->i_op->follow_link(dentry, nd);
850 + intent_release(dentry);
854 @@ -1217,13 +1312,20 @@
857 down(&dir->d_inode->i_sem);
858 - dentry = lookup_hash(&nd->last, nd->dentry);
859 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
860 putname(nd->last.name);
864 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
866 + return open_namei_it(pathname, flag, mode, nd, NULL);
871 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
872 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
873 + struct lookup_intent *it)
875 struct dentry *dentry;
877 @@ -1231,7 +1333,7 @@
878 dentry = ERR_PTR(-EEXIST);
879 if (nd->last_type != LAST_NORM)
881 - dentry = lookup_hash(&nd->last, nd->dentry);
882 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
885 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
886 @@ -1277,6 +1379,7 @@
888 struct dentry * dentry;
890 + struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
894 @@ -1287,11 +1390,12 @@
895 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
898 - dentry = lookup_create(&nd, 0);
899 + dentry = lookup_create(&nd, 0, &it);
900 error = PTR_ERR(dentry);
902 mode &= ~current->fs->umask;
903 if (!IS_ERR(dentry)) {
904 + dentry->d_it = ⁢
905 switch (mode & S_IFMT) {
906 case 0: case S_IFREG:
907 error = vfs_create(nd.dentry->d_inode,dentry,mode);
908 @@ -1305,6 +1409,7 @@
912 + intent_release(dentry);
915 up(&nd.dentry->d_inode->i_sem);
916 @@ -1345,6 +1450,7 @@
920 + struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
922 tmp = getname(pathname);
923 error = PTR_ERR(tmp);
924 @@ -1355,11 +1461,13 @@
925 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
928 - dentry = lookup_create(&nd, 1);
929 + dentry = lookup_create(&nd, 1, &it);
930 error = PTR_ERR(dentry);
931 if (!IS_ERR(dentry)) {
932 + dentry->d_it = ⁢
933 error = vfs_mkdir(nd.dentry->d_inode, dentry,
934 mode & ~current->fs->umask);
935 + intent_release(dentry);
938 up(&nd.dentry->d_inode->i_sem);
939 @@ -1439,6 +1547,7 @@
941 struct dentry *dentry;
943 + struct lookup_intent it = { .it_op = IT_RMDIR };
945 name = getname(pathname);
947 @@ -1460,10 +1569,12 @@
950 down(&nd.dentry->d_inode->i_sem);
951 - dentry = lookup_hash(&nd.last, nd.dentry);
952 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
953 error = PTR_ERR(dentry);
954 if (!IS_ERR(dentry)) {
955 + dentry->d_it = ⁢
956 error = vfs_rmdir(nd.dentry->d_inode, dentry);
957 + intent_release(dentry);
960 up(&nd.dentry->d_inode->i_sem);
961 @@ -1507,6 +1618,7 @@
963 struct dentry *dentry;
965 + struct lookup_intent it = { .it_op = IT_UNLINK };
967 name = getname(pathname);
969 @@ -1519,14 +1631,16 @@
970 if (nd.last_type != LAST_NORM)
972 down(&nd.dentry->d_inode->i_sem);
973 - dentry = lookup_hash(&nd.last, nd.dentry);
974 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
975 error = PTR_ERR(dentry);
976 if (!IS_ERR(dentry)) {
977 + dentry->d_it = ⁢
978 /* Why not before? Because we want correct error value */
979 if (nd.last.name[nd.last.len])
981 error = vfs_unlink(nd.dentry->d_inode, dentry);
983 + intent_release(dentry);
986 up(&nd.dentry->d_inode->i_sem);
987 @@ -1573,6 +1687,7 @@
991 + struct lookup_intent it = { .it_op = IT_SYMLINK };
993 from = getname(oldname);
995 @@ -1586,10 +1701,13 @@
996 error = path_lookup(to, LOOKUP_PARENT, &nd);
999 - dentry = lookup_create(&nd, 0);
1000 + it.it_data = from;
1001 + dentry = lookup_create(&nd, 0, &it);
1002 error = PTR_ERR(dentry);
1003 if (!IS_ERR(dentry)) {
1004 + dentry->d_it = ⁢
1005 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1006 + intent_release(dentry);
1009 up(&nd.dentry->d_inode->i_sem);
1010 @@ -1654,6 +1771,7 @@
1014 + struct lookup_intent it = { .it_op = IT_LINK };
1016 to = getname(newname);
1017 error = PTR_ERR(to);
1018 @@ -1670,10 +1788,12 @@
1020 if (old_nd.mnt != nd.mnt)
1022 - new_dentry = lookup_create(&nd, 0);
1023 + new_dentry = lookup_create(&nd, 0, &it);
1024 error = PTR_ERR(new_dentry);
1025 if (!IS_ERR(new_dentry)) {
1026 + new_dentry->d_it = ⁢
1027 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1028 + intent_release(new_dentry);
1031 up(&nd.dentry->d_inode->i_sem);
1032 @@ -1714,7 +1834,8 @@
1035 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1036 - struct inode *new_dir, struct dentry *new_dentry)
1037 + struct inode *new_dir, struct dentry *new_dentry,
1038 + struct lookup_intent *it)
1041 struct inode *target;
1042 @@ -1768,10 +1889,12 @@
1044 double_down(&old_dir->i_zombie,
1045 &new_dir->i_zombie);
1046 + new_dentry->d_it = it;
1047 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1050 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1051 + intent_release(new_dentry);
1054 target->i_flags |= S_DEAD;
1055 @@ -1793,7 +1916,8 @@
1058 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1059 - struct inode *new_dir, struct dentry *new_dentry)
1060 + struct inode *new_dir, struct dentry *new_dentry,
1061 + struct lookup_intent *it)
1065 @@ -1820,10 +1944,12 @@
1066 DQUOT_INIT(old_dir);
1067 DQUOT_INIT(new_dir);
1068 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1069 + new_dentry->d_it = it;
1070 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1073 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1074 + intent_release(new_dentry);
1075 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1078 @@ -1835,13 +1961,14 @@
1081 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1082 - struct inode *new_dir, struct dentry *new_dentry)
1083 + struct inode *new_dir, struct dentry *new_dentry,
1084 + struct lookup_intent *it)
1087 if (S_ISDIR(old_dentry->d_inode->i_mode))
1088 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1089 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1091 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1092 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1094 if (old_dir == new_dir)
1095 inode_dir_notify(old_dir, DN_RENAME);
1096 @@ -1858,6 +1985,7 @@
1098 struct dentry * old_dir, * new_dir;
1099 struct dentry * old_dentry, *new_dentry;
1100 + struct lookup_intent it = { .it_op = IT_RENAME };
1101 struct nameidata oldnd, newnd;
1103 error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
1104 @@ -1883,7 +2011,7 @@
1106 double_lock(new_dir, old_dir);
1108 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1109 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1110 error = PTR_ERR(old_dentry);
1111 if (IS_ERR(old_dentry))
1113 @@ -1899,18 +2027,21 @@
1114 if (newnd.last.name[newnd.last.len])
1117 - new_dentry = lookup_hash(&newnd.last, new_dir);
1118 + it.it_op = IT_RENAME2;
1119 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1120 error = PTR_ERR(new_dentry);
1121 if (IS_ERR(new_dentry))
1125 error = vfs_rename(old_dir->d_inode, old_dentry,
1126 - new_dir->d_inode, new_dentry);
1127 + new_dir->d_inode, new_dentry, &it);
1130 + intent_release(new_dentry);
1133 + intent_release(old_dentry);
1136 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1137 --- linux-2.4.18-lustre12-pristine/fs/open.c Wed Jun 26 00:16:14 2002
1138 +++ linux-2.4.18-lustre12/fs/open.c Tue Aug 13 11:19:36 2002
1140 #include <asm/uaccess.h>
1142 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1143 +extern int path_walk_it(const char *name, struct nameidata *nd,
1144 + struct lookup_intent *it);
1145 +extern void intent_release(struct dentry *de);
1147 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1149 @@ -118,14 +120,16 @@
1150 struct nameidata nd;
1151 struct inode * inode;
1153 + struct lookup_intent it = { .it_op = IT_SETATTR };
1156 if (length < 0) /* sorry, but loff_t says... */
1159 - error = user_path_walk(path, &nd);
1160 + error = user_path_walk_it(path, &nd, &it);
1163 + nd.dentry->d_it = ⁢
1164 inode = nd.dentry->d_inode;
1166 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1168 put_write_access(inode);
1171 + intent_release(nd.dentry);
1175 @@ -259,10 +264,12 @@
1176 struct nameidata nd;
1177 struct inode * inode;
1178 struct iattr newattrs;
1179 + struct lookup_intent it = { .it_op = IT_SETATTR };
1181 - error = user_path_walk(filename, &nd);
1182 + error = user_path_walk_it(filename, &nd, &it);
1185 + nd.dentry->d_it = ⁢
1186 inode = nd.dentry->d_inode;
1191 error = notify_change(nd.dentry, &newattrs);
1193 + intent_release(nd.dentry);
1197 @@ -303,11 +311,13 @@
1198 struct nameidata nd;
1199 struct inode * inode;
1200 struct iattr newattrs;
1201 + struct lookup_intent it = { .it_op = IT_SETATTR };
1203 - error = user_path_walk(filename, &nd);
1204 + error = user_path_walk_it(filename, &nd, &it);
1208 + nd.dentry->d_it = ⁢
1209 inode = nd.dentry->d_inode;
1214 error = notify_change(nd.dentry, &newattrs);
1216 + intent_release(nd.dentry);
1221 int old_fsuid, old_fsgid;
1222 kernel_cap_t old_cap;
1224 + struct lookup_intent it = { .it_op = IT_GETATTR };
1226 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1228 @@ -363,13 +375,14 @@
1230 current->cap_effective = current->cap_permitted;
1232 - res = user_path_walk(filename, &nd);
1233 + res = user_path_walk_it(filename, &nd, &it);
1235 res = permission(nd.dentry->d_inode, mode);
1236 /* SuS v2 requires we report a read only fs too */
1237 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1238 && !special_file(nd.dentry->d_inode->i_mode))
1240 + intent_release(nd.dentry);
1244 @@ -384,11 +397,15 @@
1247 struct nameidata nd;
1248 + struct lookup_intent it = { .it_op = IT_GETATTR };
1250 - error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
1251 + error = __user_walk_it(filename,
1252 + LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
1257 + nd.dentry->d_it = ⁢
1258 error = permission(nd.dentry->d_inode,MAY_EXEC);
1262 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1265 + intent_release(nd.dentry);
1269 @@ -435,12 +451,14 @@
1272 struct nameidata nd;
1273 + struct lookup_intent it = { .it_op = IT_GETATTR };
1275 - error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1276 - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1277 + error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1278 + LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
1282 + nd.dentry->d_it = ⁢
1283 error = permission(nd.dentry->d_inode,MAY_EXEC);
1290 + intent_release(nd.dentry);
1294 @@ -497,12 +516,14 @@
1295 struct inode * inode;
1297 struct iattr newattrs;
1298 + struct lookup_intent it = { .it_op = IT_SETATTR };
1300 - error = user_path_walk(filename, &nd);
1301 + error = user_path_walk_it(filename, &nd, &it);
1304 inode = nd.dentry->d_inode;
1306 + nd.dentry->d_it = ⁢
1308 if (IS_RDONLY(inode))
1311 error = notify_change(nd.dentry, &newattrs);
1314 + intent_release(nd.dentry);
1318 @@ -587,10 +609,13 @@
1320 struct nameidata nd;
1322 + struct lookup_intent it = { .it_op = IT_SETATTR };
1324 - error = user_path_walk(filename, &nd);
1325 + error = user_path_walk_it(filename, &nd, &it);
1327 + nd.dentry->d_it = ⁢
1328 error = chown_common(nd.dentry, user, group);
1329 + intent_release(nd.dentry);
1333 @@ -600,10 +625,13 @@
1335 struct nameidata nd;
1337 + struct lookup_intent it = { .it_op = IT_SETATTR };
1339 - error = user_path_walk_link(filename, &nd);
1340 + error = user_path_walk_link_it(filename, &nd, &it);
1342 + nd.dentry->d_it = ⁢
1343 error = chown_common(nd.dentry, user, group);
1344 + intent_release(nd.dentry);
1348 @@ -637,10 +665,16 @@
1349 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1352 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1353 + struct nameidata *nd, struct lookup_intent *it);
1354 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1355 + int flags, struct lookup_intent *it);
1357 struct file *filp_open(const char * filename, int flags, int mode)
1359 int namei_flags, error;
1360 struct nameidata nd;
1361 + struct lookup_intent it = { .it_op = IT_OPEN };
1363 namei_flags = flags;
1364 if ((namei_flags+1) & O_ACCMODE)
1365 @@ -648,14 +681,15 @@
1366 if (namei_flags & O_TRUNC)
1369 - error = open_namei(filename, namei_flags, mode, &nd);
1371 - return dentry_open(nd.dentry, nd.mnt, flags);
1372 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1374 + return ERR_PTR(error);
1376 - return ERR_PTR(error);
1377 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1380 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1381 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1382 + int flags, struct lookup_intent *it)
1385 struct inode *inode;
1388 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1390 + intent_release(dentry);
1394 @@ -712,11 +746,17 @@
1398 + intent_release(dentry);
1401 return ERR_PTR(error);
1404 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1406 + return dentry_open_it(dentry, mnt, flags, NULL);
1410 * Find an empty file descriptor entry, and mark it busy.
1412 --- linux-2.4.18-lustre12-pristine/fs/stat.c Tue May 7 19:40:30 2002
1413 +++ linux-2.4.18-lustre12/fs/stat.c Tue Aug 13 11:13:09 2002
1416 #include <asm/uaccess.h>
1418 +extern void intent_release(struct dentry *de);
1420 * Revalidate the inode. This is required for proper NFS attribute caching.
1422 @@ -104,10 +106,12 @@
1424 struct nameidata nd;
1426 + struct lookup_intent it = { .it_op = IT_GETATTR };
1428 - error = user_path_walk(name, &nd);
1429 + error = user_path_walk_it(name, &nd, &it);
1431 error = do_getattr(nd.mnt, nd.dentry, stat);
1432 + intent_release(nd.dentry);
1436 @@ -117,10 +121,12 @@
1438 struct nameidata nd;
1440 + struct lookup_intent it = { .it_op = IT_GETATTR };
1442 - error = user_path_walk_link(name, &nd);
1443 + error = user_path_walk_link_it(name, &nd, &it);
1445 error = do_getattr(nd.mnt, nd.dentry, stat);
1446 + intent_release(nd.dentry);
1450 --- linux-2.4.18-lustre12-pristine/mm/slab.c Wed Jun 26 00:16:40 2002
1451 +++ linux-2.4.18-lustre12/mm/slab.c Tue Aug 13 11:13:09 2002
1452 @@ -1207,6 +1207,59 @@
1453 * Called with the cache-lock held.
1456 +extern struct page *check_get_page(unsigned long kaddr);
1457 +struct page *page_mem_map(struct page *page);
1458 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1459 + slab_t *slabp, void * objp)
1462 + unsigned int objnr;
1465 + if (cachep->flags & SLAB_RED_ZONE) {
1466 + objp -= BYTES_PER_WORD;
1467 + if ( *(unsigned long *)objp != RED_MAGIC2)
1468 + /* Either write before start, or a double free. */
1470 + if (*(unsigned long *)(objp+cachep->objsize -
1471 + BYTES_PER_WORD) != RED_MAGIC2)
1472 + /* Either write past end, or a double free. */
1477 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1478 + if (objnr >= cachep->num)
1480 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1483 + /* Check slab's freelist to see if this obj is there. */
1484 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1492 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1494 + struct page *page = check_get_page((unsigned long)objp);
1496 + if (!VALID_PAGE(page))
1499 + if (!PageSlab(page))
1502 + /* XXX check for freed slab objects ? */
1503 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1506 + return (cachep == GET_PAGE_CACHE(page));
1510 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1511 slab_t *slabp, void * objp)
1512 --- linux-2.4.18-lustre12-pristine/scripts/mkspec Wed Jun 26 00:16:49 2002
1513 +++ linux-2.4.18-lustre12/scripts/mkspec Tue Aug 13 11:13:09 2002
1516 # Back on track, again
1517 echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
1518 +echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
1519 echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"