--- linux/fs/minix/namei.c 2018/04/24 18:06:06 1.1.1.2 +++ linux/fs/minix/namei.c 2018/04/24 18:07:16 1.1.1.3 @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -103,40 +103,6 @@ static struct buffer_head * minix_find_e return NULL; } -struct inode * minix_follow_link(struct inode * dir, struct inode * inode) -{ - unsigned short fs; - struct buffer_head * bh; - - if (!dir) { - dir = current->root; - dir->i_count++; - } - if (!inode) { - iput(dir); - return NULL; - } - if (!S_ISLNK(inode->i_mode)) { - iput(dir); - return inode; - } - __asm__("mov %%fs,%0":"=r" (fs)); - if ((current->link_count > 5) || !inode->i_data[0] || - !(bh = bread(inode->i_dev, inode->i_data[0]))) { - iput(dir); - iput(inode); - return NULL; - } - iput(inode); - __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); - current->link_count++; - inode = _namei(bh->b_data,dir,1); - current->link_count--; - __asm__("mov %0,%%fs"::"r" (fs)); - brelse(bh); - return inode; -} - int minix_lookup(struct inode * dir,const char * name, int len, struct inode ** result) { @@ -249,11 +215,13 @@ int minix_create(struct inode * dir,cons iput(dir); return -ENOSPC; } + inode->i_op = &minix_file_inode_operations; inode->i_mode = mode; inode->i_dirt = 1; bh = minix_add_entry(dir,name,len,&de); if (!bh) { inode->i_nlink--; + inode->i_dirt = 1; iput(inode); iput(dir); return -ENOSPC; @@ -287,6 +255,17 @@ int minix_mknod(struct inode * dir, cons } inode->i_uid = current->euid; inode->i_mode = mode; + inode->i_op = NULL; + if (S_ISREG(inode->i_mode)) + inode->i_op = &minix_file_inode_operations; + else if (S_ISDIR(inode->i_mode)) + inode->i_op = &minix_dir_inode_operations; + else if (S_ISLNK(inode->i_mode)) + inode->i_op = &minix_symlink_inode_operations; + else if (S_ISCHR(inode->i_mode)) + inode->i_op = &minix_chrdev_inode_operations; + else if (S_ISBLK(inode->i_mode)) + inode->i_op = &minix_blkdev_inode_operations; if (S_ISBLK(mode) || S_ISCHR(mode)) inode->i_rdev = rdev; inode->i_mtime = inode->i_atime = CURRENT_TIME; @@ -294,6 +273,7 @@ int minix_mknod(struct inode * dir, cons bh = minix_add_entry(dir,name,len,&de); if (!bh) { inode->i_nlink--; + inode->i_dirt = 1; iput(inode); iput(dir); return -ENOSPC; @@ -323,12 +303,13 @@ int minix_mkdir(struct inode * dir, cons iput(dir); return -ENOSPC; } - inode->i_size = 32; - inode->i_dirt = 1; + inode->i_op = &minix_dir_inode_operations; + inode->i_size = 2 * sizeof (struct minix_dir_entry); inode->i_mtime = inode->i_atime = CURRENT_TIME; if (!(inode->i_data[0] = minix_new_block(inode->i_dev))) { iput(dir); inode->i_nlink--; + inode->i_dirt = 1; iput(inode); return -ENOSPC; } @@ -336,8 +317,9 @@ int minix_mkdir(struct inode * dir, cons if (!(dir_block = bread(inode->i_dev,inode->i_data[0]))) { iput(dir); inode->i_nlink--; + inode->i_dirt = 1; iput(inode); - return -ERROR; + return -EIO; } de = (struct minix_dir_entry *) dir_block->b_data; de->inode=inode->i_ino; @@ -517,10 +499,11 @@ int minix_symlink(struct inode * dir, co return -ENOSPC; } inode->i_mode = S_IFLNK | 0777; - inode->i_dirt = 1; + inode->i_op = &minix_symlink_inode_operations; if (!(inode->i_data[0] = minix_new_block(inode->i_dev))) { iput(dir); inode->i_nlink--; + inode->i_dirt = 1; iput(inode); return -ENOSPC; } @@ -528,8 +511,9 @@ int minix_symlink(struct inode * dir, co if (!(name_block = bread(inode->i_dev,inode->i_data[0]))) { iput(dir); inode->i_nlink--; + inode->i_dirt = 1; iput(inode); - return -ERROR; + return -EIO; } i = 0; while (i < 1023 && (c=get_fs_byte(symname++))) @@ -542,6 +526,7 @@ int minix_symlink(struct inode * dir, co bh = minix_find_entry(dir,name,len,&de); if (bh) { inode->i_nlink--; + inode->i_dirt = 1; iput(inode); brelse(bh); iput(dir); @@ -550,6 +535,7 @@ int minix_symlink(struct inode * dir, co bh = minix_add_entry(dir,name,len,&de); if (!bh) { inode->i_nlink--; + inode->i_dirt = 1; iput(inode); iput(dir); return -ENOSPC; @@ -667,6 +653,10 @@ start_up: old_inode = iget(old_dir->i_dev, old_de->inode); if (!old_inode) goto end_rename; + if ((old_dir->i_mode & S_ISVTX) && + current->euid != old_inode->i_uid && + current->euid != old_dir->i_uid && !suser()) + goto end_rename; new_bh = minix_find_entry(new_dir,new_name,new_len,&new_de); if (new_bh) { new_inode = iget(new_dir->i_dev, new_de->inode); @@ -712,8 +702,10 @@ start_up: /* ok, that's it */ old_de->inode = 0; new_de->inode = old_inode->i_ino; - if (new_inode) + if (new_inode) { new_inode->i_nlink--; + new_inode->i_dirt = 1; + } old_bh->b_dirt = 1; new_bh->b_dirt = 1; if (dir_bh) { @@ -761,31 +753,3 @@ int minix_rename(struct inode * old_dir, wake_up(&wait); return result; } - -int minix_readlink(struct inode * inode, char * buffer, int buflen) -{ - struct buffer_head * bh; - int i; - char c; - - if (!S_ISLNK(inode->i_mode)) { - iput(inode); - return -EINVAL; - } - if (buflen > 1023) - buflen = 1023; - if (inode->i_data[0]) - bh = bread(inode->i_dev, inode->i_data[0]); - else - bh = NULL; - iput(inode); - if (!bh) - return 0; - i = 0; - while (ib_data[i])) { - i++; - put_fs_byte(c,buffer++); - } - brelse(bh); - return i; -}