From 93f82a12ff5956a94199bfd74650da2c9d97cda4 Mon Sep 17 00:00:00 2001 From: braam Date: Tue, 16 Oct 2001 05:27:35 +0000 Subject: [PATCH] fix for the symlink problem. --- lustre/obdfs/namei.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index 8315aa5..219967c 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -201,6 +201,48 @@ static int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int return err; } + +/* XXX sort this out -- why is our readpage re-reading the page? */ +static int obdfs_page_symlink(struct inode *inode, const char *symname, int len) +{ + struct address_space *mapping = inode->i_mapping; + struct page *page = grab_cache_page(mapping, 0); + int err = -ENOMEM; + char *kaddr; + + if (!page) + goto fail; + err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); + if (err) + goto fail_map; + kaddr = page_address(page); + memcpy(kaddr, symname, len-1); + mapping->a_ops->commit_write(NULL, page, 0, len-1); +#if 0 + /* + * Notice that we are _not_ going to block here - end of page is + * unmapped, so this will only try to map the rest of page, see + * that it is unmapped (typically even will not look into inode - + * ->i_size will be enough for everything) and zero it out. + * OTOH it's obviously correct and should make the page up-to-date. + */ + err = mapping->a_ops->readpage(NULL, page); + wait_on_page(page); +#endif + obd_unlock_page(page); + page_cache_release(page); + if (err < 0) + goto fail; + mark_inode_dirty(inode); + return 0; +fail_map: + UnlockPage(page); + page_cache_release(page); +fail: + return err; +} + + static int obdfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname) { @@ -209,7 +251,6 @@ static int obdfs_symlink (struct inode * dir, struct dentry * dentry, unsigned l = strlen(symname)+1; struct inode * inode; struct obdfs_inode_info *oinfo; - oinfo = obdfs_i2info(inode); if (l > sb->s_blocksize) goto out; @@ -219,17 +260,20 @@ static int obdfs_symlink (struct inode * dir, struct dentry * dentry, if (IS_ERR(inode)) goto out; + oinfo = obdfs_i2info(inode); if (l >= sizeof(oinfo->oi_inline)) { /* slow symlink */ - inode->i_op = &obdfs_symlink_inode_operations; + inode->i_op = &page_symlink_inode_operations; inode->i_mapping->a_ops = &obdfs_aops; - err = block_symlink(inode, symname, l); + printk("-----> calling block symlink len %d\n", l); + err = obdfs_page_symlink(inode, symname, l); + printk("-----> calling block err %d\n", err); if (err) goto out_fail; } else { /* fast symlink */ inode->i_op = &obdfs_fast_symlink_inode_operations; - memcpy((char*)&inode->u.ext2_i.i_data,symname,l); + memcpy(oinfo->oi_inline, symname, l); inode->i_size = l-1; } mark_inode_dirty(inode); -- 1.8.3.1