summaryrefslogtreecommitdiffstats
path: root/fs/ext2/namei.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
commit33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch)
tree2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /fs/ext2/namei.c
parent216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff)
Merge with Linux 2.3.32.
Diffstat (limited to 'fs/ext2/namei.c')
-rw-r--r--fs/ext2/namei.c59
1 files changed, 21 insertions, 38 deletions
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 8bc7532de..87f39796a 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -18,7 +18,6 @@
* for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
*/
-#include <linux/module.h>
#include <linux/fs.h>
#include <linux/locks.h>
#include <linux/quotaops.h>
@@ -678,48 +677,32 @@ end_unlink:
int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symname)
{
- struct ext2_dir_entry_2 * de;
struct inode * inode;
- struct buffer_head * bh = NULL, * name_block = NULL;
- char * link;
- int i, l, err = -EIO;
- char c;
+ struct ext2_dir_entry_2 * de;
+ struct buffer_head * bh = NULL;
+ int l, err;
- if (!(inode = ext2_new_inode (dir, S_IFLNK, &err))) {
- return err;
- }
- inode->i_mode = S_IFLNK | S_IRWXUGO;
- inode->i_op = &ext2_symlink_inode_operations;
- for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
- symname [l]; l++)
- ;
- if (l >= sizeof (inode->u.ext2_i.i_data)) {
-
- ext2_debug ("l=%d, normal symlink\n", l);
-
- name_block = ext2_bread (inode, 0, 1, &err);
- if (!name_block) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput (inode);
- return err;
- }
- link = name_block->b_data;
- } else {
- link = (char *) inode->u.ext2_i.i_data;
+ err = -ENAMETOOLONG;
+ l = strlen(symname)+1;
+ if (l > dir->i_sb->s_blocksize)
+ goto out;
- ext2_debug ("l=%d, fast symlink\n", l);
+ err = -EIO;
+ if (!(inode = ext2_new_inode (dir, S_IFLNK, &err)))
+ goto out;
+ inode->i_mode = S_IFLNK | S_IRWXUGO;
+
+ if (l > sizeof (inode->u.ext2_i.i_data)) {
+ inode->i_op = &ext2_symlink_inode_operations;
+ err = block_symlink(inode, symname, l);
+ if (err)
+ goto out_no_entry;
+ } else {
+ inode->i_op = &ext2_fast_symlink_inode_operations;
+ memcpy((char*)&inode->u.ext2_i.i_data,symname,l);
+ inode->i_size = l-1;
}
- i = 0;
- while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
- link[i++] = c;
- link[i] = 0;
- if (name_block) {
- mark_buffer_dirty(name_block, 1);
- brelse (name_block);
- }
- inode->i_size = i;
mark_inode_dirty(inode);
bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);