From: braam Date: Mon, 20 Jan 2003 04:21:05 +0000 (+0000) Subject: - kernel patches for vanilla 2.4.19, 2.4.19-hp2-2 (not tested much) X-Git-Tag: v1_7_0_51~2^13~75 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=6c3c496c31a993db28a0a581869c4af534f0a810;p=fs%2Flustre-release.git - kernel patches for vanilla 2.4.19, 2.4.19-hp2-2 (not tested much) - tiny fix to dcache.c --- diff --git a/lustre/kernel_patches/patches/dev_read_only_hp.patch b/lustre/kernel_patches/patches/dev_read_only_hp.patch new file mode 100644 index 0000000..0a32769 --- /dev/null +++ b/lustre/kernel_patches/patches/dev_read_only_hp.patch @@ -0,0 +1,83 @@ + drivers/block/blkpg.c | 38 ++++++++++++++++++++++++++++++++++++++ + drivers/block/loop.c | 5 +++++ + drivers/ide/ide-disk.c | 6 ++++++ + 3 files changed, 49 insertions(+) + +--- linux-2.4.19-hp2_pnnl2/drivers/block/blkpg.c~dev_read_only_hp Sun Jan 19 18:51:12 2003 ++++ linux-2.4.19-hp2_pnnl2-root/drivers/block/blkpg.c Sun Jan 19 18:52:28 2003 +@@ -310,6 +310,44 @@ int blk_ioctl(kdev_t dev, unsigned int c + + EXPORT_SYMBOL(blk_ioctl); + ++ ++#define NUM_DEV_NO_WRITE 16 ++static int dev_no_write[NUM_DEV_NO_WRITE]; ++ ++/* ++ * Debug code for turning block devices "read-only" (will discard writes ++ * silently). This is for filesystem crash/recovery testing. ++ */ ++void dev_set_rdonly(kdev_t dev, int no_write) ++{ ++ if (dev) { ++ printk(KERN_WARNING "Turning device %s read-only\n", ++ bdevname(dev)); ++ dev_no_write[no_write] = 0xdead0000 + dev; ++ } ++} ++ ++int dev_check_rdonly(kdev_t dev) { ++ int i; ++ ++ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { ++ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && ++ dev == (dev_no_write[i] & 0xffff)) ++ return 1; ++ } ++ return 0; ++} ++ ++void dev_clear_rdonly(int no_write) { ++ dev_no_write[no_write] = 0; ++} ++ ++EXPORT_SYMBOL(dev_set_rdonly); ++EXPORT_SYMBOL(dev_check_rdonly); ++EXPORT_SYMBOL(dev_clear_rdonly); ++ ++ ++ + /** + * get_last_sector() + * +--- linux-2.4.19-hp2_pnnl2/drivers/block/loop.c~dev_read_only_hp Sun Jan 19 18:51:12 2003 ++++ linux-2.4.19-hp2_pnnl2-root/drivers/block/loop.c Sun Jan 19 18:51:12 2003 +@@ -474,6 +474,11 @@ static int loop_make_request(request_que + spin_unlock_irq(&lo->lo_lock); + + if (rw == WRITE) { ++#ifdef CONFIG_DEV_RDONLY ++ if (dev_check_rdonly(rbh->b_rdev)) ++ goto err; ++#endif ++ + if (lo->lo_flags & LO_FLAGS_READ_ONLY) + goto err; + } else if (rw == READA) { +--- linux-2.4.19-hp2_pnnl2/drivers/ide/ide-disk.c~dev_read_only_hp Sun Jan 19 18:51:12 2003 ++++ linux-2.4.19-hp2_pnnl2-root/drivers/ide/ide-disk.c Sun Jan 19 18:51:12 2003 +@@ -551,6 +551,12 @@ static ide_startstop_t lba_48_rw_disk (i + */ + static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) + { ++#ifdef CONFIG_DEV_RDONLY ++ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { ++ ide_end_request(1, HWGROUP(drive)); ++ return ide_stopped; ++ } ++#endif + if (IDE_CONTROL_REG) + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); + + +_ diff --git a/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch b/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch new file mode 100644 index 0000000..e226466 --- /dev/null +++ b/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch @@ -0,0 +1,121 @@ + arch/i386/mm/init.c | 6 +++++ + arch/ia64/mm/init.c | 6 +++++ + include/linux/slab.h | 1 + kernel/ksyms.c | 1 + mm/slab.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 67 insertions(+) + +--- linux-2.4.19-hp2_pnnl2/arch/i386/mm/init.c~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 ++++ linux-2.4.19-hp2_pnnl2-root/arch/i386/mm/init.c Sun Jan 19 18:59:24 2003 +@@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn + static unsigned long totalram_pages; + static unsigned long totalhigh_pages; + ++struct page *check_get_page(unsigned long kaddr) ++{ ++#warning FIXME: Lustre team, is this solid? ++ return virt_to_page(kaddr); ++} ++ + int do_check_pgt_cache(int low, int high) + { + int freed = 0; +--- linux-2.4.19-hp2_pnnl2/arch/ia64/mm/init.c~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 ++++ linux-2.4.19-hp2_pnnl2-root/arch/ia64/mm/init.c Sun Jan 19 18:59:24 2003 +@@ -44,6 +44,12 @@ unsigned long vmalloc_end = VMALLOC_END_ + static struct page *vmem_map; + static unsigned long num_dma_physpages; + ++struct page *check_get_page(unsigned long kaddr) ++{ ++#warning FIXME: Lustre team, is this solid? ++ return virt_to_page(kaddr); ++} ++ + int + do_check_pgt_cache (int low, int high) + { +--- linux-2.4.19-hp2_pnnl2/include/linux/slab.h~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 ++++ linux-2.4.19-hp2_pnnl2-root/include/linux/slab.h Sun Jan 19 19:01:07 2003 +@@ -56,6 +56,7 @@ extern kmem_cache_t *kmem_cache_create(c + extern int kmem_cache_destroy(kmem_cache_t *); + extern int kmem_cache_shrink(kmem_cache_t *); + extern void *kmem_cache_alloc(kmem_cache_t *, int); ++extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); + extern void kmem_cache_free(kmem_cache_t *, void *); + extern unsigned int kmem_cache_size(kmem_cache_t *); + +--- linux-2.4.19-hp2_pnnl2/kernel/ksyms.c~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 ++++ linux-2.4.19-hp2_pnnl2-root/kernel/ksyms.c Sun Jan 19 19:00:32 2003 +@@ -118,6 +118,7 @@ EXPORT_SYMBOL(kmem_find_general_cachep); + EXPORT_SYMBOL(kmem_cache_create); + EXPORT_SYMBOL(kmem_cache_destroy); + EXPORT_SYMBOL(kmem_cache_shrink); ++EXPORT_SYMBOL(kmem_cache_validate); + EXPORT_SYMBOL(kmem_cache_alloc); + EXPORT_SYMBOL(kmem_cache_free); + EXPORT_SYMBOL(kmem_cache_size); +--- linux-2.4.19-hp2_pnnl2/mm/slab.c~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 ++++ linux-2.4.19-hp2_pnnl2-root/mm/slab.c Sun Jan 19 18:59:24 2003 +@@ -1207,6 +1207,59 @@ failed: + * Called with the cache-lock held. + */ + ++extern struct page *check_get_page(unsigned long kaddr); ++struct page *page_mem_map(struct page *page); ++static int kmem_check_cache_obj (kmem_cache_t * cachep, ++ slab_t *slabp, void * objp) ++{ ++ int i; ++ unsigned int objnr; ++ ++#if DEBUG ++ if (cachep->flags & SLAB_RED_ZONE) { ++ objp -= BYTES_PER_WORD; ++ if ( *(unsigned long *)objp != RED_MAGIC2) ++ /* Either write before start, or a double free. */ ++ return 0; ++ if (*(unsigned long *)(objp+cachep->objsize - ++ BYTES_PER_WORD) != RED_MAGIC2) ++ /* Either write past end, or a double free. */ ++ return 0; ++ } ++#endif ++ ++ objnr = (objp-slabp->s_mem)/cachep->objsize; ++ if (objnr >= cachep->num) ++ return 0; ++ if (objp != slabp->s_mem + objnr*cachep->objsize) ++ return 0; ++ ++ /* Check slab's freelist to see if this obj is there. */ ++ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { ++ if (i == objnr) ++ return 0; ++ } ++ return 1; ++} ++ ++ ++int kmem_cache_validate(kmem_cache_t *cachep, void *objp) ++{ ++ struct page *page = check_get_page((unsigned long)objp); ++ ++ if (!VALID_PAGE(page)) ++ return 0; ++ ++ if (!PageSlab(page)) ++ return 0; ++ ++ /* XXX check for freed slab objects ? */ ++ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) ++ return 0; ++ ++ return (cachep == GET_PAGE_CACHE(page)); ++} ++ + #if DEBUG + static int kmem_extra_free_checks (kmem_cache_t * cachep, + slab_t *slabp, void * objp) + +_ diff --git a/lustre/kernel_patches/patches/vfs_intent_hp.patch b/lustre/kernel_patches/patches/vfs_intent_hp.patch new file mode 100644 index 0000000..b740787 --- /dev/null +++ b/lustre/kernel_patches/patches/vfs_intent_hp.patch @@ -0,0 +1,1351 @@ + fs/dcache.c | 3 + fs/namei.c | 306 ++++++++++++++++++++++++++++++++++++++++--------- + fs/nfsd/vfs.c | 2 + fs/open.c | 63 +++++++--- + fs/stat.c | 29 +++- + include/linux/dcache.h | 31 ++++ + include/linux/fs.h | 22 +++ + kernel/ksyms.c | 1 + 8 files changed, 384 insertions(+), 73 deletions(-) + +--- linux-2.4.19-hp2_pnnl2/fs/dcache.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/fs/dcache.c Sun Jan 19 19:04:47 2003 +@@ -145,6 +145,8 @@ repeat: + unhash_it: + list_del_init(&dentry->d_hash); + ++ ++ + kill_it: { + struct dentry *parent; + list_del(&dentry->d_child); +@@ -616,6 +618,7 @@ struct dentry * d_alloc(struct dentry * + dentry->d_op = NULL; + dentry->d_fsdata = NULL; + dentry->d_mounted = 0; ++ dentry->d_it = NULL; + INIT_LIST_HEAD(&dentry->d_hash); + INIT_LIST_HEAD(&dentry->d_lru); + INIT_LIST_HEAD(&dentry->d_subdirs); +--- linux-2.4.19-hp2_pnnl2/fs/namei.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/fs/namei.c Sun Jan 19 19:35:55 2003 +@@ -1,3 +1,6 @@ ++ ++ ++ + /* + * linux/fs/namei.c + * +@@ -94,6 +97,14 @@ + * XEmacs seems to be relying on it... + */ + ++void intent_release(struct dentry *de, struct lookup_intent *it) ++{ ++ if (it && de->d_op && de->d_op->d_intent_release) ++ de->d_op->d_intent_release(de, it); ++ ++} ++ ++ + /* In order to reduce some races, while at the same time doing additional + * checking and hopefully speeding things up, we copy filenames to the + * kernel data space before using them.. +@@ -260,10 +271,19 @@ void path_release(struct nameidata *nd) + * Internal lookup() using the new generic dcache. + * SMP-safe + */ +-static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) ++static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, ++ int flags, struct lookup_intent *it) + { + struct dentry * dentry = d_lookup(parent, name); + ++ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { ++ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && ++ !d_invalidate(dentry)) { ++ dput(dentry); ++ dentry = NULL; ++ } ++ return dentry; ++ } else + if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { + if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { + dput(dentry); +@@ -281,7 +301,8 @@ static struct dentry * cached_lookup(str + * make sure that nobody added the entry to the dcache in the meantime.. + * SMP-safe + */ +-static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) ++static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, ++ int flags, struct lookup_intent *it) + { + struct dentry * result; + struct inode *dir = parent->d_inode; +@@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc + result = ERR_PTR(-ENOMEM); + if (dentry) { + lock_kernel(); ++ if (dir->i_op->lookup2) ++ result = dir->i_op->lookup2(dir, dentry, it); ++ else + result = dir->i_op->lookup(dir, dentry); + unlock_kernel(); + if (result) +@@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc + dput(result); + result = ERR_PTR(-ENOENT); + } ++ } else if (result->d_op && result->d_op->d_revalidate2) { ++ if (!result->d_op->d_revalidate2(result, flags, it) && ++ !d_invalidate(result)) { ++ dput(result); ++ result = ERR_PTR(-ENOENT); ++ } + } + return result; + } +@@ -332,7 +362,8 @@ static struct dentry * real_lookup(struc + * Without that kind of total limit, nasty chains of consecutive + * symlinks can cause almost arbitrarily long lookups. + */ +-static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) ++static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, ++ struct lookup_intent *it) + { + int err; + if (current->link_count >= 5) +@@ -346,10 +377,14 @@ static inline int do_follow_link(struct + current->link_count++; + current->total_link_count++; + UPDATE_ATIME(dentry->d_inode); +- err = dentry->d_inode->i_op->follow_link(dentry, nd); ++ if (dentry->d_inode->i_op->follow_link2) ++ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); ++ else ++ err = dentry->d_inode->i_op->follow_link(dentry, nd); + current->link_count--; + return err; + loop: ++ intent_release(dentry, it); + path_release(nd); + return -ELOOP; + } +@@ -447,7 +482,8 @@ static inline void follow_dotdot(struct + * + * We expect 'base' to be positive and a directory. + */ +-int link_path_walk(const char * name, struct nameidata *nd) ++int link_path_walk_it(const char *name, struct nameidata *nd, ++ struct lookup_intent *it) + { + struct dentry *dentry; + struct inode *inode; +@@ -520,9 +556,9 @@ int link_path_walk(const char * name, st + break; + } + /* This does the actual lookups.. */ +- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); ++ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); + if (!dentry) { +- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); ++ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); + err = PTR_ERR(dentry); + if (IS_ERR(dentry)) + break; +@@ -539,8 +575,8 @@ int link_path_walk(const char * name, st + if (!inode->i_op) + goto out_dput; + +- if (inode->i_op->follow_link) { +- err = do_follow_link(dentry, nd); ++ if (inode->i_op->follow_link || inode->i_op->follow_link2) { ++ err = do_follow_link(dentry, nd, NULL); + dput(dentry); + if (err) + goto return_err; +@@ -556,7 +592,7 @@ int link_path_walk(const char * name, st + nd->dentry = dentry; + } + err = -ENOTDIR; +- if (!inode->i_op->lookup) ++ if (!inode->i_op->lookup && !inode->i_op->lookup2) + break; + continue; + /* here ends the main loop */ +@@ -583,9 +619,9 @@ last_component: + if (err < 0) + break; + } +- dentry = cached_lookup(nd->dentry, &this, 0); ++ dentry = cached_lookup(nd->dentry, &this, 0, it); + if (!dentry) { +- dentry = real_lookup(nd->dentry, &this, 0); ++ dentry = real_lookup(nd->dentry, &this, 0, it); + err = PTR_ERR(dentry); + if (IS_ERR(dentry)) + break; +@@ -594,8 +630,10 @@ last_component: + ; + inode = dentry->d_inode; + if ((lookup_flags & LOOKUP_FOLLOW) +- && inode && inode->i_op && inode->i_op->follow_link) { +- err = do_follow_link(dentry, nd); ++ && inode && inode->i_op && ++ (inode->i_op->follow_link || ++ inode->i_op->follow_link2)) { ++ err = do_follow_link(dentry, nd, it); + dput(dentry); + if (err) + goto return_err; +@@ -609,7 +647,8 @@ last_component: + goto no_inode; + if (lookup_flags & LOOKUP_DIRECTORY) { + err = -ENOTDIR; +- if (!inode->i_op || !inode->i_op->lookup) ++ if (!inode->i_op || (!inode->i_op->lookup && ++ !inode->i_op->lookup2)) + break; + } + goto return_base; +@@ -646,15 +685,28 @@ out_dput: + dput(dentry); + break; + } ++ if (err) ++ intent_release(nd->dentry, it); + path_release(nd); + return_err: + return err; + } + ++int link_path_walk(const char * name, struct nameidata *nd) ++{ ++ return link_path_walk_it(name, nd, NULL); ++} ++ ++int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) ++{ ++ current->total_link_count = 0; ++ return link_path_walk_it(name, nd, it); ++} ++ + int path_walk(const char * name, struct nameidata *nd) + { + current->total_link_count = 0; +- return link_path_walk(name, nd); ++ return link_path_walk_it(name, nd, NULL); + } + + /* SMP-safe */ +@@ -757,7 +809,8 @@ int path_init(const char *name, unsigned + * needs parent already locked. Doesn't follow mounts. + * SMP-safe. + */ +-struct dentry * lookup_hash(struct qstr *name, struct dentry * base) ++struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, ++ struct lookup_intent *it) + { + struct dentry * dentry; + struct inode *inode; +@@ -780,13 +833,16 @@ struct dentry * lookup_hash(struct qstr + goto out; + } + +- dentry = cached_lookup(base, name, 0); ++ dentry = cached_lookup(base, name, 0, it); + if (!dentry) { + struct dentry *new = d_alloc(base, name); + dentry = ERR_PTR(-ENOMEM); + if (!new) + goto out; + lock_kernel(); ++ if (inode->i_op->lookup2) ++ dentry = inode->i_op->lookup2(inode, new, it); ++ else + dentry = inode->i_op->lookup(inode, new); + unlock_kernel(); + if (!dentry) +@@ -798,6 +854,12 @@ out: + return dentry; + } + ++struct dentry * lookup_hash(struct qstr *name, struct dentry * base) ++{ ++ return lookup_hash_it(name, base, NULL); ++} ++ ++ + /* SMP-safe */ + struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) + { +@@ -819,7 +881,7 @@ struct dentry * lookup_one_len(const cha + } + this.hash = end_name_hash(hash); + +- return lookup_hash(&this, base); ++ return lookup_hash_it(&this, base, NULL); + access: + return ERR_PTR(-EACCES); + } +@@ -851,6 +913,23 @@ int __user_walk(const char *name, unsign + return err; + } + ++int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, ++ struct lookup_intent *it) ++{ ++ char *tmp; ++ int err; ++ ++ tmp = getname(name); ++ err = PTR_ERR(tmp); ++ if (!IS_ERR(tmp)) { ++ err = 0; ++ if (path_init(tmp, flags, nd)) ++ err = path_walk_it(tmp, nd, it); ++ putname(tmp); ++ } ++ return err; ++} ++ + /* + * It's inline, so penalty for filesystems that don't use sticky bit is + * minimal. +@@ -987,7 +1066,8 @@ exit_lock: + * for symlinks (where the permissions are checked later). + * SMP-safe + */ +-int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) ++int open_namei_it(const char *pathname, int flag, int mode, ++ struct nameidata *nd, struct lookup_intent *it) + { + int acc_mode, error = 0; + struct inode *inode; +@@ -1002,7 +1082,7 @@ int open_namei(const char * pathname, in + */ + if (!(flag & O_CREAT)) { + if (path_init(pathname, lookup_flags(flag), nd)) +- error = path_walk(pathname, nd); ++ error = path_walk_it(pathname, nd, it); + if (error) + return error; + dentry = nd->dentry; +@@ -1012,6 +1092,10 @@ int open_namei(const char * pathname, in + /* + * Create - we need to know the parent. + */ ++ if (it) { ++ it->it_mode = mode; ++ it->it_op |= IT_CREAT; ++ } + if (path_init(pathname, LOOKUP_PARENT, nd)) + error = path_walk(pathname, nd); + if (error) +@@ -1028,7 +1112,7 @@ int open_namei(const char * pathname, in + + dir = nd->dentry; + down(&dir->d_inode->i_sem); +- dentry = lookup_hash(&nd->last, nd->dentry); ++ dentry = lookup_hash_it(&nd->last, nd->dentry, it); + + do_last: + error = PTR_ERR(dentry); +@@ -1037,6 +1121,7 @@ do_last: + goto exit; + } + ++ it->it_mode = mode; + /* Negative dentry, just create the file */ + if (!dentry->d_inode) { + if (!IS_POSIXACL(dir->d_inode)) +@@ -1071,7 +1156,8 @@ do_last: + error = -ENOENT; + if (!dentry->d_inode) + goto exit_dput; +- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) ++ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || ++ dentry->d_inode->i_op->follow_link2)) + goto do_link; + + dput(nd->dentry); +@@ -1157,8 +1243,10 @@ ok: + return 0; + + exit_dput: ++ intent_release(dentry, it); + dput(dentry); + exit: ++ intent_release(nd->dentry, it); + path_release(nd); + return error; + +@@ -1177,7 +1265,12 @@ do_link: + * are done. Procfs-like symlinks just set LAST_BIND. + */ + UPDATE_ATIME(dentry->d_inode); +- error = dentry->d_inode->i_op->follow_link(dentry, nd); ++ if (dentry->d_inode->i_op->follow_link2) ++ error = dentry->d_inode->i_op->follow_link2(dentry, nd, it); ++ else ++ error = dentry->d_inode->i_op->follow_link(dentry, nd); ++ if (error) ++ intent_release(dentry, it); + dput(dentry); + if (error) + return error; +@@ -1199,13 +1292,20 @@ do_link: + } + dir = nd->dentry; + down(&dir->d_inode->i_sem); +- dentry = lookup_hash(&nd->last, nd->dentry); ++ dentry = lookup_hash_it(&nd->last, nd->dentry, it); + putname(nd->last.name); + goto do_last; + } + ++int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) ++{ ++ return open_namei_it(pathname, flag, mode, nd, NULL); ++} ++ ++ + /* SMP-safe */ +-static struct dentry *lookup_create(struct nameidata *nd, int is_dir) ++static struct dentry *lookup_create(struct nameidata *nd, int is_dir, ++ struct lookup_intent *it) + { + struct dentry *dentry; + +@@ -1213,7 +1313,7 @@ static struct dentry *lookup_create(stru + dentry = ERR_PTR(-EEXIST); + if (nd->last_type != LAST_NORM) + goto fail; +- dentry = lookup_hash(&nd->last, nd->dentry); ++ dentry = lookup_hash_it(&nd->last, nd->dentry, it); + if (IS_ERR(dentry)) + goto fail; + if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) +@@ -1259,6 +1359,7 @@ asmlinkage long sys_mknod(const char * f + char * tmp; + struct dentry * dentry; + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; + + if (S_ISDIR(mode)) + return -EPERM; +@@ -1270,7 +1371,19 @@ asmlinkage long sys_mknod(const char * f + error = path_walk(tmp, &nd); + if (error) + goto out; +- dentry = lookup_create(&nd, 0); ++ ++ if (nd.dentry->d_inode->i_op->mknod2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->mknod2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len, ++ mode, dev); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out2; ++ } ++ ++ dentry = lookup_create(&nd, 0, &it); + error = PTR_ERR(dentry); + + if (!IS_POSIXACL(nd.dentry->d_inode)) +@@ -1289,9 +1402,11 @@ asmlinkage long sys_mknod(const char * f + default: + error = -EINVAL; + } ++ intent_release(dentry, &it); + dput(dentry); + } + up(&nd.dentry->d_inode->i_sem); ++ out2: + path_release(&nd); + out: + putname(tmp); +@@ -1329,6 +1444,7 @@ asmlinkage long sys_mkdir(const char * p + { + int error = 0; + char * tmp; ++ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; + + tmp = getname(pathname); + error = PTR_ERR(tmp); +@@ -1340,15 +1456,26 @@ asmlinkage long sys_mkdir(const char * p + error = path_walk(tmp, &nd); + if (error) + goto out; +- dentry = lookup_create(&nd, 1); ++ if (nd.dentry->d_inode->i_op->mkdir2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->mkdir2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len, ++ mode); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out2; ++ } ++ dentry = lookup_create(&nd, 1, &it); + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { +- if (!IS_POSIXACL(nd.dentry->d_inode)) +- mode &= ~current->fs->umask; +- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); ++ error = vfs_mkdir(nd.dentry->d_inode, dentry, ++ mode & ~current->fs->umask); ++ intent_release(dentry, &it); + dput(dentry); + } + up(&nd.dentry->d_inode->i_sem); ++out2: + path_release(&nd); + out: + putname(tmp); +@@ -1429,6 +1556,7 @@ asmlinkage long sys_rmdir(const char * p + char * name; + struct dentry *dentry; + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_RMDIR }; + + name = getname(pathname); + if(IS_ERR(name)) +@@ -1450,11 +1578,21 @@ asmlinkage long sys_rmdir(const char * p + error = -EBUSY; + goto exit1; + } ++ if (nd.dentry->d_inode->i_op->rmdir2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->rmdir2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto exit1; ++ } + down(&nd.dentry->d_inode->i_sem); +- dentry = lookup_hash(&nd.last, nd.dentry); ++ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + error = vfs_rmdir(nd.dentry->d_inode, dentry); ++ intent_release(dentry, &it); + dput(dentry); + } + up(&nd.dentry->d_inode->i_sem); +@@ -1498,6 +1636,7 @@ asmlinkage long sys_unlink(const char * + char * name; + struct dentry *dentry; + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_UNLINK }; + + name = getname(pathname); + if(IS_ERR(name)) +@@ -1510,8 +1649,17 @@ asmlinkage long sys_unlink(const char * + error = -EISDIR; + if (nd.last_type != LAST_NORM) + goto exit1; ++ if (nd.dentry->d_inode->i_op->unlink2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->unlink2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto exit1; ++ } + down(&nd.dentry->d_inode->i_sem); +- dentry = lookup_hash(&nd.last, nd.dentry); ++ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + /* Why not before? Because we want correct error value */ +@@ -1519,6 +1667,7 @@ asmlinkage long sys_unlink(const char * + goto slashes; + error = vfs_unlink(nd.dentry->d_inode, dentry); + exit2: ++ intent_release(dentry, &it); + dput(dentry); + } + up(&nd.dentry->d_inode->i_sem); +@@ -1565,6 +1714,7 @@ asmlinkage long sys_symlink(const char * + int error = 0; + char * from; + char * to; ++ struct lookup_intent it = { .it_op = IT_SYMLINK }; + + from = getname(oldname); + if(IS_ERR(from)) +@@ -1579,15 +1729,28 @@ asmlinkage long sys_symlink(const char * + error = path_walk(to, &nd); + if (error) + goto out; +- dentry = lookup_create(&nd, 0); ++ if (nd.dentry->d_inode->i_op->symlink2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->symlink2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len, ++ from); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out2; ++ } ++ it.it_data = from; ++ dentry = lookup_create(&nd, 0, &it); + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + error = vfs_symlink(nd.dentry->d_inode, dentry, from); ++ intent_release(dentry, &it); + dput(dentry); + } + up(&nd.dentry->d_inode->i_sem); ++ out2: + path_release(&nd); +-out: ++ out: + putname(to); + } + putname(from); +@@ -1648,6 +1811,7 @@ asmlinkage long sys_link(const char * ol + int error; + char * from; + char * to; ++ struct lookup_intent it = { .it_op = IT_LINK }; + + from = getname(oldname); + if(IS_ERR(from)) +@@ -1660,7 +1824,7 @@ asmlinkage long sys_link(const char * ol + + error = 0; + if (path_init(from, LOOKUP_POSITIVE, &old_nd)) +- error = path_walk(from, &old_nd); ++ error = path_walk_it(from, &old_nd, &it); + if (error) + goto exit; + if (path_init(to, LOOKUP_PARENT, &nd)) +@@ -1670,10 +1834,22 @@ asmlinkage long sys_link(const char * ol + error = -EXDEV; + if (old_nd.mnt != nd.mnt) + goto out_release; +- new_dentry = lookup_create(&nd, 0); ++ if (nd.dentry->d_inode->i_op->link2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->link2(old_nd.dentry->d_inode, ++ nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out_release; ++ } ++ it.it_op = IT_LINK2; ++ new_dentry = lookup_create(&nd, 0, &it); + error = PTR_ERR(new_dentry); + if (!IS_ERR(new_dentry)) { + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); ++ intent_release(new_dentry, &it); + dput(new_dentry); + } + up(&nd.dentry->d_inode->i_sem); +@@ -1716,7 +1892,8 @@ exit: + * locking]. + */ + int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, +- struct inode *new_dir, struct dentry *new_dentry) ++ struct inode *new_dir, struct dentry *new_dentry, ++ struct lookup_intent *it) + { + int error; + struct inode *target; +@@ -1774,6 +1951,7 @@ int vfs_rename_dir(struct inode *old_dir + error = -EBUSY; + else + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); ++ intent_release(new_dentry, it); + if (target) { + if (!error) + target->i_flags |= S_DEAD; +@@ -1795,7 +1973,8 @@ out_unlock: + } + + int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, +- struct inode *new_dir, struct dentry *new_dentry) ++ struct inode *new_dir, struct dentry *new_dentry, ++ struct lookup_intent *it) + { + int error; + +@@ -1826,6 +2005,7 @@ int vfs_rename_other(struct inode *old_d + error = -EBUSY; + else + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); ++ intent_release(new_dentry, it); + double_up(&old_dir->i_zombie, &new_dir->i_zombie); + if (error) + return error; +@@ -1837,13 +2017,14 @@ int vfs_rename_other(struct inode *old_d + } + + int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, +- struct inode *new_dir, struct dentry *new_dentry) ++ struct inode *new_dir, struct dentry *new_dentry, ++ struct lookup_intent *it) + { + int error; + if (S_ISDIR(old_dentry->d_inode->i_mode)) +- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); ++ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); + else +- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); ++ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); + if (!error) { + if (old_dir == new_dir) + inode_dir_notify(old_dir, DN_RENAME); +@@ -1860,6 +2041,7 @@ static inline int do_rename(const char * + int error = 0; + struct dentry * old_dir, * new_dir; + struct dentry * old_dentry, *new_dentry; ++ struct lookup_intent it = { .it_op = IT_RENAME }; + struct nameidata oldnd, newnd; + + if (path_init(oldname, LOOKUP_PARENT, &oldnd)) +@@ -1886,9 +2068,23 @@ static inline int do_rename(const char * + if (newnd.last_type != LAST_NORM) + goto exit2; + ++ if (old_dir->d_inode->i_op->rename2) { ++ lock_kernel(); ++ error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, ++ new_dir->d_inode, ++ oldnd.last.name, ++ oldnd.last.len, ++ newnd.last.name, ++ newnd.last.len); ++ unlock_kernel(); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto exit2; ++ } ++ + double_lock(new_dir, old_dir); + +- old_dentry = lookup_hash(&oldnd.last, old_dir); ++ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); + error = PTR_ERR(old_dentry); + if (IS_ERR(old_dentry)) + goto exit3; +@@ -1904,18 +2100,21 @@ static inline int do_rename(const char * + if (newnd.last.name[newnd.last.len]) + goto exit4; + } +- new_dentry = lookup_hash(&newnd.last, new_dir); ++ it.it_op = IT_RENAME2; ++ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); + error = PTR_ERR(new_dentry); + if (IS_ERR(new_dentry)) + goto exit4; + + lock_kernel(); + error = vfs_rename(old_dir->d_inode, old_dentry, +- new_dir->d_inode, new_dentry); ++ new_dir->d_inode, new_dentry, &it); + unlock_kernel(); + ++ intent_release(new_dentry, &it); + dput(new_dentry); + exit4: ++ intent_release(old_dentry, &it); + dput(old_dentry); + exit3: + double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); +@@ -1964,7 +2163,8 @@ out: + } + + static inline int +-__vfs_follow_link(struct nameidata *nd, const char *link) ++__vfs_follow_link(struct nameidata *nd, const char *link, ++ struct lookup_intent *it) + { + int res = 0; + char *name; +@@ -1977,7 +2177,7 @@ __vfs_follow_link(struct nameidata *nd, + /* weird __emul_prefix() stuff did it */ + goto out; + } +- res = link_path_walk(link, nd); ++ res = link_path_walk_it(link, nd, it); + out: + if (current->link_count || res || nd->last_type!=LAST_NORM) + return res; +@@ -1999,7 +2199,13 @@ fail: + + int vfs_follow_link(struct nameidata *nd, const char *link) + { +- return __vfs_follow_link(nd, link); ++ return __vfs_follow_link(nd, link, NULL); ++} ++ ++int vfs_follow_link_it(struct nameidata *nd, const char *link, ++ struct lookup_intent *it) ++{ ++ return __vfs_follow_link(nd, link, it); + } + + /* get the link contents into pagecache */ +@@ -2041,7 +2247,7 @@ int page_follow_link(struct dentry *dent + { + struct page *page = NULL; + char *s = page_getlink(dentry, &page); +- int res = __vfs_follow_link(nd, s); ++ int res = __vfs_follow_link(nd, s, NULL); + if (page) { + kunmap(page); + page_cache_release(page); +--- linux-2.4.19-hp2_pnnl2/fs/nfsd/vfs.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/fs/nfsd/vfs.c Sun Jan 19 19:37:57 2003 +@@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru + err = nfserr_perm; + } else + #endif +- err = vfs_rename(fdir, odentry, tdir, ndentry); ++ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); + if (!err && EX_ISSYNC(tfhp->fh_export)) { + nfsd_sync_dir(tdentry); + nfsd_sync_dir(fdentry); +--- linux-2.4.19-hp2_pnnl2/fs/open.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/fs/open.c Sun Jan 19 19:41:00 2003 +@@ -19,6 +19,9 @@ + #include + + #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) ++extern int path_walk_it(const char *name, struct nameidata *nd, ++ struct lookup_intent *it); ++extern void intent_release(struct dentry *de, struct lookup_intent *it); + + int vfs_statfs(struct super_block *sb, struct statfs *buf) + { +@@ -118,12 +121,13 @@ static inline long do_sys_truncate(const + struct nameidata nd; + struct inode * inode; + int error; ++ struct lookup_intent it = { .it_op = IT_SETATTR }; + + error = -EINVAL; + if (length < 0) /* sorry, but loff_t says... */ + goto out; + +- error = user_path_walk(path, &nd); ++ error = user_path_walk_it(path, &nd, &it); + if (error) + goto out; + inode = nd.dentry->d_inode; +@@ -168,6 +172,7 @@ static inline long do_sys_truncate(const + put_write_access(inode); + + dput_and_out: ++ intent_release(nd.dentry, &it); + path_release(&nd); + out: + return error; +@@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam + struct nameidata nd; + struct inode * inode; + struct iattr newattrs; ++ struct lookup_intent it = { .it_op = IT_SETATTR }; + +- error = user_path_walk(filename, &nd); ++ error = user_path_walk_it(filename, &nd, &it); + if (error) + goto out; + inode = nd.dentry->d_inode; +@@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam + } + error = notify_change(nd.dentry, &newattrs); + dput_and_out: ++ intent_release(nd.dentry, &it); + path_release(&nd); + out: + return error; +@@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena + struct nameidata nd; + struct inode * inode; + struct iattr newattrs; ++ struct lookup_intent it = { .it_op = IT_SETATTR }; + +- error = user_path_walk(filename, &nd); ++ error = user_path_walk_it(filename, &nd, &it); + + if (error) + goto out; +@@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena + } + error = notify_change(nd.dentry, &newattrs); + dput_and_out: ++ intent_release(nd.dentry, &it); + path_release(&nd); + out: + return error; +@@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * + int old_fsuid, old_fsgid; + kernel_cap_t old_cap; + int res; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ + return -EINVAL; +@@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * + else + current->cap_effective = current->cap_permitted; + +- res = user_path_walk(filename, &nd); ++ res = user_path_walk_it(filename, &nd, &it); + if (!res) { + res = permission(nd.dentry->d_inode, mode); + /* SuS v2 requires we report a read only fs too */ + if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) + && !special_file(nd.dentry->d_inode->i_mode)) + res = -EROFS; ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + +@@ -386,6 +397,7 @@ asmlinkage long sys_chdir(const char * f + int error; + struct nameidata nd; + char *name; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + + name = getname(filename); + error = PTR_ERR(name); +@@ -394,7 +406,7 @@ asmlinkage long sys_chdir(const char * f + + error = 0; + if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd)) +- error = path_walk(name, &nd); ++ error = path_walk_it(name, &nd, &it); + putname(name); + if (error) + goto out; +@@ -406,6 +418,7 @@ asmlinkage long sys_chdir(const char * f + set_fs_pwd(current->fs, nd.mnt, nd.dentry); + + dput_and_out: ++ intent_release(nd.dentry, &it); + path_release(&nd); + out: + return error; +@@ -446,6 +459,7 @@ asmlinkage long sys_chroot(const char * + int error; + struct nameidata nd; + char *name; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + + name = getname(filename); + error = PTR_ERR(name); +@@ -454,7 +468,7 @@ asmlinkage long sys_chroot(const char * + + path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW | + LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); +- error = path_walk(name, &nd); ++ error = path_walk_it(name, &nd, &it); + putname(name); + if (error) + goto out; +@@ -471,6 +485,7 @@ asmlinkage long sys_chroot(const char * + set_fs_altroot(); + error = 0; + dput_and_out: ++ intent_release(nd.dentry, &it); + path_release(&nd); + out: + return error; +@@ -515,8 +530,9 @@ asmlinkage long sys_chmod(const char * f + struct inode * inode; + int error; + struct iattr newattrs; ++ struct lookup_intent it = { .it_op = IT_SETATTR }; + +- error = user_path_walk(filename, &nd); ++ error = user_path_walk_it(filename, &nd, &it); + if (error) + goto out; + inode = nd.dentry->d_inode; +@@ -536,6 +552,7 @@ asmlinkage long sys_chmod(const char * f + error = notify_change(nd.dentry, &newattrs); + + dput_and_out: ++ intent_release(nd.dentry, &it); + path_release(&nd); + out: + return error; +@@ -605,10 +622,12 @@ asmlinkage long sys_chown(const char * f + { + struct nameidata nd; + int error; ++ struct lookup_intent it = { .it_op = IT_SETATTR }; + +- error = user_path_walk(filename, &nd); ++ error = user_path_walk_it(filename, &nd, &it); + if (!error) { + error = chown_common(nd.dentry, user, group); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -618,10 +637,12 @@ asmlinkage long sys_lchown(const char * + { + struct nameidata nd; + int error; ++ struct lookup_intent it = { .it_op = IT_SETATTR }; + +- error = user_path_walk_link(filename, &nd); ++ error = user_path_walk_link_it(filename, &nd, &it); + if (!error) { + error = chown_common(nd.dentry, user, group); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int + * for the internal routines (ie open_namei()/follow_link() etc). 00 is + * used by symlinks. + */ ++extern int open_namei_it(const char *filename, int namei_flags, int mode, ++ struct nameidata *nd, struct lookup_intent *it); ++struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, ++ int flags, struct lookup_intent *it); ++ + struct file *filp_open(const char * filename, int flags, int mode) + { + int namei_flags, error; + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_OPEN }; + + namei_flags = flags; + if ((namei_flags+1) & O_ACCMODE) +@@ -666,14 +693,15 @@ struct file *filp_open(const char * file + if (namei_flags & O_TRUNC) + namei_flags |= 2; + +- error = open_namei(filename, namei_flags, mode, &nd); +- if (!error) +- return dentry_open(nd.dentry, nd.mnt, flags); ++ error = open_namei_it(filename, namei_flags, mode, &nd, &it); ++ if (error) ++ return ERR_PTR(error); + +- return ERR_PTR(error); ++ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); + } + +-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) ++struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, ++ int flags, struct lookup_intent *it) + { + struct file * f; + struct inode *inode; +@@ -716,6 +744,7 @@ struct file *dentry_open(struct dentry * + } + f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); + ++ intent_release(dentry, it); + return f; + + cleanup_all: +@@ -730,11 +759,17 @@ cleanup_all: + cleanup_file: + put_filp(f); + cleanup_dentry: ++ intent_release(dentry, it); + dput(dentry); + mntput(mnt); + return ERR_PTR(error); + } + ++struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) ++{ ++ return dentry_open_it(dentry, mnt, flags, NULL); ++} ++ + /* + * Find an empty file descriptor entry, and mark it busy. + */ +--- linux-2.4.19-hp2_pnnl2/fs/stat.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/fs/stat.c Sun Jan 19 19:44:51 2003 +@@ -13,6 +13,7 @@ + + #include + ++extern void intent_release(struct dentry *de, struct lookup_intent *it); + /* + * Revalidate the inode. This is required for proper NFS attribute caching. + */ +@@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in + asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) + { + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + int error; + +- error = user_path_walk(filename, &nd); ++ error = user_path_walk_it(filename, &nd, &it); + if (!error) { + error = do_revalidate(nd.dentry); + if (!error) + error = cp_old_stat(nd.dentry->d_inode, statbuf); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -151,13 +154,15 @@ asmlinkage long sys_stat(char * filename + asmlinkage long sys_newstat(char * filename, struct stat * statbuf) + { + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + int error; + +- error = user_path_walk(filename, &nd); ++ error = user_path_walk_it(filename, &nd, &it); + if (!error) { + error = do_revalidate(nd.dentry); + if (!error) + error = cp_new_stat(nd.dentry->d_inode, statbuf); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -172,13 +177,15 @@ asmlinkage long sys_newstat(char * filen + asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) + { + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + int error; + +- error = user_path_walk_link(filename, &nd); ++ error = user_path_walk_link_it(filename, &nd, &it); + if (!error) { + error = do_revalidate(nd.dentry); + if (!error) + error = cp_old_stat(nd.dentry->d_inode, statbuf); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -189,13 +196,15 @@ asmlinkage long sys_lstat(char * filenam + asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) + { + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + int error; + +- error = user_path_walk_link(filename, &nd); ++ error = user_path_walk_link_it(filename, &nd, &it); + if (!error) { + error = do_revalidate(nd.dentry); + if (!error) + error = cp_new_stat(nd.dentry->d_inode, statbuf); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -247,11 +256,12 @@ asmlinkage long sys_readlink(const char + { + struct nameidata nd; + int error; ++ struct lookup_intent it = { .it_op = IT_READLINK }; + + if (bufsiz <= 0) + return -EINVAL; + +- error = user_path_walk_link(path, &nd); ++ error = user_path_walk_link_it(path, &nd, &it); + if (!error) { + struct inode * inode = nd.dentry->d_inode; + +@@ -261,6 +271,7 @@ asmlinkage long sys_readlink(const char + UPDATE_ATIME(inode); + error = inode->i_op->readlink(nd.dentry, buf, bufsiz); + } ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -333,12 +344,14 @@ asmlinkage long sys_stat64(char * filena + { + struct nameidata nd; + int error; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + +- error = user_path_walk(filename, &nd); ++ error = user_path_walk_it(filename, &nd, &it); + if (!error) { + error = do_revalidate(nd.dentry); + if (!error) + error = cp_new_stat64(nd.dentry->d_inode, statbuf); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +@@ -348,12 +361,14 @@ asmlinkage long sys_lstat64(char * filen + { + struct nameidata nd; + int error; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; + +- error = user_path_walk_link(filename, &nd); ++ error = user_path_walk_link_it(filename, &nd, &it); + if (!error) { + error = do_revalidate(nd.dentry); + if (!error) + error = cp_new_stat64(nd.dentry->d_inode, statbuf); ++ intent_release(nd.dentry, &it); + path_release(&nd); + } + return error; +--- linux-2.4.19-hp2_pnnl2/include/linux/dcache.h~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/include/linux/dcache.h Sun Jan 19 19:04:48 2003 +@@ -6,6 +6,34 @@ + #include + #include + ++#define IT_OPEN (1) ++#define IT_CREAT (1<<1) ++#define IT_MKDIR (1<<2) ++#define IT_LINK (1<<3) ++#define IT_LINK2 (1<<4) ++#define IT_SYMLINK (1<<5) ++#define IT_UNLINK (1<<6) ++#define IT_RMDIR (1<<7) ++#define IT_RENAME (1<<8) ++#define IT_RENAME2 (1<<9) ++#define IT_READDIR (1<<10) ++#define IT_GETATTR (1<<11) ++#define IT_SETATTR (1<<12) ++#define IT_READLINK (1<<13) ++#define IT_MKNOD (1<<14) ++#define IT_LOOKUP (1<<15) ++ ++struct lookup_intent { ++ int it_op; ++ int it_mode; ++ int it_disposition; ++ int it_status; ++ struct iattr *it_iattr; ++ __u64 it_lock_handle[2]; ++ int it_lock_mode; ++ void *it_data; ++}; ++ + /* + * linux/include/linux/dcache.h + * +@@ -78,6 +106,7 @@ struct dentry { + unsigned long d_time; /* used by d_revalidate */ + struct dentry_operations *d_op; + struct super_block * d_sb; /* The root of the dentry tree */ ++ struct lookup_intent *d_it; + unsigned long d_vfs_flags; + void * d_fsdata; /* fs-specific data */ + unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ +@@ -90,6 +119,8 @@ struct dentry_operations { + int (*d_delete)(struct dentry *); + void (*d_release)(struct dentry *); + void (*d_iput)(struct dentry *, struct inode *); ++ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); ++ void (*d_intent_release)(struct dentry *, struct lookup_intent *); + }; + + /* the dentry parameter passed to d_hash and d_compare is the parent +--- linux-2.4.19-hp2_pnnl2/include/linux/fs.h~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/include/linux/fs.h Sun Jan 19 19:04:48 2003 +@@ -575,6 +575,7 @@ struct file { + + /* needed for tty driver, and maybe others */ + void *private_data; ++ struct lookup_intent *f_intent; + + /* preallocated helper kiobuf to speedup O_DIRECT */ + struct kiobuf *f_iobuf; +@@ -815,7 +816,9 @@ extern int vfs_symlink(struct inode *, s + extern int vfs_link(struct dentry *, struct inode *, struct dentry *); + extern int vfs_rmdir(struct inode *, struct dentry *); + extern int vfs_unlink(struct inode *, struct dentry *); +-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); ++int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry, ++ struct lookup_intent *it); + + /* + * File types +@@ -876,16 +879,28 @@ struct file_operations { + struct inode_operations { + int (*create) (struct inode *,struct dentry *,int); + struct dentry * (*lookup) (struct inode *,struct dentry *); ++ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); + int (*link) (struct dentry *,struct inode *,struct dentry *); ++ int (*link2) (struct inode *,struct inode *, const char *, int); + int (*unlink) (struct inode *,struct dentry *); ++ int (*unlink2) (struct inode *, char *, int); + int (*symlink) (struct inode *,struct dentry *,const char *); ++ int (*symlink2) (struct inode *,const char *, int, const char *); + int (*mkdir) (struct inode *,struct dentry *,int); ++ int (*mkdir2) (struct inode *,char *, int,int); + int (*rmdir) (struct inode *,struct dentry *); ++ int (*rmdir2) (struct inode *, char *, int); + int (*mknod) (struct inode *,struct dentry *,int,int); ++ int (*mknod2) (struct inode *,char *, int,int,int); + int (*rename) (struct inode *, struct dentry *, + struct inode *, struct dentry *); ++ int (*rename2) (struct inode *, struct inode *, ++ char *oldname, int oldlen, ++ char *newname, int newlen); + int (*readlink) (struct dentry *, char *,int); + int (*follow_link) (struct dentry *, struct nameidata *); ++ int (*follow_link2) (struct dentry *, struct nameidata *, ++ struct lookup_intent *it); + void (*truncate) (struct inode *); + int (*permission) (struct inode *, int); + int (*revalidate) (struct dentry *); +@@ -1354,6 +1369,7 @@ typedef int (*read_actor_t)(read_descrip + extern loff_t default_llseek(struct file *file, loff_t offset, int origin); + + extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); ++extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); + extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); + extern int FASTCALL(path_walk(const char *, struct nameidata *)); + extern int FASTCALL(link_path_walk(const char *, struct nameidata *)); +@@ -1364,6 +1380,8 @@ extern struct dentry * lookup_one_len(co + extern struct dentry * lookup_hash(struct qstr *, struct dentry *); + #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) + #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) ++#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) ++#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) + + extern void inode_init_once(struct inode *); + extern void iput(struct inode *); +@@ -1499,6 +1517,8 @@ extern struct file_operations generic_ro + + extern int vfs_readlink(struct dentry *, char *, int, const char *); + extern int vfs_follow_link(struct nameidata *, const char *); ++extern int vfs_follow_link_it(struct nameidata *, const char *, ++ struct lookup_intent *it); + extern int page_readlink(struct dentry *, char *, int); + extern int page_follow_link(struct dentry *, struct nameidata *); + extern struct inode_operations page_symlink_inode_operations; +--- linux-2.4.19-hp2_pnnl2/kernel/ksyms.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 ++++ linux-2.4.19-hp2_pnnl2-root/kernel/ksyms.c Sun Jan 19 19:04:48 2003 +@@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page); + EXPORT_SYMBOL(set_page_dirty); + EXPORT_SYMBOL(vfs_readlink); + EXPORT_SYMBOL(vfs_follow_link); ++EXPORT_SYMBOL(vfs_follow_link_it); + EXPORT_SYMBOL(page_readlink); + EXPORT_SYMBOL(page_follow_link); + EXPORT_SYMBOL(page_symlink_inode_operations); + +_ diff --git a/lustre/kernel_patches/pc/dev_read_only_hp.pc b/lustre/kernel_patches/pc/dev_read_only_hp.pc new file mode 100644 index 0000000..4760ad1 --- /dev/null +++ b/lustre/kernel_patches/pc/dev_read_only_hp.pc @@ -0,0 +1,3 @@ +drivers/block/blkpg.c +drivers/block/loop.c +drivers/ide/ide-disk.c diff --git a/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc b/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc new file mode 100644 index 0000000..a0a6297 --- /dev/null +++ b/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc @@ -0,0 +1,5 @@ +arch/i386/mm/init.c +arch/ia64/mm/init.c +include/linux/slab.h +kernel/ksyms.c +mm/slab.c diff --git a/lustre/kernel_patches/pc/vfs_intent_hp.pc b/lustre/kernel_patches/pc/vfs_intent_hp.pc new file mode 100644 index 0000000..881576c --- /dev/null +++ b/lustre/kernel_patches/pc/vfs_intent_hp.pc @@ -0,0 +1,8 @@ +fs/dcache.c +fs/namei.c +fs/nfsd/vfs.c +fs/open.c +fs/stat.c +include/linux/dcache.h +include/linux/fs.h +kernel/ksyms.c diff --git a/lustre/kernel_patches/series/hp-pnnl b/lustre/kernel_patches/series/hp-pnnl index d0171e0..915ecd2 100644 --- a/lustre/kernel_patches/series/hp-pnnl +++ b/lustre/kernel_patches/series/hp-pnnl @@ -1 +1,5 @@ -patch-2.4.18-hp1_pnnl18.2.8qsnet +dev_read_only_hp.patch +exports.patch +kmem_cache_validate_hp.patch +lustre_version.patch +vfs_intent_hp.patch