Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+571 -438
+28 -12
fs/cifs/cifsacl.c
··· 895 895 int oplock = 0; 896 896 unsigned int xid; 897 897 int rc, create_options = 0; 898 - __u16 fid; 899 898 struct cifs_tcon *tcon; 900 899 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 900 + struct cifs_fid fid; 901 + struct cifs_open_parms oparms; 901 902 902 903 if (IS_ERR(tlink)) 903 904 return ERR_CAST(tlink); ··· 909 908 if (backup_cred(cifs_sb)) 910 909 create_options |= CREATE_OPEN_BACKUP_INTENT; 911 910 912 - rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 913 - create_options, &fid, &oplock, NULL, cifs_sb->local_nls, 914 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 911 + oparms.tcon = tcon; 912 + oparms.cifs_sb = cifs_sb; 913 + oparms.desired_access = READ_CONTROL; 914 + oparms.create_options = create_options; 915 + oparms.disposition = FILE_OPEN; 916 + oparms.path = path; 917 + oparms.fid = &fid; 918 + oparms.reconnect = false; 919 + 920 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 915 921 if (!rc) { 916 - rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen); 917 - CIFSSMBClose(xid, tcon, fid); 922 + rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen); 923 + CIFSSMBClose(xid, tcon, fid.netfid); 918 924 } 919 925 920 926 cifs_put_tlink(tlink); ··· 958 950 int oplock = 0; 959 951 unsigned int xid; 960 952 int rc, access_flags, create_options = 0; 961 - __u16 fid; 962 953 struct cifs_tcon *tcon; 963 954 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 964 955 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 956 + struct cifs_fid fid; 957 + struct cifs_open_parms oparms; 965 958 966 959 if (IS_ERR(tlink)) 967 960 return PTR_ERR(tlink); ··· 978 969 else 979 970 access_flags = WRITE_DAC; 980 971 981 - rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags, 982 - create_options, &fid, &oplock, NULL, cifs_sb->local_nls, 983 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 972 + oparms.tcon = tcon; 973 + oparms.cifs_sb = cifs_sb; 974 + oparms.desired_access = access_flags; 975 + oparms.create_options = create_options; 976 + oparms.disposition = FILE_OPEN; 977 + oparms.path = path; 978 + oparms.fid = &fid; 979 + oparms.reconnect = false; 980 + 981 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 984 982 if (rc) { 985 983 cifs_dbg(VFS, "Unable to open file to set ACL\n"); 986 984 goto out; 987 985 } 988 986 989 - rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag); 987 + rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag); 990 988 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc); 991 989 992 - CIFSSMBClose(xid, tcon, fid); 990 + CIFSSMBClose(xid, tcon, fid.netfid); 993 991 out: 994 992 free_xid(xid); 995 993 cifs_put_tlink(tlink);
+12 -2
fs/cifs/cifsglob.h
··· 370 370 void (*new_lease_key)(struct cifs_fid *); 371 371 int (*generate_signingkey)(struct cifs_ses *); 372 372 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 *); 375 379 /* if we can do cache read operations */ 376 380 bool (*is_read_op)(__u32); 377 381 /* set oplock level for the inode */ ··· 389 385 struct cifsFileInfo *target_file, u64 src_off, u64 len, 390 386 u64 dest_off); 391 387 int (*validate_negotiate)(const unsigned int, struct cifs_tcon *); 388 + ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *, 389 + const unsigned char *, const unsigned char *, char *, 390 + size_t, const struct nls_table *, int); 391 + int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, 392 + const char *, const void *, const __u16, 393 + const struct nls_table *, int); 392 394 }; 393 395 394 396 struct smb_version_values {
+12 -10
fs/cifs/cifsproto.h
··· 362 362 const struct nls_table *nls_codepage); 363 363 extern int CIFSSMB_set_compression(const unsigned int xid, 364 364 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); 370 367 extern int SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon, 371 368 const char *fileName, const int disposition, 372 369 const int access_flags, const int omode, ··· 473 476 extern int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, 474 477 const int netfid, __u64 *pExtAttrBits, __u64 *pMask); 475 478 extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb); 476 - extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr); 477 - extern int CIFSCheckMFSymlink(unsigned int xid, struct cifs_tcon *tcon, 479 + extern bool couldbe_mf_symlink(const struct cifs_fattr *fattr); 480 + extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 478 481 struct cifs_sb_info *cifs_sb, 479 482 struct cifs_fattr *fattr, 480 483 const unsigned char *path); ··· 493 496 struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, 494 497 work_func_t complete); 495 498 void cifs_writedata_release(struct kref *refcount); 496 - int open_query_close_cifs_symlink(const unsigned char *path, char *pbuf, 497 - unsigned int *pbytes_read, struct cifs_sb_info *cifs_sb, 498 - unsigned int xid); 499 + int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 500 + struct cifs_sb_info *cifs_sb, 501 + const unsigned char *path, char *pbuf, 502 + unsigned int *pbytes_read); 503 + int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 504 + struct cifs_sb_info *cifs_sb, 505 + const unsigned char *path, char *pbuf, 506 + unsigned int *pbytes_written); 499 507 #endif /* _CIFSPROTO_H */
+91 -71
fs/cifs/cifssmb.c
··· 1273 1273 } 1274 1274 1275 1275 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) 1281 1278 { 1282 1279 int rc = -EACCES; 1283 - OPEN_REQ *pSMB = NULL; 1284 - OPEN_RSP *pSMBr = NULL; 1280 + OPEN_REQ *req = NULL; 1281 + OPEN_RSP *rsp = NULL; 1285 1282 int bytes_returned; 1286 1283 int name_len; 1287 1284 __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; 1288 1293 1289 1294 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); 1292 1297 if (rc) 1293 1298 return rc; 1294 1299 1295 - pSMB->AndXCommand = 0xFF; /* none */ 1300 + /* no commands go after this */ 1301 + req->AndXCommand = 0xFF; 1296 1302 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++; 1303 1310 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); 1311 1321 } 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 */ 1321 - if (create_options & CREATE_OPTION_SPECIAL) 1322 - pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM); 1323 - else 1324 - pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); 1325 1322 1326 - /* XP does not handle ATTR_POSIX_SEMANTICS */ 1327 - /* but it helps speed up case sensitive checks for other 1328 - servers such as Samba */ 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 + */ 1335 + if (create_options & CREATE_OPTION_SPECIAL) 1336 + req->FileAttributes = cpu_to_le32(ATTR_SYSTEM); 1337 + else 1338 + req->FileAttributes = cpu_to_le32(ATTR_NORMAL); 1339 + 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 + */ 1329 1344 if (tcon->ses->capabilities & CAP_UNIX) 1330 - pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); 1345 + req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); 1331 1346 1332 1347 if (create_options & CREATE_OPTION_READONLY) 1333 - pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY); 1348 + req->FileAttributes |= cpu_to_le32(ATTR_READONLY); 1334 1349 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); 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); 1353 + 1338 1354 /* 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; 1342 1357 1343 1358 count += name_len; 1344 - inc_rfc1001_len(pSMB, count); 1359 + inc_rfc1001_len(req, count); 1345 1360 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); 1350 1364 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); 1351 1365 if (rc) { 1352 1366 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; 1369 1371 } 1370 1372 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); 1374 1394 return rc; 1375 1395 } 1376 1396
+31 -28
fs/cifs/dir.c
··· 565 565 int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL; 566 566 struct cifs_sb_info *cifs_sb; 567 567 struct tcon_link *tlink; 568 - struct cifs_tcon *pTcon; 568 + struct cifs_tcon *tcon; 569 569 struct cifs_io_parms io_parms; 570 570 char *full_path = NULL; 571 571 struct inode *newinode = NULL; 572 572 int oplock = 0; 573 - u16 fileHandle; 573 + struct cifs_fid fid; 574 + struct cifs_open_parms oparms; 574 575 FILE_ALL_INFO *buf = NULL; 575 576 unsigned int bytes_written; 576 577 struct win_dev *pdev; ··· 584 583 if (IS_ERR(tlink)) 585 584 return PTR_ERR(tlink); 586 585 587 - pTcon = tlink_tcon(tlink); 586 + tcon = tlink_tcon(tlink); 588 587 589 588 xid = get_xid(); 590 589 ··· 594 593 goto mknod_out; 595 594 } 596 595 597 - if (pTcon->unix_ext) { 596 + if (tcon->unix_ext) { 598 597 struct cifs_unix_set_info_args args = { 599 598 .mode = mode & ~current_umask(), 600 599 .ctime = NO_CHANGE_64, ··· 609 608 args.uid = INVALID_UID; /* no change */ 610 609 args.gid = INVALID_GID; /* no change */ 611 610 } 612 - rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, 611 + rc = CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, 613 612 cifs_sb->local_nls, 614 613 cifs_sb->mnt_cifs_flags & 615 614 CIFS_MOUNT_MAP_SPECIAL_CHR); ··· 641 640 if (backup_cred(cifs_sb)) 642 641 create_options |= CREATE_OPEN_BACKUP_INTENT; 643 642 644 - rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE, 645 - GENERIC_WRITE, create_options, 646 - &fileHandle, &oplock, buf, cifs_sb->local_nls, 647 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 643 + oparms.tcon = tcon; 644 + oparms.cifs_sb = cifs_sb; 645 + oparms.desired_access = GENERIC_WRITE; 646 + oparms.create_options = create_options; 647 + oparms.disposition = FILE_CREATE; 648 + oparms.path = full_path; 649 + oparms.fid = &fid; 650 + oparms.reconnect = false; 651 + 652 + rc = CIFS_open(xid, &oparms, &oplock, buf); 648 653 if (rc) 649 654 goto mknod_out; 650 655 651 - /* BB Do not bother to decode buf since no local inode yet to put 652 - * timestamps in, but we can reuse it safely */ 656 + /* 657 + * BB Do not bother to decode buf since no local inode yet to put 658 + * timestamps in, but we can reuse it safely. 659 + */ 653 660 654 661 pdev = (struct win_dev *)buf; 655 - io_parms.netfid = fileHandle; 662 + io_parms.netfid = fid.netfid; 656 663 io_parms.pid = current->tgid; 657 - io_parms.tcon = pTcon; 664 + io_parms.tcon = tcon; 658 665 io_parms.offset = 0; 659 666 io_parms.length = sizeof(struct win_dev); 660 667 if (S_ISCHR(mode)) { 661 668 memcpy(pdev->type, "IntxCHR", 8); 662 - pdev->major = 663 - cpu_to_le64(MAJOR(device_number)); 664 - pdev->minor = 665 - cpu_to_le64(MINOR(device_number)); 666 - rc = CIFSSMBWrite(xid, &io_parms, 667 - &bytes_written, (char *)pdev, 668 - NULL, 0); 669 + pdev->major = cpu_to_le64(MAJOR(device_number)); 670 + pdev->minor = cpu_to_le64(MINOR(device_number)); 671 + rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, (char *)pdev, 672 + NULL, 0); 669 673 } else if (S_ISBLK(mode)) { 670 674 memcpy(pdev->type, "IntxBLK", 8); 671 - pdev->major = 672 - cpu_to_le64(MAJOR(device_number)); 673 - pdev->minor = 674 - cpu_to_le64(MINOR(device_number)); 675 - rc = CIFSSMBWrite(xid, &io_parms, 676 - &bytes_written, (char *)pdev, 677 - NULL, 0); 675 + pdev->major = cpu_to_le64(MAJOR(device_number)); 676 + pdev->minor = cpu_to_le64(MINOR(device_number)); 677 + rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, (char *)pdev, 678 + NULL, 0); 678 679 } /* else if (S_ISFIFO) */ 679 - CIFSSMBClose(xid, pTcon, fileHandle); 680 + CIFSSMBClose(xid, tcon, fid.netfid); 680 681 d_drop(direntry); 681 682 682 683 /* FIXME: add code here to set EAs */
+1 -1
fs/cifs/file.c
··· 678 678 679 679 /* 680 680 * Can not refresh inode by passing in file_info buf to be returned by 681 - * CIFSSMBOpen and then calling get_inode_info with returned buf since 681 + * ops->open and then calling get_inode_info with returned buf since 682 682 * file might have write behind data that needs to be flushed and server 683 683 * version of file size can be stale. If we knew for sure that inode was 684 684 * not dirty locally we could do this.
+105 -81
fs/cifs/inode.c
··· 383 383 384 384 /* check for Minshall+French symlinks */ 385 385 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { 386 - int tmprc = CIFSCheckMFSymlink(xid, tcon, cifs_sb, &fattr, 387 - full_path); 386 + int tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, 387 + full_path); 388 388 if (tmprc) 389 - cifs_dbg(FYI, "CIFSCheckMFSymlink: %d\n", tmprc); 389 + cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); 390 390 } 391 391 392 392 if (*pinode == NULL) { ··· 404 404 } 405 405 406 406 static int 407 - cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, 407 + cifs_sfu_type(struct cifs_fattr *fattr, const char *path, 408 408 struct cifs_sb_info *cifs_sb, unsigned int xid) 409 409 { 410 410 int rc; 411 411 int oplock = 0; 412 - __u16 netfid; 413 412 struct tcon_link *tlink; 414 413 struct cifs_tcon *tcon; 414 + struct cifs_fid fid; 415 + struct cifs_open_parms oparms; 415 416 struct cifs_io_parms io_parms; 416 417 char buf[24]; 417 418 unsigned int bytes_read; 418 419 char *pbuf; 420 + int buf_type = CIFS_NO_BUFFER; 419 421 420 422 pbuf = buf; 421 423 ··· 438 436 return PTR_ERR(tlink); 439 437 tcon = tlink_tcon(tlink); 440 438 441 - rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ, 442 - CREATE_NOT_DIR, &netfid, &oplock, NULL, 443 - cifs_sb->local_nls, 444 - cifs_sb->mnt_cifs_flags & 445 - CIFS_MOUNT_MAP_SPECIAL_CHR); 446 - if (rc == 0) { 447 - int buf_type = CIFS_NO_BUFFER; 448 - /* Read header */ 449 - io_parms.netfid = netfid; 450 - io_parms.pid = current->tgid; 451 - io_parms.tcon = tcon; 452 - io_parms.offset = 0; 453 - io_parms.length = 24; 454 - rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, 455 - &buf_type); 456 - if ((rc == 0) && (bytes_read >= 8)) { 457 - if (memcmp("IntxBLK", pbuf, 8) == 0) { 458 - cifs_dbg(FYI, "Block device\n"); 459 - fattr->cf_mode |= S_IFBLK; 460 - fattr->cf_dtype = DT_BLK; 461 - if (bytes_read == 24) { 462 - /* we have enough to decode dev num */ 463 - __u64 mjr; /* major */ 464 - __u64 mnr; /* minor */ 465 - mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 466 - mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 467 - fattr->cf_rdev = MKDEV(mjr, mnr); 468 - } 469 - } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 470 - cifs_dbg(FYI, "Char device\n"); 471 - fattr->cf_mode |= S_IFCHR; 472 - fattr->cf_dtype = DT_CHR; 473 - if (bytes_read == 24) { 474 - /* we have enough to decode dev num */ 475 - __u64 mjr; /* major */ 476 - __u64 mnr; /* minor */ 477 - mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 478 - mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 479 - fattr->cf_rdev = MKDEV(mjr, mnr); 480 - } 481 - } else if (memcmp("IntxLNK", pbuf, 7) == 0) { 482 - cifs_dbg(FYI, "Symlink\n"); 483 - fattr->cf_mode |= S_IFLNK; 484 - fattr->cf_dtype = DT_LNK; 485 - } else { 486 - fattr->cf_mode |= S_IFREG; /* file? */ 487 - fattr->cf_dtype = DT_REG; 488 - rc = -EOPNOTSUPP; 489 - } 490 - } else { 491 - fattr->cf_mode |= S_IFREG; /* then it is a file */ 492 - fattr->cf_dtype = DT_REG; 493 - rc = -EOPNOTSUPP; /* or some unknown SFU type */ 494 - } 495 - CIFSSMBClose(xid, tcon, netfid); 439 + oparms.tcon = tcon; 440 + oparms.cifs_sb = cifs_sb; 441 + oparms.desired_access = GENERIC_READ; 442 + oparms.create_options = CREATE_NOT_DIR; 443 + oparms.disposition = FILE_OPEN; 444 + oparms.path = path; 445 + oparms.fid = &fid; 446 + oparms.reconnect = false; 447 + 448 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 449 + if (rc) { 450 + cifs_put_tlink(tlink); 451 + return rc; 496 452 } 453 + 454 + /* Read header */ 455 + io_parms.netfid = fid.netfid; 456 + io_parms.pid = current->tgid; 457 + io_parms.tcon = tcon; 458 + io_parms.offset = 0; 459 + io_parms.length = 24; 460 + 461 + rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type); 462 + if ((rc == 0) && (bytes_read >= 8)) { 463 + if (memcmp("IntxBLK", pbuf, 8) == 0) { 464 + cifs_dbg(FYI, "Block device\n"); 465 + fattr->cf_mode |= S_IFBLK; 466 + fattr->cf_dtype = DT_BLK; 467 + if (bytes_read == 24) { 468 + /* we have enough to decode dev num */ 469 + __u64 mjr; /* major */ 470 + __u64 mnr; /* minor */ 471 + mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 472 + mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 473 + fattr->cf_rdev = MKDEV(mjr, mnr); 474 + } 475 + } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 476 + cifs_dbg(FYI, "Char device\n"); 477 + fattr->cf_mode |= S_IFCHR; 478 + fattr->cf_dtype = DT_CHR; 479 + if (bytes_read == 24) { 480 + /* we have enough to decode dev num */ 481 + __u64 mjr; /* major */ 482 + __u64 mnr; /* minor */ 483 + mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 484 + mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 485 + fattr->cf_rdev = MKDEV(mjr, mnr); 486 + } 487 + } else if (memcmp("IntxLNK", pbuf, 7) == 0) { 488 + cifs_dbg(FYI, "Symlink\n"); 489 + fattr->cf_mode |= S_IFLNK; 490 + fattr->cf_dtype = DT_LNK; 491 + } else { 492 + fattr->cf_mode |= S_IFREG; /* file? */ 493 + fattr->cf_dtype = DT_REG; 494 + rc = -EOPNOTSUPP; 495 + } 496 + } else { 497 + fattr->cf_mode |= S_IFREG; /* then it is a file */ 498 + fattr->cf_dtype = DT_REG; 499 + rc = -EOPNOTSUPP; /* or some unknown SFU type */ 500 + } 501 + CIFSSMBClose(xid, tcon, fid.netfid); 497 502 cifs_put_tlink(tlink); 498 503 return rc; 499 504 } ··· 809 800 810 801 /* check for Minshall+French symlinks */ 811 802 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { 812 - tmprc = CIFSCheckMFSymlink(xid, tcon, cifs_sb, &fattr, 813 - full_path); 803 + tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, 804 + full_path); 814 805 if (tmprc) 815 - cifs_dbg(FYI, "CIFSCheckMFSymlink: %d\n", tmprc); 806 + cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); 816 807 } 817 808 818 809 if (!*inode) { ··· 1041 1032 { 1042 1033 int oplock = 0; 1043 1034 int rc; 1044 - __u16 netfid; 1035 + struct cifs_fid fid; 1036 + struct cifs_open_parms oparms; 1045 1037 struct inode *inode = dentry->d_inode; 1046 1038 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1047 1039 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); ··· 1065 1055 goto out; 1066 1056 } 1067 1057 1068 - rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, 1069 - DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, 1070 - &netfid, &oplock, NULL, cifs_sb->local_nls, 1071 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 1058 + oparms.tcon = tcon; 1059 + oparms.cifs_sb = cifs_sb; 1060 + oparms.desired_access = DELETE | FILE_WRITE_ATTRIBUTES; 1061 + oparms.create_options = CREATE_NOT_DIR; 1062 + oparms.disposition = FILE_OPEN; 1063 + oparms.path = full_path; 1064 + oparms.fid = &fid; 1065 + oparms.reconnect = false; 1066 + 1067 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 1072 1068 if (rc != 0) 1073 1069 goto out; 1074 1070 ··· 1095 1079 goto out_close; 1096 1080 } 1097 1081 info_buf->Attributes = cpu_to_le32(dosattr); 1098 - rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid, 1082 + rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid, 1099 1083 current->tgid); 1100 1084 /* although we would like to mark the file hidden 1101 1085 if that fails we will still try to rename it */ ··· 1106 1090 } 1107 1091 1108 1092 /* rename the file */ 1109 - rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls, 1093 + rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, NULL, 1094 + cifs_sb->local_nls, 1110 1095 cifs_sb->mnt_cifs_flags & 1111 1096 CIFS_MOUNT_MAP_SPECIAL_CHR); 1112 1097 if (rc != 0) { ··· 1117 1100 1118 1101 /* try to set DELETE_ON_CLOSE */ 1119 1102 if (!cifsInode->delete_pending) { 1120 - rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid, 1103 + rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid, 1121 1104 current->tgid); 1122 1105 /* 1123 1106 * some samba versions return -ENOENT when we try to set the ··· 1137 1120 } 1138 1121 1139 1122 out_close: 1140 - CIFSSMBClose(xid, tcon, netfid); 1123 + CIFSSMBClose(xid, tcon, fid.netfid); 1141 1124 out: 1142 1125 kfree(info_buf); 1143 1126 cifs_put_tlink(tlink); ··· 1149 1132 * them anyway. 1150 1133 */ 1151 1134 undo_rename: 1152 - CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name, 1135 + CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, dentry->d_name.name, 1153 1136 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 1154 1137 CIFS_MOUNT_MAP_SPECIAL_CHR); 1155 1138 undo_setattr: 1156 1139 if (dosattr != origattr) { 1157 1140 info_buf->Attributes = cpu_to_le32(origattr); 1158 - if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid, 1141 + if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid, 1159 1142 current->tgid)) 1160 1143 cifsInode->cifsAttrs = origattr; 1161 1144 } ··· 1566 1549 struct tcon_link *tlink; 1567 1550 struct cifs_tcon *tcon; 1568 1551 struct TCP_Server_Info *server; 1569 - __u16 srcfid; 1552 + struct cifs_fid fid; 1553 + struct cifs_open_parms oparms; 1570 1554 int oplock, rc; 1571 1555 1572 1556 tlink = cifs_sb_tlink(cifs_sb); ··· 1594 1576 if (to_dentry->d_parent != from_dentry->d_parent) 1595 1577 goto do_rename_exit; 1596 1578 1579 + oparms.tcon = tcon; 1580 + oparms.cifs_sb = cifs_sb; 1597 1581 /* open the file to be renamed -- we need DELETE perms */ 1598 - rc = CIFSSMBOpen(xid, tcon, from_path, FILE_OPEN, DELETE, 1599 - CREATE_NOT_DIR, &srcfid, &oplock, NULL, 1600 - cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 1601 - CIFS_MOUNT_MAP_SPECIAL_CHR); 1582 + oparms.desired_access = DELETE; 1583 + oparms.create_options = CREATE_NOT_DIR; 1584 + oparms.disposition = FILE_OPEN; 1585 + oparms.path = from_path; 1586 + oparms.fid = &fid; 1587 + oparms.reconnect = false; 1588 + 1589 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 1602 1590 if (rc == 0) { 1603 - rc = CIFSSMBRenameOpenFile(xid, tcon, srcfid, 1591 + rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, 1604 1592 (const char *) to_dentry->d_name.name, 1605 1593 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 1606 1594 CIFS_MOUNT_MAP_SPECIAL_CHR); 1607 - CIFSSMBClose(xid, tcon, srcfid); 1595 + CIFSSMBClose(xid, tcon, fid.netfid); 1608 1596 } 1609 1597 do_rename_exit: 1610 1598 cifs_put_tlink(tlink);
+168 -177
fs/cifs/link.c
··· 29 29 #include "cifs_debug.h" 30 30 #include "cifs_fs_sb.h" 31 31 32 + /* 33 + * M-F Symlink Functions - Begin 34 + */ 35 + 32 36 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) 33 37 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) 34 38 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1)) ··· 95 91 } 96 92 97 93 static int 98 - CIFSParseMFSymlink(const u8 *buf, 99 - unsigned int buf_len, 100 - unsigned int *_link_len, 101 - char **_link_str) 94 + parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len, 95 + char **_link_str) 102 96 { 103 97 int rc; 104 98 unsigned int link_len; ··· 139 137 } 140 138 141 139 static int 142 - CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) 140 + format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str) 143 141 { 144 142 int rc; 145 143 unsigned int link_len; ··· 182 180 return 0; 183 181 } 184 182 185 - static int 186 - CIFSCreateMFSymLink(const unsigned int xid, struct cifs_tcon *tcon, 187 - const char *fromName, const char *toName, 188 - struct cifs_sb_info *cifs_sb) 189 - { 190 - int rc; 191 - int oplock = 0; 192 - int remap; 193 - int create_options = CREATE_NOT_DIR; 194 - __u16 netfid = 0; 195 - u8 *buf; 196 - unsigned int bytes_written = 0; 197 - struct cifs_io_parms io_parms; 198 - struct nls_table *nls_codepage; 199 - 200 - nls_codepage = cifs_sb->local_nls; 201 - remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; 202 - 203 - buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 204 - if (!buf) 205 - return -ENOMEM; 206 - 207 - rc = CIFSFormatMFSymlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); 208 - if (rc != 0) { 209 - kfree(buf); 210 - return rc; 211 - } 212 - 213 - if (backup_cred(cifs_sb)) 214 - create_options |= CREATE_OPEN_BACKUP_INTENT; 215 - 216 - rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE, 217 - create_options, &netfid, &oplock, NULL, 218 - nls_codepage, remap); 219 - if (rc != 0) { 220 - kfree(buf); 221 - return rc; 222 - } 223 - 224 - io_parms.netfid = netfid; 225 - io_parms.pid = current->tgid; 226 - io_parms.tcon = tcon; 227 - io_parms.offset = 0; 228 - io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 229 - 230 - rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0); 231 - CIFSSMBClose(xid, tcon, netfid); 232 - kfree(buf); 233 - if (rc != 0) 234 - return rc; 235 - 236 - if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) 237 - return -EIO; 238 - 239 - return 0; 240 - } 241 - 242 - static int 243 - CIFSQueryMFSymLink(const unsigned int xid, struct cifs_tcon *tcon, 244 - const unsigned char *searchName, char **symlinkinfo, 245 - const struct nls_table *nls_codepage, int remap) 246 - { 247 - int rc; 248 - int oplock = 0; 249 - __u16 netfid = 0; 250 - u8 *buf; 251 - char *pbuf; 252 - unsigned int bytes_read = 0; 253 - int buf_type = CIFS_NO_BUFFER; 254 - unsigned int link_len = 0; 255 - struct cifs_io_parms io_parms; 256 - FILE_ALL_INFO file_info; 257 - 258 - rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ, 259 - CREATE_NOT_DIR, &netfid, &oplock, &file_info, 260 - nls_codepage, remap); 261 - if (rc != 0) 262 - return rc; 263 - 264 - if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { 265 - CIFSSMBClose(xid, tcon, netfid); 266 - /* it's not a symlink */ 267 - return -EINVAL; 268 - } 269 - 270 - buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 271 - if (!buf) 272 - return -ENOMEM; 273 - pbuf = buf; 274 - io_parms.netfid = netfid; 275 - io_parms.pid = current->tgid; 276 - io_parms.tcon = tcon; 277 - io_parms.offset = 0; 278 - io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 279 - 280 - rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type); 281 - CIFSSMBClose(xid, tcon, netfid); 282 - if (rc != 0) { 283 - kfree(buf); 284 - return rc; 285 - } 286 - 287 - rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo); 288 - kfree(buf); 289 - if (rc != 0) 290 - return rc; 291 - 292 - return 0; 293 - } 294 - 295 183 bool 296 - CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr) 184 + couldbe_mf_symlink(const struct cifs_fattr *fattr) 297 185 { 298 - if (!(fattr->cf_mode & S_IFREG)) 186 + if (!S_ISREG(fattr->cf_mode)) 299 187 /* it's not a symlink */ 300 188 return false; 301 189 ··· 196 304 return true; 197 305 } 198 306 199 - int 200 - open_query_close_cifs_symlink(const unsigned char *path, char *pbuf, 201 - unsigned int *pbytes_read, struct cifs_sb_info *cifs_sb, 202 - unsigned int xid) 307 + static int 308 + create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, 309 + struct cifs_sb_info *cifs_sb, const char *fromName, 310 + const char *toName) 203 311 { 204 312 int rc; 205 - int oplock = 0; 206 - __u16 netfid = 0; 207 - struct tcon_link *tlink; 208 - struct cifs_tcon *ptcon; 209 - struct cifs_io_parms io_parms; 210 - int buf_type = CIFS_NO_BUFFER; 211 - FILE_ALL_INFO file_info; 313 + u8 *buf; 314 + unsigned int bytes_written = 0; 212 315 213 - tlink = cifs_sb_tlink(cifs_sb); 214 - if (IS_ERR(tlink)) 215 - return PTR_ERR(tlink); 216 - ptcon = tlink_tcon(tlink); 316 + buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 317 + if (!buf) 318 + return -ENOMEM; 217 319 218 - rc = CIFSSMBOpen(xid, ptcon, path, FILE_OPEN, GENERIC_READ, 219 - CREATE_NOT_DIR, &netfid, &oplock, &file_info, 220 - cifs_sb->local_nls, 221 - cifs_sb->mnt_cifs_flags & 222 - CIFS_MOUNT_MAP_SPECIAL_CHR); 223 - if (rc != 0) { 224 - cifs_put_tlink(tlink); 225 - return rc; 226 - } 320 + rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); 321 + if (rc) 322 + goto out; 227 323 228 - if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { 229 - CIFSSMBClose(xid, ptcon, netfid); 230 - cifs_put_tlink(tlink); 231 - /* it's not a symlink */ 232 - return rc; 233 - } 324 + rc = tcon->ses->server->ops->create_mf_symlink(xid, tcon, cifs_sb, 325 + fromName, buf, &bytes_written); 326 + if (rc) 327 + goto out; 234 328 235 - io_parms.netfid = netfid; 236 - io_parms.pid = current->tgid; 237 - io_parms.tcon = ptcon; 238 - io_parms.offset = 0; 239 - io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 240 - 241 - rc = CIFSSMBRead(xid, &io_parms, pbytes_read, &pbuf, &buf_type); 242 - CIFSSMBClose(xid, ptcon, netfid); 243 - cifs_put_tlink(tlink); 329 + if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) 330 + rc = -EIO; 331 + out: 332 + kfree(buf); 244 333 return rc; 245 334 } 246 335 247 - 248 - int 249 - CIFSCheckMFSymlink(unsigned int xid, struct cifs_tcon *tcon, 250 - struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, 251 - const unsigned char *path) 336 + static int 337 + query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, 338 + struct cifs_sb_info *cifs_sb, const unsigned char *path, 339 + char **symlinkinfo) 252 340 { 253 341 int rc; 254 342 u8 *buf = NULL; 255 343 unsigned int link_len = 0; 256 344 unsigned int bytes_read = 0; 257 345 258 - if (!CIFSCouldBeMFSymlink(fattr)) 346 + buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 347 + if (!buf) 348 + return -ENOMEM; 349 + 350 + if (tcon->ses->server->ops->query_mf_symlink) 351 + rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon, 352 + cifs_sb, path, buf, &bytes_read); 353 + else 354 + rc = -ENOSYS; 355 + 356 + if (rc) 357 + goto out; 358 + 359 + if (bytes_read == 0) { /* not a symlink */ 360 + rc = -EINVAL; 361 + goto out; 362 + } 363 + 364 + rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo); 365 + out: 366 + kfree(buf); 367 + return rc; 368 + } 369 + 370 + int 371 + check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 372 + struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, 373 + const unsigned char *path) 374 + { 375 + int rc; 376 + u8 *buf = NULL; 377 + unsigned int link_len = 0; 378 + unsigned int bytes_read = 0; 379 + 380 + if (!couldbe_mf_symlink(fattr)) 259 381 /* it's not a symlink */ 260 382 return 0; 261 383 ··· 278 372 return -ENOMEM; 279 373 280 374 if (tcon->ses->server->ops->query_mf_symlink) 281 - rc = tcon->ses->server->ops->query_mf_symlink(path, buf, 282 - &bytes_read, cifs_sb, xid); 375 + rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon, 376 + cifs_sb, path, buf, &bytes_read); 283 377 else 284 378 rc = -ENOSYS; 285 379 ··· 289 383 if (bytes_read == 0) /* not a symlink */ 290 384 goto out; 291 385 292 - rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL); 386 + rc = parse_mf_symlink(buf, bytes_read, &link_len, NULL); 293 387 if (rc == -EINVAL) { 294 388 /* it's not a symlink */ 295 389 rc = 0; ··· 308 402 kfree(buf); 309 403 return rc; 310 404 } 405 + 406 + /* 407 + * SMB 1.0 Protocol specific functions 408 + */ 409 + 410 + int 411 + cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 412 + struct cifs_sb_info *cifs_sb, const unsigned char *path, 413 + char *pbuf, unsigned int *pbytes_read) 414 + { 415 + int rc; 416 + int oplock = 0; 417 + struct cifs_fid fid; 418 + struct cifs_open_parms oparms; 419 + struct cifs_io_parms io_parms; 420 + int buf_type = CIFS_NO_BUFFER; 421 + FILE_ALL_INFO file_info; 422 + 423 + oparms.tcon = tcon; 424 + oparms.cifs_sb = cifs_sb; 425 + oparms.desired_access = GENERIC_READ; 426 + oparms.create_options = CREATE_NOT_DIR; 427 + oparms.disposition = FILE_OPEN; 428 + oparms.path = path; 429 + oparms.fid = &fid; 430 + oparms.reconnect = false; 431 + 432 + rc = CIFS_open(xid, &oparms, &oplock, &file_info); 433 + if (rc) 434 + return rc; 435 + 436 + if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) 437 + /* it's not a symlink */ 438 + goto out; 439 + 440 + io_parms.netfid = fid.netfid; 441 + io_parms.pid = current->tgid; 442 + io_parms.tcon = tcon; 443 + io_parms.offset = 0; 444 + io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 445 + 446 + rc = CIFSSMBRead(xid, &io_parms, pbytes_read, &pbuf, &buf_type); 447 + out: 448 + CIFSSMBClose(xid, tcon, fid.netfid); 449 + return rc; 450 + } 451 + 452 + int 453 + cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 454 + struct cifs_sb_info *cifs_sb, const unsigned char *path, 455 + char *pbuf, unsigned int *pbytes_written) 456 + { 457 + int rc; 458 + int oplock = 0; 459 + struct cifs_fid fid; 460 + struct cifs_open_parms oparms; 461 + struct cifs_io_parms io_parms; 462 + int create_options = CREATE_NOT_DIR; 463 + 464 + if (backup_cred(cifs_sb)) 465 + create_options |= CREATE_OPEN_BACKUP_INTENT; 466 + 467 + oparms.tcon = tcon; 468 + oparms.cifs_sb = cifs_sb; 469 + oparms.desired_access = GENERIC_WRITE; 470 + oparms.create_options = create_options; 471 + oparms.disposition = FILE_OPEN; 472 + oparms.path = path; 473 + oparms.fid = &fid; 474 + oparms.reconnect = false; 475 + 476 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 477 + if (rc) 478 + return rc; 479 + 480 + io_parms.netfid = fid.netfid; 481 + io_parms.pid = current->tgid; 482 + io_parms.tcon = tcon; 483 + io_parms.offset = 0; 484 + io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 485 + 486 + rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf, NULL, 0); 487 + CIFSSMBClose(xid, tcon, fid.netfid); 488 + return rc; 489 + } 490 + 491 + /* 492 + * M-F Symlink Functions - End 493 + */ 311 494 312 495 int 313 496 cifs_hardlink(struct dentry *old_file, struct inode *inode, ··· 433 438 CIFS_MOUNT_MAP_SPECIAL_CHR); 434 439 else { 435 440 server = tcon->ses->server; 436 - if (!server->ops->create_hardlink) 437 - return -ENOSYS; 441 + if (!server->ops->create_hardlink) { 442 + rc = -ENOSYS; 443 + goto cifs_hl_exit; 444 + } 438 445 rc = server->ops->create_hardlink(xid, tcon, from_name, to_name, 439 446 cifs_sb); 440 447 if ((rc == -EIO) || (rc == -EINVAL)) ··· 527 530 * and fallback to UNIX Extensions Symlinks. 528 531 */ 529 532 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) 530 - rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path, 531 - cifs_sb->local_nls, 532 - cifs_sb->mnt_cifs_flags & 533 - CIFS_MOUNT_MAP_SPECIAL_CHR); 533 + rc = query_mf_symlink(xid, tcon, cifs_sb, full_path, 534 + &target_path); 534 535 535 - if ((rc != 0) && cap_unix(tcon->ses)) 536 - rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, 537 - cifs_sb->local_nls); 538 - else if (rc != 0 && server->ops->query_symlink) 536 + if (rc != 0 && server->ops->query_symlink) 539 537 rc = server->ops->query_symlink(xid, tcon, full_path, 540 538 &target_path, cifs_sb); 541 539 ··· 579 587 580 588 /* BB what if DFS and this volume is on different share? BB */ 581 589 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) 582 - rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname, 583 - cifs_sb); 590 + rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname); 584 591 else if (pTcon->unix_ext) 585 592 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 586 593 cifs_sb->local_nls);
+1 -1
fs/cifs/readdir.c
··· 749 749 } 750 750 751 751 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) && 752 - CIFSCouldBeMFSymlink(&fattr)) 752 + couldbe_mf_symlink(&fattr)) 753 753 /* 754 754 * trying to get the type and mode can be slow, 755 755 * so just call those regular files for now, and mark
+92 -36
fs/cifs/smb1ops.c
··· 560 560 if (!rc && (le32_to_cpu(data->Attributes) & ATTR_REPARSE)) { 561 561 int tmprc; 562 562 int oplock = 0; 563 - __u16 netfid; 563 + struct cifs_fid fid; 564 + struct cifs_open_parms oparms; 565 + 566 + oparms.tcon = tcon; 567 + oparms.cifs_sb = cifs_sb; 568 + oparms.desired_access = FILE_READ_ATTRIBUTES; 569 + oparms.create_options = 0; 570 + oparms.disposition = FILE_OPEN; 571 + oparms.path = full_path; 572 + oparms.fid = &fid; 573 + oparms.reconnect = false; 564 574 565 575 /* Need to check if this is a symbolic link or not */ 566 - tmprc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, 567 - FILE_READ_ATTRIBUTES, 0, &netfid, &oplock, 568 - NULL, cifs_sb->local_nls, 569 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 576 + tmprc = CIFS_open(xid, &oparms, &oplock, NULL); 570 577 if (tmprc == -EOPNOTSUPP) 571 578 *symlink = true; 572 579 else 573 - CIFSSMBClose(xid, tcon, netfid); 580 + CIFSSMBClose(xid, tcon, fid.netfid); 574 581 } 575 582 576 583 return rc; ··· 712 705 oparms->cifs_sb->local_nls, 713 706 oparms->cifs_sb->mnt_cifs_flags 714 707 & CIFS_MOUNT_MAP_SPECIAL_CHR); 715 - return CIFSSMBOpen(xid, oparms->tcon, oparms->path, 716 - oparms->disposition, oparms->desired_access, 717 - oparms->create_options, &oparms->fid->netfid, oplock, 718 - buf, oparms->cifs_sb->local_nls, 719 - oparms->cifs_sb->mnt_cifs_flags & 720 - CIFS_MOUNT_MAP_SPECIAL_CHR); 708 + return CIFS_open(xid, oparms, oplock, buf); 721 709 } 722 710 723 711 static void ··· 763 761 { 764 762 int oplock = 0; 765 763 int rc; 766 - __u16 netfid; 767 764 __u32 netpid; 765 + struct cifs_fid fid; 766 + struct cifs_open_parms oparms; 768 767 struct cifsFileInfo *open_file; 769 768 struct cifsInodeInfo *cinode = CIFS_I(inode); 770 769 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); ··· 775 772 /* if the file is already open for write, just use that fileid */ 776 773 open_file = find_writable_file(cinode, true); 777 774 if (open_file) { 778 - netfid = open_file->fid.netfid; 775 + fid.netfid = open_file->fid.netfid; 779 776 netpid = open_file->pid; 780 777 tcon = tlink_tcon(open_file->tlink); 781 778 goto set_via_filehandle; ··· 799 796 goto out; 800 797 } 801 798 802 - cifs_dbg(FYI, "calling SetFileInfo since SetPathInfo for times not supported by this server\n"); 803 - rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, 804 - SYNCHRONIZE | FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, 805 - &netfid, &oplock, NULL, cifs_sb->local_nls, 806 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 799 + oparms.tcon = tcon; 800 + oparms.cifs_sb = cifs_sb; 801 + oparms.desired_access = SYNCHRONIZE | FILE_WRITE_ATTRIBUTES; 802 + oparms.create_options = CREATE_NOT_DIR; 803 + oparms.disposition = FILE_OPEN; 804 + oparms.path = full_path; 805 + oparms.fid = &fid; 806 + oparms.reconnect = false; 807 807 808 + cifs_dbg(FYI, "calling SetFileInfo since SetPathInfo for times not supported by this server\n"); 809 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 808 810 if (rc != 0) { 809 811 if (rc == -EIO) 810 812 rc = -EINVAL; ··· 819 811 netpid = current->tgid; 820 812 821 813 set_via_filehandle: 822 - rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid); 814 + rc = CIFSSMBSetFileInfo(xid, tcon, buf, fid.netfid, netpid); 823 815 if (!rc) 824 816 cinode->cifsAttrs = le32_to_cpu(buf->Attributes); 825 817 826 818 if (open_file == NULL) 827 - CIFSSMBClose(xid, tcon, netfid); 819 + CIFSSMBClose(xid, tcon, fid.netfid); 828 820 else 829 821 cifsFileInfo_put(open_file); 830 822 out: ··· 916 908 } 917 909 918 910 static int 911 + cifs_unix_dfs_readlink(const unsigned int xid, struct cifs_tcon *tcon, 912 + const unsigned char *searchName, char **symlinkinfo, 913 + const struct nls_table *nls_codepage) 914 + { 915 + #ifdef CONFIG_CIFS_DFS_UPCALL 916 + int rc; 917 + unsigned int num_referrals = 0; 918 + struct dfs_info3_param *referrals = NULL; 919 + 920 + rc = get_dfs_path(xid, tcon->ses, searchName, nls_codepage, 921 + &num_referrals, &referrals, 0); 922 + 923 + if (!rc && num_referrals > 0) { 924 + *symlinkinfo = kstrndup(referrals->node_name, 925 + strlen(referrals->node_name), 926 + GFP_KERNEL); 927 + if (!*symlinkinfo) 928 + rc = -ENOMEM; 929 + free_dfs_info_array(referrals, num_referrals); 930 + } 931 + return rc; 932 + #else /* No DFS support */ 933 + return -EREMOTE; 934 + #endif 935 + } 936 + 937 + static int 919 938 cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, 920 939 const char *full_path, char **target_path, 921 940 struct cifs_sb_info *cifs_sb) 922 941 { 923 942 int rc; 924 943 int oplock = 0; 925 - __u16 netfid; 944 + struct cifs_fid fid; 945 + struct cifs_open_parms oparms; 926 946 927 947 cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); 928 948 929 - rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, 930 - FILE_READ_ATTRIBUTES, OPEN_REPARSE_POINT, &netfid, 931 - &oplock, NULL, cifs_sb->local_nls, 932 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 933 - if (rc) 934 - return rc; 949 + /* Check for unix extensions */ 950 + if (cap_unix(tcon->ses)) { 951 + rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path, 952 + cifs_sb->local_nls); 953 + if (rc == -EREMOTE) 954 + rc = cifs_unix_dfs_readlink(xid, tcon, full_path, 955 + target_path, 956 + cifs_sb->local_nls); 935 957 936 - rc = CIFSSMBQuerySymLink(xid, tcon, netfid, target_path, 937 - cifs_sb->local_nls); 938 - if (rc) { 939 - CIFSSMBClose(xid, tcon, netfid); 940 - return rc; 958 + goto out; 941 959 } 942 960 961 + oparms.tcon = tcon; 962 + oparms.cifs_sb = cifs_sb; 963 + oparms.desired_access = FILE_READ_ATTRIBUTES; 964 + oparms.create_options = OPEN_REPARSE_POINT; 965 + oparms.disposition = FILE_OPEN; 966 + oparms.path = full_path; 967 + oparms.fid = &fid; 968 + oparms.reconnect = false; 969 + 970 + rc = CIFS_open(xid, &oparms, &oplock, NULL); 971 + if (rc) 972 + goto out; 973 + 974 + rc = CIFSSMBQuerySymLink(xid, tcon, fid.netfid, target_path, 975 + cifs_sb->local_nls); 976 + if (rc) 977 + goto out_close; 978 + 943 979 convert_delimiter(*target_path, '/'); 944 - CIFSSMBClose(xid, tcon, netfid); 945 - cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path); 980 + out_close: 981 + CIFSSMBClose(xid, tcon, fid.netfid); 982 + out: 983 + if (!rc) 984 + cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path); 946 985 return rc; 947 986 } 948 987 ··· 1064 1009 .mand_lock = cifs_mand_lock, 1065 1010 .mand_unlock_range = cifs_unlock_range, 1066 1011 .push_mand_locks = cifs_push_mandatory_locks, 1067 - .query_mf_symlink = open_query_close_cifs_symlink, 1012 + .query_mf_symlink = cifs_query_mf_symlink, 1013 + .create_mf_symlink = cifs_create_mf_symlink, 1068 1014 .is_read_op = cifs_is_read_op, 1069 1015 }; 1070 1016
+30 -19
fs/cifs/xattr.c
··· 82 82 goto remove_ea_exit; 83 83 84 84 ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */ 85 - rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL, 86 - (__u16)0, cifs_sb->local_nls, 87 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 85 + if (pTcon->ses->server->ops->set_EA) 86 + rc = pTcon->ses->server->ops->set_EA(xid, pTcon, 87 + full_path, ea_name, NULL, (__u16)0, 88 + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 89 + CIFS_MOUNT_MAP_SPECIAL_CHR); 88 90 } 89 91 remove_ea_exit: 90 92 kfree(full_path); ··· 151 149 cifs_dbg(FYI, "attempt to set cifs inode metadata\n"); 152 150 153 151 ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */ 154 - rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, 155 - (__u16)value_size, cifs_sb->local_nls, 156 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 152 + if (pTcon->ses->server->ops->set_EA) 153 + rc = pTcon->ses->server->ops->set_EA(xid, pTcon, 154 + full_path, ea_name, ea_value, (__u16)value_size, 155 + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 156 + CIFS_MOUNT_MAP_SPECIAL_CHR); 157 157 } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) 158 158 == 0) { 159 159 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 160 160 goto set_ea_exit; 161 161 162 162 ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */ 163 - rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, 164 - (__u16)value_size, cifs_sb->local_nls, 165 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 163 + if (pTcon->ses->server->ops->set_EA) 164 + rc = pTcon->ses->server->ops->set_EA(xid, pTcon, 165 + full_path, ea_name, ea_value, (__u16)value_size, 166 + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 167 + CIFS_MOUNT_MAP_SPECIAL_CHR); 166 168 } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, 167 169 strlen(CIFS_XATTR_CIFS_ACL)) == 0) { 168 170 #ifdef CONFIG_CIFS_ACL ··· 278 272 /* revalidate/getattr then populate from inode */ 279 273 } /* BB add else when above is implemented */ 280 274 ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */ 281 - rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value, 282 - buf_size, cifs_sb->local_nls, 283 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 275 + if (pTcon->ses->server->ops->query_all_EAs) 276 + rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, 277 + full_path, ea_name, ea_value, buf_size, 278 + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 279 + CIFS_MOUNT_MAP_SPECIAL_CHR); 284 280 } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { 285 281 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 286 282 goto get_ea_exit; 287 283 288 284 ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */ 289 - rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value, 290 - buf_size, cifs_sb->local_nls, 291 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 285 + if (pTcon->ses->server->ops->query_all_EAs) 286 + rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, 287 + full_path, ea_name, ea_value, buf_size, 288 + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 289 + CIFS_MOUNT_MAP_SPECIAL_CHR); 292 290 } else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS, 293 291 strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { 294 292 #ifdef CONFIG_CIFS_POSIX ··· 410 400 /* if proc/fs/cifs/streamstoxattr is set then 411 401 search server for EAs or streams to 412 402 returns as xattrs */ 413 - rc = CIFSSMBQAllEAs(xid, pTcon, full_path, NULL, data, 414 - buf_size, cifs_sb->local_nls, 415 - cifs_sb->mnt_cifs_flags & 416 - CIFS_MOUNT_MAP_SPECIAL_CHR); 417 403 404 + if (pTcon->ses->server->ops->query_all_EAs) 405 + rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, 406 + full_path, NULL, data, buf_size, 407 + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 408 + CIFS_MOUNT_MAP_SPECIAL_CHR); 418 409 list_ea_exit: 419 410 kfree(full_path); 420 411 free_xid(xid);