1 --- kernel-rh-2.4.18-pristine/drivers/block/blkpg.c Thu Jun 13 12:26:40 2002
2 +++ kernel-rh-2.4.18/drivers/block/blkpg.c Thu Jun 13 14:49:48 2002
6 EXPORT_SYMBOL(blk_ioctl);
8 +#define NUM_DEV_NO_WRITE 16
9 +static int dev_no_write[NUM_DEV_NO_WRITE];
12 + * Debug code for turning block devices "read-only" (will discard writes
13 + * silently). This is for filesystem crash/recovery testing.
15 +void dev_set_rdonly(kdev_t dev, int no_write)
18 + printk(KERN_WARNING "Turning device %s read-only\n",
20 + dev_no_write[no_write] = 0xdead0000 + dev;
24 +int dev_check_rdonly(kdev_t dev) {
27 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
28 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
29 + dev == (dev_no_write[i] & 0xffff))
35 +void dev_clear_rdonly(int no_write) {
36 + dev_no_write[no_write] = 0;
39 +EXPORT_SYMBOL(dev_set_rdonly);
40 +EXPORT_SYMBOL(dev_check_rdonly);
41 +EXPORT_SYMBOL(dev_clear_rdonly);
42 --- kernel-rh-2.4.18-pristine/drivers/block/loop.c Thu Jun 13 12:26:40 2002
43 +++ kernel-rh-2.4.18/drivers/block/loop.c Thu Jun 13 14:49:48 2002
45 spin_unlock_irq(&lo->lo_lock);
48 +#ifdef CONFIG_DEV_RDONLY
49 + if (dev_check_rdonly(rbh->b_rdev))
53 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
55 } else if (rw == READA) {
56 --- kernel-rh-2.4.18-pristine/drivers/ide/ide-disk.c Thu Jun 13 12:26:43 2002
57 +++ kernel-rh-2.4.18/drivers/ide/ide-disk.c Thu Jun 13 14:49:48 2002
60 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
62 +#ifdef CONFIG_DEV_RDONLY
63 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
64 + ide_end_request(1, HWGROUP(drive));
69 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
71 --- kernel-rh-2.4.18-pristine/fs/ext3/Makefile Thu Jun 13 12:27:00 2002
72 +++ kernel-rh-2.4.18/fs/ext3/Makefile Thu Jun 13 14:49:48 2002
77 +export-objs := super.o
79 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
80 ioctl.o namei.o super.o symlink.o
82 --- kernel-rh-2.4.18-pristine/fs/ext3/super.c Thu Jun 13 12:27:01 2002
83 +++ kernel-rh-2.4.18/fs/ext3/super.c Thu Jun 13 14:49:48 2002
85 unregister_filesystem(&ext3_fs_type);
89 +EXPORT_SYMBOL(ext3_bread);
91 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
92 MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
93 --- kernel-rh-2.4.18-pristine/fs/jbd/commit.c Thu Jun 13 12:27:05 2002
94 +++ kernel-rh-2.4.18/fs/jbd/commit.c Thu Jun 13 14:49:48 2002
96 transaction's t_log_list queue, and metadata buffers are on
97 the t_iobuf_list queue.
99 - Wait for the transactions in reverse order. That way we are
100 + Wait for the buffers in reverse order. That way we are
101 less likely to be woken up until all IOs have completed, and
102 so we incur less scheduling load.
106 jbd_debug(3, "JBD: commit phase 6\n");
108 - if (is_journal_aborted(journal))
109 + if (is_journal_aborted(journal)) {
110 + unlock_journal(journal);
114 /* Done it all: now write the commit record. We should have
115 * cleaned up our previous buffers by now, so if we are in abort
117 descriptor = journal_get_descriptor_buffer(journal);
119 __journal_abort_hard(journal);
120 + unlock_journal(journal);
125 /* AKPM: buglet - add `i' to tmp! */
126 for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
127 journal_header_t *tmp =
129 put_bh(bh); /* One for getblk() */
130 journal_unlock_journal_head(descriptor);
132 - lock_journal(journal);
134 /* End of a transaction! Finally, we can do checkpoint
135 processing: any buffers committed as a result of this
140 + /* Call any callbacks that had been registered for handles in this
141 + * transaction. It is up to the callback to free any allocated
144 + if (!list_empty(&commit_transaction->t_jcb)) {
145 + struct list_head *p, *n;
146 + int error = is_journal_aborted(journal);
148 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
149 + struct journal_callback *jcb;
151 + jcb = list_entry(p, struct journal_callback, jcb_list);
153 + jcb->jcb_func(jcb, error);
157 + lock_journal(journal);
159 jbd_debug(3, "JBD: commit phase 7\n");
161 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
162 --- kernel-rh-2.4.18-pristine/fs/jbd/journal.c Thu Jun 13 12:27:05 2002
163 +++ kernel-rh-2.4.18/fs/jbd/journal.c Thu Jun 13 14:49:48 2002
166 EXPORT_SYMBOL(journal_flush);
167 EXPORT_SYMBOL(journal_revoke);
168 +EXPORT_SYMBOL(journal_callback_set);
170 EXPORT_SYMBOL(journal_init_dev);
171 EXPORT_SYMBOL(journal_init_inode);
172 --- kernel-rh-2.4.18-pristine/fs/jbd/transaction.c Thu Jun 13 12:27:05 2002
173 +++ kernel-rh-2.4.18/fs/jbd/transaction.c Thu Jun 13 14:49:48 2002
175 transaction->t_state = T_RUNNING;
176 transaction->t_tid = journal->j_transaction_sequence++;
177 transaction->t_expires = jiffies + journal->j_commit_interval;
178 + INIT_LIST_HEAD(&transaction->t_jcb);
180 /* Set up the commit timer for the new transaction. */
181 J_ASSERT (!journal->j_commit_timer_active);
186 +/* Allocate a new handle. This should probably be in a slab... */
187 +static handle_t *get_handle(int nblocks)
189 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
192 + memset(handle, 0, sizeof (handle_t));
193 + handle->h_buffer_credits = nblocks;
195 + INIT_LIST_HEAD(&handle->h_jcb);
201 * Obtain a new handle.
203 @@ -227,14 +242,11 @@
208 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
210 + handle = get_handle(nblocks);
212 return ERR_PTR(-ENOMEM);
213 - memset (handle, 0, sizeof (handle_t));
215 - handle->h_buffer_credits = nblocks;
217 current->journal_info = handle;
219 err = start_this_handle(journal, handle);
220 @@ -333,14 +345,11 @@
222 if (is_journal_aborted(journal))
223 return ERR_PTR(-EIO);
225 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
227 + handle = get_handle(nblocks);
229 return ERR_PTR(-ENOMEM);
230 - memset (handle, 0, sizeof (handle_t));
232 - handle->h_buffer_credits = nblocks;
234 current->journal_info = handle;
236 err = try_start_this_handle(journal, handle);
237 @@ -1319,6 +1328,29 @@
241 + * Register a callback function for this handle. The function will be
242 + * called when the transaction that this handle is part of has been
243 + * committed to disk with the original callback data struct and the
244 + * error status of the journal as parameters. There is no guarantee of
245 + * ordering between handles within a single transaction, nor between
246 + * callbacks registered on the same handle.
248 + * The caller is responsible for allocating the journal_callback struct.
249 + * This is to allow the caller to add as much extra data to the callback
250 + * as needed, but reduce the overhead of multiple allocations. The caller
251 + * allocated struct must start with a struct journal_callback at offset 0,
252 + * and has the caller-specific data afterwards.
254 +void journal_callback_set(handle_t *handle, void (*func)(void *, int),
257 + struct journal_callback *jcb = cb_data;
259 + list_add(&jcb->jcb_list, &handle->h_jcb);
260 + jcb->jcb_func = func;
264 * All done for a particular handle.
266 * There is not much action needed here. We just return any remaining
267 @@ -1383,7 +1415,10 @@
268 wake_up(&journal->j_wait_transaction_locked);
272 + /* Move callbacks from the handle to the transaction. */
273 + list_splice(&handle->h_jcb, &transaction->t_jcb);
276 * If the handle is marked SYNC, we need to set another commit
277 * going! We also want to force a commit if the current
278 * transaction is occupying too much of the log, or if the
279 --- kernel-rh-2.4.18-pristine/include/linux/blkdev.h Thu Jun 13 12:27:14 2002
280 +++ kernel-rh-2.4.18/include/linux/blkdev.h Thu Jun 13 15:18:33 2002
286 +#define CONFIG_DEV_RDONLY
287 +void dev_set_rdonly(kdev_t, int);
288 +int dev_check_rdonly(kdev_t);
289 +void dev_clear_rdonly(int);
291 --- kernel-rh-2.4.18-pristine/include/linux/jbd.h Thu Jun 13 12:27:14 2002
292 +++ kernel-rh-2.4.18/include/linux/jbd.h Thu Jun 13 15:18:35 2002
294 return bh->b_private;
297 +#define HAVE_JOURNAL_CALLBACK_STATUS
298 +struct journal_callback {
299 + struct list_head jcb_list;
300 + void (*jcb_func)(void *cb_data, int error);
301 + /* user data goes here */
304 struct jbd_revoke_table_s;
306 /* The handle_t type represents a single atomic update being performed
311 + /* List of application registered callbacks for this handle.
312 + * The function(s) will be called after the transaction that
313 + * this handle is part of has been committed to disk.
315 + struct list_head h_jcb;
318 unsigned int h_sync: 1; /* sync-on-close */
319 unsigned int h_jdata: 1; /* force data journaling */
322 /* How many handles used this transaction? */
325 + /* List of registered callback functions for this transaction.
326 + * Called when the transaction is committed. */
327 + struct list_head t_jcb;
332 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
333 extern int journal_stop(handle_t *);
334 extern int journal_flush (journal_t *);
335 +extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int),
338 extern void journal_lock_updates (journal_t *);
339 extern void journal_unlock_updates (journal_t *);
340 --- kernel-rh-2.4.18-pristine/kernel/ksyms.c Thu Jun 13 12:27:15 2002
341 +++ kernel-rh-2.4.18/kernel/ksyms.c Thu Jun 13 14:49:48 2002
343 EXPORT_SYMBOL(lock_may_write);
344 EXPORT_SYMBOL(dcache_readdir);
347 +EXPORT_SYMBOL(pagecache_lock);
348 +EXPORT_SYMBOL(do_kern_mount);
351 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
352 EXPORT_SYMBOL(default_llseek);
353 EXPORT_SYMBOL(dentry_open);
354 --- kernel-rh-2.4.18-pristine/include/linux/dcache.h Thu Jun 13 12:27:14 2002
355 +++ kernel-rh-2.4.18/include/linux/dcache.h Thu Jun 13 15:18:21 2002
357 #include <asm/atomic.h>
358 #include <linux/mount.h>
361 +#define IT_CREAT (1<<1)
362 +#define IT_MKDIR (1<<2)
363 +#define IT_LINK (1<<3)
364 +#define IT_SYMLINK (1<<4)
365 +#define IT_UNLINK (1<<5)
366 +#define IT_RMDIR (1<<6)
367 +#define IT_RENAME (1<<7)
368 +#define IT_RENAME2 (1<<8)
369 +#define IT_READDIR (1<<9)
370 +#define IT_GETATTR (1<<10)
371 +#define IT_SETATTR (1<<11)
372 +#define IT_READLINK (1<<12)
374 +struct lookup_intent {
377 + int it_disposition;
379 + struct iattr *it_iattr;
380 + __u64 it_lock_handle[2];
386 * linux/include/linux/dcache.h
389 unsigned long d_time; /* used by d_revalidate */
390 struct dentry_operations *d_op;
391 struct super_block * d_sb; /* The root of the dentry tree */
392 + struct lookup_intent *d_it;
393 unsigned long d_vfs_flags;
394 void * d_fsdata; /* fs-specific data */
395 void * d_extra_attributes; /* TUX-specific data */
397 int (*d_delete)(struct dentry *);
398 void (*d_release)(struct dentry *);
399 void (*d_iput)(struct dentry *, struct inode *);
400 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
401 + void (*d_intent_release)(struct dentry *);
404 /* the dentry parameter passed to d_hash and d_compare is the parent
405 --- kernel-rh-2.4.18-pristine/include/linux/fs.h Thu Jun 13 12:27:14 2002
406 +++ kernel-rh-2.4.18/include/linux/fs.h Thu Jun 13 15:18:21 2002
409 /* needed for tty driver, and maybe others */
411 + struct lookup_intent *f_intent;
413 /* preallocated helper kiobuf to speedup O_DIRECT */
414 struct kiobuf *f_iobuf;
416 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
417 extern int vfs_rmdir(struct inode *, struct dentry *);
418 extern int vfs_unlink(struct inode *, struct dentry *);
419 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
420 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
421 + struct inode *new_dir, struct dentry *new_dentry,
422 + struct lookup_intent *it);
427 struct inode_operations {
428 int (*create) (struct inode *,struct dentry *,int);
429 struct dentry * (*lookup) (struct inode *,struct dentry *);
430 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
431 int (*link) (struct dentry *,struct inode *,struct dentry *);
432 int (*unlink) (struct inode *,struct dentry *);
433 int (*symlink) (struct inode *,struct dentry *,const char *);
434 @@ -1034,6 +1038,7 @@
435 extern struct vfsmount *kern_mount(struct file_system_type *);
436 extern int may_umount(struct vfsmount *);
437 extern long do_mount(char *, char *, char *, unsigned long, void *);
438 +struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
439 extern void umount_tree(struct vfsmount *);
441 #define kern_umount mntput
442 @@ -1360,6 +1365,7 @@
443 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
445 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
446 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
447 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
448 extern int FASTCALL(path_walk(const char *, struct nameidata *));
449 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
450 @@ -1370,6 +1376,8 @@
451 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
452 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
453 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
454 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
455 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
457 extern void iput(struct inode *);
458 extern void force_delete(struct inode *);
459 --- kernel-rh-2.4.18-pristine/fs/namei.c Thu Jun 13 12:27:05 2002
460 +++ kernel-rh-2.4.18/fs/namei.c Thu Jun 13 15:08:19 2002
462 * XEmacs seems to be relying on it...
465 +void intent_release(struct dentry *de)
467 + if (de->d_op && de->d_op->d_intent_release)
468 + de->d_op->d_intent_release(de);
473 /* In order to reduce some races, while at the same time doing additional
474 * checking and hopefully speeding things up, we copy filenames to the
475 * kernel data space before using them..
476 @@ -260,10 +268,18 @@
477 * Internal lookup() using the new generic dcache.
480 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
481 +static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
483 struct dentry * dentry = d_lookup(parent, name);
485 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
486 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) && !d_invalidate(dentry)) {
493 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
494 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
497 * make sure that nobody added the entry to the dcache in the meantime..
500 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
501 +static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
503 struct dentry * result;
504 struct inode *dir = parent->d_inode;
506 result = ERR_PTR(-ENOMEM);
509 + if (dir->i_op->lookup2)
510 + result = dir->i_op->lookup2(dir, dentry, it);
512 result = dir->i_op->lookup(dir, dentry);
516 result = ERR_PTR(-ENOENT);
519 + if (result->d_op && result->d_op->d_revalidate2) {
520 + if (!result->d_op->d_revalidate2(result, flags, it) && !d_invalidate(result)) {
522 + result = ERR_PTR(-ENOENT);
530 * We expect 'base' to be positive and a directory.
532 -int link_path_walk(const char * name, struct nameidata *nd)
533 +int link_path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
535 struct dentry *dentry;
537 @@ -524,12 +549,12 @@
540 /* This does the actual lookups.. */
541 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
542 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
544 err = -EWOULDBLOCKIO;
547 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
548 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
549 err = PTR_ERR(dentry);
556 - if (!inode->i_op->lookup)
557 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
560 /* here ends the main loop */
561 @@ -590,12 +615,12 @@
565 - dentry = cached_lookup(nd->dentry, &this, 0);
566 + dentry = cached_lookup(nd->dentry, &this, 0, it);
568 err = -EWOULDBLOCKIO;
571 - dentry = real_lookup(nd->dentry, &this, 0);
572 + dentry = real_lookup(nd->dentry, &this, 0, it);
573 err = PTR_ERR(dentry);
578 if (lookup_flags & LOOKUP_DIRECTORY) {
580 - if (!inode->i_op || !inode->i_op->lookup)
581 + if (!inode->i_op || (!inode->i_op->lookup &&
582 + !inode->i_op->lookup2))
586 @@ -648,12 +674,24 @@
590 +int link_path_walk(const char * name, struct nameidata *nd)
592 + return link_path_walk_it(name, nd, NULL);
595 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
597 + current->total_link_count = 0;
598 + return link_path_walk_it(name, nd, it);
601 int path_walk(const char * name, struct nameidata *nd)
603 current->total_link_count = 0;
604 - return link_path_walk(name, nd);
605 + return link_path_walk_it(name, nd, NULL);
610 /* returns 1 if everything is done */
611 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
613 * needs parent already locked. Doesn't follow mounts.
616 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
617 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
618 + struct lookup_intent *it)
620 struct dentry * dentry;
622 @@ -777,13 +816,16 @@
626 - dentry = cached_lookup(base, name, 0);
627 + dentry = cached_lookup(base, name, 0, it);
629 struct dentry *new = d_alloc(base, name);
630 dentry = ERR_PTR(-ENOMEM);
634 + if (inode->i_op->lookup2)
635 + dentry = inode->i_op->lookup2(inode, new, it);
637 dentry = inode->i_op->lookup(inode, new);
644 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
646 + return lookup_hash_it(name, base, NULL);
651 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
655 this.hash = end_name_hash(hash);
657 - return lookup_hash(&this, base);
658 + return lookup_hash_it(&this, base, NULL);
660 return ERR_PTR(-EACCES);
666 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
671 + tmp = getname(name);
672 + err = PTR_ERR(tmp);
673 + if (!IS_ERR(tmp)) {
675 + if (path_init(tmp, flags, nd))
676 + err = path_walk_it(tmp, nd, it);
683 * It's inline, so penalty for filesystems that don't use sticky bit is
686 * for symlinks (where the permissions are checked later).
689 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
690 +int open_namei_it(const char * pathname, int flag, int mode, struct nameidata *nd,
691 + struct lookup_intent *it)
693 int acc_mode, error = 0;
696 * The simplest case - just a plain lookup.
698 if (!(flag & O_CREAT)) {
700 if (path_init(pathname, lookup_flags(flag), nd))
701 - error = path_walk(pathname, nd);
702 + error = path_walk_it(pathname, nd, it);
706 @@ -1009,6 +1075,8 @@
708 * Create - we need to know the parent.
711 + it->it_op |= IT_CREAT;
712 if (path_init(pathname, LOOKUP_PARENT, nd))
713 error = path_walk(pathname, nd);
715 @@ -1025,7 +1093,7 @@
718 down(&dir->d_inode->i_sem);
719 - dentry = lookup_hash(&nd->last, nd->dentry);
720 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
723 error = PTR_ERR(dentry);
724 @@ -1036,6 +1104,7 @@
726 /* Negative dentry, just create the file */
727 if (!dentry->d_inode) {
729 error = vfs_create(dir->d_inode, dentry,
730 mode & ~current->fs->umask);
731 up(&dir->d_inode->i_sem);
732 @@ -1195,13 +1264,20 @@
735 down(&dir->d_inode->i_sem);
736 - dentry = lookup_hash(&nd->last, nd->dentry);
737 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
738 putname(nd->last.name);
742 +int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
744 + return open_namei_it(pathname, flag, mode, nd, NULL);
749 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
750 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
751 + struct lookup_intent *it)
753 struct dentry *dentry;
755 @@ -1209,7 +1285,7 @@
756 dentry = ERR_PTR(-EEXIST);
757 if (nd->last_type != LAST_NORM)
759 - dentry = lookup_hash(&nd->last, nd->dentry);
760 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
763 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
764 @@ -1255,6 +1331,7 @@
766 struct dentry * dentry;
768 + struct lookup_intent it = { IT_CREAT , mode };
772 @@ -1266,11 +1343,12 @@
773 error = path_walk(tmp, &nd);
776 - dentry = lookup_create(&nd, 0);
777 + dentry = lookup_create(&nd, 0, &it);
778 error = PTR_ERR(dentry);
780 mode &= ~current->fs->umask;
781 if (!IS_ERR(dentry)) {
782 + dentry->d_it = ⁢
783 switch (mode & S_IFMT) {
784 case 0: case S_IFREG:
785 error = vfs_create(nd.dentry->d_inode,dentry,mode);
786 @@ -1286,6 +1364,7 @@
790 + intent_release(dentry);
791 up(&nd.dentry->d_inode->i_sem);
794 @@ -1324,6 +1403,7 @@
798 + struct lookup_intent it = { IT_MKDIR, mode };
800 tmp = getname(pathname);
801 error = PTR_ERR(tmp);
802 @@ -1335,13 +1415,15 @@
803 error = path_walk(tmp, &nd);
806 - dentry = lookup_create(&nd, 1);
807 + dentry = lookup_create(&nd, 1, &it);
808 error = PTR_ERR(dentry);
809 if (!IS_ERR(dentry)) {
810 + dentry->d_it = ⁢
811 error = vfs_mkdir(nd.dentry->d_inode, dentry,
812 mode & ~current->fs->umask);
815 + intent_release(dentry);
816 up(&nd.dentry->d_inode->i_sem);
819 @@ -1421,6 +1503,7 @@
821 struct dentry *dentry;
823 + struct lookup_intent it = { IT_RMDIR, 0 };
825 name = getname(pathname);
827 @@ -1443,10 +1526,12 @@
830 down(&nd.dentry->d_inode->i_sem);
831 - dentry = lookup_hash(&nd.last, nd.dentry);
832 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
833 error = PTR_ERR(dentry);
834 if (!IS_ERR(dentry)) {
835 + dentry->d_it = ⁢
836 error = vfs_rmdir(nd.dentry->d_inode, dentry);
837 + intent_release(dentry);
840 up(&nd.dentry->d_inode->i_sem);
841 @@ -1490,6 +1575,7 @@
843 struct dentry *dentry;
845 + struct lookup_intent it = { IT_UNLINK, 0 };
847 name = getname(pathname);
849 @@ -1503,14 +1589,16 @@
850 if (nd.last_type != LAST_NORM)
852 down(&nd.dentry->d_inode->i_sem);
853 - dentry = lookup_hash(&nd.last, nd.dentry);
854 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
855 error = PTR_ERR(dentry);
856 if (!IS_ERR(dentry)) {
857 + dentry->d_it = ⁢
858 /* Why not before? Because we want correct error value */
859 if (nd.last.name[nd.last.len])
861 error = vfs_unlink(nd.dentry->d_inode, dentry);
863 + intent_release(dentry);
866 up(&nd.dentry->d_inode->i_sem);
867 @@ -1557,6 +1645,7 @@
871 + struct lookup_intent it = { IT_SYMLINK, 0 };
873 from = getname(oldname);
875 @@ -1571,12 +1660,14 @@
876 error = path_walk(to, &nd);
879 - dentry = lookup_create(&nd, 0);
880 + dentry = lookup_create(&nd, 0, &it);
881 error = PTR_ERR(dentry);
882 if (!IS_ERR(dentry)) {
883 + dentry->d_it = ⁢
884 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
887 + intent_release(dentry);
888 up(&nd.dentry->d_inode->i_sem);
891 @@ -1640,6 +1731,7 @@
895 + struct lookup_intent it = { IT_LINK, 0 };
897 from = getname(oldname);
899 @@ -1662,12 +1754,14 @@
901 if (old_nd.mnt != nd.mnt)
903 - new_dentry = lookup_create(&nd, 0);
904 + new_dentry = lookup_create(&nd, 0, &it);
905 error = PTR_ERR(new_dentry);
906 if (!IS_ERR(new_dentry)) {
907 + new_dentry->d_it = ⁢
908 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
911 + intent_release(new_dentry);
912 up(&nd.dentry->d_inode->i_sem);
915 @@ -1708,7 +1802,8 @@
918 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
919 - struct inode *new_dir, struct dentry *new_dentry)
920 + struct inode *new_dir, struct dentry *new_dentry,
921 + struct lookup_intent *it)
924 struct inode *target;
925 @@ -1762,12 +1857,14 @@
927 double_down(&old_dir->i_zombie,
929 + new_dentry->d_it = it;
930 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
932 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
935 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
936 + intent_release(new_dentry);
939 target->i_flags |= S_DEAD;
940 @@ -1789,7 +1886,8 @@
943 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
944 - struct inode *new_dir, struct dentry *new_dentry)
945 + struct inode *new_dir, struct dentry *new_dentry,
946 + struct lookup_intent *it)
950 @@ -1816,10 +1914,12 @@
953 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
954 + new_dentry->d_it = it;
955 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
958 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
959 + intent_release(new_dentry);
960 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
963 @@ -1831,13 +1931,14 @@
966 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
967 - struct inode *new_dir, struct dentry *new_dentry)
968 + struct inode *new_dir, struct dentry *new_dentry,
969 + struct lookup_intent *it)
972 if (S_ISDIR(old_dentry->d_inode->i_mode))
973 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
974 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it);
976 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
977 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it);
979 if (old_dir == new_dir)
980 inode_dir_notify(old_dir, DN_RENAME);
981 @@ -1855,6 +1956,7 @@
982 struct dentry * old_dir, * new_dir;
983 struct dentry * old_dentry, *new_dentry;
984 struct nameidata oldnd, newnd;
985 + struct lookup_intent it = {IT_RENAME, 0};
987 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
988 error = path_walk(oldname, &oldnd);
989 @@ -1882,7 +1984,9 @@
991 double_lock(new_dir, old_dir);
993 - old_dentry = lookup_hash(&oldnd.last, old_dir);
994 + it.it_op = IT_RENAME;
996 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
997 error = PTR_ERR(old_dentry);
998 if (IS_ERR(old_dentry))
1000 @@ -1898,14 +2002,15 @@
1001 if (newnd.last.name[newnd.last.len])
1004 - new_dentry = lookup_hash(&newnd.last, new_dir);
1005 + it.it_op = IT_RENAME2;
1006 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1007 error = PTR_ERR(new_dentry);
1008 if (IS_ERR(new_dentry))
1012 error = vfs_rename(old_dir->d_inode, old_dentry,
1013 - new_dir->d_inode, new_dentry);
1014 + new_dir->d_inode, new_dentry, &it);
1018 --- kernel-rh-2.4.18-pristine/fs/open.c Thu Jun 13 12:27:08 2002
1019 +++ kernel-rh-2.4.18/fs/open.c Thu Jun 13 14:54:40 2002
1021 #include <asm/uaccess.h>
1023 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1024 +extern int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it);
1025 +extern void intent_release(struct dentry *de);
1027 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1030 struct nameidata nd;
1031 struct inode * inode;
1033 + struct lookup_intent it;
1035 + it.it_op = IT_SETATTR;
1039 if (length < 0) /* sorry, but loff_t says... */
1042 - error = user_path_walk(path, &nd);
1043 + error = user_path_walk_it(path, &nd, &it);
1046 + nd.dentry->d_it = ⁢
1047 inode = nd.dentry->d_inode;
1049 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1051 put_write_access(inode);
1054 + intent_release(nd.dentry);
1058 @@ -235,10 +243,14 @@
1059 struct nameidata nd;
1060 struct inode * inode;
1061 struct iattr newattrs;
1062 + struct lookup_intent it;
1064 + it.it_op = IT_SETATTR;
1066 - error = user_path_walk(filename, &nd);
1067 + error = user_path_walk_it(filename, &nd, &it);
1070 + nd.dentry->d_it = ⁢
1071 inode = nd.dentry->d_inode;
1076 error = notify_change(nd.dentry, &newattrs);
1078 + intent_release(nd.dentry);
1082 @@ -279,11 +292,15 @@
1083 struct nameidata nd;
1084 struct inode * inode;
1085 struct iattr newattrs;
1086 + struct lookup_intent it;
1088 + it.it_op = IT_SETATTR;
1090 - error = user_path_walk(filename, &nd);
1091 + error = user_path_walk_it(filename, &nd, &it);
1095 + nd.dentry->d_it = ⁢
1096 inode = nd.dentry->d_inode;
1101 error = notify_change(nd.dentry, &newattrs);
1103 + intent_release(nd.dentry);
1108 int old_fsuid, old_fsgid;
1109 kernel_cap_t old_cap;
1111 + struct lookup_intent it;
1113 + it.it_op = IT_GETATTR;
1115 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1119 current->cap_effective = current->cap_permitted;
1121 - res = user_path_walk(filename, &nd);
1122 + res = user_path_walk_it(filename, &nd, &it);
1124 res = permission(nd.dentry->d_inode, mode);
1125 /* SuS v2 requires we report a read only fs too */
1128 struct nameidata nd;
1130 + struct lookup_intent it;
1132 + it.it_op = IT_GETATTR;
1134 name = getname(filename);
1135 error = PTR_ERR(name);
1136 @@ -369,11 +393,12 @@
1139 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1140 - error = path_walk(name, &nd);
1141 + error = path_walk_it(name, &nd, &it);
1146 + nd.dentry->d_it = ⁢
1147 error = permission(nd.dentry->d_inode,MAY_EXEC);
1151 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1154 + intent_release(nd.dentry);
1160 struct nameidata nd;
1162 + struct lookup_intent it;
1164 + it.it_op = IT_GETATTR;
1166 name = getname(filename);
1167 error = PTR_ERR(name);
1168 @@ -429,11 +458,12 @@
1170 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1171 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1172 - error = path_walk(name, &nd);
1173 + error = path_walk_it(name, &nd, &it);
1178 + nd.dentry->d_it = ⁢
1179 error = permission(nd.dentry->d_inode,MAY_EXEC);
1186 + intent_release(nd.dentry);
1190 @@ -490,12 +521,15 @@
1191 struct inode * inode;
1193 struct iattr newattrs;
1194 + struct lookup_intent it;
1196 - error = user_path_walk(filename, &nd);
1197 + it.it_op = IT_SETATTR;
1198 + error = user_path_walk_it(filename, &nd, &it);
1201 inode = nd.dentry->d_inode;
1203 + nd.dentry->d_it = ⁢
1205 if (IS_RDONLY(inode))
1208 error = notify_change(nd.dentry, &newattrs);
1211 + intent_release(nd.dentry);
1215 @@ -580,10 +615,15 @@
1217 struct nameidata nd;
1219 + struct lookup_intent it;
1221 + it.it_op = IT_SETATTR;
1223 - error = user_path_walk(filename, &nd);
1224 + error = user_path_walk_it(filename, &nd, &it);
1226 + nd.dentry->d_it = ⁢
1227 error = chown_common(nd.dentry, user, group);
1228 + intent_release(nd.dentry);
1232 @@ -593,10 +633,15 @@
1234 struct nameidata nd;
1236 + struct lookup_intent it;
1238 - error = user_path_walk_link(filename, &nd);
1239 + it.it_op = IT_SETATTR;
1241 + error = user_path_walk_link_it(filename, &nd, &it);
1243 + nd.dentry->d_it = ⁢
1244 error = chown_common(nd.dentry, user, group);
1245 + intent_release(nd.dentry);
1249 @@ -630,10 +675,15 @@
1250 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1253 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1254 + struct nameidata *nd, struct lookup_intent *it);
1255 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it);
1257 struct file *filp_open(const char * filename, int flags, int mode)
1259 int namei_flags, error;
1260 struct nameidata nd;
1261 + struct lookup_intent it = {IT_OPEN, 0};
1263 namei_flags = flags;
1264 if ((namei_flags+1) & O_ACCMODE)
1265 @@ -641,14 +691,14 @@
1266 if (namei_flags & O_TRUNC)
1269 - error = open_namei(filename, namei_flags, mode, &nd);
1270 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1272 - return dentry_open(nd.dentry, nd.mnt, flags);
1273 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1275 return ERR_PTR(error);
1278 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1279 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it)
1282 struct inode *inode;
1286 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1291 @@ -710,6 +761,13 @@
1292 return ERR_PTR(error);
1295 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1297 + return dentry_open_it(dentry, mnt, flags, NULL);
1303 * Find an empty file descriptor entry, and mark it busy.
1305 --- kernel-rh-2.4.18-pristine/fs/stat.c Thu Jun 13 12:27:08 2002
1306 +++ kernel-rh-2.4.18/fs/stat.c Thu Jun 13 15:12:21 2002
1307 @@ -117,8 +117,11 @@
1309 struct nameidata nd;
1311 + struct lookup_intent it;
1312 + it.it_op = IT_GETATTR;
1314 - error = user_path_walk_link(name, &nd);
1316 + error = user_path_walk_link_it(name, &nd, &it);
1318 error = do_getattr(nd.mnt, nd.dentry, stat);
1320 @@ -269,14 +272,16 @@
1322 struct nameidata nd;
1324 + struct lookup_intent it;
1325 + it.it_op = IT_READLINK;
1330 - error = user_path_walk_link(path, &nd);
1331 + error = user_path_walk_link_it(path, &nd, &it);
1333 struct inode * inode = nd.dentry->d_inode;
1335 + nd.dentry->d_it = ⁢
1337 if (inode->i_op && inode->i_op->readlink &&
1338 !(error = do_revalidate(nd.dentry))) {
1339 --- kernel-rh-2.4.18/fs/nfsd/vfs.c.orig-lustre Thu Jun 13 15:28:25 2002
1340 +++ kernel-rh-2.4.18/fs/nfsd/vfs.c Thu Jun 13 15:28:40 2002
1341 @@ -1285,7 +1285,7 @@
1345 - err = vfs_rename(fdir, odentry, tdir, ndentry);
1346 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
1347 if (!err && EX_ISSYNC(tfhp->fh_export)) {
1348 nfsd_sync_dir(tdentry);
1349 nfsd_sync_dir(fdentry);