diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsglob.h | 4 | ||||
-rw-r--r-- | fs/cifs/connect.c | 16 | ||||
-rw-r--r-- | fs/cifs/dir.c | 22 | ||||
-rw-r--r-- | fs/cifs/file.c | 6 | ||||
-rw-r--r-- | fs/cifs/inode.c | 15 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 8 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 12 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 2 |
8 files changed, 55 insertions, 30 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 25b8392bfdd2..dae7e3709cc6 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -323,11 +323,11 @@ struct smb_version_operations { | |||
323 | int (*async_writev)(struct cifs_writedata *, | 323 | int (*async_writev)(struct cifs_writedata *, |
324 | void (*release)(struct kref *)); | 324 | void (*release)(struct kref *)); |
325 | /* sync read from the server */ | 325 | /* sync read from the server */ |
326 | int (*sync_read)(const unsigned int, struct cifsFileInfo *, | 326 | int (*sync_read)(const unsigned int, struct cifs_fid *, |
327 | struct cifs_io_parms *, unsigned int *, char **, | 327 | struct cifs_io_parms *, unsigned int *, char **, |
328 | int *); | 328 | int *); |
329 | /* sync write to the server */ | 329 | /* sync write to the server */ |
330 | int (*sync_write)(const unsigned int, struct cifsFileInfo *, | 330 | int (*sync_write)(const unsigned int, struct cifs_fid *, |
331 | struct cifs_io_parms *, unsigned int *, struct kvec *, | 331 | struct cifs_io_parms *, unsigned int *, struct kvec *, |
332 | unsigned long); | 332 | unsigned long); |
333 | /* open dir, start readdir */ | 333 | /* open dir, start readdir */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 239e1fb33000..d8eb6a74b211 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -3239,10 +3239,20 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
3239 | } | 3239 | } |
3240 | if (pvolume_info->mfsymlinks) { | 3240 | if (pvolume_info->mfsymlinks) { |
3241 | if (pvolume_info->sfu_emul) { | 3241 | if (pvolume_info->sfu_emul) { |
3242 | cifs_dbg(VFS, "mount option mfsymlinks ignored if sfu mount option is used\n"); | 3242 | /* |
3243 | } else { | 3243 | * Our SFU ("Services for Unix" emulation does not allow |
3244 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; | 3244 | * creating symlinks but does allow reading existing SFU |
3245 | * symlinks (it does allow both creating and reading SFU | ||
3246 | * style mknod and FIFOs though). When "mfsymlinks" and | ||
3247 | * "sfu" are both enabled at the same time, it allows | ||
3248 | * reading both types of symlinks, but will only create | ||
3249 | * them with mfsymlinks format. This allows better | ||
3250 | * Apple compatibility (probably better for Samba too) | ||
3251 | * while still recognizing old Windows style symlinks. | ||
3252 | */ | ||
3253 | cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n"); | ||
3245 | } | 3254 | } |
3255 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; | ||
3246 | } | 3256 | } |
3247 | 3257 | ||
3248 | if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) | 3258 | if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 073640675a39..b72bc29cba23 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -577,12 +577,13 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
577 | struct cifs_io_parms io_parms; | 577 | struct cifs_io_parms io_parms; |
578 | char *full_path = NULL; | 578 | char *full_path = NULL; |
579 | struct inode *newinode = NULL; | 579 | struct inode *newinode = NULL; |
580 | int oplock = 0; | 580 | __u32 oplock = 0; |
581 | struct cifs_fid fid; | 581 | struct cifs_fid fid; |
582 | struct cifs_open_parms oparms; | 582 | struct cifs_open_parms oparms; |
583 | FILE_ALL_INFO *buf = NULL; | 583 | FILE_ALL_INFO *buf = NULL; |
584 | unsigned int bytes_written; | 584 | unsigned int bytes_written; |
585 | struct win_dev *pdev; | 585 | struct win_dev *pdev; |
586 | struct kvec iov[2]; | ||
586 | 587 | ||
587 | if (!old_valid_dev(device_number)) | 588 | if (!old_valid_dev(device_number)) |
588 | return -EINVAL; | 589 | return -EINVAL; |
@@ -658,7 +659,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
658 | oparms.fid = &fid; | 659 | oparms.fid = &fid; |
659 | oparms.reconnect = false; | 660 | oparms.reconnect = false; |
660 | 661 | ||
661 | rc = CIFS_open(xid, &oparms, &oplock, buf); | 662 | if (tcon->ses->server->oplocks) |
663 | oplock = REQ_OPLOCK; | ||
664 | else | ||
665 | oplock = 0; | ||
666 | rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf); | ||
662 | if (rc) | 667 | if (rc) |
663 | goto mknod_out; | 668 | goto mknod_out; |
664 | 669 | ||
@@ -668,25 +673,26 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
668 | */ | 673 | */ |
669 | 674 | ||
670 | pdev = (struct win_dev *)buf; | 675 | pdev = (struct win_dev *)buf; |
671 | io_parms.netfid = fid.netfid; | ||
672 | io_parms.pid = current->tgid; | 676 | io_parms.pid = current->tgid; |
673 | io_parms.tcon = tcon; | 677 | io_parms.tcon = tcon; |
674 | io_parms.offset = 0; | 678 | io_parms.offset = 0; |
675 | io_parms.length = sizeof(struct win_dev); | 679 | io_parms.length = sizeof(struct win_dev); |
680 | iov[1].iov_base = buf; | ||
681 | iov[1].iov_len = sizeof(struct win_dev); | ||
676 | if (S_ISCHR(mode)) { | 682 | if (S_ISCHR(mode)) { |
677 | memcpy(pdev->type, "IntxCHR", 8); | 683 | memcpy(pdev->type, "IntxCHR", 8); |
678 | pdev->major = cpu_to_le64(MAJOR(device_number)); | 684 | pdev->major = cpu_to_le64(MAJOR(device_number)); |
679 | pdev->minor = cpu_to_le64(MINOR(device_number)); | 685 | pdev->minor = cpu_to_le64(MINOR(device_number)); |
680 | rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, (char *)pdev, | 686 | rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms, |
681 | NULL, 0); | 687 | &bytes_written, iov, 1); |
682 | } else if (S_ISBLK(mode)) { | 688 | } else if (S_ISBLK(mode)) { |
683 | memcpy(pdev->type, "IntxBLK", 8); | 689 | memcpy(pdev->type, "IntxBLK", 8); |
684 | pdev->major = cpu_to_le64(MAJOR(device_number)); | 690 | pdev->major = cpu_to_le64(MAJOR(device_number)); |
685 | pdev->minor = cpu_to_le64(MINOR(device_number)); | 691 | pdev->minor = cpu_to_le64(MINOR(device_number)); |
686 | rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, (char *)pdev, | 692 | rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms, |
687 | NULL, 0); | 693 | &bytes_written, iov, 1); |
688 | } /* else if (S_ISFIFO) */ | 694 | } /* else if (S_ISFIFO) */ |
689 | CIFSSMBClose(xid, tcon, fid.netfid); | 695 | tcon->ses->server->ops->close(xid, tcon, &fid); |
690 | d_drop(direntry); | 696 | d_drop(direntry); |
691 | 697 | ||
692 | /* FIXME: add code here to set EAs */ | 698 | /* FIXME: add code here to set EAs */ |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8f7b40fd8f3b..3e4d00a06c44 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1687,8 +1687,8 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, | |||
1687 | io_parms.tcon = tcon; | 1687 | io_parms.tcon = tcon; |
1688 | io_parms.offset = *offset; | 1688 | io_parms.offset = *offset; |
1689 | io_parms.length = len; | 1689 | io_parms.length = len; |
1690 | rc = server->ops->sync_write(xid, open_file, &io_parms, | 1690 | rc = server->ops->sync_write(xid, &open_file->fid, |
1691 | &bytes_written, iov, 1); | 1691 | &io_parms, &bytes_written, iov, 1); |
1692 | } | 1692 | } |
1693 | if (rc || (bytes_written == 0)) { | 1693 | if (rc || (bytes_written == 0)) { |
1694 | if (total_written) | 1694 | if (total_written) |
@@ -3206,7 +3206,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) | |||
3206 | io_parms.tcon = tcon; | 3206 | io_parms.tcon = tcon; |
3207 | io_parms.offset = *offset; | 3207 | io_parms.offset = *offset; |
3208 | io_parms.length = current_read_size; | 3208 | io_parms.length = current_read_size; |
3209 | rc = server->ops->sync_read(xid, open_file, &io_parms, | 3209 | rc = server->ops->sync_read(xid, &open_file->fid, &io_parms, |
3210 | &bytes_read, &cur_offset, | 3210 | &bytes_read, &cur_offset, |
3211 | &buf_type); | 3211 | &buf_type); |
3212 | } while (rc == -EAGAIN); | 3212 | } while (rc == -EAGAIN); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 8fd4ee8e07ff..4ff36ea8c693 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -412,7 +412,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, | |||
412 | struct cifs_sb_info *cifs_sb, unsigned int xid) | 412 | struct cifs_sb_info *cifs_sb, unsigned int xid) |
413 | { | 413 | { |
414 | int rc; | 414 | int rc; |
415 | int oplock = 0; | 415 | __u32 oplock; |
416 | struct tcon_link *tlink; | 416 | struct tcon_link *tlink; |
417 | struct cifs_tcon *tcon; | 417 | struct cifs_tcon *tcon; |
418 | struct cifs_fid fid; | 418 | struct cifs_fid fid; |
@@ -451,8 +451,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, | |||
451 | oparms.fid = &fid; | 451 | oparms.fid = &fid; |
452 | oparms.reconnect = false; | 452 | oparms.reconnect = false; |
453 | 453 | ||
454 | rc = CIFS_open(xid, &oparms, &oplock, NULL); | 454 | if (tcon->ses->server->oplocks) |
455 | oplock = REQ_OPLOCK; | ||
456 | else | ||
457 | oplock = 0; | ||
458 | rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL); | ||
455 | if (rc) { | 459 | if (rc) { |
460 | cifs_dbg(FYI, "check sfu type of %s, open rc = %d\n", path, rc); | ||
456 | cifs_put_tlink(tlink); | 461 | cifs_put_tlink(tlink); |
457 | return rc; | 462 | return rc; |
458 | } | 463 | } |
@@ -464,7 +469,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, | |||
464 | io_parms.offset = 0; | 469 | io_parms.offset = 0; |
465 | io_parms.length = 24; | 470 | io_parms.length = 24; |
466 | 471 | ||
467 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type); | 472 | rc = tcon->ses->server->ops->sync_read(xid, &fid, &io_parms, |
473 | &bytes_read, &pbuf, &buf_type); | ||
468 | if ((rc == 0) && (bytes_read >= 8)) { | 474 | if ((rc == 0) && (bytes_read >= 8)) { |
469 | if (memcmp("IntxBLK", pbuf, 8) == 0) { | 475 | if (memcmp("IntxBLK", pbuf, 8) == 0) { |
470 | cifs_dbg(FYI, "Block device\n"); | 476 | cifs_dbg(FYI, "Block device\n"); |
@@ -504,7 +510,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, | |||
504 | fattr->cf_dtype = DT_REG; | 510 | fattr->cf_dtype = DT_REG; |
505 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ | 511 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ |
506 | } | 512 | } |
507 | CIFSSMBClose(xid, tcon, fid.netfid); | 513 | |
514 | tcon->ses->server->ops->close(xid, tcon, &fid); | ||
508 | cifs_put_tlink(tlink); | 515 | cifs_put_tlink(tlink); |
509 | return rc; | 516 | return rc; |
510 | } | 517 | } |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 52131d8cb4d5..2aca620193cd 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -749,21 +749,21 @@ cifs_flush_file(const unsigned int xid, struct cifs_tcon *tcon, | |||
749 | } | 749 | } |
750 | 750 | ||
751 | static int | 751 | static int |
752 | cifs_sync_read(const unsigned int xid, struct cifsFileInfo *cfile, | 752 | cifs_sync_read(const unsigned int xid, struct cifs_fid *pfid, |
753 | struct cifs_io_parms *parms, unsigned int *bytes_read, | 753 | struct cifs_io_parms *parms, unsigned int *bytes_read, |
754 | char **buf, int *buf_type) | 754 | char **buf, int *buf_type) |
755 | { | 755 | { |
756 | parms->netfid = cfile->fid.netfid; | 756 | parms->netfid = pfid->netfid; |
757 | return CIFSSMBRead(xid, parms, bytes_read, buf, buf_type); | 757 | return CIFSSMBRead(xid, parms, bytes_read, buf, buf_type); |
758 | } | 758 | } |
759 | 759 | ||
760 | static int | 760 | static int |
761 | cifs_sync_write(const unsigned int xid, struct cifsFileInfo *cfile, | 761 | cifs_sync_write(const unsigned int xid, struct cifs_fid *pfid, |
762 | struct cifs_io_parms *parms, unsigned int *written, | 762 | struct cifs_io_parms *parms, unsigned int *written, |
763 | struct kvec *iov, unsigned long nr_segs) | 763 | struct kvec *iov, unsigned long nr_segs) |
764 | { | 764 | { |
765 | 765 | ||
766 | parms->netfid = cfile->fid.netfid; | 766 | parms->netfid = pfid->netfid; |
767 | return CIFSSMBWrite2(xid, parms, written, iov, nr_segs); | 767 | return CIFSSMBWrite2(xid, parms, written, iov, nr_segs); |
768 | } | 768 | } |
769 | 769 | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index f522193b7184..ea158c9dea15 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -711,23 +711,23 @@ smb2_read_data_length(char *buf) | |||
711 | 711 | ||
712 | 712 | ||
713 | static int | 713 | static int |
714 | smb2_sync_read(const unsigned int xid, struct cifsFileInfo *cfile, | 714 | smb2_sync_read(const unsigned int xid, struct cifs_fid *pfid, |
715 | struct cifs_io_parms *parms, unsigned int *bytes_read, | 715 | struct cifs_io_parms *parms, unsigned int *bytes_read, |
716 | char **buf, int *buf_type) | 716 | char **buf, int *buf_type) |
717 | { | 717 | { |
718 | parms->persistent_fid = cfile->fid.persistent_fid; | 718 | parms->persistent_fid = pfid->persistent_fid; |
719 | parms->volatile_fid = cfile->fid.volatile_fid; | 719 | parms->volatile_fid = pfid->volatile_fid; |
720 | return SMB2_read(xid, parms, bytes_read, buf, buf_type); | 720 | return SMB2_read(xid, parms, bytes_read, buf, buf_type); |
721 | } | 721 | } |
722 | 722 | ||
723 | static int | 723 | static int |
724 | smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile, | 724 | smb2_sync_write(const unsigned int xid, struct cifs_fid *pfid, |
725 | struct cifs_io_parms *parms, unsigned int *written, | 725 | struct cifs_io_parms *parms, unsigned int *written, |
726 | struct kvec *iov, unsigned long nr_segs) | 726 | struct kvec *iov, unsigned long nr_segs) |
727 | { | 727 | { |
728 | 728 | ||
729 | parms->persistent_fid = cfile->fid.persistent_fid; | 729 | parms->persistent_fid = pfid->persistent_fid; |
730 | parms->volatile_fid = cfile->fid.volatile_fid; | 730 | parms->volatile_fid = pfid->volatile_fid; |
731 | return SMB2_write(xid, parms, written, iov, nr_segs); | 731 | return SMB2_write(xid, parms, written, iov, nr_segs); |
732 | } | 732 | } |
733 | 733 | ||
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 74b3a6684383..8f1672bb82d5 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1098,6 +1098,8 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | |||
1098 | 1098 | ||
1099 | if (oparms->create_options & CREATE_OPTION_READONLY) | 1099 | if (oparms->create_options & CREATE_OPTION_READONLY) |
1100 | file_attributes |= ATTR_READONLY; | 1100 | file_attributes |= ATTR_READONLY; |
1101 | if (oparms->create_options & CREATE_OPTION_SPECIAL) | ||
1102 | file_attributes |= ATTR_SYSTEM; | ||
1101 | 1103 | ||
1102 | req->ImpersonationLevel = IL_IMPERSONATION; | 1104 | req->ImpersonationLevel = IL_IMPERSONATION; |
1103 | req->DesiredAccess = cpu_to_le32(oparms->desired_access); | 1105 | req->DesiredAccess = cpu_to_le32(oparms->desired_access); |