1 --- kernel-2.4.18-pristine/arch/ia64/mm/init.c 2002-10-14 13:47:20.000000000 -0600
2 +++ kernel-2.4.18/arch/ia64/mm/init.c 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/arch/i386/mm/init.c 2002-10-14 13:47:20.000000000 -0600
17 +++ kernel-2.4.18/arch/i386/mm/init.c 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/drivers/block/blkpg.c 2002-10-14 13:47:20.000000000 -0600
32 +++ kernel-2.4.18/drivers/block/blkpg.c 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/drivers/block/loop.c 2002-10-14 13:47:20.000000000 -0600
73 +++ kernel-2.4.18/drivers/block/loop.c 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/drivers/ide/ide-disk.c 2002-10-14 13:47:20.000000000 -0600
87 +++ kernel-2.4.18/drivers/ide/ide-disk.c 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/fs/ext3/Makefile 2002-10-14 13:47:20.000000000 -0600
102 +++ kernel-2.4.18/fs/ext3/Makefile 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/fs/ext3/super.c 2002-10-14 13:47:20.000000000 -0600
113 +++ kernel-2.4.18/fs/ext3/super.c 2002-10-14 14:08:23.000000000 -0600
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 --- kernel-2.4.18-pristine/include/linux/slab.h 2002-10-14 13:47:20.000000000 -0600
124 +++ kernel-2.4.18/include/linux/slab.h 2002-10-14 14:08:23.000000000 -0600
126 extern int kmem_cache_shrink(kmem_cache_t *);
127 extern void *kmem_cache_alloc(kmem_cache_t *, int);
128 extern void kmem_cache_free(kmem_cache_t *, void *);
129 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
131 extern void *kmalloc(size_t, int);
132 extern void kfree(const void *);
133 --- kernel-2.4.18-pristine/kernel/ksyms.c 2002-10-14 13:47:20.000000000 -0600
134 +++ kernel-2.4.18/kernel/ksyms.c 2002-10-14 14:08:23.000000000 -0600
136 EXPORT_SYMBOL(lock_may_write);
137 EXPORT_SYMBOL(dcache_readdir);
140 +EXPORT_SYMBOL(panic_notifier_list);
141 +EXPORT_SYMBOL(pagecache_lock_cacheline);
142 +EXPORT_SYMBOL(do_kern_mount);
143 +EXPORT_SYMBOL(kmem_cache_validate);
145 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
146 EXPORT_SYMBOL(default_llseek);
147 EXPORT_SYMBOL(dentry_open);
148 --- kernel-2.4.18-pristine/include/linux/dcache.h 2002-10-14 13:51:28.000000000 -0600
149 +++ kernel-2.4.18/include/linux/dcache.h 2002-10-14 14:08:23.000000000 -0600
151 #include <asm/atomic.h>
152 #include <linux/mount.h>
155 +#define IT_CREAT (1<<1)
156 +#define IT_MKDIR (1<<2)
157 +#define IT_LINK (1<<3)
158 +#define IT_LINK2 (1<<4)
159 +#define IT_SYMLINK (1<<5)
160 +#define IT_UNLINK (1<<6)
161 +#define IT_RMDIR (1<<7)
162 +#define IT_RENAME (1<<8)
163 +#define IT_RENAME2 (1<<9)
164 +#define IT_READDIR (1<<10)
165 +#define IT_GETATTR (1<<11)
166 +#define IT_SETATTR (1<<12)
167 +#define IT_READLINK (1<<13)
168 +#define IT_MKNOD (1<<14)
169 +#define IT_LOOKUP (1<<15)
171 +struct lookup_intent {
174 + int it_disposition;
176 + struct iattr *it_iattr;
177 + __u64 it_lock_handle[2];
183 * linux/include/linux/dcache.h
186 unsigned long d_time; /* used by d_revalidate */
187 struct dentry_operations *d_op;
188 struct super_block * d_sb; /* The root of the dentry tree */
189 + struct lookup_intent *d_it;
190 unsigned long d_vfs_flags;
191 void * d_fsdata; /* fs-specific data */
192 void * d_extra_attributes; /* TUX-specific data */
194 int (*d_delete)(struct dentry *);
195 void (*d_release)(struct dentry *);
196 void (*d_iput)(struct dentry *, struct inode *);
197 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
198 + void (*d_intent_release)(struct dentry *, struct lookup_intent *);
201 /* the dentry parameter passed to d_hash and d_compare is the parent
202 --- kernel-2.4.18-pristine/include/linux/fs.h 2002-10-14 13:47:27.000000000 -0600
203 +++ kernel-2.4.18/include/linux/fs.h 2002-10-14 14:08:23.000000000 -0600
206 /* needed for tty driver, and maybe others */
208 + struct lookup_intent *f_intent;
210 /* preallocated helper kiobuf to speedup O_DIRECT */
211 struct kiobuf *f_iobuf;
213 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
214 extern int vfs_rmdir(struct inode *, struct dentry *);
215 extern int vfs_unlink(struct inode *, struct dentry *);
216 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
217 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
218 + struct inode *new_dir, struct dentry *new_dentry,
219 + struct lookup_intent *it);
224 struct inode_operations {
225 int (*create) (struct inode *,struct dentry *,int);
226 struct dentry * (*lookup) (struct inode *,struct dentry *);
227 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
228 int (*link) (struct dentry *,struct inode *,struct dentry *);
229 int (*unlink) (struct inode *,struct dentry *);
230 int (*symlink) (struct inode *,struct dentry *,const char *);
231 @@ -1036,6 +1040,7 @@
232 extern struct vfsmount *kern_mount(struct file_system_type *);
233 extern int may_umount(struct vfsmount *);
234 extern long do_mount(char *, char *, char *, unsigned long, void *);
235 +struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
236 extern void umount_tree(struct vfsmount *);
238 #define kern_umount mntput
239 @@ -1370,6 +1375,7 @@
240 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
242 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
243 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
244 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
245 extern int FASTCALL(path_walk(const char *, struct nameidata *));
246 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
247 @@ -1381,6 +1387,8 @@
248 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
249 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
250 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
251 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
252 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
254 extern void iput(struct inode *);
255 extern void force_delete(struct inode *);
256 --- kernel-2.4.18-pristine/fs/dcache.c 2002-10-14 13:47:27.000000000 -0600
257 +++ kernel-2.4.18/fs/dcache.c 2002-10-14 14:08:23.000000000 -0600
259 dentry->d_fsdata = NULL;
260 dentry->d_extra_attributes = NULL;
261 dentry->d_mounted = 0;
262 + dentry->d_it = NULL;
263 INIT_LIST_HEAD(&dentry->d_hash);
264 INIT_LIST_HEAD(&dentry->d_lru);
265 INIT_LIST_HEAD(&dentry->d_subdirs);
266 --- kernel-2.4.18-pristine/fs/nfsd/vfs.c 2002-10-14 13:47:27.000000000 -0600
267 +++ kernel-2.4.18/fs/nfsd/vfs.c 2002-10-14 14:08:23.000000000 -0600
268 @@ -1298,7 +1298,7 @@
272 - err = vfs_rename(fdir, odentry, tdir, ndentry);
273 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
275 if (!err && EX_ISSYNC(tfhp->fh_export)) {
276 nfsd_sync_dir(tdentry);
277 --- kernel-2.4.18-pristine/fs/namei.c 2002-10-14 13:56:44.000000000 -0600
278 +++ kernel-2.4.18/fs/namei.c 2002-10-14 14:08:23.000000000 -0600
280 * XEmacs seems to be relying on it...
283 +void intent_release(struct dentry *de, struct lookup_intent *it)
285 + if (de->d_op && de->d_op->d_intent_release)
286 + de->d_op->d_intent_release(de, it);
291 /* In order to reduce some races, while at the same time doing additional
292 * checking and hopefully speeding things up, we copy filenames to the
293 * kernel data space before using them..
294 @@ -260,10 +268,19 @@
295 * Internal lookup() using the new generic dcache.
298 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
299 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
300 + int flags, struct lookup_intent *it)
302 struct dentry * dentry = d_lookup(parent, name);
304 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
305 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
306 + !d_invalidate(dentry)) {
312 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
313 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
316 * make sure that nobody added the entry to the dcache in the meantime..
319 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
320 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
321 + int flags, struct lookup_intent *it)
323 struct dentry * result;
324 struct inode *dir = parent->d_inode;
326 result = ERR_PTR(-ENOMEM);
329 + if (dir->i_op->lookup2)
330 + result = dir->i_op->lookup2(dir, dentry, it);
332 result = dir->i_op->lookup(dir, dentry);
337 result = ERR_PTR(-ENOENT);
339 + } else if (result->d_op && result->d_op->d_revalidate2) {
340 + if (!result->d_op->d_revalidate2(result, flags, it) &&
341 + !d_invalidate(result)) {
343 + result = ERR_PTR(-ENOENT);
350 * We expect 'base' to be positive and a directory.
352 -int link_path_walk(const char * name, struct nameidata *nd)
353 +int link_path_walk_it(const char *name, struct nameidata *nd,
354 + struct lookup_intent *it)
356 struct dentry *dentry;
358 @@ -524,12 +552,12 @@
361 /* This does the actual lookups.. */
362 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
363 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
365 err = -EWOULDBLOCKIO;
368 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
369 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
370 err = PTR_ERR(dentry);
377 - if (!inode->i_op->lookup)
378 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
381 /* here ends the main loop */
382 @@ -590,12 +618,12 @@
386 - dentry = cached_lookup(nd->dentry, &this, 0);
387 + dentry = cached_lookup(nd->dentry, &this, 0, it);
389 err = -EWOULDBLOCKIO;
392 - dentry = real_lookup(nd->dentry, &this, 0);
393 + dentry = real_lookup(nd->dentry, &this, 0, it);
394 err = PTR_ERR(dentry);
399 if (lookup_flags & LOOKUP_DIRECTORY) {
401 - if (!inode->i_op || !inode->i_op->lookup)
402 + if (!inode->i_op || (!inode->i_op->lookup &&
403 + !inode->i_op->lookup2))
407 @@ -661,10 +690,21 @@
411 +int link_path_walk(const char * name, struct nameidata *nd)
413 + return link_path_walk_it(name, nd, NULL);
416 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
418 + current->total_link_count = 0;
419 + return link_path_walk_it(name, nd, it);
422 int path_walk(const char * name, struct nameidata *nd)
424 current->total_link_count = 0;
425 - return link_path_walk(name, nd);
426 + return link_path_walk_it(name, nd, NULL);
434 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
435 + struct lookup_intent *it)
438 + if (path_init(path, flags, nd))
439 + error = path_walk_it(path, nd, it);
445 int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
449 * needs parent already locked. Doesn't follow mounts.
452 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
453 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
454 + struct lookup_intent *it)
456 struct dentry * dentry;
458 @@ -800,13 +852,16 @@
462 - dentry = cached_lookup(base, name, 0);
463 + dentry = cached_lookup(base, name, 0, it);
465 struct dentry *new = d_alloc(base, name);
466 dentry = ERR_PTR(-ENOMEM);
470 + if (inode->i_op->lookup2)
471 + dentry = inode->i_op->lookup2(inode, new, it);
473 dentry = inode->i_op->lookup(inode, new);
480 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
482 + return lookup_hash_it(name, base, NULL);
487 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
491 this.hash = end_name_hash(hash);
493 - return lookup_hash(&this, base);
494 + return lookup_hash_it(&this, base, NULL);
496 return ERR_PTR(-EACCES);
502 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
503 + struct lookup_intent *it)
508 + tmp = getname(name);
509 + err = PTR_ERR(tmp);
510 + if (!IS_ERR(tmp)) {
512 + if (path_init(tmp, flags, nd))
513 + err = path_walk_it(tmp, nd, it);
520 * It's inline, so penalty for filesystems that don't use sticky bit is
522 @@ -1008,7 +1086,8 @@
523 * for symlinks (where the permissions are checked later).
526 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
527 +int open_namei_it(const char *pathname, int flag, int mode,
528 + struct nameidata *nd, struct lookup_intent *it)
530 int acc_mode, error = 0;
532 @@ -1022,7 +1101,7 @@
533 * The simplest case - just a plain lookup.
535 if (!(flag & O_CREAT)) {
536 - error = path_lookup(pathname, lookup_flags(flag), nd);
537 + error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
541 @@ -1032,6 +1111,10 @@
543 * Create - we need to know the parent.
546 + it->it_mode = mode;
547 + it->it_op |= IT_CREAT;
549 error = path_lookup(pathname, LOOKUP_PARENT, nd);
552 @@ -1047,7 +1130,7 @@
555 down(&dir->d_inode->i_sem);
556 - dentry = lookup_hash(&nd->last, nd->dentry);
557 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
560 error = PTR_ERR(dentry);
561 @@ -1056,6 +1139,7 @@
565 + it->it_mode = mode;
566 /* Negative dentry, just create the file */
567 if (!dentry->d_inode) {
568 error = vfs_create(dir->d_inode, dentry,
569 @@ -1175,8 +1259,10 @@
573 + intent_release(dentry, it);
576 + intent_release(nd->dentry, it);
580 @@ -1196,6 +1282,8 @@
582 UPDATE_ATIME(dentry->d_inode);
583 error = dentry->d_inode->i_op->follow_link(dentry, nd);
585 + intent_release(dentry, it);
589 @@ -1217,13 +1305,20 @@
592 down(&dir->d_inode->i_sem);
593 - dentry = lookup_hash(&nd->last, nd->dentry);
594 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
595 putname(nd->last.name);
599 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
601 + return open_namei_it(pathname, flag, mode, nd, NULL);
606 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
607 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
608 + struct lookup_intent *it)
610 struct dentry *dentry;
612 @@ -1231,7 +1326,7 @@
613 dentry = ERR_PTR(-EEXIST);
614 if (nd->last_type != LAST_NORM)
616 - dentry = lookup_hash(&nd->last, nd->dentry);
617 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
620 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
621 @@ -1277,6 +1372,7 @@
623 struct dentry * dentry;
625 + struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
629 @@ -1287,7 +1383,7 @@
630 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
633 - dentry = lookup_create(&nd, 0);
634 + dentry = lookup_create(&nd, 0, &it);
635 error = PTR_ERR(dentry);
637 mode &= ~current->fs->umask;
638 @@ -1305,6 +1401,7 @@
642 + intent_release(dentry, &it);
645 up(&nd.dentry->d_inode->i_sem);
646 @@ -1345,6 +1442,7 @@
650 + struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
652 tmp = getname(pathname);
653 error = PTR_ERR(tmp);
654 @@ -1355,11 +1453,12 @@
655 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
658 - dentry = lookup_create(&nd, 1);
659 + dentry = lookup_create(&nd, 1, &it);
660 error = PTR_ERR(dentry);
661 if (!IS_ERR(dentry)) {
662 error = vfs_mkdir(nd.dentry->d_inode, dentry,
663 mode & ~current->fs->umask);
664 + intent_release(dentry, &it);
667 up(&nd.dentry->d_inode->i_sem);
668 @@ -1439,6 +1538,7 @@
670 struct dentry *dentry;
672 + struct lookup_intent it = { .it_op = IT_RMDIR };
674 name = getname(pathname);
676 @@ -1460,10 +1560,11 @@
679 down(&nd.dentry->d_inode->i_sem);
680 - dentry = lookup_hash(&nd.last, nd.dentry);
681 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
682 error = PTR_ERR(dentry);
683 if (!IS_ERR(dentry)) {
684 error = vfs_rmdir(nd.dentry->d_inode, dentry);
685 + intent_release(dentry, &it);
688 up(&nd.dentry->d_inode->i_sem);
689 @@ -1507,6 +1608,7 @@
691 struct dentry *dentry;
693 + struct lookup_intent it = { .it_op = IT_UNLINK };
695 name = getname(pathname);
697 @@ -1519,7 +1621,7 @@
698 if (nd.last_type != LAST_NORM)
700 down(&nd.dentry->d_inode->i_sem);
701 - dentry = lookup_hash(&nd.last, nd.dentry);
702 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
703 error = PTR_ERR(dentry);
704 if (!IS_ERR(dentry)) {
705 /* Why not before? Because we want correct error value */
706 @@ -1527,6 +1629,7 @@
708 error = vfs_unlink(nd.dentry->d_inode, dentry);
710 + intent_release(dentry, &it);
713 up(&nd.dentry->d_inode->i_sem);
714 @@ -1573,6 +1676,7 @@
718 + struct lookup_intent it = { .it_op = IT_SYMLINK };
720 from = getname(oldname);
722 @@ -1586,10 +1690,12 @@
723 error = path_lookup(to, LOOKUP_PARENT, &nd);
726 - dentry = lookup_create(&nd, 0);
728 + dentry = lookup_create(&nd, 0, &it);
729 error = PTR_ERR(dentry);
730 if (!IS_ERR(dentry)) {
731 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
732 + intent_release(dentry, &it);
735 up(&nd.dentry->d_inode->i_sem);
736 @@ -1654,6 +1760,7 @@
740 + struct lookup_intent it = { .it_op = IT_LINK };
742 to = getname(newname);
744 @@ -1661,7 +1768,7 @@
745 struct dentry *new_dentry;
746 struct nameidata nd, old_nd;
748 - error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd);
749 + error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it);
752 error = path_lookup(to, LOOKUP_PARENT, &nd);
753 @@ -1670,10 +1778,12 @@
755 if (old_nd.mnt != nd.mnt)
757 - new_dentry = lookup_create(&nd, 0);
758 + it.it_op = IT_LINK2;
759 + new_dentry = lookup_create(&nd, 0, &it);
760 error = PTR_ERR(new_dentry);
761 if (!IS_ERR(new_dentry)) {
762 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
763 + intent_release(new_dentry, &it);
766 up(&nd.dentry->d_inode->i_sem);
767 @@ -1715,7 +1822,8 @@
770 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
771 - struct inode *new_dir, struct dentry *new_dentry)
772 + struct inode *new_dir, struct dentry *new_dentry,
773 + struct lookup_intent *it)
776 struct inode *target;
777 @@ -1773,6 +1881,7 @@
780 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
781 + intent_release(new_dentry, it);
784 target->i_flags |= S_DEAD;
785 @@ -1794,7 +1903,8 @@
788 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
789 - struct inode *new_dir, struct dentry *new_dentry)
790 + struct inode *new_dir, struct dentry *new_dentry,
791 + struct lookup_intent *it)
795 @@ -1825,6 +1935,7 @@
798 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
799 + intent_release(new_dentry, it);
800 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
803 @@ -1836,13 +1947,14 @@
806 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
807 - struct inode *new_dir, struct dentry *new_dentry)
808 + struct inode *new_dir, struct dentry *new_dentry,
809 + struct lookup_intent *it)
812 if (S_ISDIR(old_dentry->d_inode->i_mode))
813 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
814 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
816 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
817 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
819 if (old_dir == new_dir)
820 inode_dir_notify(old_dir, DN_RENAME);
821 @@ -1859,6 +1971,7 @@
823 struct dentry * old_dir, * new_dir;
824 struct dentry * old_dentry, *new_dentry;
825 + struct lookup_intent it = { .it_op = IT_RENAME };
826 struct nameidata oldnd, newnd;
828 error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
829 @@ -1884,7 +1997,7 @@
831 double_lock(new_dir, old_dir);
833 - old_dentry = lookup_hash(&oldnd.last, old_dir);
834 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
835 error = PTR_ERR(old_dentry);
836 if (IS_ERR(old_dentry))
838 @@ -1900,18 +2013,21 @@
839 if (newnd.last.name[newnd.last.len])
842 - new_dentry = lookup_hash(&newnd.last, new_dir);
843 + it.it_op = IT_RENAME2;
844 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
845 error = PTR_ERR(new_dentry);
846 if (IS_ERR(new_dentry))
850 error = vfs_rename(old_dir->d_inode, old_dentry,
851 - new_dir->d_inode, new_dentry);
852 + new_dir->d_inode, new_dentry, &it);
855 + intent_release(new_dentry, &it);
858 + intent_release(old_dentry, &it); // FIXME: release same intent twice!!!
861 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
862 --- kernel-2.4.18-pristine/fs/open.c 2002-10-14 13:47:27.000000000 -0600
863 +++ kernel-2.4.18/fs/open.c 2002-10-14 14:08:23.000000000 -0600
865 #include <asm/uaccess.h>
867 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
868 +extern int path_walk_it(const char *name, struct nameidata *nd,
869 + struct lookup_intent *it);
870 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
872 int vfs_statfs(struct super_block *sb, struct statfs *buf)
874 @@ -118,12 +121,13 @@
876 struct inode * inode;
878 + struct lookup_intent it = { .it_op = IT_SETATTR };
881 if (length < 0) /* sorry, but loff_t says... */
884 - error = user_path_walk(path, &nd);
885 + error = user_path_walk_it(path, &nd, &it);
888 inode = nd.dentry->d_inode;
890 put_write_access(inode);
893 + intent_release(nd.dentry, &it);
899 struct inode * inode;
900 struct iattr newattrs;
901 + struct lookup_intent it = { .it_op = IT_SETATTR };
903 - error = user_path_walk(filename, &nd);
904 + error = user_path_walk_it(filename, &nd, &it);
907 inode = nd.dentry->d_inode;
910 error = notify_change(nd.dentry, &newattrs);
912 + intent_release(nd.dentry, &it);
918 struct inode * inode;
919 struct iattr newattrs;
920 + struct lookup_intent it = { .it_op = IT_SETATTR };
922 - error = user_path_walk(filename, &nd);
923 + error = user_path_walk_it(filename, &nd, &it);
929 error = notify_change(nd.dentry, &newattrs);
931 + intent_release(nd.dentry, &it);
936 int old_fsuid, old_fsgid;
937 kernel_cap_t old_cap;
939 + struct lookup_intent it = { .it_op = IT_GETATTR };
941 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
943 @@ -363,13 +373,14 @@
945 current->cap_effective = current->cap_permitted;
947 - res = user_path_walk(filename, &nd);
948 + res = user_path_walk_it(filename, &nd, &it);
950 res = permission(nd.dentry->d_inode, mode);
951 /* SuS v2 requires we report a read only fs too */
952 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
953 && !special_file(nd.dentry->d_inode->i_mode))
955 + intent_release(nd.dentry, &it);
963 + struct lookup_intent it = { .it_op = IT_GETATTR };
965 - error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
966 + error = __user_walk_it(filename,
967 + LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
973 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
976 + intent_release(nd.dentry, &it);
984 + struct lookup_intent it = { .it_op = IT_GETATTR };
986 - error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
987 - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
988 + error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
989 + LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
997 + intent_release(nd.dentry, &it);
1002 struct inode * inode;
1004 struct iattr newattrs;
1005 + struct lookup_intent it = { .it_op = IT_SETATTR };
1007 - error = user_path_walk(filename, &nd);
1008 + error = user_path_walk_it(filename, &nd, &it);
1011 inode = nd.dentry->d_inode;
1013 error = notify_change(nd.dentry, &newattrs);
1016 + intent_release(nd.dentry, &it);
1020 @@ -587,10 +606,12 @@
1022 struct nameidata nd;
1024 + struct lookup_intent it = { .it_op = IT_SETATTR };
1026 - error = user_path_walk(filename, &nd);
1027 + error = user_path_walk_it(filename, &nd, &it);
1029 error = chown_common(nd.dentry, user, group);
1030 + intent_release(nd.dentry, &it);
1034 @@ -600,10 +621,12 @@
1036 struct nameidata nd;
1038 + struct lookup_intent it = { .it_op = IT_SETATTR };
1040 - error = user_path_walk_link(filename, &nd);
1041 + error = user_path_walk_link_it(filename, &nd, &it);
1043 error = chown_common(nd.dentry, user, group);
1044 + intent_release(nd.dentry, &it);
1048 @@ -637,10 +660,16 @@
1049 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1052 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1053 + struct nameidata *nd, struct lookup_intent *it);
1054 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1055 + int flags, struct lookup_intent *it);
1057 struct file *filp_open(const char * filename, int flags, int mode)
1059 int namei_flags, error;
1060 struct nameidata nd;
1061 + struct lookup_intent it = { .it_op = IT_OPEN };
1063 namei_flags = flags;
1064 if ((namei_flags+1) & O_ACCMODE)
1065 @@ -648,14 +677,15 @@
1066 if (namei_flags & O_TRUNC)
1069 - error = open_namei(filename, namei_flags, mode, &nd);
1071 - return dentry_open(nd.dentry, nd.mnt, flags);
1073 - return ERR_PTR(error);
1074 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1076 + return ERR_PTR(error);
1078 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1081 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1082 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1083 + int flags, struct lookup_intent *it)
1086 struct inode *inode;
1089 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1091 + intent_release(dentry, it);
1095 @@ -712,11 +743,17 @@
1099 + intent_release(dentry, it);
1102 return ERR_PTR(error);
1105 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1107 + return dentry_open_it(dentry, mnt, flags, NULL);
1111 * Find an empty file descriptor entry, and mark it busy.
1113 --- kernel-2.4.18-pristine/fs/stat.c 2002-10-14 13:47:27.000000000 -0600
1114 +++ kernel-2.4.18/fs/stat.c 2002-10-14 14:08:23.000000000 -0600
1117 #include <asm/uaccess.h>
1119 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1121 * Revalidate the inode. This is required for proper NFS attribute caching.
1123 @@ -104,10 +105,12 @@
1125 struct nameidata nd;
1127 + struct lookup_intent it = { .it_op = IT_GETATTR };
1129 - error = user_path_walk(name, &nd);
1130 + error = user_path_walk_it(name, &nd, &it);
1132 error = do_getattr(nd.mnt, nd.dentry, stat);
1133 + intent_release(nd.dentry, &it);
1137 @@ -117,10 +120,12 @@
1139 struct nameidata nd;
1141 + struct lookup_intent it = { .it_op = IT_GETATTR };
1143 - error = user_path_walk_link(name, &nd);
1144 + error = user_path_walk_link_it(name, &nd, &it);
1146 error = do_getattr(nd.mnt, nd.dentry, stat);
1147 + intent_release(nd.dentry, &it);
1151 --- kernel-2.4.18-pristine/mm/slab.c 2002-10-14 13:47:27.000000000 -0600
1152 +++ kernel-2.4.18/mm/slab.c 2002-10-14 14:08:23.000000000 -0600
1153 @@ -1207,6 +1207,59 @@
1154 * Called with the cache-lock held.
1157 +extern struct page *check_get_page(unsigned long kaddr);
1158 +struct page *page_mem_map(struct page *page);
1159 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1160 + slab_t *slabp, void * objp)
1163 + unsigned int objnr;
1166 + if (cachep->flags & SLAB_RED_ZONE) {
1167 + objp -= BYTES_PER_WORD;
1168 + if ( *(unsigned long *)objp != RED_MAGIC2)
1169 + /* Either write before start, or a double free. */
1171 + if (*(unsigned long *)(objp+cachep->objsize -
1172 + BYTES_PER_WORD) != RED_MAGIC2)
1173 + /* Either write past end, or a double free. */
1178 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1179 + if (objnr >= cachep->num)
1181 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1184 + /* Check slab's freelist to see if this obj is there. */
1185 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1193 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1195 + struct page *page = check_get_page((unsigned long)objp);
1197 + if (!VALID_PAGE(page))
1200 + if (!PageSlab(page))
1203 + /* XXX check for freed slab objects ? */
1204 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1207 + return (cachep == GET_PAGE_CACHE(page));
1211 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1212 slab_t *slabp, void * objp)
1213 --- kernel-2.4.18-pristine/fs/jbd/commit.c 2002-10-14 13:47:20.000000000 -0600
1214 +++ kernel-2.4.18/fs/jbd/commit.c 2002-10-14 14:08:23.000000000 -0600
1216 transaction's t_log_list queue, and metadata buffers are on
1217 the t_iobuf_list queue.
1219 - Wait for the transactions in reverse order. That way we are
1220 + Wait for the buffers in reverse order. That way we are
1221 less likely to be woken up until all IOs have completed, and
1222 so we incur less scheduling load.
1224 @@ -575,8 +575,10 @@
1226 jbd_debug(3, "JBD: commit phase 6\n");
1228 - if (is_journal_aborted(journal))
1229 + if (is_journal_aborted(journal)) {
1230 + unlock_journal(journal);
1234 /* Done it all: now write the commit record. We should have
1235 * cleaned up our previous buffers by now, so if we are in abort
1237 descriptor = journal_get_descriptor_buffer(journal);
1239 __journal_abort_hard(journal);
1240 + unlock_journal(journal);
1245 put_bh(bh); /* One for getblk() */
1246 journal_unlock_journal_head(descriptor);
1248 - lock_journal(journal);
1250 /* End of a transaction! Finally, we can do checkpoint
1251 processing: any buffers committed as a result of this
1252 @@ -618,6 +620,25 @@
1256 + /* Call any callbacks that had been registered for handles in this
1257 + * transaction. It is up to the callback to free any allocated
1260 + if (!list_empty(&commit_transaction->t_jcb)) {
1261 + struct list_head *p, *n;
1262 + int error = is_journal_aborted(journal);
1264 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
1265 + struct journal_callback *jcb;
1267 + jcb = list_entry(p, struct journal_callback, jcb_list);
1269 + jcb->jcb_func(jcb, error);
1273 + lock_journal(journal);
1275 jbd_debug(3, "JBD: commit phase 7\n");
1277 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
1278 --- kernel-2.4.18-pristine/fs/jbd/journal.c 2002-10-14 13:47:20.000000000 -0600
1279 +++ kernel-2.4.18/fs/jbd/journal.c 2002-10-14 14:08:23.000000000 -0600
1282 EXPORT_SYMBOL(journal_flush);
1283 EXPORT_SYMBOL(journal_revoke);
1284 +EXPORT_SYMBOL(journal_callback_set);
1286 EXPORT_SYMBOL(journal_init_dev);
1287 EXPORT_SYMBOL(journal_init_inode);
1288 --- kernel-2.4.18-pristine/fs/jbd/transaction.c 2002-10-14 13:47:20.000000000 -0600
1289 +++ kernel-2.4.18/fs/jbd/transaction.c 2002-10-14 14:08:23.000000000 -0600
1291 transaction->t_state = T_RUNNING;
1292 transaction->t_tid = journal->j_transaction_sequence++;
1293 transaction->t_expires = jiffies + journal->j_commit_interval;
1294 + INIT_LIST_HEAD(&transaction->t_jcb);
1296 /* Set up the commit timer for the new transaction. */
1297 J_ASSERT (!journal->j_commit_timer_active);
1298 @@ -201,6 +202,20 @@
1302 +/* Allocate a new handle. This should probably be in a slab... */
1303 +static handle_t *new_handle(int nblocks)
1305 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
1308 + memset(handle, 0, sizeof (handle_t));
1309 + handle->h_buffer_credits = nblocks;
1310 + handle->h_ref = 1;
1311 + INIT_LIST_HEAD(&handle->h_jcb);
1317 * Obtain a new handle.
1319 @@ -227,14 +242,11 @@
1324 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
1326 + handle = new_handle(nblocks);
1328 return ERR_PTR(-ENOMEM);
1329 - memset (handle, 0, sizeof (handle_t));
1331 - handle->h_buffer_credits = nblocks;
1332 - handle->h_ref = 1;
1333 current->journal_info = handle;
1335 err = start_this_handle(journal, handle);
1336 @@ -333,14 +345,11 @@
1338 if (is_journal_aborted(journal))
1339 return ERR_PTR(-EIO);
1341 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
1343 + handle = new_handle(nblocks);
1345 return ERR_PTR(-ENOMEM);
1346 - memset (handle, 0, sizeof (handle_t));
1348 - handle->h_buffer_credits = nblocks;
1349 - handle->h_ref = 1;
1350 current->journal_info = handle;
1352 err = try_start_this_handle(journal, handle);
1353 @@ -1319,6 +1328,28 @@
1357 + * Register a callback function for this handle. The function will be
1358 + * called when the transaction that this handle is part of has been
1359 + * committed to disk with the original callback data struct and the
1360 + * error status of the journal as parameters. There is no guarantee of
1361 + * ordering between handles within a single transaction, nor between
1362 + * callbacks registered on the same handle.
1364 + * The caller is responsible for allocating the journal_callback struct.
1365 + * This is to allow the caller to add as much extra data to the callback
1366 + * as needed, but reduce the overhead of multiple allocations. The caller
1367 + * allocated struct must start with a struct journal_callback at offset 0,
1368 + * and has the caller-specific data afterwards.
1370 +void journal_callback_set(handle_t *handle,
1371 + void (*func)(struct journal_callback *jcb, int error),
1372 + struct journal_callback *jcb)
1374 + list_add(&jcb->jcb_list, &handle->h_jcb);
1375 + jcb->jcb_func = func;
1379 * All done for a particular handle.
1381 * There is not much action needed here. We just return any remaining
1382 @@ -1383,7 +1414,10 @@
1383 wake_up(&journal->j_wait_transaction_locked);
1387 + /* Move callbacks from the handle to the transaction. */
1388 + list_splice(&handle->h_jcb, &transaction->t_jcb);
1391 * If the handle is marked SYNC, we need to set another commit
1392 * going! We also want to force a commit if the current
1393 * transaction is occupying too much of the log, or if the
1394 --- kernel-2.4.18-pristine/include/linux/jbd.h 2002-10-14 13:47:20.000000000 -0600
1395 +++ kernel-2.4.18/include/linux/jbd.h 2002-10-14 14:08:23.000000000 -0600
1396 @@ -257,6 +257,13 @@
1397 return bh->b_private;
1400 +#define HAVE_JOURNAL_CALLBACK_STATUS
1401 +struct journal_callback {
1402 + struct list_head jcb_list;
1403 + void (*jcb_func)(struct journal_callback *jcb, int error);
1404 + /* user data goes here */
1407 struct jbd_revoke_table_s;
1409 /* The handle_t type represents a single atomic update being performed
1410 @@ -287,6 +294,12 @@
1414 + /* List of application registered callbacks for this handle.
1415 + * The function(s) will be called after the transaction that
1416 + * this handle is part of has been committed to disk.
1418 + struct list_head h_jcb;
1421 unsigned int h_sync: 1; /* sync-on-close */
1422 unsigned int h_jdata: 1; /* force data journaling */
1423 @@ -406,6 +419,10 @@
1425 /* How many handles used this transaction? */
1428 + /* List of registered callback functions for this transaction.
1429 + * Called when the transaction is committed. */
1430 + struct list_head t_jcb;
1435 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
1436 extern int journal_stop(handle_t *);
1437 extern int journal_flush (journal_t *);
1438 +extern void journal_callback_set(handle_t *handle,
1439 + void (*fn)(struct journal_callback *,int),
1440 + struct journal_callback *jcb);
1442 extern void journal_lock_updates (journal_t *);
1443 extern void journal_unlock_updates (journal_t *);