--- linux/fs/minix/symlink.c 2018/04/24 18:12:30 1.1.1.3 +++ linux/fs/minix/symlink.c 2018/04/24 18:14:28 1.1.1.4 @@ -15,7 +15,7 @@ #include static int minix_readlink(struct inode *, char *, int); -static struct inode * minix_follow_link(struct inode *, struct inode *); +static int minix_follow_link(struct inode *, struct inode *, int, int, struct inode **); /* * symlinks can't do much... @@ -37,38 +37,46 @@ struct inode_operations minix_symlink_in NULL /* truncate */ }; -static struct inode * minix_follow_link(struct inode * dir, struct inode * inode) +static int minix_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], BLOCK_SIZE))) { + if (current->link_count > 5) { + iput(inode); iput(dir); + return -ELOOP; + } + if (!(bh = minix_bread(inode, 0, 0))) { iput(inode); - return NULL; + 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 minix_readlink(struct inode * inode, char * buffer, int buflen) @@ -83,10 +91,7 @@ static int minix_readlink(struct inode * } if (buflen > 1023) buflen = 1023; - if (inode->i_data[0]) - bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE); - else - bh = NULL; + bh = minix_bread(inode, 0, 0); iput(inode); if (!bh) return 0;