| .. | .. |
|---|
| 69 | 69 | return full_path; |
|---|
| 70 | 70 | |
|---|
| 71 | 71 | if (dfsplen) |
|---|
| 72 | | - strncpy(full_path, tcon->treeName, dfsplen); |
|---|
| 72 | + memcpy(full_path, tcon->treeName, dfsplen); |
|---|
| 73 | 73 | full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb); |
|---|
| 74 | | - strncpy(full_path + dfsplen + 1, vol->prepath, pplen); |
|---|
| 74 | + memcpy(full_path + dfsplen + 1, vol->prepath, pplen); |
|---|
| 75 | 75 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
|---|
| 76 | | - full_path[dfsplen + pplen] = 0; /* add trailing null */ |
|---|
| 77 | 76 | return full_path; |
|---|
| 78 | 77 | } |
|---|
| 79 | 78 | |
|---|
| .. | .. |
|---|
| 126 | 125 | } |
|---|
| 127 | 126 | rcu_read_unlock(); |
|---|
| 128 | 127 | |
|---|
| 129 | | - full_path = kmalloc(namelen+1, GFP_KERNEL); |
|---|
| 128 | + full_path = kmalloc(namelen+1, GFP_ATOMIC); |
|---|
| 130 | 129 | if (full_path == NULL) |
|---|
| 131 | 130 | return full_path; |
|---|
| 132 | 131 | full_path[namelen] = 0; /* trailing null */ |
|---|
| .. | .. |
|---|
| 245 | 244 | *oplock = REQ_OPLOCK; |
|---|
| 246 | 245 | |
|---|
| 247 | 246 | full_path = build_path_from_dentry(direntry); |
|---|
| 248 | | - if (full_path == NULL) { |
|---|
| 249 | | - rc = -ENOMEM; |
|---|
| 250 | | - goto out; |
|---|
| 251 | | - } |
|---|
| 247 | + if (!full_path) |
|---|
| 248 | + return -ENOMEM; |
|---|
| 252 | 249 | |
|---|
| 253 | 250 | if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open && |
|---|
| 254 | 251 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
|---|
| .. | .. |
|---|
| 358 | 355 | if (!tcon->unix_ext && (mode & S_IWUGO) == 0) |
|---|
| 359 | 356 | create_options |= CREATE_OPTION_READONLY; |
|---|
| 360 | 357 | |
|---|
| 361 | | - if (backup_cred(cifs_sb)) |
|---|
| 362 | | - create_options |= CREATE_OPEN_BACKUP_INTENT; |
|---|
| 363 | | - |
|---|
| 364 | 358 | oparms.tcon = tcon; |
|---|
| 365 | 359 | oparms.cifs_sb = cifs_sb; |
|---|
| 366 | 360 | oparms.desired_access = desired_access; |
|---|
| 367 | | - oparms.create_options = create_options; |
|---|
| 361 | + oparms.create_options = cifs_create_options(cifs_sb, create_options); |
|---|
| 368 | 362 | oparms.disposition = disposition; |
|---|
| 369 | 363 | oparms.path = full_path; |
|---|
| 370 | 364 | oparms.fid = fid; |
|---|
| .. | .. |
|---|
| 417 | 411 | rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, |
|---|
| 418 | 412 | xid); |
|---|
| 419 | 413 | else { |
|---|
| 414 | + /* TODO: Add support for calling POSIX query info here, but passing in fid */ |
|---|
| 420 | 415 | rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, |
|---|
| 421 | 416 | xid, fid); |
|---|
| 422 | 417 | if (newinode) { |
|---|
| .. | .. |
|---|
| 472 | 467 | struct tcon_link *tlink; |
|---|
| 473 | 468 | struct cifs_tcon *tcon; |
|---|
| 474 | 469 | struct TCP_Server_Info *server; |
|---|
| 475 | | - struct cifs_fid fid; |
|---|
| 470 | + struct cifs_fid fid = {}; |
|---|
| 476 | 471 | struct cifs_pending_open open; |
|---|
| 477 | 472 | __u32 oplock; |
|---|
| 478 | 473 | struct cifsFileInfo *file_info; |
|---|
| .. | .. |
|---|
| 620 | 615 | { |
|---|
| 621 | 616 | int rc = -EPERM; |
|---|
| 622 | 617 | unsigned int xid; |
|---|
| 623 | | - int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL; |
|---|
| 624 | 618 | struct cifs_sb_info *cifs_sb; |
|---|
| 625 | 619 | struct tcon_link *tlink; |
|---|
| 626 | 620 | struct cifs_tcon *tcon; |
|---|
| 627 | | - struct cifs_io_parms io_parms; |
|---|
| 628 | 621 | char *full_path = NULL; |
|---|
| 629 | | - struct inode *newinode = NULL; |
|---|
| 630 | | - __u32 oplock = 0; |
|---|
| 631 | | - struct cifs_fid fid; |
|---|
| 632 | | - struct cifs_open_parms oparms; |
|---|
| 633 | | - FILE_ALL_INFO *buf = NULL; |
|---|
| 634 | | - unsigned int bytes_written; |
|---|
| 635 | | - struct win_dev *pdev; |
|---|
| 636 | | - struct kvec iov[2]; |
|---|
| 637 | 622 | |
|---|
| 638 | 623 | if (!old_valid_dev(device_number)) |
|---|
| 639 | 624 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 653 | 638 | goto mknod_out; |
|---|
| 654 | 639 | } |
|---|
| 655 | 640 | |
|---|
| 656 | | - if (tcon->unix_ext) { |
|---|
| 657 | | - struct cifs_unix_set_info_args args = { |
|---|
| 658 | | - .mode = mode & ~current_umask(), |
|---|
| 659 | | - .ctime = NO_CHANGE_64, |
|---|
| 660 | | - .atime = NO_CHANGE_64, |
|---|
| 661 | | - .mtime = NO_CHANGE_64, |
|---|
| 662 | | - .device = device_number, |
|---|
| 663 | | - }; |
|---|
| 664 | | - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
|---|
| 665 | | - args.uid = current_fsuid(); |
|---|
| 666 | | - args.gid = current_fsgid(); |
|---|
| 667 | | - } else { |
|---|
| 668 | | - args.uid = INVALID_UID; /* no change */ |
|---|
| 669 | | - args.gid = INVALID_GID; /* no change */ |
|---|
| 670 | | - } |
|---|
| 671 | | - rc = CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, |
|---|
| 672 | | - cifs_sb->local_nls, |
|---|
| 673 | | - cifs_remap(cifs_sb)); |
|---|
| 674 | | - if (rc) |
|---|
| 675 | | - goto mknod_out; |
|---|
| 676 | | - |
|---|
| 677 | | - rc = cifs_get_inode_info_unix(&newinode, full_path, |
|---|
| 678 | | - inode->i_sb, xid); |
|---|
| 679 | | - |
|---|
| 680 | | - if (rc == 0) |
|---|
| 681 | | - d_instantiate(direntry, newinode); |
|---|
| 682 | | - goto mknod_out; |
|---|
| 683 | | - } |
|---|
| 684 | | - |
|---|
| 685 | | - if (!S_ISCHR(mode) && !S_ISBLK(mode)) |
|---|
| 686 | | - goto mknod_out; |
|---|
| 687 | | - |
|---|
| 688 | | - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) |
|---|
| 689 | | - goto mknod_out; |
|---|
| 690 | | - |
|---|
| 691 | | - |
|---|
| 692 | | - cifs_dbg(FYI, "sfu compat create special file\n"); |
|---|
| 693 | | - |
|---|
| 694 | | - buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
|---|
| 695 | | - if (buf == NULL) { |
|---|
| 696 | | - rc = -ENOMEM; |
|---|
| 697 | | - goto mknod_out; |
|---|
| 698 | | - } |
|---|
| 699 | | - |
|---|
| 700 | | - if (backup_cred(cifs_sb)) |
|---|
| 701 | | - create_options |= CREATE_OPEN_BACKUP_INTENT; |
|---|
| 702 | | - |
|---|
| 703 | | - oparms.tcon = tcon; |
|---|
| 704 | | - oparms.cifs_sb = cifs_sb; |
|---|
| 705 | | - oparms.desired_access = GENERIC_WRITE; |
|---|
| 706 | | - oparms.create_options = create_options; |
|---|
| 707 | | - oparms.disposition = FILE_CREATE; |
|---|
| 708 | | - oparms.path = full_path; |
|---|
| 709 | | - oparms.fid = &fid; |
|---|
| 710 | | - oparms.reconnect = false; |
|---|
| 711 | | - |
|---|
| 712 | | - if (tcon->ses->server->oplocks) |
|---|
| 713 | | - oplock = REQ_OPLOCK; |
|---|
| 714 | | - else |
|---|
| 715 | | - oplock = 0; |
|---|
| 716 | | - rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf); |
|---|
| 717 | | - if (rc) |
|---|
| 718 | | - goto mknod_out; |
|---|
| 719 | | - |
|---|
| 720 | | - /* |
|---|
| 721 | | - * BB Do not bother to decode buf since no local inode yet to put |
|---|
| 722 | | - * timestamps in, but we can reuse it safely. |
|---|
| 723 | | - */ |
|---|
| 724 | | - |
|---|
| 725 | | - pdev = (struct win_dev *)buf; |
|---|
| 726 | | - io_parms.pid = current->tgid; |
|---|
| 727 | | - io_parms.tcon = tcon; |
|---|
| 728 | | - io_parms.offset = 0; |
|---|
| 729 | | - io_parms.length = sizeof(struct win_dev); |
|---|
| 730 | | - iov[1].iov_base = buf; |
|---|
| 731 | | - iov[1].iov_len = sizeof(struct win_dev); |
|---|
| 732 | | - if (S_ISCHR(mode)) { |
|---|
| 733 | | - memcpy(pdev->type, "IntxCHR", 8); |
|---|
| 734 | | - pdev->major = cpu_to_le64(MAJOR(device_number)); |
|---|
| 735 | | - pdev->minor = cpu_to_le64(MINOR(device_number)); |
|---|
| 736 | | - rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms, |
|---|
| 737 | | - &bytes_written, iov, 1); |
|---|
| 738 | | - } else if (S_ISBLK(mode)) { |
|---|
| 739 | | - memcpy(pdev->type, "IntxBLK", 8); |
|---|
| 740 | | - pdev->major = cpu_to_le64(MAJOR(device_number)); |
|---|
| 741 | | - pdev->minor = cpu_to_le64(MINOR(device_number)); |
|---|
| 742 | | - rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms, |
|---|
| 743 | | - &bytes_written, iov, 1); |
|---|
| 744 | | - } |
|---|
| 745 | | - tcon->ses->server->ops->close(xid, tcon, &fid); |
|---|
| 746 | | - d_drop(direntry); |
|---|
| 747 | | - |
|---|
| 748 | | - /* FIXME: add code here to set EAs */ |
|---|
| 641 | + rc = tcon->ses->server->ops->make_node(xid, inode, direntry, tcon, |
|---|
| 642 | + full_path, mode, |
|---|
| 643 | + device_number); |
|---|
| 749 | 644 | |
|---|
| 750 | 645 | mknod_out: |
|---|
| 751 | 646 | kfree(full_path); |
|---|
| 752 | | - kfree(buf); |
|---|
| 753 | 647 | free_xid(xid); |
|---|
| 754 | 648 | cifs_put_tlink(tlink); |
|---|
| 755 | 649 | return rc; |
|---|
| .. | .. |
|---|
| 807 | 701 | cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", |
|---|
| 808 | 702 | full_path, d_inode(direntry)); |
|---|
| 809 | 703 | |
|---|
| 810 | | - if (pTcon->unix_ext) { |
|---|
| 704 | + if (pTcon->posix_extensions) |
|---|
| 705 | + rc = smb311_posix_get_inode_info(&newInode, full_path, parent_dir_inode->i_sb, xid); |
|---|
| 706 | + else if (pTcon->unix_ext) { |
|---|
| 811 | 707 | rc = cifs_get_inode_info_unix(&newInode, full_path, |
|---|
| 812 | 708 | parent_dir_inode->i_sb, xid); |
|---|
| 813 | 709 | } else { |
|---|