Skip to content

Commit 0f44bc3

Browse files
committed
Merge branch 'for-linus' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French: "A set of cifs fixes (mostly for symlinks, and SMB2 xattrs) and cleanups" * 'for-linus' of git://git.samba.org/sfrench/cifs-2.6: cifs: Fix check for regular file in couldbe_mf_symlink() [CIFS] Fix SMB2 mounts so they don't try to set or get xattrs via cifs CIFS: Cleanup cifs open codepath CIFS: Remove extra indentation in cifs_sfu_type CIFS: Cleanup cifs_mknod CIFS: Cleanup CIFSSMBOpen cifs: Add support for follow_link on dfs shares under posix extensions cifs: move unix extension call to cifs_query_symlink() cifs: Re-order M-F Symlink code cifs: Add create MFSymlinks to protocol ops struct cifs: use protocol specific call for query_mf_symlink() cifs: Rename MF symlink function names cifs: Rename and cleanup open_query_close_cifs_symlink() cifs: Fix memory leak in cifs_hardlink()
2 parents efc518e + a9a315d commit 0f44bc3

File tree

11 files changed

+553
-420
lines changed

11 files changed

+553
-420
lines changed

fs/cifs/cifsacl.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -895,9 +895,10 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
895895
int oplock = 0;
896896
unsigned int xid;
897897
int rc, create_options = 0;
898-
__u16 fid;
899898
struct cifs_tcon *tcon;
900899
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
900+
struct cifs_fid fid;
901+
struct cifs_open_parms oparms;
901902

902903
if (IS_ERR(tlink))
903904
return ERR_CAST(tlink);
@@ -908,12 +909,19 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
908909
if (backup_cred(cifs_sb))
909910
create_options |= CREATE_OPEN_BACKUP_INTENT;
910911

911-
rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
912-
create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
913-
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
912+
oparms.tcon = tcon;
913+
oparms.cifs_sb = cifs_sb;
914+
oparms.desired_access = READ_CONTROL;
915+
oparms.create_options = create_options;
916+
oparms.disposition = FILE_OPEN;
917+
oparms.path = path;
918+
oparms.fid = &fid;
919+
oparms.reconnect = false;
920+
921+
rc = CIFS_open(xid, &oparms, &oplock, NULL);
914922
if (!rc) {
915-
rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
916-
CIFSSMBClose(xid, tcon, fid);
923+
rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
924+
CIFSSMBClose(xid, tcon, fid.netfid);
917925
}
918926

919927
cifs_put_tlink(tlink);
@@ -950,10 +958,11 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
950958
int oplock = 0;
951959
unsigned int xid;
952960
int rc, access_flags, create_options = 0;
953-
__u16 fid;
954961
struct cifs_tcon *tcon;
955962
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
956963
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
964+
struct cifs_fid fid;
965+
struct cifs_open_parms oparms;
957966

958967
if (IS_ERR(tlink))
959968
return PTR_ERR(tlink);
@@ -969,18 +978,25 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
969978
else
970979
access_flags = WRITE_DAC;
971980

972-
rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
973-
create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
974-
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
981+
oparms.tcon = tcon;
982+
oparms.cifs_sb = cifs_sb;
983+
oparms.desired_access = access_flags;
984+
oparms.create_options = create_options;
985+
oparms.disposition = FILE_OPEN;
986+
oparms.path = path;
987+
oparms.fid = &fid;
988+
oparms.reconnect = false;
989+
990+
rc = CIFS_open(xid, &oparms, &oplock, NULL);
975991
if (rc) {
976992
cifs_dbg(VFS, "Unable to open file to set ACL\n");
977993
goto out;
978994
}
979995

980-
rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
996+
rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
981997
cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
982998

983-
CIFSSMBClose(xid, tcon, fid);
999+
CIFSSMBClose(xid, tcon, fid.netfid);
9841000
out:
9851001
free_xid(xid);
9861002
cifs_put_tlink(tlink);

fs/cifs/cifsglob.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,12 @@ struct smb_version_operations {
370370
void (*new_lease_key)(struct cifs_fid *);
371371
int (*generate_signingkey)(struct cifs_ses *);
372372
int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *);
373-
int (*query_mf_symlink)(const unsigned char *, char *, unsigned int *,
374-
struct cifs_sb_info *, unsigned int);
373+
int (*query_mf_symlink)(unsigned int, struct cifs_tcon *,
374+
struct cifs_sb_info *, const unsigned char *,
375+
char *, unsigned int *);
376+
int (*create_mf_symlink)(unsigned int, struct cifs_tcon *,
377+
struct cifs_sb_info *, const unsigned char *,
378+
char *, unsigned int *);
375379
/* if we can do cache read operations */
376380
bool (*is_read_op)(__u32);
377381
/* set oplock level for the inode */
@@ -385,6 +389,12 @@ struct smb_version_operations {
385389
struct cifsFileInfo *target_file, u64 src_off, u64 len,
386390
u64 dest_off);
387391
int (*validate_negotiate)(const unsigned int, struct cifs_tcon *);
392+
ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *,
393+
const unsigned char *, const unsigned char *, char *,
394+
size_t, const struct nls_table *, int);
395+
int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *,
396+
const char *, const void *, const __u16,
397+
const struct nls_table *, int);
388398
};
389399

390400
struct smb_version_values {

fs/cifs/cifsproto.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,8 @@ extern int CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
362362
const struct nls_table *nls_codepage);
363363
extern int CIFSSMB_set_compression(const unsigned int xid,
364364
struct cifs_tcon *tcon, __u16 fid);
365-
extern int CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
366-
const char *fileName, const int disposition,
367-
const int access_flags, const int omode,
368-
__u16 *netfid, int *pOplock, FILE_ALL_INFO *,
369-
const struct nls_table *nls_codepage, int remap);
365+
extern int CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms,
366+
int *oplock, FILE_ALL_INFO *buf);
370367
extern int SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
371368
const char *fileName, const int disposition,
372369
const int access_flags, const int omode,
@@ -476,8 +473,8 @@ extern int CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
476473
extern int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
477474
const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
478475
extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
479-
extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
480-
extern int CIFSCheckMFSymlink(unsigned int xid, struct cifs_tcon *tcon,
476+
extern bool couldbe_mf_symlink(const struct cifs_fattr *fattr);
477+
extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
481478
struct cifs_sb_info *cifs_sb,
482479
struct cifs_fattr *fattr,
483480
const unsigned char *path);
@@ -496,7 +493,12 @@ void cifs_writev_complete(struct work_struct *work);
496493
struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages,
497494
work_func_t complete);
498495
void cifs_writedata_release(struct kref *refcount);
499-
int open_query_close_cifs_symlink(const unsigned char *path, char *pbuf,
500-
unsigned int *pbytes_read, struct cifs_sb_info *cifs_sb,
501-
unsigned int xid);
496+
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
497+
struct cifs_sb_info *cifs_sb,
498+
const unsigned char *path, char *pbuf,
499+
unsigned int *pbytes_read);
500+
int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
501+
struct cifs_sb_info *cifs_sb,
502+
const unsigned char *path, char *pbuf,
503+
unsigned int *pbytes_written);
502504
#endif /* _CIFSPROTO_H */

fs/cifs/cifssmb.c

Lines changed: 89 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,104 +1273,124 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
12731273
}
12741274

12751275
int
1276-
CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
1277-
const char *fileName, const int openDisposition,
1278-
const int access_flags, const int create_options, __u16 *netfid,
1279-
int *pOplock, FILE_ALL_INFO *pfile_info,
1280-
const struct nls_table *nls_codepage, int remap)
1276+
CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
1277+
FILE_ALL_INFO *buf)
12811278
{
12821279
int rc = -EACCES;
1283-
OPEN_REQ *pSMB = NULL;
1284-
OPEN_RSP *pSMBr = NULL;
1280+
OPEN_REQ *req = NULL;
1281+
OPEN_RSP *rsp = NULL;
12851282
int bytes_returned;
12861283
int name_len;
12871284
__u16 count;
1285+
struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
1286+
struct cifs_tcon *tcon = oparms->tcon;
1287+
int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
1288+
const struct nls_table *nls = cifs_sb->local_nls;
1289+
int create_options = oparms->create_options;
1290+
int desired_access = oparms->desired_access;
1291+
int disposition = oparms->disposition;
1292+
const char *path = oparms->path;
12881293

12891294
openRetry:
1290-
rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
1291-
(void **) &pSMBr);
1295+
rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
1296+
(void **)&rsp);
12921297
if (rc)
12931298
return rc;
12941299

1295-
pSMB->AndXCommand = 0xFF; /* none */
1300+
/* no commands go after this */
1301+
req->AndXCommand = 0xFF;
12961302

1297-
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1298-
count = 1; /* account for one byte pad to word boundary */
1299-
name_len =
1300-
cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
1301-
fileName, PATH_MAX, nls_codepage, remap);
1302-
name_len++; /* trailing null */
1303+
if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
1304+
/* account for one byte pad to word boundary */
1305+
count = 1;
1306+
name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
1307+
path, PATH_MAX, nls, remap);
1308+
/* trailing null */
1309+
name_len++;
13031310
name_len *= 2;
1304-
pSMB->NameLength = cpu_to_le16(name_len);
1305-
} else { /* BB improve check for buffer overruns BB */
1306-
count = 0; /* no pad */
1307-
name_len = strnlen(fileName, PATH_MAX);
1308-
name_len++; /* trailing null */
1309-
pSMB->NameLength = cpu_to_le16(name_len);
1310-
strncpy(pSMB->fileName, fileName, name_len);
1311+
req->NameLength = cpu_to_le16(name_len);
1312+
} else {
1313+
/* BB improve check for buffer overruns BB */
1314+
/* no pad */
1315+
count = 0;
1316+
name_len = strnlen(path, PATH_MAX);
1317+
/* trailing null */
1318+
name_len++;
1319+
req->NameLength = cpu_to_le16(name_len);
1320+
strncpy(req->fileName, path, name_len);
13111321
}
1312-
if (*pOplock & REQ_OPLOCK)
1313-
pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1314-
else if (*pOplock & REQ_BATCHOPLOCK)
1315-
pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1316-
pSMB->DesiredAccess = cpu_to_le32(access_flags);
1317-
pSMB->AllocationSize = 0;
1318-
/* set file as system file if special file such
1319-
as fifo and server expecting SFU style and
1320-
no Unix extensions */
1322+
1323+
if (*oplock & REQ_OPLOCK)
1324+
req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
1325+
else if (*oplock & REQ_BATCHOPLOCK)
1326+
req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
1327+
1328+
req->DesiredAccess = cpu_to_le32(desired_access);
1329+
req->AllocationSize = 0;
1330+
1331+
/*
1332+
* Set file as system file if special file such as fifo and server
1333+
* expecting SFU style and no Unix extensions.
1334+
*/
13211335
if (create_options & CREATE_OPTION_SPECIAL)
1322-
pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1336+
req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
13231337
else
1324-
pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
1338+
req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
13251339

1326-
/* XP does not handle ATTR_POSIX_SEMANTICS */
1327-
/* but it helps speed up case sensitive checks for other
1328-
servers such as Samba */
1340+
/*
1341+
* XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
1342+
* sensitive checks for other servers such as Samba.
1343+
*/
13291344
if (tcon->ses->capabilities & CAP_UNIX)
1330-
pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
1345+
req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
13311346

13321347
if (create_options & CREATE_OPTION_READONLY)
1333-
pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1348+
req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
1349+
1350+
req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1351+
req->CreateDisposition = cpu_to_le32(disposition);
1352+
req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
13341353

1335-
pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
1336-
pSMB->CreateDisposition = cpu_to_le32(openDisposition);
1337-
pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
13381354
/* BB Expirement with various impersonation levels and verify */
1339-
pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1340-
pSMB->SecurityFlags =
1341-
SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1355+
req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
1356+
req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
13421357

13431358
count += name_len;
1344-
inc_rfc1001_len(pSMB, count);
1359+
inc_rfc1001_len(req, count);
13451360

1346-
pSMB->ByteCount = cpu_to_le16(count);
1347-
/* long_op set to 1 to allow for oplock break timeouts */
1348-
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1349-
(struct smb_hdr *)pSMBr, &bytes_returned, 0);
1361+
req->ByteCount = cpu_to_le16(count);
1362+
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
1363+
(struct smb_hdr *)rsp, &bytes_returned, 0);
13501364
cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
13511365
if (rc) {
13521366
cifs_dbg(FYI, "Error in Open = %d\n", rc);
1353-
} else {
1354-
*pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
1355-
*netfid = pSMBr->Fid; /* cifs fid stays in le */
1356-
/* Let caller know file was created so we can set the mode. */
1357-
/* Do we care about the CreateAction in any other cases? */
1358-
if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1359-
*pOplock |= CIFS_CREATE_ACTION;
1360-
if (pfile_info) {
1361-
memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1362-
36 /* CreationTime to Attributes */);
1363-
/* the file_info buf is endian converted by caller */
1364-
pfile_info->AllocationSize = pSMBr->AllocationSize;
1365-
pfile_info->EndOfFile = pSMBr->EndOfFile;
1366-
pfile_info->NumberOfLinks = cpu_to_le32(1);
1367-
pfile_info->DeletePending = 0;
1368-
}
1367+
cifs_buf_release(req);
1368+
if (rc == -EAGAIN)
1369+
goto openRetry;
1370+
return rc;
13691371
}
13701372

1371-
cifs_buf_release(pSMB);
1372-
if (rc == -EAGAIN)
1373-
goto openRetry;
1373+
/* 1 byte no need to le_to_cpu */
1374+
*oplock = rsp->OplockLevel;
1375+
/* cifs fid stays in le */
1376+
oparms->fid->netfid = rsp->Fid;
1377+
1378+
/* Let caller know file was created so we can set the mode. */
1379+
/* Do we care about the CreateAction in any other cases? */
1380+
if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
1381+
*oplock |= CIFS_CREATE_ACTION;
1382+
1383+
if (buf) {
1384+
/* copy from CreationTime to Attributes */
1385+
memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
1386+
/* the file_info buf is endian converted by caller */
1387+
buf->AllocationSize = rsp->AllocationSize;
1388+
buf->EndOfFile = rsp->EndOfFile;
1389+
buf->NumberOfLinks = cpu_to_le32(1);
1390+
buf->DeletePending = 0;
1391+
}
1392+
1393+
cifs_buf_release(req);
13741394
return rc;
13751395
}
13761396

0 commit comments

Comments
 (0)