--- linux/fs/ext/symlink.c 2018/04/24 18:10:41 1.1 +++ linux/fs/ext/symlink.c 2018/04/24 18:14:22 1.1.1.3 @@ -1,28 +1,27 @@ /* * linux/fs/ext/symlink.c * - * (C) 1992 Remy Card (card@masi.ibp.fr) + * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) * * from * * linux/fs/minix/symlink.c * - * (C) 1991 Linus Torvalds + * Copyright (C) 1991, 1992 Linus Torvalds * * ext symlink handling code */ -#include - #include +#include #include #include #include #include static int ext_readlink(struct inode *, char *, int); -static struct inode * ext_follow_link(struct inode *, struct inode *); +static int ext_follow_link(struct inode *, struct inode *, int, int, struct inode **); /* * symlinks can't do much... @@ -44,38 +43,46 @@ struct inode_operations ext_symlink_inod NULL /* truncate */ }; -static struct inode * ext_follow_link(struct inode * dir, struct inode * inode) +static int ext_follow_link(struct inode * dir, struct inode * inode, + int flag, int mode, struct inode ** res_inode) { + int error; unsigned short fs; struct buffer_head * bh; + *res_inode = NULL; if (!dir) { dir = current->root; dir->i_count++; } if (!inode) { iput(dir); - return NULL; + return -ENOENT; } if (!S_ISLNK(inode->i_mode)) { iput(dir); - return inode; + *res_inode = inode; + return 0; } - __asm__("mov %%fs,%0":"=r" (fs)); - if ((current->link_count > 5) || !inode->i_data[0] || - !(bh = bread(inode->i_dev, inode->i_data[0]))) { + if (current->link_count > 5) { iput(dir); iput(inode); - return NULL; + return -ELOOP; + } + if (!(bh = ext_bread(inode, 0, 0))) { + iput(inode); + iput(dir); + return -EIO; } iput(inode); + __asm__("mov %%fs,%0":"=r" (fs)); __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); current->link_count++; - inode = _namei(bh->b_data,dir,1); + error = open_namei(bh->b_data,flag,mode,res_inode,dir); current->link_count--; __asm__("mov %0,%%fs"::"r" (fs)); brelse(bh); - return inode; + return error; } static int ext_readlink(struct inode * inode, char * buffer, int buflen) @@ -90,10 +97,7 @@ static int ext_readlink(struct inode * i } if (buflen > 1023) buflen = 1023; - if (inode->i_data[0]) - bh = bread(inode->i_dev, inode->i_data[0]); - else - bh = NULL; + bh = ext_bread(inode, 0, 0); iput(inode); if (!bh) return 0;