Skip to content

Commit 9217cbb

Browse files
committed
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull CIFS fixes from Steve French: "Three small CIFS Fixes (the most important of the three fixes a recent problem authenticating to Windows 8 using cifs rather than SMB2)" * 'for-next' of git://git.samba.org/sfrench/cifs-2.6: cifs: ignore everything in SPNEGO blob after mechTypes cifs: delay super block destruction until all cifsFileInfo objects are gone cifs: map NT_STATUS_SHARING_VIOLATION to EBUSY instead of ETXTBSY
2 parents d3c9262 + f853c61 commit 9217cbb

File tree

6 files changed

+43
-56
lines changed

6 files changed

+43
-56
lines changed

fs/cifs/asn1.c

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -614,53 +614,10 @@ decode_negTokenInit(unsigned char *security_blob, int length,
614614
}
615615
}
616616

617-
/* mechlistMIC */
618-
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
619-
/* Check if we have reached the end of the blob, but with
620-
no mechListMic (e.g. NTLMSSP instead of KRB5) */
621-
if (ctx.error == ASN1_ERR_DEC_EMPTY)
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:
617+
/*
618+
* We currently ignore anything at the end of the SPNEGO blob after
619+
* the mechTypes have been parsed, since none of that info is
620+
* used at the moment.
621+
*/
665622
return 1;
666623
}

fs/cifs/cifsfs.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,30 @@ struct workqueue_struct *cifsiod_wq;
9191
__u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE];
9292
#endif
9393

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+
94118
static int
95119
cifs_read_super(struct super_block *sb)
96120
{

fs/cifs/cifsfs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ extern struct file_system_type cifs_fs_type;
4141
extern const struct address_space_operations cifs_addr_ops;
4242
extern const struct address_space_operations cifs_addr_ops_smallbuf;
4343

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+
4448
/* Functions related to inodes */
4549
extern const struct inode_operations cifs_dir_inode_ops;
4650
extern struct inode *cifs_root_iget(struct super_block *);

fs/cifs/file.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
300300
INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
301301
mutex_init(&cfile->fh_mutex);
302302

303+
cifs_sb_active(inode->i_sb);
304+
303305
/*
304306
* If the server returned a read oplock and we have mandatory brlocks,
305307
* set oplock level to None.
@@ -349,7 +351,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
349351
struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
350352
struct TCP_Server_Info *server = tcon->ses->server;
351353
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);
353356
struct cifsLockInfo *li, *tmp;
354357
struct cifs_fid fid;
355358
struct cifs_pending_open open;
@@ -414,6 +417,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
414417

415418
cifs_put_tlink(cifs_file->tlink);
416419
dput(cifs_file->dentry);
420+
cifs_sb_deactive(sb);
417421
kfree(cifs_file);
418422
}
419423

fs/cifs/inode.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
10431043
cifs_sb->mnt_cifs_flags &
10441044
CIFS_MOUNT_MAP_SPECIAL_CHR);
10451045
if (rc != 0) {
1046-
rc = -ETXTBSY;
1046+
rc = -EBUSY;
10471047
goto undo_setattr;
10481048
}
10491049

@@ -1062,7 +1062,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
10621062
if (rc == -ENOENT)
10631063
rc = 0;
10641064
else if (rc != 0) {
1065-
rc = -ETXTBSY;
1065+
rc = -EBUSY;
10661066
goto undo_rename;
10671067
}
10681068
cifsInode->delete_pending = true;
@@ -1169,15 +1169,13 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
11691169
cifs_drop_nlink(inode);
11701170
} else if (rc == -ENOENT) {
11711171
d_drop(dentry);
1172-
} else if (rc == -ETXTBSY) {
1172+
} else if (rc == -EBUSY) {
11731173
if (server->ops->rename_pending_delete) {
11741174
rc = server->ops->rename_pending_delete(full_path,
11751175
dentry, xid);
11761176
if (rc == 0)
11771177
cifs_drop_nlink(inode);
11781178
}
1179-
if (rc == -ETXTBSY)
1180-
rc = -EBUSY;
11811179
} else if ((rc == -EACCES) && (dosattr == 0) && inode) {
11821180
attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
11831181
if (attrs == NULL) {
@@ -1518,7 +1516,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
15181516
* source. Note that cross directory moves do not work with
15191517
* rename by filehandle to various Windows servers.
15201518
*/
1521-
if (rc == 0 || rc != -ETXTBSY)
1519+
if (rc == 0 || rc != -EBUSY)
15221520
goto do_rename_exit;
15231521

15241522
/* open-file renames don't work across directories */

fs/cifs/netmisc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
6262
{ERRdiffdevice, -EXDEV},
6363
{ERRnofiles, -ENOENT},
6464
{ERRwriteprot, -EROFS},
65-
{ERRbadshare, -ETXTBSY},
65+
{ERRbadshare, -EBUSY},
6666
{ERRlock, -EACCES},
6767
{ERRunsup, -EINVAL},
6868
{ERRnosuchshare, -ENXIO},

0 commit comments

Comments
 (0)