1 arch/i386/mm/init.c | 6 +
2 arch/ia64/mm/init.c | 6 +
3 drivers/block/blkpg.c | 35 ++++++
4 drivers/block/loop.c | 5
5 drivers/ide/ide-disk.c | 6 +
9 fs/jbd/commit.c | 27 ++++-
11 fs/jbd/transaction.c | 56 ++++++++--
12 fs/namei.c | 215 ++++++++++++++++++++++++++++++++---------
14 fs/open.c | 63 +++++++++---
16 include/linux/blkdev.h | 4
17 include/linux/dcache.h | 31 +++++
18 include/linux/fs.h | 14 ++
19 include/linux/jbd.h | 20 +++
20 include/linux/lustre_version.h | 1
21 include/linux/slab.h | 1
23 mm/slab.c | 53 ++++++++++
24 23 files changed, 502 insertions(+), 86 deletions(-)
26 --- /dev/null Fri Aug 30 17:31:37 2002
27 +++ linux-2.4.19-root/include/linux/lustre_version.h Sun Dec 15 16:58:43 2002
29 +#define LUSTRE_KERNEL_VERSION 4
30 --- linux-2.4.19/arch/ia64/mm/init.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
31 +++ linux-2.4.19-root/arch/ia64/mm/init.c Sun Dec 15 16:58:43 2002
32 @@ -37,6 +37,12 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF
34 static unsigned long totalram_pages;
36 +struct page *check_get_page(unsigned long kaddr)
38 +#warning FIXME: Lustre team, is this solid?
39 + return virt_to_page(kaddr);
43 do_check_pgt_cache (int low, int high)
45 --- linux-2.4.19/arch/i386/mm/init.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
46 +++ linux-2.4.19-root/arch/i386/mm/init.c Sun Dec 15 16:58:43 2002
47 @@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn
48 static unsigned long totalram_pages;
49 static unsigned long totalhigh_pages;
51 +struct page *check_get_page(unsigned long kaddr)
53 +#warning FIXME: Lustre team, is this solid?
54 + return virt_to_page(kaddr);
57 int do_check_pgt_cache(int low, int high)
60 --- linux-2.4.19/drivers/block/blkpg.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
61 +++ linux-2.4.19-root/drivers/block/blkpg.c Sun Dec 15 16:58:43 2002
62 @@ -296,3 +296,38 @@ int blk_ioctl(kdev_t dev, unsigned int c
65 EXPORT_SYMBOL(blk_ioctl);
67 +#define NUM_DEV_NO_WRITE 16
68 +static int dev_no_write[NUM_DEV_NO_WRITE];
71 + * Debug code for turning block devices "read-only" (will discard writes
72 + * silently). This is for filesystem crash/recovery testing.
74 +void dev_set_rdonly(kdev_t dev, int no_write)
77 + printk(KERN_WARNING "Turning device %s read-only\n",
79 + dev_no_write[no_write] = 0xdead0000 + dev;
83 +int dev_check_rdonly(kdev_t dev) {
86 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
87 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
88 + dev == (dev_no_write[i] & 0xffff))
94 +void dev_clear_rdonly(int no_write) {
95 + dev_no_write[no_write] = 0;
98 +EXPORT_SYMBOL(dev_set_rdonly);
99 +EXPORT_SYMBOL(dev_check_rdonly);
100 +EXPORT_SYMBOL(dev_clear_rdonly);
101 --- linux-2.4.19/drivers/block/loop.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
102 +++ linux-2.4.19-root/drivers/block/loop.c Sun Dec 15 16:58:43 2002
103 @@ -474,6 +474,11 @@ static int loop_make_request(request_que
104 spin_unlock_irq(&lo->lo_lock);
107 +#ifdef CONFIG_DEV_RDONLY
108 + if (dev_check_rdonly(rbh->b_rdev))
112 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
114 } else if (rw == READA) {
115 --- linux-2.4.19/drivers/ide/ide-disk.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
116 +++ linux-2.4.19-root/drivers/ide/ide-disk.c Sun Dec 15 16:58:43 2002
117 @@ -551,6 +551,12 @@ static ide_startstop_t lba_48_rw_disk (i
119 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
121 +#ifdef CONFIG_DEV_RDONLY
122 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
123 + ide_end_request(1, HWGROUP(drive));
124 + return ide_stopped;
128 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
130 --- linux-2.4.19/fs/ext3/Makefile~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
131 +++ linux-2.4.19-root/fs/ext3/Makefile Sun Dec 15 16:58:43 2002
136 +export-objs := super.o
138 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
139 ioctl.o namei.o super.o symlink.o
141 --- linux-2.4.19/fs/ext3/super.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
142 +++ linux-2.4.19-root/fs/ext3/super.c Sun Dec 15 16:58:43 2002
143 @@ -1744,7 +1744,7 @@ static void __exit exit_ext3_fs(void)
144 unregister_filesystem(&ext3_fs_type);
148 +EXPORT_SYMBOL(ext3_bread);
150 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
151 MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
152 --- linux-2.4.19/fs/jbd/commit.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
153 +++ linux-2.4.19-root/fs/jbd/commit.c Sun Dec 15 16:58:43 2002
154 @@ -475,7 +475,7 @@ start_journal_io:
155 transaction's t_log_list queue, and metadata buffers are on
156 the t_iobuf_list queue.
158 - Wait for the transactions in reverse order. That way we are
159 + Wait for the buffers in reverse order. That way we are
160 less likely to be woken up until all IOs have completed, and
161 so we incur less scheduling load.
163 @@ -566,8 +566,10 @@ start_journal_io:
165 jbd_debug(3, "JBD: commit phase 6\n");
167 - if (is_journal_aborted(journal))
168 + if (is_journal_aborted(journal)) {
169 + unlock_journal(journal);
173 /* Done it all: now write the commit record. We should have
174 * cleaned up our previous buffers by now, so if we are in abort
175 @@ -577,6 +579,7 @@ start_journal_io:
176 descriptor = journal_get_descriptor_buffer(journal);
178 __journal_abort_hard(journal);
179 + unlock_journal(journal);
183 @@ -600,7 +603,6 @@ start_journal_io:
184 put_bh(bh); /* One for getblk() */
185 journal_unlock_journal_head(descriptor);
187 - lock_journal(journal);
189 /* End of a transaction! Finally, we can do checkpoint
190 processing: any buffers committed as a result of this
191 @@ -609,6 +611,25 @@ start_journal_io:
195 + /* Call any callbacks that had been registered for handles in this
196 + * transaction. It is up to the callback to free any allocated
199 + if (!list_empty(&commit_transaction->t_jcb)) {
200 + struct list_head *p, *n;
201 + int error = is_journal_aborted(journal);
203 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
204 + struct journal_callback *jcb;
206 + jcb = list_entry(p, struct journal_callback, jcb_list);
208 + jcb->jcb_func(jcb, error);
212 + lock_journal(journal);
214 jbd_debug(3, "JBD: commit phase 7\n");
216 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
217 --- linux-2.4.19/fs/jbd/journal.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
218 +++ linux-2.4.19-root/fs/jbd/journal.c Sun Dec 15 16:58:43 2002
219 @@ -58,6 +58,7 @@ EXPORT_SYMBOL(journal_sync_buffer);
221 EXPORT_SYMBOL(journal_flush);
222 EXPORT_SYMBOL(journal_revoke);
223 +EXPORT_SYMBOL(journal_callback_set);
225 EXPORT_SYMBOL(journal_init_dev);
226 EXPORT_SYMBOL(journal_init_inode);
227 --- linux-2.4.19/fs/jbd/transaction.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
228 +++ linux-2.4.19-root/fs/jbd/transaction.c Sun Dec 15 16:58:43 2002
229 @@ -57,6 +57,7 @@ static transaction_t * get_transaction (
230 transaction->t_state = T_RUNNING;
231 transaction->t_tid = journal->j_transaction_sequence++;
232 transaction->t_expires = jiffies + journal->j_commit_interval;
233 + INIT_LIST_HEAD(&transaction->t_jcb);
235 /* Set up the commit timer for the new transaction. */
236 J_ASSERT (!journal->j_commit_timer_active);
237 @@ -201,6 +202,20 @@ repeat_locked:
241 +/* Allocate a new handle. This should probably be in a slab... */
242 +static handle_t *new_handle(int nblocks)
244 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
247 + memset(handle, 0, sizeof (handle_t));
248 + handle->h_buffer_credits = nblocks;
250 + INIT_LIST_HEAD(&handle->h_jcb);
256 * Obtain a new handle.
258 @@ -227,14 +242,11 @@ handle_t *journal_start(journal_t *journ
263 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
265 + handle = new_handle(nblocks);
267 return ERR_PTR(-ENOMEM);
268 - memset (handle, 0, sizeof (handle_t));
270 - handle->h_buffer_credits = nblocks;
272 current->journal_info = handle;
274 err = start_this_handle(journal, handle);
275 @@ -333,14 +345,11 @@ handle_t *journal_try_start(journal_t *j
277 if (is_journal_aborted(journal))
278 return ERR_PTR(-EIO);
280 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
282 + handle = new_handle(nblocks);
284 return ERR_PTR(-ENOMEM);
285 - memset (handle, 0, sizeof (handle_t));
287 - handle->h_buffer_credits = nblocks;
289 current->journal_info = handle;
291 err = try_start_this_handle(journal, handle);
292 @@ -1328,6 +1337,28 @@ out:
296 + * Register a callback function for this handle. The function will be
297 + * called when the transaction that this handle is part of has been
298 + * committed to disk with the original callback data struct and the
299 + * error status of the journal as parameters. There is no guarantee of
300 + * ordering between handles within a single transaction, nor between
301 + * callbacks registered on the same handle.
303 + * The caller is responsible for allocating the journal_callback struct.
304 + * This is to allow the caller to add as much extra data to the callback
305 + * as needed, but reduce the overhead of multiple allocations. The caller
306 + * allocated struct must start with a struct journal_callback at offset 0,
307 + * and has the caller-specific data afterwards.
309 +void journal_callback_set(handle_t *handle,
310 + void (*func)(struct journal_callback *jcb, int error),
311 + struct journal_callback *jcb)
313 + list_add(&jcb->jcb_list, &handle->h_jcb);
314 + jcb->jcb_func = func;
318 * All done for a particular handle.
320 * There is not much action needed here. We just return any remaining
321 @@ -1393,7 +1424,10 @@ int journal_stop(handle_t *handle)
322 wake_up(&journal->j_wait_transaction_locked);
326 + /* Move callbacks from the handle to the transaction. */
327 + list_splice(&handle->h_jcb, &transaction->t_jcb);
330 * If the handle is marked SYNC, we need to set another commit
331 * going! We also want to force a commit if the current
332 * transaction is occupying too much of the log, or if the
333 --- linux-2.4.19/include/linux/blkdev.h~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
334 +++ linux-2.4.19-root/include/linux/blkdev.h Sun Dec 15 17:02:24 2002
335 @@ -240,4 +240,8 @@ static inline unsigned int block_size(kd
339 +#define CONFIG_DEV_RDONLY
340 +void dev_set_rdonly(kdev_t, int);
341 +int dev_check_rdonly(kdev_t);
342 +void dev_clear_rdonly(int);
344 --- linux-2.4.19/include/linux/slab.h~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
345 +++ linux-2.4.19-root/include/linux/slab.h Sun Dec 15 17:02:12 2002
346 @@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache
347 extern int kmem_cache_shrink(kmem_cache_t *);
348 extern void *kmem_cache_alloc(kmem_cache_t *, int);
349 extern void kmem_cache_free(kmem_cache_t *, void *);
350 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
352 extern void *kmalloc(size_t, int);
353 extern void kfree(const void *);
354 --- linux-2.4.19/include/linux/jbd.h~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
355 +++ linux-2.4.19-root/include/linux/jbd.h Sun Dec 15 16:58:43 2002
356 @@ -249,6 +249,13 @@ static inline struct journal_head *bh2jh
357 return bh->b_private;
360 +#define HAVE_JOURNAL_CALLBACK_STATUS
361 +struct journal_callback {
362 + struct list_head jcb_list;
363 + void (*jcb_func)(struct journal_callback *jcb, int error);
364 + /* user data goes here */
367 struct jbd_revoke_table_s;
369 /* The handle_t type represents a single atomic update being performed
370 @@ -279,6 +286,12 @@ struct handle_s
374 + /* List of application registered callbacks for this handle.
375 + * The function(s) will be called after the transaction that
376 + * this handle is part of has been committed to disk.
378 + struct list_head h_jcb;
381 unsigned int h_sync: 1; /* sync-on-close */
382 unsigned int h_jdata: 1; /* force data journaling */
383 @@ -398,6 +411,10 @@ struct transaction_s
385 /* How many handles used this transaction? */
388 + /* List of registered callback functions for this transaction.
389 + * Called when the transaction is committed. */
390 + struct list_head t_jcb;
394 @@ -646,6 +663,9 @@ extern int journal_flushpage(journal_t
395 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
396 extern int journal_stop(handle_t *);
397 extern int journal_flush (journal_t *);
398 +extern void journal_callback_set(handle_t *handle,
399 + void (*fn)(struct journal_callback *,int),
400 + struct journal_callback *jcb);
402 extern void journal_lock_updates (journal_t *);
403 extern void journal_unlock_updates (journal_t *);
404 --- linux-2.4.19/kernel/ksyms.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
405 +++ linux-2.4.19-root/kernel/ksyms.c Sun Dec 15 17:03:55 2002
406 @@ -264,6 +264,7 @@ EXPORT_SYMBOL(read_cache_page);
407 EXPORT_SYMBOL(set_page_dirty);
408 EXPORT_SYMBOL(vfs_readlink);
409 EXPORT_SYMBOL(vfs_follow_link);
410 +EXPORT_SYMBOL(vfs_follow_link_it);
411 EXPORT_SYMBOL(page_readlink);
412 EXPORT_SYMBOL(page_follow_link);
413 EXPORT_SYMBOL(page_symlink_inode_operations);
414 @@ -280,6 +281,12 @@ EXPORT_SYMBOL(dcache_dir_fsync);
415 EXPORT_SYMBOL(dcache_readdir);
416 EXPORT_SYMBOL(dcache_dir_ops);
419 +EXPORT_SYMBOL(panic_notifier_list);
420 +EXPORT_SYMBOL(pagecache_lock_cacheline);
421 +EXPORT_SYMBOL(do_kern_mount);
422 +EXPORT_SYMBOL(kmem_cache_validate);
424 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
425 EXPORT_SYMBOL(default_llseek);
426 EXPORT_SYMBOL(dentry_open);
427 --- linux-2.4.19/include/linux/dcache.h~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
428 +++ linux-2.4.19-root/include/linux/dcache.h Sun Dec 15 17:02:11 2002
430 #include <asm/atomic.h>
431 #include <linux/mount.h>
434 +#define IT_CREAT (1<<1)
435 +#define IT_MKDIR (1<<2)
436 +#define IT_LINK (1<<3)
437 +#define IT_LINK2 (1<<4)
438 +#define IT_SYMLINK (1<<5)
439 +#define IT_UNLINK (1<<6)
440 +#define IT_RMDIR (1<<7)
441 +#define IT_RENAME (1<<8)
442 +#define IT_RENAME2 (1<<9)
443 +#define IT_READDIR (1<<10)
444 +#define IT_GETATTR (1<<11)
445 +#define IT_SETATTR (1<<12)
446 +#define IT_READLINK (1<<13)
447 +#define IT_MKNOD (1<<14)
448 +#define IT_LOOKUP (1<<15)
450 +struct lookup_intent {
453 + int it_disposition;
455 + struct iattr *it_iattr;
456 + __u64 it_lock_handle[2];
462 * linux/include/linux/dcache.h
464 @@ -78,6 +106,7 @@ struct dentry {
465 unsigned long d_time; /* used by d_revalidate */
466 struct dentry_operations *d_op;
467 struct super_block * d_sb; /* The root of the dentry tree */
468 + struct lookup_intent *d_it;
469 unsigned long d_vfs_flags;
470 void * d_fsdata; /* fs-specific data */
471 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
472 @@ -90,6 +119,8 @@ struct dentry_operations {
473 int (*d_delete)(struct dentry *);
474 void (*d_release)(struct dentry *);
475 void (*d_iput)(struct dentry *, struct inode *);
476 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
477 + void (*d_intent_release)(struct dentry *, struct lookup_intent *);
480 /* the dentry parameter passed to d_hash and d_compare is the parent
481 --- linux-2.4.19/include/linux/fs.h~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
482 +++ linux-2.4.19-root/include/linux/fs.h Sun Dec 15 17:02:11 2002
483 @@ -541,6 +541,7 @@ struct file {
485 /* needed for tty driver, and maybe others */
487 + struct lookup_intent *f_intent;
489 /* preallocated helper kiobuf to speedup O_DIRECT */
490 struct kiobuf *f_iobuf;
491 @@ -792,7 +793,9 @@ extern int vfs_symlink(struct inode *, s
492 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
493 extern int vfs_rmdir(struct inode *, struct dentry *);
494 extern int vfs_unlink(struct inode *, struct dentry *);
495 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
496 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
497 + struct inode *new_dir, struct dentry *new_dentry,
498 + struct lookup_intent *it);
502 @@ -853,6 +856,7 @@ struct file_operations {
503 struct inode_operations {
504 int (*create) (struct inode *,struct dentry *,int);
505 struct dentry * (*lookup) (struct inode *,struct dentry *);
506 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
507 int (*link) (struct dentry *,struct inode *,struct dentry *);
508 int (*unlink) (struct inode *,struct dentry *);
509 int (*symlink) (struct inode *,struct dentry *,const char *);
510 @@ -863,6 +867,8 @@ struct inode_operations {
511 struct inode *, struct dentry *);
512 int (*readlink) (struct dentry *, char *,int);
513 int (*follow_link) (struct dentry *, struct nameidata *);
514 + int (*follow_link2) (struct dentry *, struct nameidata *,
515 + struct lookup_intent *it);
516 void (*truncate) (struct inode *);
517 int (*permission) (struct inode *, int);
518 int (*revalidate) (struct dentry *);
519 @@ -999,6 +1005,7 @@ extern int unregister_filesystem(struct
520 extern struct vfsmount *kern_mount(struct file_system_type *);
521 extern int may_umount(struct vfsmount *);
522 extern long do_mount(char *, char *, char *, unsigned long, void *);
523 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
524 extern void umount_tree(struct vfsmount *);
526 #define kern_umount mntput
527 @@ -1329,6 +1336,7 @@ typedef int (*read_actor_t)(read_descrip
528 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
530 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
531 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
532 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
533 extern int FASTCALL(path_walk(const char *, struct nameidata *));
534 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
535 @@ -1339,6 +1347,8 @@ extern struct dentry * lookup_one_len(co
536 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
537 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
538 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
539 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
540 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
542 extern void iput(struct inode *);
543 extern void force_delete(struct inode *);
544 @@ -1448,6 +1458,8 @@ extern struct file_operations generic_ro
546 extern int vfs_readlink(struct dentry *, char *, int, const char *);
547 extern int vfs_follow_link(struct nameidata *, const char *);
548 +extern int vfs_follow_link_it(struct nameidata *, const char *,
549 + struct lookup_intent *it);
550 extern int page_readlink(struct dentry *, char *, int);
551 extern int page_follow_link(struct dentry *, struct nameidata *);
552 extern struct inode_operations page_symlink_inode_operations;
553 --- linux-2.4.19/fs/dcache.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
554 +++ linux-2.4.19-root/fs/dcache.c Sun Dec 15 16:58:43 2002
555 @@ -616,6 +616,7 @@ struct dentry * d_alloc(struct dentry *
557 dentry->d_fsdata = NULL;
558 dentry->d_mounted = 0;
559 + dentry->d_it = NULL;
560 INIT_LIST_HEAD(&dentry->d_hash);
561 INIT_LIST_HEAD(&dentry->d_lru);
562 INIT_LIST_HEAD(&dentry->d_subdirs);
563 --- linux-2.4.19/fs/nfsd/vfs.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
564 +++ linux-2.4.19-root/fs/nfsd/vfs.c Sun Dec 15 16:58:43 2002
565 @@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
569 - err = vfs_rename(fdir, odentry, tdir, ndentry);
570 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
571 if (!err && EX_ISSYNC(tfhp->fh_export)) {
572 nfsd_sync_dir(tdentry);
573 nfsd_sync_dir(fdentry);
574 --- linux-2.4.19/fs/namei.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
575 +++ linux-2.4.19-root/fs/namei.c Sun Dec 15 16:58:43 2002
577 * XEmacs seems to be relying on it...
580 +void intent_release(struct dentry *de, struct lookup_intent *it)
582 + if (it && de->d_op && de->d_op->d_intent_release)
583 + de->d_op->d_intent_release(de, it);
586 /* In order to reduce some races, while at the same time doing additional
587 * checking and hopefully speeding things up, we copy filenames to the
588 * kernel data space before using them..
589 @@ -260,10 +266,19 @@ void path_release(struct nameidata *nd)
590 * Internal lookup() using the new generic dcache.
593 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
594 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
595 + int flags, struct lookup_intent *it)
597 struct dentry * dentry = d_lookup(parent, name);
599 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
600 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
601 + !d_invalidate(dentry)) {
607 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
608 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
610 @@ -281,7 +296,8 @@ static struct dentry * cached_lookup(str
611 * make sure that nobody added the entry to the dcache in the meantime..
614 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
615 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
616 + int flags, struct lookup_intent *it)
618 struct dentry * result;
619 struct inode *dir = parent->d_inode;
620 @@ -300,6 +316,9 @@ static struct dentry * real_lookup(struc
621 result = ERR_PTR(-ENOMEM);
624 + if (dir->i_op->lookup2)
625 + result = dir->i_op->lookup2(dir, dentry, it);
627 result = dir->i_op->lookup(dir, dentry);
630 @@ -321,6 +340,12 @@ static struct dentry * real_lookup(struc
632 result = ERR_PTR(-ENOENT);
634 + } else if (result->d_op && result->d_op->d_revalidate2) {
635 + if (!result->d_op->d_revalidate2(result, flags, it) &&
636 + !d_invalidate(result)) {
638 + result = ERR_PTR(-ENOENT);
643 @@ -332,7 +357,8 @@ static struct dentry * real_lookup(struc
644 * Without that kind of total limit, nasty chains of consecutive
645 * symlinks can cause almost arbitrarily long lookups.
647 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
648 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
649 + struct lookup_intent *it)
652 if (current->link_count >= 5)
653 @@ -346,10 +372,14 @@ static inline int do_follow_link(struct
654 current->link_count++;
655 current->total_link_count++;
656 UPDATE_ATIME(dentry->d_inode);
657 - err = dentry->d_inode->i_op->follow_link(dentry, nd);
658 + if (dentry->d_inode->i_op->follow_link2)
659 + err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
661 + err = dentry->d_inode->i_op->follow_link(dentry, nd);
662 current->link_count--;
665 + intent_release(dentry, it);
669 @@ -447,7 +477,8 @@ static inline void follow_dotdot(struct
671 * We expect 'base' to be positive and a directory.
673 -int link_path_walk(const char * name, struct nameidata *nd)
674 +int link_path_walk_it(const char *name, struct nameidata *nd,
675 + struct lookup_intent *it)
677 struct dentry *dentry;
679 @@ -520,9 +551,9 @@ int link_path_walk(const char * name, st
682 /* This does the actual lookups.. */
683 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
684 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
686 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
687 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
688 err = PTR_ERR(dentry);
691 @@ -539,8 +570,8 @@ int link_path_walk(const char * name, st
695 - if (inode->i_op->follow_link) {
696 - err = do_follow_link(dentry, nd);
697 + if (inode->i_op->follow_link || inode->i_op->follow_link2) {
698 + err = do_follow_link(dentry, nd, it);
702 @@ -556,7 +587,7 @@ int link_path_walk(const char * name, st
706 - if (!inode->i_op->lookup)
707 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
710 /* here ends the main loop */
711 @@ -583,9 +614,9 @@ last_component:
715 - dentry = cached_lookup(nd->dentry, &this, 0);
716 + dentry = cached_lookup(nd->dentry, &this, 0, it);
718 - dentry = real_lookup(nd->dentry, &this, 0);
719 + dentry = real_lookup(nd->dentry, &this, 0, it);
720 err = PTR_ERR(dentry);
723 @@ -593,9 +624,9 @@ last_component:
724 while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
726 inode = dentry->d_inode;
727 - if ((lookup_flags & LOOKUP_FOLLOW)
728 - && inode && inode->i_op && inode->i_op->follow_link) {
729 - err = do_follow_link(dentry, nd);
730 + if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op &&
731 + (inode->i_op->follow_link || inode->i_op->follow_link2)) {
732 + err = do_follow_link(dentry, nd, it);
736 @@ -609,7 +640,8 @@ last_component:
738 if (lookup_flags & LOOKUP_DIRECTORY) {
740 - if (!inode->i_op || !inode->i_op->lookup)
741 + if (!inode->i_op ||
742 + (!inode->i_op->lookup && !inode->i_op->lookup2))
746 @@ -651,10 +683,21 @@ return_err:
750 +int link_path_walk(const char * name, struct nameidata *nd)
752 + return link_path_walk_it(name, nd, NULL);
755 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
757 + current->total_link_count = 0;
758 + return link_path_walk_it(name, nd, it);
761 int path_walk(const char * name, struct nameidata *nd)
763 current->total_link_count = 0;
764 - return link_path_walk(name, nd);
765 + return link_path_walk_it(name, nd, NULL);
769 @@ -757,7 +800,8 @@ int path_init(const char *name, unsigned
770 * needs parent already locked. Doesn't follow mounts.
773 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
774 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
775 + struct lookup_intent *it)
777 struct dentry * dentry;
779 @@ -780,13 +824,16 @@ struct dentry * lookup_hash(struct qstr
783 - dentry = cached_lookup(base, name, 0);
784 + dentry = cached_lookup(base, name, 0, it);
786 struct dentry *new = d_alloc(base, name);
787 dentry = ERR_PTR(-ENOMEM);
791 + if (inode->i_op->lookup2)
792 + dentry = inode->i_op->lookup2(inode, new, it);
794 dentry = inode->i_op->lookup(inode, new);
797 @@ -798,6 +845,12 @@ out:
801 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
803 + return lookup_hash_it(name, base, NULL);
808 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
810 @@ -819,7 +872,7 @@ struct dentry * lookup_one_len(const cha
812 this.hash = end_name_hash(hash);
814 - return lookup_hash(&this, base);
815 + return lookup_hash_it(&this, base, NULL);
817 return ERR_PTR(-EACCES);
819 @@ -851,6 +904,23 @@ int __user_walk(const char *name, unsign
823 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
824 + struct lookup_intent *it)
829 + tmp = getname(name);
830 + err = PTR_ERR(tmp);
831 + if (!IS_ERR(tmp)) {
833 + if (path_init(tmp, flags, nd))
834 + err = path_walk_it(tmp, nd, it);
841 * It's inline, so penalty for filesystems that don't use sticky bit is
843 @@ -987,7 +1057,8 @@ exit_lock:
844 * for symlinks (where the permissions are checked later).
847 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
848 +int open_namei_it(const char *pathname, int flag, int mode,
849 + struct nameidata *nd, struct lookup_intent *it)
851 int acc_mode, error = 0;
853 @@ -1002,7 +1073,7 @@ int open_namei(const char * pathname, in
855 if (!(flag & O_CREAT)) {
856 if (path_init(pathname, lookup_flags(flag), nd))
857 - error = path_walk(pathname, nd);
858 + error = path_walk_it(pathname, nd, it);
862 @@ -1012,6 +1083,10 @@ int open_namei(const char * pathname, in
864 * Create - we need to know the parent.
867 + it->it_mode = mode;
868 + it->it_op |= IT_CREAT;
870 if (path_init(pathname, LOOKUP_PARENT, nd))
871 error = path_walk(pathname, nd);
873 @@ -1028,7 +1103,7 @@ int open_namei(const char * pathname, in
876 down(&dir->d_inode->i_sem);
877 - dentry = lookup_hash(&nd->last, nd->dentry);
878 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
881 error = PTR_ERR(dentry);
882 @@ -1037,6 +1112,7 @@ do_last:
886 + it->it_mode = mode;
887 /* Negative dentry, just create the file */
888 if (!dentry->d_inode) {
889 error = vfs_create(dir->d_inode, dentry,
890 @@ -1070,7 +1146,8 @@ do_last:
892 if (!dentry->d_inode)
894 - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
895 + if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
896 + dentry->d_inode->i_op->follow_link2))
900 @@ -1156,8 +1233,10 @@ ok:
904 + intent_release(dentry, it);
907 + intent_release(nd->dentry, it);
911 @@ -1176,7 +1255,12 @@ do_link:
912 * are done. Procfs-like symlinks just set LAST_BIND.
914 UPDATE_ATIME(dentry->d_inode);
915 - error = dentry->d_inode->i_op->follow_link(dentry, nd);
916 + if (dentry->d_inode->i_op->follow_link2)
917 + error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
919 + error = dentry->d_inode->i_op->follow_link(dentry, nd);
921 + intent_release(dentry, it);
925 @@ -1198,13 +1282,20 @@ do_link:
928 down(&dir->d_inode->i_sem);
929 - dentry = lookup_hash(&nd->last, nd->dentry);
930 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
931 putname(nd->last.name);
935 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
937 + return open_namei_it(pathname, flag, mode, nd, NULL);
942 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
943 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
944 + struct lookup_intent *it)
946 struct dentry *dentry;
948 @@ -1212,7 +1303,7 @@ static struct dentry *lookup_create(stru
949 dentry = ERR_PTR(-EEXIST);
950 if (nd->last_type != LAST_NORM)
952 - dentry = lookup_hash(&nd->last, nd->dentry);
953 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
956 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
957 @@ -1258,6 +1349,7 @@ asmlinkage long sys_mknod(const char * f
959 struct dentry * dentry;
961 + struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
965 @@ -1269,7 +1361,7 @@ asmlinkage long sys_mknod(const char * f
966 error = path_walk(tmp, &nd);
969 - dentry = lookup_create(&nd, 0);
970 + dentry = lookup_create(&nd, 0, &it);
971 error = PTR_ERR(dentry);
973 mode &= ~current->fs->umask;
974 @@ -1287,6 +1379,7 @@ asmlinkage long sys_mknod(const char * f
978 + intent_release(dentry, &it);
981 up(&nd.dentry->d_inode->i_sem);
982 @@ -1327,6 +1420,7 @@ asmlinkage long sys_mkdir(const char * p
986 + struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
988 tmp = getname(pathname);
989 error = PTR_ERR(tmp);
990 @@ -1338,11 +1432,12 @@ asmlinkage long sys_mkdir(const char * p
991 error = path_walk(tmp, &nd);
994 - dentry = lookup_create(&nd, 1);
995 + dentry = lookup_create(&nd, 1, &it);
996 error = PTR_ERR(dentry);
997 if (!IS_ERR(dentry)) {
998 error = vfs_mkdir(nd.dentry->d_inode, dentry,
999 mode & ~current->fs->umask);
1000 + intent_release(dentry, &it);
1003 up(&nd.dentry->d_inode->i_sem);
1004 @@ -1426,6 +1521,7 @@ asmlinkage long sys_rmdir(const char * p
1006 struct dentry *dentry;
1007 struct nameidata nd;
1008 + struct lookup_intent it = { .it_op = IT_RMDIR };
1010 name = getname(pathname);
1012 @@ -1448,10 +1544,11 @@ asmlinkage long sys_rmdir(const char * p
1015 down(&nd.dentry->d_inode->i_sem);
1016 - dentry = lookup_hash(&nd.last, nd.dentry);
1017 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1018 error = PTR_ERR(dentry);
1019 if (!IS_ERR(dentry)) {
1020 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1021 + intent_release(dentry, &it);
1024 up(&nd.dentry->d_inode->i_sem);
1025 @@ -1495,6 +1592,7 @@ asmlinkage long sys_unlink(const char *
1027 struct dentry *dentry;
1028 struct nameidata nd;
1029 + struct lookup_intent it = { .it_op = IT_UNLINK };
1031 name = getname(pathname);
1033 @@ -1508,7 +1606,7 @@ asmlinkage long sys_unlink(const char *
1034 if (nd.last_type != LAST_NORM)
1036 down(&nd.dentry->d_inode->i_sem);
1037 - dentry = lookup_hash(&nd.last, nd.dentry);
1038 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
1039 error = PTR_ERR(dentry);
1040 if (!IS_ERR(dentry)) {
1041 /* Why not before? Because we want correct error value */
1042 @@ -1516,6 +1614,7 @@ asmlinkage long sys_unlink(const char *
1044 error = vfs_unlink(nd.dentry->d_inode, dentry);
1046 + intent_release(dentry, &it);
1049 up(&nd.dentry->d_inode->i_sem);
1050 @@ -1562,6 +1661,7 @@ asmlinkage long sys_symlink(const char *
1054 + struct lookup_intent it = { .it_op = IT_SYMLINK };
1056 from = getname(oldname);
1058 @@ -1576,10 +1676,12 @@ asmlinkage long sys_symlink(const char *
1059 error = path_walk(to, &nd);
1062 - dentry = lookup_create(&nd, 0);
1063 + it.it_data = from;
1064 + dentry = lookup_create(&nd, 0, &it);
1065 error = PTR_ERR(dentry);
1066 if (!IS_ERR(dentry)) {
1067 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
1068 + intent_release(dentry, &it);
1071 up(&nd.dentry->d_inode->i_sem);
1072 @@ -1645,6 +1747,7 @@ asmlinkage long sys_link(const char * ol
1076 + struct lookup_intent it = { .it_op = IT_LINK };
1078 from = getname(oldname);
1080 @@ -1657,7 +1760,7 @@ asmlinkage long sys_link(const char * ol
1083 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
1084 - error = path_walk(from, &old_nd);
1085 + error = path_walk_it(from, &old_nd, &it);
1088 if (path_init(to, LOOKUP_PARENT, &nd))
1089 @@ -1667,10 +1770,12 @@ asmlinkage long sys_link(const char * ol
1091 if (old_nd.mnt != nd.mnt)
1093 - new_dentry = lookup_create(&nd, 0);
1094 + it.it_op = IT_LINK2;
1095 + new_dentry = lookup_create(&nd, 0, &it);
1096 error = PTR_ERR(new_dentry);
1097 if (!IS_ERR(new_dentry)) {
1098 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1099 + intent_release(new_dentry, &it);
1102 up(&nd.dentry->d_inode->i_sem);
1103 @@ -1713,7 +1818,8 @@ exit:
1106 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1107 - struct inode *new_dir, struct dentry *new_dentry)
1108 + struct inode *new_dir, struct dentry *new_dentry,
1109 + struct lookup_intent *it)
1112 struct inode *target;
1113 @@ -1771,6 +1877,7 @@ int vfs_rename_dir(struct inode *old_dir
1116 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1117 + intent_release(new_dentry, it);
1120 target->i_flags |= S_DEAD;
1121 @@ -1792,7 +1899,8 @@ out_unlock:
1124 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1125 - struct inode *new_dir, struct dentry *new_dentry)
1126 + struct inode *new_dir, struct dentry *new_dentry,
1127 + struct lookup_intent *it)
1131 @@ -1823,6 +1931,7 @@ int vfs_rename_other(struct inode *old_d
1134 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1135 + intent_release(new_dentry, it);
1136 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1139 @@ -1834,13 +1943,14 @@ int vfs_rename_other(struct inode *old_d
1142 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1143 - struct inode *new_dir, struct dentry *new_dentry)
1144 + struct inode *new_dir, struct dentry *new_dentry,
1145 + struct lookup_intent *it)
1148 if (S_ISDIR(old_dentry->d_inode->i_mode))
1149 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1150 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1152 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1153 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1155 if (old_dir == new_dir)
1156 inode_dir_notify(old_dir, DN_RENAME);
1157 @@ -1857,6 +1967,7 @@ static inline int do_rename(const char *
1159 struct dentry * old_dir, * new_dir;
1160 struct dentry * old_dentry, *new_dentry;
1161 + struct lookup_intent it = { .it_op = IT_RENAME };
1162 struct nameidata oldnd, newnd;
1164 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1165 @@ -1885,7 +1996,7 @@ static inline int do_rename(const char *
1167 double_lock(new_dir, old_dir);
1169 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1170 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1171 error = PTR_ERR(old_dentry);
1172 if (IS_ERR(old_dentry))
1174 @@ -1901,18 +2012,21 @@ static inline int do_rename(const char *
1175 if (newnd.last.name[newnd.last.len])
1178 - new_dentry = lookup_hash(&newnd.last, new_dir);
1179 + it.it_op = IT_RENAME2;
1180 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1181 error = PTR_ERR(new_dentry);
1182 if (IS_ERR(new_dentry))
1186 error = vfs_rename(old_dir->d_inode, old_dentry,
1187 - new_dir->d_inode, new_dentry);
1188 + new_dir->d_inode, new_dentry, &it);
1191 + intent_release(new_dentry, &it);
1194 + intent_release(old_dentry, &it);
1197 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1198 @@ -1961,7 +2075,8 @@ out:
1202 -__vfs_follow_link(struct nameidata *nd, const char *link)
1203 +__vfs_follow_link(struct nameidata *nd, const char *link,
1204 + struct lookup_intent *it)
1208 @@ -1974,7 +2089,7 @@ __vfs_follow_link(struct nameidata *nd,
1209 /* weird __emul_prefix() stuff did it */
1212 - res = link_path_walk(link, nd);
1213 + res = link_path_walk_it(link, nd, it);
1215 if (current->link_count || res || nd->last_type!=LAST_NORM)
1217 @@ -1996,7 +2111,13 @@ fail:
1219 int vfs_follow_link(struct nameidata *nd, const char *link)
1221 - return __vfs_follow_link(nd, link);
1222 + return __vfs_follow_link(nd, link, NULL);
1225 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
1226 + struct lookup_intent *it)
1228 + return __vfs_follow_link(nd, link, it);
1231 /* get the link contents into pagecache */
1232 @@ -2038,7 +2159,7 @@ int page_follow_link(struct dentry *dent
1234 struct page *page = NULL;
1235 char *s = page_getlink(dentry, &page);
1236 - int res = __vfs_follow_link(nd, s);
1237 + int res = __vfs_follow_link(nd, s, NULL);
1240 page_cache_release(page);
1241 --- linux-2.4.19/fs/open.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
1242 +++ linux-2.4.19-root/fs/open.c Sun Dec 15 16:58:43 2002
1244 #include <asm/uaccess.h>
1246 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1247 +extern int path_walk_it(const char *name, struct nameidata *nd,
1248 + struct lookup_intent *it);
1249 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1251 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1253 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
1254 struct nameidata nd;
1255 struct inode * inode;
1257 + struct lookup_intent it = { .it_op = IT_SETATTR };
1260 if (length < 0) /* sorry, but loff_t says... */
1263 - error = user_path_walk(path, &nd);
1264 + error = user_path_walk_it(path, &nd, &it);
1267 inode = nd.dentry->d_inode;
1268 @@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
1269 put_write_access(inode);
1272 + intent_release(nd.dentry, &it);
1276 @@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
1277 struct nameidata nd;
1278 struct inode * inode;
1279 struct iattr newattrs;
1280 + struct lookup_intent it = { .it_op = IT_SETATTR };
1282 - error = user_path_walk(filename, &nd);
1283 + error = user_path_walk_it(filename, &nd, &it);
1286 inode = nd.dentry->d_inode;
1287 @@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
1289 error = notify_change(nd.dentry, &newattrs);
1291 + intent_release(nd.dentry, &it);
1295 @@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
1296 struct nameidata nd;
1297 struct inode * inode;
1298 struct iattr newattrs;
1299 + struct lookup_intent it = { .it_op = IT_SETATTR };
1301 - error = user_path_walk(filename, &nd);
1302 + error = user_path_walk_it(filename, &nd, &it);
1306 @@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
1308 error = notify_change(nd.dentry, &newattrs);
1310 + intent_release(nd.dentry, &it);
1314 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char *
1315 int old_fsuid, old_fsgid;
1316 kernel_cap_t old_cap;
1318 + struct lookup_intent it = { .it_op = IT_GETATTR };
1320 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1322 @@ -364,13 +374,14 @@ asmlinkage long sys_access(const char *
1324 current->cap_effective = current->cap_permitted;
1326 - res = user_path_walk(filename, &nd);
1327 + res = user_path_walk_it(filename, &nd, &it);
1329 res = permission(nd.dentry->d_inode, mode);
1330 /* SuS v2 requires we report a read only fs too */
1331 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1332 && !special_file(nd.dentry->d_inode->i_mode))
1334 + intent_release(nd.dentry, &it);
1338 @@ -386,6 +397,7 @@ asmlinkage long sys_chdir(const char * f
1340 struct nameidata nd;
1342 + struct lookup_intent it = { .it_op = IT_GETATTR };
1344 name = getname(filename);
1345 error = PTR_ERR(name);
1346 @@ -394,7 +406,7 @@ asmlinkage long sys_chdir(const char * f
1349 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1350 - error = path_walk(name, &nd);
1351 + error = path_walk_it(name, &nd, &it);
1355 @@ -406,6 +418,7 @@ asmlinkage long sys_chdir(const char * f
1356 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1359 + intent_release(nd.dentry, &it);
1363 @@ -446,6 +459,7 @@ asmlinkage long sys_chroot(const char *
1365 struct nameidata nd;
1367 + struct lookup_intent it = { .it_op = IT_GETATTR };
1369 name = getname(filename);
1370 error = PTR_ERR(name);
1371 @@ -454,7 +468,7 @@ asmlinkage long sys_chroot(const char *
1373 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1374 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1375 - error = path_walk(name, &nd);
1376 + error = path_walk_it(name, &nd, &it);
1380 @@ -471,6 +485,7 @@ asmlinkage long sys_chroot(const char *
1384 + intent_release(nd.dentry, &it);
1388 @@ -515,8 +530,9 @@ asmlinkage long sys_chmod(const char * f
1389 struct inode * inode;
1391 struct iattr newattrs;
1392 + struct lookup_intent it = { .it_op = IT_SETATTR };
1394 - error = user_path_walk(filename, &nd);
1395 + error = user_path_walk_it(filename, &nd, &it);
1398 inode = nd.dentry->d_inode;
1399 @@ -536,6 +552,7 @@ asmlinkage long sys_chmod(const char * f
1400 error = notify_change(nd.dentry, &newattrs);
1403 + intent_release(nd.dentry, &it);
1407 @@ -605,10 +622,12 @@ asmlinkage long sys_chown(const char * f
1409 struct nameidata nd;
1411 + struct lookup_intent it = { .it_op = IT_SETATTR };
1413 - error = user_path_walk(filename, &nd);
1414 + error = user_path_walk_it(filename, &nd, &it);
1416 error = chown_common(nd.dentry, user, group);
1417 + intent_release(nd.dentry, &it);
1421 @@ -618,10 +637,12 @@ asmlinkage long sys_lchown(const char *
1423 struct nameidata nd;
1425 + struct lookup_intent it = { .it_op = IT_SETATTR };
1427 - error = user_path_walk_link(filename, &nd);
1428 + error = user_path_walk_link_it(filename, &nd, &it);
1430 error = chown_common(nd.dentry, user, group);
1431 + intent_release(nd.dentry, &it);
1435 @@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int
1436 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1439 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1440 + struct nameidata *nd, struct lookup_intent *it);
1441 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1442 + int flags, struct lookup_intent *it);
1444 struct file *filp_open(const char * filename, int flags, int mode)
1446 int namei_flags, error;
1447 struct nameidata nd;
1448 + struct lookup_intent it = { .it_op = IT_OPEN };
1450 namei_flags = flags;
1451 if ((namei_flags+1) & O_ACCMODE)
1452 @@ -666,14 +693,15 @@ struct file *filp_open(const char * file
1453 if (namei_flags & O_TRUNC)
1456 - error = open_namei(filename, namei_flags, mode, &nd);
1458 - return dentry_open(nd.dentry, nd.mnt, flags);
1459 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1461 + return ERR_PTR(error);
1463 - return ERR_PTR(error);
1464 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1467 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1468 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1469 + int flags, struct lookup_intent *it)
1472 struct inode *inode;
1473 @@ -716,6 +744,7 @@ struct file *dentry_open(struct dentry *
1475 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1477 + intent_release(dentry, it);
1481 @@ -730,11 +759,17 @@ cleanup_all:
1485 + intent_release(dentry, it);
1488 return ERR_PTR(error);
1491 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1493 + return dentry_open_it(dentry, mnt, flags, NULL);
1497 * Find an empty file descriptor entry, and mark it busy.
1499 --- linux-2.4.19/fs/stat.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
1500 +++ linux-2.4.19-root/fs/stat.c Sun Dec 15 16:58:43 2002
1503 #include <asm/uaccess.h>
1505 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1507 * Revalidate the inode. This is required for proper NFS attribute caching.
1509 @@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in
1510 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1512 struct nameidata nd;
1513 + struct lookup_intent it = { .it_op = IT_GETATTR };
1516 - error = user_path_walk(filename, &nd);
1517 + error = user_path_walk_it(filename, &nd, &it);
1519 error = do_revalidate(nd.dentry);
1521 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1522 + intent_release(nd.dentry, &it);
1526 @@ -151,13 +154,15 @@ asmlinkage long sys_stat(char * filename
1527 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1529 struct nameidata nd;
1530 + struct lookup_intent it = { .it_op = IT_GETATTR };
1533 - error = user_path_walk(filename, &nd);
1534 + error = user_path_walk_it(filename, &nd, &it);
1536 error = do_revalidate(nd.dentry);
1538 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1539 + intent_release(nd.dentry, &it);
1543 @@ -172,13 +177,15 @@ asmlinkage long sys_newstat(char * filen
1544 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1546 struct nameidata nd;
1547 + struct lookup_intent it = { .it_op = IT_GETATTR };
1550 - error = user_path_walk_link(filename, &nd);
1551 + error = user_path_walk_link_it(filename, &nd, &it);
1553 error = do_revalidate(nd.dentry);
1555 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1556 + intent_release(nd.dentry, &it);
1560 @@ -189,13 +196,15 @@ asmlinkage long sys_lstat(char * filenam
1561 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1563 struct nameidata nd;
1564 + struct lookup_intent it = { .it_op = IT_GETATTR };
1567 - error = user_path_walk_link(filename, &nd);
1568 + error = user_path_walk_link_it(filename, &nd, &it);
1570 error = do_revalidate(nd.dentry);
1572 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1573 + intent_release(nd.dentry, &it);
1577 @@ -247,20 +256,21 @@ asmlinkage long sys_readlink(const char
1579 struct nameidata nd;
1581 + struct lookup_intent it = { .it_op = IT_READLINK };
1586 - error = user_path_walk_link(path, &nd);
1587 + error = user_path_walk_link_it(path, &nd, &it);
1589 struct inode * inode = nd.dentry->d_inode;
1592 if (inode->i_op && inode->i_op->readlink &&
1593 !(error = do_revalidate(nd.dentry))) {
1594 UPDATE_ATIME(inode);
1595 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1597 + intent_release(nd.dentry, &it);
1601 @@ -333,12 +343,14 @@ asmlinkage long sys_stat64(char * filena
1603 struct nameidata nd;
1605 + struct lookup_intent it = { .it_op = IT_GETATTR };
1607 - error = user_path_walk(filename, &nd);
1608 + error = user_path_walk_it(filename, &nd, &it);
1610 error = do_revalidate(nd.dentry);
1612 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1613 + intent_release(nd.dentry, &it);
1617 @@ -348,12 +360,14 @@ asmlinkage long sys_lstat64(char * filen
1619 struct nameidata nd;
1621 + struct lookup_intent it = { .it_op = IT_GETATTR };
1623 - error = user_path_walk_link(filename, &nd);
1624 + error = user_path_walk_link_it(filename, &nd, &it);
1626 error = do_revalidate(nd.dentry);
1628 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1629 + intent_release(nd.dentry, &it);
1633 --- linux-2.4.19/mm/slab.c~vanilla-2.4.19 Sun Dec 15 16:58:43 2002
1634 +++ linux-2.4.19-root/mm/slab.c Sun Dec 15 16:58:43 2002
1635 @@ -1207,6 +1207,59 @@ failed:
1636 * Called with the cache-lock held.
1639 +extern struct page *check_get_page(unsigned long kaddr);
1640 +struct page *page_mem_map(struct page *page);
1641 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1642 + slab_t *slabp, void * objp)
1645 + unsigned int objnr;
1648 + if (cachep->flags & SLAB_RED_ZONE) {
1649 + objp -= BYTES_PER_WORD;
1650 + if ( *(unsigned long *)objp != RED_MAGIC2)
1651 + /* Either write before start, or a double free. */
1653 + if (*(unsigned long *)(objp+cachep->objsize -
1654 + BYTES_PER_WORD) != RED_MAGIC2)
1655 + /* Either write past end, or a double free. */
1660 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1661 + if (objnr >= cachep->num)
1663 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1666 + /* Check slab's freelist to see if this obj is there. */
1667 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1675 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1677 + struct page *page = check_get_page((unsigned long)objp);
1679 + if (!VALID_PAGE(page))
1682 + if (!PageSlab(page))
1685 + /* XXX check for freed slab objects ? */
1686 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1689 + return (cachep == GET_PAGE_CACHE(page));
1693 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1694 slab_t *slabp, void * objp)