diff options
| -rw-r--r-- | fs/cifs/asn1.c | 53 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 24 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 4 | ||||
| -rw-r--r-- | fs/cifs/file.c | 6 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 10 | ||||
| -rw-r--r-- | fs/cifs/netmisc.c | 2 |
6 files changed, 43 insertions, 56 deletions
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index cfd1ce34e0bc..1d36db114772 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
| @@ -614,53 +614,10 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 614 | } | 614 | } |
| 615 | } | 615 | } |
| 616 | 616 | ||
| 617 | /* mechlistMIC */ | 617 | /* |
| 618 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 618 | * We currently ignore anything at the end of the SPNEGO blob after |
| 619 | /* Check if we have reached the end of the blob, but with | 619 | * the mechTypes have been parsed, since none of that info is |
| 620 | no mechListMic (e.g. NTLMSSP instead of KRB5) */ | 620 | * used at the moment. |
| 621 | if (ctx.error == ASN1_ERR_DEC_EMPTY) | 621 | */ |
| 622 | goto decode_negtoken_exit; | ||
| 623 | cFYI(1, "Error decoding last part negTokenInit exit3"); | ||
| 624 | return 0; | ||
| 625 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | ||
| 626 | /* tag = 3 indicating mechListMIC */ | ||
| 627 | cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)", | ||
| 628 | cls, con, tag, end, *end); | ||
| 629 | return 0; | ||
| 630 | } | ||
| 631 | |||
| 632 | /* sequence */ | ||
| 633 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | ||
| 634 | cFYI(1, "Error decoding last part negTokenInit exit5"); | ||
| 635 | return 0; | ||
| 636 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) | ||
| 637 | || (tag != ASN1_SEQ)) { | ||
| 638 | cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)", | ||
| 639 | cls, con, tag, end, *end); | ||
| 640 | } | ||
| 641 | |||
| 642 | /* sequence of */ | ||
| 643 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | ||
| 644 | cFYI(1, "Error decoding last part negTokenInit exit 7"); | ||
| 645 | return 0; | ||
| 646 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | ||
| 647 | cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)", | ||
| 648 | cls, con, tag, end, *end); | ||
| 649 | return 0; | ||
| 650 | } | ||
| 651 | |||
| 652 | /* general string */ | ||
| 653 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | ||
| 654 | cFYI(1, "Error decoding last part negTokenInit exit9"); | ||
| 655 | return 0; | ||
| 656 | } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) | ||
| 657 | || (tag != ASN1_GENSTR)) { | ||
| 658 | cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)", | ||
| 659 | cls, con, tag, end, *end); | ||
| 660 | return 0; | ||
| 661 | } | ||
| 662 | cFYI(1, "Need to call asn1_octets_decode() function for %s", | ||
| 663 | ctx.pointer); /* is this UTF-8 or ASCII? */ | ||
| 664 | decode_negtoken_exit: | ||
| 665 | return 1; | 622 | return 1; |
| 666 | } | 623 | } |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 3cf8a15af916..345fc89c4286 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -91,6 +91,30 @@ struct workqueue_struct *cifsiod_wq; | |||
| 91 | __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; | 91 | __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| 94 | /* | ||
| 95 | * Bumps refcount for cifs super block. | ||
| 96 | * Note that it should be only called if a referece to VFS super block is | ||
| 97 | * already held, e.g. in open-type syscalls context. Otherwise it can race with | ||
| 98 | * atomic_dec_and_test in deactivate_locked_super. | ||
| 99 | */ | ||
| 100 | void | ||
| 101 | cifs_sb_active(struct super_block *sb) | ||
| 102 | { | ||
| 103 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
| 104 | |||
| 105 | if (atomic_inc_return(&server->active) == 1) | ||
| 106 | atomic_inc(&sb->s_active); | ||
| 107 | } | ||
| 108 | |||
| 109 | void | ||
| 110 | cifs_sb_deactive(struct super_block *sb) | ||
| 111 | { | ||
| 112 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
| 113 | |||
| 114 | if (atomic_dec_and_test(&server->active)) | ||
| 115 | deactivate_super(sb); | ||
| 116 | } | ||
| 117 | |||
| 94 | static int | 118 | static int |
| 95 | cifs_read_super(struct super_block *sb) | 119 | cifs_read_super(struct super_block *sb) |
| 96 | { | 120 | { |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 7163419cecd9..0e32c3446ce9 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -41,6 +41,10 @@ extern struct file_system_type cifs_fs_type; | |||
| 41 | extern const struct address_space_operations cifs_addr_ops; | 41 | extern const struct address_space_operations cifs_addr_ops; |
| 42 | extern const struct address_space_operations cifs_addr_ops_smallbuf; | 42 | extern const struct address_space_operations cifs_addr_ops_smallbuf; |
| 43 | 43 | ||
| 44 | /* Functions related to super block operations */ | ||
| 45 | extern void cifs_sb_active(struct super_block *sb); | ||
| 46 | extern void cifs_sb_deactive(struct super_block *sb); | ||
| 47 | |||
| 44 | /* Functions related to inodes */ | 48 | /* Functions related to inodes */ |
| 45 | extern const struct inode_operations cifs_dir_inode_ops; | 49 | extern const struct inode_operations cifs_dir_inode_ops; |
| 46 | extern struct inode *cifs_root_iget(struct super_block *); | 50 | extern struct inode *cifs_root_iget(struct super_block *); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8c0d85577314..7a0dd99e4507 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -300,6 +300,8 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, | |||
| 300 | INIT_WORK(&cfile->oplock_break, cifs_oplock_break); | 300 | INIT_WORK(&cfile->oplock_break, cifs_oplock_break); |
| 301 | mutex_init(&cfile->fh_mutex); | 301 | mutex_init(&cfile->fh_mutex); |
| 302 | 302 | ||
| 303 | cifs_sb_active(inode->i_sb); | ||
| 304 | |||
| 303 | /* | 305 | /* |
| 304 | * If the server returned a read oplock and we have mandatory brlocks, | 306 | * If the server returned a read oplock and we have mandatory brlocks, |
| 305 | * set oplock level to None. | 307 | * set oplock level to None. |
| @@ -349,7 +351,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 349 | struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); | 351 | struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); |
| 350 | struct TCP_Server_Info *server = tcon->ses->server; | 352 | struct TCP_Server_Info *server = tcon->ses->server; |
| 351 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 353 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
| 352 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 354 | struct super_block *sb = inode->i_sb; |
| 355 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | ||
| 353 | struct cifsLockInfo *li, *tmp; | 356 | struct cifsLockInfo *li, *tmp; |
| 354 | struct cifs_fid fid; | 357 | struct cifs_fid fid; |
| 355 | struct cifs_pending_open open; | 358 | struct cifs_pending_open open; |
| @@ -414,6 +417,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 414 | 417 | ||
| 415 | cifs_put_tlink(cifs_file->tlink); | 418 | cifs_put_tlink(cifs_file->tlink); |
| 416 | dput(cifs_file->dentry); | 419 | dput(cifs_file->dentry); |
| 420 | cifs_sb_deactive(sb); | ||
| 417 | kfree(cifs_file); | 421 | kfree(cifs_file); |
| 418 | } | 422 | } |
| 419 | 423 | ||
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0079696305c9..20887bf63121 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -1043,7 +1043,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, | |||
| 1043 | cifs_sb->mnt_cifs_flags & | 1043 | cifs_sb->mnt_cifs_flags & |
| 1044 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1044 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 1045 | if (rc != 0) { | 1045 | if (rc != 0) { |
| 1046 | rc = -ETXTBSY; | 1046 | rc = -EBUSY; |
| 1047 | goto undo_setattr; | 1047 | goto undo_setattr; |
| 1048 | } | 1048 | } |
| 1049 | 1049 | ||
| @@ -1062,7 +1062,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, | |||
| 1062 | if (rc == -ENOENT) | 1062 | if (rc == -ENOENT) |
| 1063 | rc = 0; | 1063 | rc = 0; |
| 1064 | else if (rc != 0) { | 1064 | else if (rc != 0) { |
| 1065 | rc = -ETXTBSY; | 1065 | rc = -EBUSY; |
| 1066 | goto undo_rename; | 1066 | goto undo_rename; |
| 1067 | } | 1067 | } |
| 1068 | cifsInode->delete_pending = true; | 1068 | cifsInode->delete_pending = true; |
| @@ -1169,15 +1169,13 @@ psx_del_no_retry: | |||
| 1169 | cifs_drop_nlink(inode); | 1169 | cifs_drop_nlink(inode); |
| 1170 | } else if (rc == -ENOENT) { | 1170 | } else if (rc == -ENOENT) { |
| 1171 | d_drop(dentry); | 1171 | d_drop(dentry); |
| 1172 | } else if (rc == -ETXTBSY) { | 1172 | } else if (rc == -EBUSY) { |
| 1173 | if (server->ops->rename_pending_delete) { | 1173 | if (server->ops->rename_pending_delete) { |
| 1174 | rc = server->ops->rename_pending_delete(full_path, | 1174 | rc = server->ops->rename_pending_delete(full_path, |
| 1175 | dentry, xid); | 1175 | dentry, xid); |
| 1176 | if (rc == 0) | 1176 | if (rc == 0) |
| 1177 | cifs_drop_nlink(inode); | 1177 | cifs_drop_nlink(inode); |
| 1178 | } | 1178 | } |
| 1179 | if (rc == -ETXTBSY) | ||
| 1180 | rc = -EBUSY; | ||
| 1181 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { | 1179 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { |
| 1182 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); | 1180 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); |
| 1183 | if (attrs == NULL) { | 1181 | if (attrs == NULL) { |
| @@ -1518,7 +1516,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, | |||
| 1518 | * source. Note that cross directory moves do not work with | 1516 | * source. Note that cross directory moves do not work with |
| 1519 | * rename by filehandle to various Windows servers. | 1517 | * rename by filehandle to various Windows servers. |
| 1520 | */ | 1518 | */ |
| 1521 | if (rc == 0 || rc != -ETXTBSY) | 1519 | if (rc == 0 || rc != -EBUSY) |
| 1522 | goto do_rename_exit; | 1520 | goto do_rename_exit; |
| 1523 | 1521 | ||
| 1524 | /* open-file renames don't work across directories */ | 1522 | /* open-file renames don't work across directories */ |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index a82bc51fdc82..c0b25b28be6c 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
| @@ -62,7 +62,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = { | |||
| 62 | {ERRdiffdevice, -EXDEV}, | 62 | {ERRdiffdevice, -EXDEV}, |
| 63 | {ERRnofiles, -ENOENT}, | 63 | {ERRnofiles, -ENOENT}, |
| 64 | {ERRwriteprot, -EROFS}, | 64 | {ERRwriteprot, -EROFS}, |
| 65 | {ERRbadshare, -ETXTBSY}, | 65 | {ERRbadshare, -EBUSY}, |
| 66 | {ERRlock, -EACCES}, | 66 | {ERRlock, -EACCES}, |
| 67 | {ERRunsup, -EINVAL}, | 67 | {ERRunsup, -EINVAL}, |
| 68 | {ERRnosuchshare, -ENXIO}, | 68 | {ERRnosuchshare, -ENXIO}, |
