Whamcloud - gitweb
fix for the symlink problem.
authorbraam <braam>
Tue, 16 Oct 2001 05:27:35 +0000 (05:27 +0000)
committerbraam <braam>
Tue, 16 Oct 2001 05:27:35 +0000 (05:27 +0000)
lustre/obdfs/namei.c

index 8315aa5..219967c 100644 (file)
@@ -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);