1 --- lum-pristine/arch/ia64/mm/init.c Fri Nov 9 17:26:17 2001
2 +++ lum/arch/ia64/mm/init.c Thu Aug 1 18:07:35 2002
5 static unsigned long totalram_pages;
7 +struct page *check_get_page(unsigned long kaddr)
9 +#warning FIXME: Lustre team, is this solid?
10 + return virt_to_page(kaddr);
14 do_check_pgt_cache (int low, int high)
16 --- lum-pristine/arch/i386/mm/init.c Fri Dec 21 12:41:53 2001
17 +++ lum/arch/i386/mm/init.c Thu Aug 1 18:07:35 2002
19 static unsigned long totalram_pages;
20 static unsigned long totalhigh_pages;
22 +struct page *check_get_page(unsigned long kaddr)
24 +#warning FIXME: Lustre team, is this solid?
25 + return virt_to_page(kaddr);
28 int do_check_pgt_cache(int low, int high)
31 --- lum-pristine/drivers/block/blkpg.c Mon Feb 25 14:37:57 2002
32 +++ lum/drivers/block/blkpg.c Thu Aug 1 18:07:35 2002
36 EXPORT_SYMBOL(blk_ioctl);
38 +#define NUM_DEV_NO_WRITE 16
39 +static int dev_no_write[NUM_DEV_NO_WRITE];
42 + * Debug code for turning block devices "read-only" (will discard writes
43 + * silently). This is for filesystem crash/recovery testing.
45 +void dev_set_rdonly(kdev_t dev, int no_write)
48 + printk(KERN_WARNING "Turning device %s read-only\n",
50 + dev_no_write[no_write] = 0xdead0000 + dev;
54 +int dev_check_rdonly(kdev_t dev) {
57 + for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
58 + if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
59 + dev == (dev_no_write[i] & 0xffff))
65 +void dev_clear_rdonly(int no_write) {
66 + dev_no_write[no_write] = 0;
69 +EXPORT_SYMBOL(dev_set_rdonly);
70 +EXPORT_SYMBOL(dev_check_rdonly);
71 +EXPORT_SYMBOL(dev_clear_rdonly);
72 --- lum-pristine/drivers/block/loop.c Fri Dec 21 12:41:53 2001
73 +++ lum/drivers/block/loop.c Thu Aug 1 18:07:35 2002
75 spin_unlock_irq(&lo->lo_lock);
78 +#ifdef CONFIG_DEV_RDONLY
79 + if (dev_check_rdonly(rbh->b_rdev))
83 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
85 } else if (rw == READA) {
86 --- lum-pristine/drivers/ide/ide-disk.c Fri Dec 21 12:41:54 2001
87 +++ lum/drivers/ide/ide-disk.c Thu Aug 1 18:07:35 2002
90 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
92 +#ifdef CONFIG_DEV_RDONLY
93 + if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
94 + ide_end_request(1, HWGROUP(drive));
99 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
100 OUT_BYTE(0x00, IDE_FEATURE_REG);
101 --- lum-pristine/fs/ext3/Makefile Fri Dec 21 12:41:55 2001
102 +++ lum/fs/ext3/Makefile Thu Aug 1 18:07:35 2002
107 +export-objs := super.o
109 obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
110 ioctl.o namei.o super.o symlink.o
112 --- lum-pristine/fs/ext3/super.c Mon Feb 25 14:38:08 2002
113 +++ lum/fs/ext3/super.c Thu Aug 1 18:07:35 2002
114 @@ -1744,7 +1744,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 --- lum-pristine/fs/jbd/commit.c Mon Feb 25 14:38:08 2002
124 +++ lum/fs/jbd/commit.c Thu Aug 1 18:07:35 2002
126 transaction's t_log_list queue, and metadata buffers are on
127 the t_iobuf_list queue.
129 - Wait for the transactions in reverse order. That way we are
130 + Wait for the buffers in reverse order. That way we are
131 less likely to be woken up until all IOs have completed, and
132 so we incur less scheduling load.
136 jbd_debug(3, "JBD: commit phase 6\n");
138 - if (is_journal_aborted(journal))
139 + if (is_journal_aborted(journal)) {
140 + unlock_journal(journal);
144 /* Done it all: now write the commit record. We should have
145 * cleaned up our previous buffers by now, so if we are in abort
147 descriptor = journal_get_descriptor_buffer(journal);
149 __journal_abort_hard(journal);
150 + unlock_journal(journal);
155 put_bh(bh); /* One for getblk() */
156 journal_unlock_journal_head(descriptor);
158 - lock_journal(journal);
160 /* End of a transaction! Finally, we can do checkpoint
161 processing: any buffers committed as a result of this
166 + /* Call any callbacks that had been registered for handles in this
167 + * transaction. It is up to the callback to free any allocated
170 + if (!list_empty(&commit_transaction->t_jcb)) {
171 + struct list_head *p, *n;
172 + int error = is_journal_aborted(journal);
174 + list_for_each_safe(p, n, &commit_transaction->t_jcb) {
175 + struct journal_callback *jcb;
177 + jcb = list_entry(p, struct journal_callback, jcb_list);
179 + jcb->jcb_func(jcb, error);
183 + lock_journal(journal);
185 jbd_debug(3, "JBD: commit phase 7\n");
187 J_ASSERT(commit_transaction->t_sync_datalist == NULL);
188 --- lum-pristine/fs/jbd/journal.c Mon Feb 25 14:38:08 2002
189 +++ lum/fs/jbd/journal.c Thu Aug 1 18:07:35 2002
192 EXPORT_SYMBOL(journal_flush);
193 EXPORT_SYMBOL(journal_revoke);
194 +EXPORT_SYMBOL(journal_callback_set);
196 EXPORT_SYMBOL(journal_init_dev);
197 EXPORT_SYMBOL(journal_init_inode);
198 --- lum-pristine/fs/jbd/transaction.c Mon Feb 25 14:38:08 2002
199 +++ lum/fs/jbd/transaction.c Thu Aug 1 18:07:35 2002
201 transaction->t_state = T_RUNNING;
202 transaction->t_tid = journal->j_transaction_sequence++;
203 transaction->t_expires = jiffies + journal->j_commit_interval;
204 + INIT_LIST_HEAD(&transaction->t_jcb);
206 /* Set up the commit timer for the new transaction. */
207 J_ASSERT (!journal->j_commit_timer_active);
212 +/* Allocate a new handle. This should probably be in a slab... */
213 +static handle_t *get_handle(int nblocks)
215 + handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
218 + memset(handle, 0, sizeof (handle_t));
219 + handle->h_buffer_credits = nblocks;
221 + INIT_LIST_HEAD(&handle->h_jcb);
227 * Obtain a new handle.
229 @@ -227,14 +242,11 @@
234 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
236 + handle = get_handle(nblocks);
238 return ERR_PTR(-ENOMEM);
239 - memset (handle, 0, sizeof (handle_t));
241 - handle->h_buffer_credits = nblocks;
243 current->journal_info = handle;
245 err = start_this_handle(journal, handle);
246 @@ -333,14 +345,11 @@
248 if (is_journal_aborted(journal))
249 return ERR_PTR(-EIO);
251 - handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
253 + handle = get_handle(nblocks);
255 return ERR_PTR(-ENOMEM);
256 - memset (handle, 0, sizeof (handle_t));
258 - handle->h_buffer_credits = nblocks;
260 current->journal_info = handle;
262 err = try_start_this_handle(journal, handle);
263 @@ -1328,6 +1337,29 @@
267 + * Register a callback function for this handle. The function will be
268 + * called when the transaction that this handle is part of has been
269 + * committed to disk with the original callback data struct and the
270 + * error status of the journal as parameters. There is no guarantee of
271 + * ordering between handles within a single transaction, nor between
272 + * callbacks registered on the same handle.
274 + * The caller is responsible for allocating the journal_callback struct.
275 + * This is to allow the caller to add as much extra data to the callback
276 + * as needed, but reduce the overhead of multiple allocations. The caller
277 + * allocated struct must start with a struct journal_callback at offset 0,
278 + * and has the caller-specific data afterwards.
280 +void journal_callback_set(handle_t *handle, void (*func)(void *, int),
283 + struct journal_callback *jcb = cb_data;
285 + list_add(&jcb->jcb_list, &handle->h_jcb);
286 + jcb->jcb_func = func;
290 * All done for a particular handle.
292 * There is not much action needed here. We just return any remaining
293 @@ -1383,7 +1415,10 @@
294 wake_up(&journal->j_wait_transaction_locked);
298 + /* Move callbacks from the handle to the transaction. */
299 + list_splice(&handle->h_jcb, &transaction->t_jcb);
302 * If the handle is marked SYNC, we need to set another commit
303 * going! We also want to force a commit if the current
304 * transaction is occupying too much of the log, or if the
305 --- lum-pristine/include/linux/blkdev.h Mon Nov 26 08:29:17 2001
306 +++ lum/include/linux/blkdev.h Mon Aug 12 11:48:39 2002
311 +#define CONFIG_DEV_RDONLY
312 +void dev_set_rdonly(kdev_t, int);
313 +int dev_check_rdonly(kdev_t);
314 +void dev_clear_rdonly(int);
316 --- lum-pristine/include/linux/slab.h Fri Dec 21 12:42:04 2001
317 +++ lum/include/linux/slab.h Mon Aug 12 11:48:38 2002
319 extern int kmem_cache_shrink(kmem_cache_t *);
320 extern void *kmem_cache_alloc(kmem_cache_t *, int);
321 extern void kmem_cache_free(kmem_cache_t *, void *);
322 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
324 extern void *kmalloc(size_t, int);
325 extern void kfree(const void *);
326 --- lum-pristine/include/linux/jbd.h Mon Feb 25 14:38:13 2002
327 +++ lum/include/linux/jbd.h Mon Aug 12 11:50:09 2002
329 return bh->b_private;
332 +#define HAVE_JOURNAL_CALLBACK_STATUS
333 +struct journal_callback {
334 + struct list_head jcb_list;
335 + void (*jcb_func)(void *cb_data, int error);
336 + /* user data goes here */
339 struct jbd_revoke_table_s;
341 /* The handle_t type represents a single atomic update being performed
346 + /* List of application registered callbacks for this handle.
347 + * The function(s) will be called after the transaction that
348 + * this handle is part of has been committed to disk.
350 + struct list_head h_jcb;
353 unsigned int h_sync: 1; /* sync-on-close */
354 unsigned int h_jdata: 1; /* force data journaling */
357 /* How many handles used this transaction? */
360 + /* List of registered callback functions for this transaction.
361 + * Called when the transaction is committed. */
362 + struct list_head t_jcb;
367 extern int journal_try_to_free_buffers(journal_t *, struct page *, int);
368 extern int journal_stop(handle_t *);
369 extern int journal_flush (journal_t *);
370 +extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int),
373 extern void journal_lock_updates (journal_t *);
374 extern void journal_unlock_updates (journal_t *);
375 --- lum-pristine/kernel/ksyms.c Mon Feb 25 14:38:13 2002
376 +++ lum/kernel/ksyms.c Thu Aug 1 18:07:35 2002
378 EXPORT_SYMBOL(lock_may_write);
379 EXPORT_SYMBOL(dcache_readdir);
382 +EXPORT_SYMBOL(panic_notifier_list);
383 +EXPORT_SYMBOL(pagecache_lock);
384 +EXPORT_SYMBOL(do_kern_mount);
385 +EXPORT_SYMBOL(kmem_cache_validate);
387 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
388 EXPORT_SYMBOL(default_llseek);
389 EXPORT_SYMBOL(dentry_open);
390 --- lum-pristine/include/linux/dcache.h Thu Nov 22 14:46:18 2001
391 +++ lum/include/linux/dcache.h Mon Aug 12 00:02:29 2002
393 #include <asm/atomic.h>
394 #include <linux/mount.h>
397 +#define IT_CREAT (1<<1)
398 +#define IT_MKDIR (1<<2)
399 +#define IT_LINK (1<<3)
400 +#define IT_SYMLINK (1<<4)
401 +#define IT_UNLINK (1<<5)
402 +#define IT_RMDIR (1<<6)
403 +#define IT_RENAME (1<<7)
404 +#define IT_RENAME2 (1<<8)
405 +#define IT_READDIR (1<<9)
406 +#define IT_GETATTR (1<<10)
407 +#define IT_SETATTR (1<<11)
408 +#define IT_READLINK (1<<12)
409 +#define IT_MKNOD (1<<13)
410 +#define IT_LOOKUP (1<<14)
412 +struct lookup_intent {
415 + int it_disposition;
417 + struct iattr *it_iattr;
418 + __u64 it_lock_handle[2];
424 * linux/include/linux/dcache.h
427 unsigned long d_time; /* used by d_revalidate */
428 struct dentry_operations *d_op;
429 struct super_block * d_sb; /* The root of the dentry tree */
430 + struct lookup_intent *d_it;
431 unsigned long d_vfs_flags;
432 void * d_fsdata; /* fs-specific data */
433 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
435 int (*d_delete)(struct dentry *);
436 void (*d_release)(struct dentry *);
437 void (*d_iput)(struct dentry *, struct inode *);
438 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
439 + void (*d_intent_release)(struct dentry *);
442 /* the dentry parameter passed to d_hash and d_compare is the parent
443 --- lum-pristine/include/linux/fs.h Mon Aug 12 11:02:53 2002
444 +++ lum/include/linux/fs.h Mon Aug 12 11:48:38 2002
447 /* needed for tty driver, and maybe others */
449 + struct lookup_intent *f_intent;
451 /* preallocated helper kiobuf to speedup O_DIRECT */
452 struct kiobuf *f_iobuf;
454 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
455 extern int vfs_rmdir(struct inode *, struct dentry *);
456 extern int vfs_unlink(struct inode *, struct dentry *);
457 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
458 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
459 + struct inode *new_dir, struct dentry *new_dentry,
460 + struct lookup_intent *it);
465 struct inode_operations {
466 int (*create) (struct inode *,struct dentry *,int);
467 struct dentry * (*lookup) (struct inode *,struct dentry *);
468 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
469 int (*link) (struct dentry *,struct inode *,struct dentry *);
470 int (*unlink) (struct inode *,struct dentry *);
471 int (*symlink) (struct inode *,struct dentry *,const char *);
473 extern struct vfsmount *kern_mount(struct file_system_type *);
474 extern int may_umount(struct vfsmount *);
475 extern long do_mount(char *, char *, char *, unsigned long, void *);
477 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
478 #define kern_umount mntput
480 extern int vfs_statfs(struct super_block *, struct statfs *);
481 @@ -1307,6 +1311,7 @@
482 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
484 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
485 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
486 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
487 extern int FASTCALL(path_walk(const char *, struct nameidata *));
488 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
489 @@ -1317,6 +1322,8 @@
490 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
491 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
492 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
493 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
494 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
496 extern void iput(struct inode *);
497 extern void force_delete(struct inode *);
498 --- lum-pristine/fs/dcache.c Mon Feb 25 14:38:08 2002
499 +++ lum/fs/dcache.c Thu Aug 1 18:07:35 2002
502 dentry->d_fsdata = NULL;
503 dentry->d_mounted = 0;
504 + dentry->d_it = NULL;
505 INIT_LIST_HEAD(&dentry->d_hash);
506 INIT_LIST_HEAD(&dentry->d_lru);
507 INIT_LIST_HEAD(&dentry->d_subdirs);
508 --- lum-pristine/fs/nfsd/vfs.c Fri Dec 21 12:41:55 2001
509 +++ lum/fs/nfsd/vfs.c Thu Aug 1 18:07:35 2002
510 @@ -1285,7 +1285,7 @@
514 - err = vfs_rename(fdir, odentry, tdir, ndentry);
515 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
516 if (!err && EX_ISSYNC(tfhp->fh_export)) {
517 nfsd_sync_dir(tdentry);
518 nfsd_sync_dir(fdentry);
519 --- lum-pristine/fs/namei.c Mon Feb 25 14:38:09 2002
520 +++ lum/fs/namei.c Mon Aug 12 11:47:56 2002
522 * XEmacs seems to be relying on it...
525 +void intent_release(struct dentry *de)
527 + if (de->d_op && de->d_op->d_intent_release)
528 + de->d_op->d_intent_release(de);
533 /* In order to reduce some races, while at the same time doing additional
534 * checking and hopefully speeding things up, we copy filenames to the
535 * kernel data space before using them..
536 @@ -260,10 +268,19 @@
537 * Internal lookup() using the new generic dcache.
540 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
541 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
542 + int flags, struct lookup_intent *it)
544 struct dentry * dentry = d_lookup(parent, name);
546 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
547 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
548 + !d_invalidate(dentry)) {
554 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
555 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
558 * make sure that nobody added the entry to the dcache in the meantime..
561 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
562 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
563 + int flags, struct lookup_intent *it)
565 struct dentry * result;
566 struct inode *dir = parent->d_inode;
568 result = ERR_PTR(-ENOMEM);
571 + if (dir->i_op->lookup2)
572 + result = dir->i_op->lookup2(dir, dentry, it);
574 result = dir->i_op->lookup(dir, dentry);
579 result = ERR_PTR(-ENOENT);
581 + } else if (result->d_op && result->d_op->d_revalidate2) {
582 + if (!result->d_op->d_revalidate2(result, flags, it) &&
583 + !d_invalidate(result)) {
585 + result = ERR_PTR(-ENOENT);
592 * We expect 'base' to be positive and a directory.
594 -int link_path_walk(const char * name, struct nameidata *nd)
595 +int link_path_walk_it(const char *name, struct nameidata *nd,
596 + struct lookup_intent *it)
598 struct dentry *dentry;
603 /* This does the actual lookups.. */
604 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
605 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
607 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
608 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
609 err = PTR_ERR(dentry);
616 - if (!inode->i_op->lookup)
617 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
620 /* here ends the main loop */
625 - dentry = cached_lookup(nd->dentry, &this, 0);
626 + dentry = cached_lookup(nd->dentry, &this, 0, it);
628 - dentry = real_lookup(nd->dentry, &this, 0);
629 + dentry = real_lookup(nd->dentry, &this, 0, it);
630 err = PTR_ERR(dentry);
635 if (lookup_flags & LOOKUP_DIRECTORY) {
637 - if (!inode->i_op || !inode->i_op->lookup)
638 + if (!inode->i_op || (!inode->i_op->lookup &&
639 + !inode->i_op->lookup2))
644 else if (this.len == 2 && this.name[1] == '.')
645 nd->last_type = LAST_DOTDOT;
647 + nd->dentry->d_it = it;
651 @@ -633,15 +663,29 @@
656 + nd->dentry->d_it = it;
660 +int link_path_walk(const char * name, struct nameidata *nd)
662 + return link_path_walk_it(name, nd, NULL);
665 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
667 + current->total_link_count = 0;
668 + return link_path_walk_it(name, nd, it);
671 int path_walk(const char * name, struct nameidata *nd)
673 current->total_link_count = 0;
674 - return link_path_walk(name, nd);
675 + return link_path_walk_it(name, nd, NULL);
680 /* returns 1 if everything is done */
681 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
683 * needs parent already locked. Doesn't follow mounts.
686 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
687 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
688 + struct lookup_intent *it)
690 struct dentry * dentry;
692 @@ -765,13 +810,16 @@
696 - dentry = cached_lookup(base, name, 0);
697 + dentry = cached_lookup(base, name, 0, it);
699 struct dentry *new = d_alloc(base, name);
700 dentry = ERR_PTR(-ENOMEM);
704 + if (inode->i_op->lookup2)
705 + dentry = inode->i_op->lookup2(inode, new, it);
707 dentry = inode->i_op->lookup(inode, new);
714 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
716 + return lookup_hash_it(name, base, NULL);
721 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
725 this.hash = end_name_hash(hash);
727 - return lookup_hash(&this, base);
728 + return lookup_hash_it(&this, base, NULL);
730 return ERR_PTR(-EACCES);
736 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
737 + struct lookup_intent *it)
742 + tmp = getname(name);
743 + err = PTR_ERR(tmp);
744 + if (!IS_ERR(tmp)) {
746 + if (path_init(tmp, flags, nd))
747 + err = path_walk_it(tmp, nd, it);
754 * It's inline, so penalty for filesystems that don't use sticky bit is
757 * for symlinks (where the permissions are checked later).
760 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
761 +int open_namei_it(const char *pathname, int flag, int mode,
762 + struct nameidata *nd, struct lookup_intent *it)
764 int acc_mode, error = 0;
766 @@ -984,17 +1056,22 @@
767 * The simplest case - just a plain lookup.
769 if (!(flag & O_CREAT)) {
770 if (path_init(pathname, lookup_flags(flag), nd))
771 - error = path_walk(pathname, nd);
772 + error = path_walk_it(pathname, nd, it);
781 * Create - we need to know the parent.
784 + it->it_mode = mode;
785 + it->it_op |= IT_CREAT;
787 if (path_init(pathname, LOOKUP_PARENT, nd))
788 error = path_walk(pathname, nd);
790 @@ -1011,7 +1089,7 @@
793 down(&dir->d_inode->i_sem);
794 - dentry = lookup_hash(&nd->last, nd->dentry);
795 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
798 error = PTR_ERR(dentry);
799 @@ -1020,6 +1098,8 @@
804 + dentry->d_it->it_mode = mode;
805 /* Negative dentry, just create the file */
806 if (!dentry->d_inode) {
807 error = vfs_create(dir->d_inode, dentry,
808 @@ -1139,8 +1219,10 @@
812 + intent_release(dentry);
815 + intent_release(nd->dentry);
819 @@ -1160,6 +1242,8 @@
821 UPDATE_ATIME(dentry->d_inode);
822 error = dentry->d_inode->i_op->follow_link(dentry, nd);
824 + intent_release(dentry);
828 @@ -1181,13 +1265,20 @@
831 down(&dir->d_inode->i_sem);
832 - dentry = lookup_hash(&nd->last, nd->dentry);
833 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
834 putname(nd->last.name);
838 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
840 + return open_namei_it(pathname, flag, mode, nd, NULL);
845 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
846 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
847 + struct lookup_intent *it)
849 struct dentry *dentry;
851 @@ -1195,7 +1286,7 @@
852 dentry = ERR_PTR(-EEXIST);
853 if (nd->last_type != LAST_NORM)
855 - dentry = lookup_hash(&nd->last, nd->dentry);
856 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
859 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
860 @@ -1241,6 +1332,7 @@
862 struct dentry * dentry;
864 + struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
868 @@ -1252,11 +1344,12 @@
869 error = path_walk(tmp, &nd);
872 - dentry = lookup_create(&nd, 0);
873 + dentry = lookup_create(&nd, 0, &it);
874 error = PTR_ERR(dentry);
876 mode &= ~current->fs->umask;
877 if (!IS_ERR(dentry)) {
878 + dentry->d_it = ⁢
879 switch (mode & S_IFMT) {
880 case 0: case S_IFREG:
881 error = vfs_create(nd.dentry->d_inode,dentry,mode);
882 @@ -1270,6 +1363,7 @@
886 + intent_release(dentry);
889 up(&nd.dentry->d_inode->i_sem);
890 @@ -1310,6 +1404,7 @@
894 + struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
896 tmp = getname(pathname);
897 error = PTR_ERR(tmp);
898 @@ -1321,11 +1416,13 @@
899 error = path_walk(tmp, &nd);
902 - dentry = lookup_create(&nd, 1);
903 + dentry = lookup_create(&nd, 1, &it);
904 error = PTR_ERR(dentry);
905 if (!IS_ERR(dentry)) {
906 + dentry->d_it = ⁢
907 error = vfs_mkdir(nd.dentry->d_inode, dentry,
908 mode & ~current->fs->umask);
909 + intent_release(dentry);
912 up(&nd.dentry->d_inode->i_sem);
913 @@ -1407,6 +1504,7 @@
915 struct dentry *dentry;
917 + struct lookup_intent it = { .it_op = IT_RMDIR };
919 name = getname(pathname);
921 @@ -1429,10 +1527,12 @@
924 down(&nd.dentry->d_inode->i_sem);
925 - dentry = lookup_hash(&nd.last, nd.dentry);
926 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
927 error = PTR_ERR(dentry);
928 if (!IS_ERR(dentry)) {
929 + dentry->d_it = ⁢
930 error = vfs_rmdir(nd.dentry->d_inode, dentry);
931 + intent_release(dentry);
934 up(&nd.dentry->d_inode->i_sem);
935 @@ -1476,6 +1576,7 @@
937 struct dentry *dentry;
939 + struct lookup_intent it = { .it_op = IT_UNLINK };
941 name = getname(pathname);
943 @@ -1489,14 +1590,16 @@
944 if (nd.last_type != LAST_NORM)
946 down(&nd.dentry->d_inode->i_sem);
947 - dentry = lookup_hash(&nd.last, nd.dentry);
948 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
949 error = PTR_ERR(dentry);
950 if (!IS_ERR(dentry)) {
951 + dentry->d_it = ⁢
952 /* Why not before? Because we want correct error value */
953 if (nd.last.name[nd.last.len])
955 error = vfs_unlink(nd.dentry->d_inode, dentry);
957 + intent_release(dentry);
960 up(&nd.dentry->d_inode->i_sem);
961 @@ -1543,6 +1646,7 @@
965 + struct lookup_intent it = { .it_op = IT_SYMLINK };
967 from = getname(oldname);
969 @@ -1557,10 +1661,13 @@
970 error = path_walk(to, &nd);
973 - dentry = lookup_create(&nd, 0);
975 + dentry = lookup_create(&nd, 0, &it);
976 error = PTR_ERR(dentry);
977 if (!IS_ERR(dentry)) {
978 + dentry->d_it = ⁢
979 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
980 + intent_release(dentry);
983 up(&nd.dentry->d_inode->i_sem);
984 @@ -1626,6 +1732,7 @@
988 + struct lookup_intent it = { .it_op = IT_LINK };
990 from = getname(oldname);
992 @@ -1639,7 +1745,7 @@
995 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
996 - error = path_walk(from, &old_nd);
997 + error = path_walk_it(from, &old_nd, &it);
1000 if (path_init(to, LOOKUP_PARENT, &nd))
1001 @@ -1648,10 +1755,13 @@
1003 if (old_nd.mnt != nd.mnt)
1005 - new_dentry = lookup_create(&nd, 0);
1006 + it.it_op = IT_LINK2;
1007 + new_dentry = lookup_create(&nd, 0, &it);
1008 error = PTR_ERR(new_dentry);
1009 if (!IS_ERR(new_dentry)) {
1010 + new_dentry->d_it = ⁢
1011 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
1012 + intent_release(new_dentry);
1015 up(&nd.dentry->d_inode->i_sem);
1016 @@ -1694,7 +1803,8 @@
1019 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1020 - struct inode *new_dir, struct dentry *new_dentry)
1021 + struct inode *new_dir, struct dentry *new_dentry,
1022 + struct lookup_intent *it)
1025 struct inode *target;
1026 @@ -1748,12 +1858,14 @@
1028 double_down(&old_dir->i_zombie,
1029 &new_dir->i_zombie);
1030 + new_dentry->d_it = it;
1031 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
1033 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1036 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1037 + intent_release(new_dentry);
1040 target->i_flags |= S_DEAD;
1041 @@ -1775,7 +1887,8 @@
1044 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1045 - struct inode *new_dir, struct dentry *new_dentry)
1046 + struct inode *new_dir, struct dentry *new_dentry,
1047 + struct lookup_intent *it)
1051 @@ -1802,10 +1915,12 @@
1052 DQUOT_INIT(old_dir);
1053 DQUOT_INIT(new_dir);
1054 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
1055 + new_dentry->d_it = it;
1056 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
1059 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
1060 + intent_release(new_dentry);
1061 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1064 @@ -1817,13 +1932,14 @@
1067 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1068 - struct inode *new_dir, struct dentry *new_dentry)
1069 + struct inode *new_dir, struct dentry *new_dentry,
1070 + struct lookup_intent *it)
1073 if (S_ISDIR(old_dentry->d_inode->i_mode))
1074 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1075 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1077 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1078 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1080 if (old_dir == new_dir)
1081 inode_dir_notify(old_dir, DN_RENAME);
1082 @@ -1840,6 +1956,7 @@
1084 struct dentry * old_dir, * new_dir;
1085 struct dentry * old_dentry, *new_dentry;
1086 + struct lookup_intent it = { .it_op = IT_RENAME };
1087 struct nameidata oldnd, newnd;
1089 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1090 @@ -1868,7 +1985,7 @@
1092 double_lock(new_dir, old_dir);
1094 - old_dentry = lookup_hash(&oldnd.last, old_dir);
1095 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1096 error = PTR_ERR(old_dentry);
1097 if (IS_ERR(old_dentry))
1099 @@ -1884,18 +2003,21 @@
1100 if (newnd.last.name[newnd.last.len])
1103 - new_dentry = lookup_hash(&newnd.last, new_dir);
1104 + it.it_op = IT_RENAME2;
1105 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1106 error = PTR_ERR(new_dentry);
1107 if (IS_ERR(new_dentry))
1111 error = vfs_rename(old_dir->d_inode, old_dentry,
1112 - new_dir->d_inode, new_dentry);
1113 + new_dir->d_inode, new_dentry, &it);
1116 + intent_release(new_dentry);
1119 + intent_release(old_dentry);
1122 double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1123 --- lum-pristine/fs/open.c Fri Oct 12 16:48:42 2001
1124 +++ lum/fs/open.c Sun Aug 11 15:26:29 2002
1126 #include <asm/uaccess.h>
1128 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1129 +extern int path_walk_it(const char *name, struct nameidata *nd,
1130 + struct lookup_intent *it);
1131 +extern void intent_release(struct dentry *de);
1133 int vfs_statfs(struct super_block *sb, struct statfs *buf)
1136 struct nameidata nd;
1137 struct inode * inode;
1139 + struct lookup_intent it = { .it_op = IT_SETATTR };
1142 if (length < 0) /* sorry, but loff_t says... */
1145 - error = user_path_walk(path, &nd);
1146 + error = user_path_walk_it(path, &nd, &it);
1149 + nd.dentry->d_it = ⁢
1150 inode = nd.dentry->d_inode;
1152 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
1154 put_write_access(inode);
1157 + intent_release(nd.dentry);
1161 @@ -235,10 +241,12 @@
1162 struct nameidata nd;
1163 struct inode * inode;
1164 struct iattr newattrs;
1165 + struct lookup_intent it = { .it_op = IT_SETATTR };
1167 - error = user_path_walk(filename, &nd);
1168 + error = user_path_walk_it(filename, &nd, &it);
1171 + nd.dentry->d_it = ⁢
1172 inode = nd.dentry->d_inode;
1177 error = notify_change(nd.dentry, &newattrs);
1179 + intent_release(nd.dentry);
1183 @@ -279,11 +288,13 @@
1184 struct nameidata nd;
1185 struct inode * inode;
1186 struct iattr newattrs;
1187 + struct lookup_intent it = { .it_op = IT_SETATTR };
1189 - error = user_path_walk(filename, &nd);
1190 + error = user_path_walk_it(filename, &nd, &it);
1194 + nd.dentry->d_it = ⁢
1195 inode = nd.dentry->d_inode;
1200 error = notify_change(nd.dentry, &newattrs);
1202 + intent_release(nd.dentry);
1207 int old_fsuid, old_fsgid;
1208 kernel_cap_t old_cap;
1210 + struct lookup_intent it = { .it_op = IT_GETATTR };
1212 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1214 @@ -339,13 +352,14 @@
1216 current->cap_effective = current->cap_permitted;
1218 - res = user_path_walk(filename, &nd);
1219 + res = user_path_walk_it(filename, &nd, &it);
1221 res = permission(nd.dentry->d_inode, mode);
1222 /* SuS v2 requires we report a read only fs too */
1223 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1224 && !special_file(nd.dentry->d_inode->i_mode))
1226 + intent_release(nd.dentry);
1232 struct nameidata nd;
1234 + struct lookup_intent it = { .it_op = IT_GETATTR };
1236 name = getname(filename);
1237 error = PTR_ERR(name);
1238 @@ -369,11 +384,12 @@
1241 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1242 - error = path_walk(name, &nd);
1243 + error = path_walk_it(name, &nd, &it);
1248 + nd.dentry->d_it = ⁢
1249 error = permission(nd.dentry->d_inode,MAY_EXEC);
1253 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1256 + intent_release(nd.dentry);
1262 struct nameidata nd;
1264 + struct lookup_intent it = { .it_op = IT_GETATTR };
1266 name = getname(filename);
1267 error = PTR_ERR(name);
1268 @@ -429,11 +447,12 @@
1270 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1271 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1272 - error = path_walk(name, &nd);
1273 + error = path_walk_it(name, &nd, &it);
1278 + nd.dentry->d_it = ⁢
1279 error = permission(nd.dentry->d_inode,MAY_EXEC);
1286 + intent_release(nd.dentry);
1290 @@ -490,12 +510,14 @@
1291 struct inode * inode;
1293 struct iattr newattrs;
1294 + struct lookup_intent it = { .it_op = IT_SETATTR };
1296 - error = user_path_walk(filename, &nd);
1297 + error = user_path_walk_it(filename, &nd, &it);
1300 inode = nd.dentry->d_inode;
1302 + nd.dentry->d_it = ⁢
1304 if (IS_RDONLY(inode))
1307 error = notify_change(nd.dentry, &newattrs);
1310 + intent_release(nd.dentry);
1314 @@ -580,10 +602,13 @@
1316 struct nameidata nd;
1318 + struct lookup_intent it = { .it_op = IT_SETATTR };
1320 - error = user_path_walk(filename, &nd);
1321 + error = user_path_walk_it(filename, &nd, &it);
1323 + nd.dentry->d_it = ⁢
1324 error = chown_common(nd.dentry, user, group);
1325 + intent_release(nd.dentry);
1329 @@ -593,10 +618,13 @@
1331 struct nameidata nd;
1333 + struct lookup_intent it = { .it_op = IT_SETATTR };
1335 - error = user_path_walk_link(filename, &nd);
1336 + error = user_path_walk_link_it(filename, &nd, &it);
1338 + nd.dentry->d_it = ⁢
1339 error = chown_common(nd.dentry, user, group);
1340 + intent_release(nd.dentry);
1344 @@ -630,10 +658,16 @@
1345 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1348 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1349 + struct nameidata *nd, struct lookup_intent *it);
1350 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1351 + int flags, struct lookup_intent *it);
1353 struct file *filp_open(const char * filename, int flags, int mode)
1355 int namei_flags, error;
1356 struct nameidata nd;
1357 + struct lookup_intent it = { .it_op = IT_OPEN };
1359 namei_flags = flags;
1360 if ((namei_flags+1) & O_ACCMODE)
1361 @@ -641,14 +675,15 @@
1362 if (namei_flags & O_TRUNC)
1365 - error = open_namei(filename, namei_flags, mode, &nd);
1367 - return dentry_open(nd.dentry, nd.mnt, flags);
1368 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1370 + return ERR_PTR(error);
1372 - return ERR_PTR(error);
1373 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1376 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1377 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1378 + int flags, struct lookup_intent *it)
1381 struct inode *inode;
1384 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1386 + intent_release(dentry);
1390 @@ -705,11 +741,17 @@
1394 + intent_release(dentry);
1397 return ERR_PTR(error);
1400 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1402 + return dentry_open_it(dentry, mnt, flags, NULL);
1406 * Find an empty file descriptor entry, and mark it busy.
1408 --- lum-pristine/fs/stat.c Thu Sep 13 19:04:43 2001
1409 +++ lum/fs/stat.c Mon Aug 12 00:04:39 2002
1412 #include <asm/uaccess.h>
1414 +extern void intent_release(struct dentry *de);
1416 * Revalidate the inode. This is required for proper NFS attribute caching.
1418 @@ -135,13 +135,15 @@
1419 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1421 struct nameidata nd;
1422 + struct lookup_intent it = { .it_op = IT_GETATTR };
1425 - error = user_path_walk(filename, &nd);
1426 + error = user_path_walk_it(filename, &nd, &it);
1428 error = do_revalidate(nd.dentry);
1430 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1431 + intent_release(nd.dentry);
1435 @@ -151,13 +153,15 @@
1436 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1438 struct nameidata nd;
1439 + struct lookup_intent it = { .it_op = IT_GETATTR };
1442 - error = user_path_walk(filename, &nd);
1443 + error = user_path_walk_it(filename, &nd, &it);
1445 error = do_revalidate(nd.dentry);
1447 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1448 + intent_release(nd.dentry);
1452 @@ -172,13 +176,15 @@
1453 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1455 struct nameidata nd;
1456 + struct lookup_intent it = { .it_op = IT_GETATTR };
1459 - error = user_path_walk_link(filename, &nd);
1460 + error = user_path_walk_link_it(filename, &nd, &it);
1462 error = do_revalidate(nd.dentry);
1464 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1465 + intent_release(nd.dentry);
1469 @@ -189,13 +195,15 @@
1470 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1472 struct nameidata nd;
1473 + struct lookup_intent it = { .it_op = IT_GETATTR };
1476 - error = user_path_walk_link(filename, &nd);
1477 + error = user_path_walk_link_it(filename, &nd, &it);
1479 error = do_revalidate(nd.dentry);
1481 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1482 + intent_release(nd.dentry);
1486 @@ -247,20 +255,21 @@
1488 struct nameidata nd;
1490 + struct lookup_intent it = { .it_op = IT_READLINK };
1495 - error = user_path_walk_link(path, &nd);
1496 + error = user_path_walk_link_it(path, &nd, &it);
1498 struct inode * inode = nd.dentry->d_inode;
1501 if (inode->i_op && inode->i_op->readlink &&
1502 !(error = do_revalidate(nd.dentry))) {
1503 UPDATE_ATIME(inode);
1504 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1506 + intent_release(nd.dentry);
1510 @@ -333,12 +342,14 @@
1512 struct nameidata nd;
1514 + 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_new_stat64(nd.dentry->d_inode, statbuf);
1522 + intent_release(nd.dentry);
1526 @@ -348,12 +359,14 @@
1528 struct nameidata nd;
1530 + struct lookup_intent it = { .it_op = IT_GETATTR };
1532 - error = user_path_walk_link(filename, &nd);
1533 + error = user_path_walk_link_it(filename, &nd, &it);
1535 error = do_revalidate(nd.dentry);
1537 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1538 + intent_release(nd.dentry);
1546 + struct lookup_intent it = { .it_op = IT_GETATTR };
1550 --- lum-pristine/mm/slab.c Fri Dec 21 12:42:05 2001
1551 +++ lum/mm/slab.c Thu Aug 1 18:07:35 2002
1552 @@ -1187,6 +1187,59 @@
1553 * Called with the cache-lock held.
1556 +extern struct page *check_get_page(unsigned long kaddr);
1557 +struct page *page_mem_map(struct page *page);
1558 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1559 + slab_t *slabp, void * objp)
1562 + unsigned int objnr;
1565 + if (cachep->flags & SLAB_RED_ZONE) {
1566 + objp -= BYTES_PER_WORD;
1567 + if ( *(unsigned long *)objp != RED_MAGIC2)
1568 + /* Either write before start, or a double free. */
1570 + if (*(unsigned long *)(objp+cachep->objsize -
1571 + BYTES_PER_WORD) != RED_MAGIC2)
1572 + /* Either write past end, or a double free. */
1577 + objnr = (objp-slabp->s_mem)/cachep->objsize;
1578 + if (objnr >= cachep->num)
1580 + if (objp != slabp->s_mem + objnr*cachep->objsize)
1583 + /* Check slab's freelist to see if this obj is there. */
1584 + for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1592 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1594 + struct page *page = check_get_page((unsigned long)objp);
1596 + if (!VALID_PAGE(page))
1599 + if (!PageSlab(page))
1602 + /* XXX check for freed slab objects ? */
1603 + if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1606 + return (cachep == GET_PAGE_CACHE(page));
1610 static int kmem_extra_free_checks (kmem_cache_t * cachep,
1611 slab_t *slabp, void * objp)