aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c193
1 files changed, 111 insertions, 82 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 49719b8228e5..aadc2b68678b 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -383,10 +383,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
383 383
384 /* check for Minshall+French symlinks */ 384 /* check for Minshall+French symlinks */
385 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { 385 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
386 int tmprc = CIFSCheckMFSymlink(xid, tcon, cifs_sb, &fattr, 386 int tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr,
387 full_path); 387 full_path);
388 if (tmprc) 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 if (*pinode == NULL) { 392 if (*pinode == NULL) {
@@ -404,18 +404,20 @@ int cifs_get_inode_info_unix(struct inode **pinode,
404} 404}
405 405
406static int 406static int
407cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, 407cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
408 struct cifs_sb_info *cifs_sb, unsigned int xid) 408 struct cifs_sb_info *cifs_sb, unsigned int xid)
409{ 409{
410 int rc; 410 int rc;
411 int oplock = 0; 411 int oplock = 0;
412 __u16 netfid;
413 struct tcon_link *tlink; 412 struct tcon_link *tlink;
414 struct cifs_tcon *tcon; 413 struct cifs_tcon *tcon;
414 struct cifs_fid fid;
415 struct cifs_open_parms oparms;
415 struct cifs_io_parms io_parms; 416 struct cifs_io_parms io_parms;
416 char buf[24]; 417 char buf[24];
417 unsigned int bytes_read; 418 unsigned int bytes_read;
418 char *pbuf; 419 char *pbuf;
420 int buf_type = CIFS_NO_BUFFER;
419 421
420 pbuf = buf; 422 pbuf = buf;
421 423
@@ -436,62 +438,69 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
436 return PTR_ERR(tlink); 438 return PTR_ERR(tlink);
437 tcon = tlink_tcon(tlink); 439 tcon = tlink_tcon(tlink);
438 440
439 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ, 441 oparms.tcon = tcon;
440 CREATE_NOT_DIR, &netfid, &oplock, NULL, 442 oparms.cifs_sb = cifs_sb;
441 cifs_sb->local_nls, 443 oparms.desired_access = GENERIC_READ;
442 cifs_sb->mnt_cifs_flags & 444 oparms.create_options = CREATE_NOT_DIR;
443 CIFS_MOUNT_MAP_SPECIAL_CHR); 445 oparms.disposition = FILE_OPEN;
444 if (rc == 0) { 446 oparms.path = path;
445 int buf_type = CIFS_NO_BUFFER; 447 oparms.fid = &fid;
446 /* Read header */ 448 oparms.reconnect = false;
447 io_parms.netfid = netfid; 449
448 io_parms.pid = current->tgid; 450 rc = CIFS_open(xid, &oparms, &oplock, NULL);
449 io_parms.tcon = tcon; 451 if (rc) {
450 io_parms.offset = 0; 452 cifs_put_tlink(tlink);
451 io_parms.length = 24; 453 return rc;
452 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, 454 }
453 &buf_type); 455
454 if ((rc == 0) && (bytes_read >= 8)) { 456 /* Read header */
455 if (memcmp("IntxBLK", pbuf, 8) == 0) { 457 io_parms.netfid = fid.netfid;
456 cifs_dbg(FYI, "Block device\n"); 458 io_parms.pid = current->tgid;
457 fattr->cf_mode |= S_IFBLK; 459 io_parms.tcon = tcon;
458 fattr->cf_dtype = DT_BLK; 460 io_parms.offset = 0;
459 if (bytes_read == 24) { 461 io_parms.length = 24;
460 /* we have enough to decode dev num */ 462
461 __u64 mjr; /* major */ 463 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
462 __u64 mnr; /* minor */ 464 if ((rc == 0) && (bytes_read >= 8)) {
463 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 465 if (memcmp("IntxBLK", pbuf, 8) == 0) {
464 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 466 cifs_dbg(FYI, "Block device\n");
465 fattr->cf_rdev = MKDEV(mjr, mnr); 467 fattr->cf_mode |= S_IFBLK;
466 } 468 fattr->cf_dtype = DT_BLK;
467 } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 469 if (bytes_read == 24) {
468 cifs_dbg(FYI, "Char device\n"); 470 /* we have enough to decode dev num */
469 fattr->cf_mode |= S_IFCHR; 471 __u64 mjr; /* major */
470 fattr->cf_dtype = DT_CHR; 472 __u64 mnr; /* minor */
471 if (bytes_read == 24) { 473 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
472 /* we have enough to decode dev num */ 474 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
473 __u64 mjr; /* major */ 475 fattr->cf_rdev = MKDEV(mjr, mnr);
474 __u64 mnr; /* minor */
475 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
476 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
477 fattr->cf_rdev = MKDEV(mjr, mnr);
478 }
479 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
480 cifs_dbg(FYI, "Symlink\n");
481 fattr->cf_mode |= S_IFLNK;
482 fattr->cf_dtype = DT_LNK;
483 } else {
484 fattr->cf_mode |= S_IFREG; /* file? */
485 fattr->cf_dtype = DT_REG;
486 rc = -EOPNOTSUPP;
487 } 476 }
477 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
478 cifs_dbg(FYI, "Char device\n");
479 fattr->cf_mode |= S_IFCHR;
480 fattr->cf_dtype = DT_CHR;
481 if (bytes_read == 24) {
482 /* we have enough to decode dev num */
483 __u64 mjr; /* major */
484 __u64 mnr; /* minor */
485 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
486 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
487 fattr->cf_rdev = MKDEV(mjr, mnr);
488 }
489 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
490 cifs_dbg(FYI, "Symlink\n");
491 fattr->cf_mode |= S_IFLNK;
492 fattr->cf_dtype = DT_LNK;
488 } else { 493 } else {
489 fattr->cf_mode |= S_IFREG; /* then it is a file */ 494 fattr->cf_mode |= S_IFREG; /* file? */
490 fattr->cf_dtype = DT_REG; 495 fattr->cf_dtype = DT_REG;
491 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 496 rc = -EOPNOTSUPP;
492 } 497 }
493 CIFSSMBClose(xid, tcon, netfid); 498 } else {
499 fattr->cf_mode |= S_IFREG; /* then it is a file */
500 fattr->cf_dtype = DT_REG;
501 rc = -EOPNOTSUPP; /* or some unknown SFU type */
494 } 502 }
503 CIFSSMBClose(xid, tcon, fid.netfid);
495 cifs_put_tlink(tlink); 504 cifs_put_tlink(tlink);
496 return rc; 505 return rc;
497} 506}
@@ -518,10 +527,15 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
518 return PTR_ERR(tlink); 527 return PTR_ERR(tlink);
519 tcon = tlink_tcon(tlink); 528 tcon = tlink_tcon(tlink);
520 529
521 rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS", 530 if (tcon->ses->server->ops->query_all_EAs == NULL) {
522 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 531 cifs_put_tlink(tlink);
523 cifs_sb->mnt_cifs_flags & 532 return -EOPNOTSUPP;
524 CIFS_MOUNT_MAP_SPECIAL_CHR); 533 }
534
535 rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path,
536 "SETFILEBITS", ea_value, 4 /* size of buf */,
537 cifs_sb->local_nls,
538 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
525 cifs_put_tlink(tlink); 539 cifs_put_tlink(tlink);
526 if (rc < 0) 540 if (rc < 0)
527 return (int)rc; 541 return (int)rc;
@@ -663,7 +677,7 @@ cgfi_exit:
663int 677int
664cifs_get_inode_info(struct inode **inode, const char *full_path, 678cifs_get_inode_info(struct inode **inode, const char *full_path,
665 FILE_ALL_INFO *data, struct super_block *sb, int xid, 679 FILE_ALL_INFO *data, struct super_block *sb, int xid,
666 const __u16 *fid) 680 const struct cifs_fid *fid)
667{ 681{
668 bool validinum = false; 682 bool validinum = false;
669 __u16 srchflgs; 683 __u16 srchflgs;
@@ -800,10 +814,10 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
800 814
801 /* check for Minshall+French symlinks */ 815 /* check for Minshall+French symlinks */
802 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { 816 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
803 tmprc = CIFSCheckMFSymlink(xid, tcon, cifs_sb, &fattr, 817 tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr,
804 full_path); 818 full_path);
805 if (tmprc) 819 if (tmprc)
806 cifs_dbg(FYI, "CIFSCheckMFSymlink: %d\n", tmprc); 820 cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
807 } 821 }
808 822
809 if (!*inode) { 823 if (!*inode) {
@@ -1032,7 +1046,8 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1032{ 1046{
1033 int oplock = 0; 1047 int oplock = 0;
1034 int rc; 1048 int rc;
1035 __u16 netfid; 1049 struct cifs_fid fid;
1050 struct cifs_open_parms oparms;
1036 struct inode *inode = dentry->d_inode; 1051 struct inode *inode = dentry->d_inode;
1037 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1052 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1038 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1053 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
@@ -1055,10 +1070,16 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1055 goto out; 1070 goto out;
1056 } 1071 }
1057 1072
1058 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, 1073 oparms.tcon = tcon;
1059 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, 1074 oparms.cifs_sb = cifs_sb;
1060 &netfid, &oplock, NULL, cifs_sb->local_nls, 1075 oparms.desired_access = DELETE | FILE_WRITE_ATTRIBUTES;
1061 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 1076 oparms.create_options = CREATE_NOT_DIR;
1077 oparms.disposition = FILE_OPEN;
1078 oparms.path = full_path;
1079 oparms.fid = &fid;
1080 oparms.reconnect = false;
1081
1082 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1062 if (rc != 0) 1083 if (rc != 0)
1063 goto out; 1084 goto out;
1064 1085
@@ -1079,7 +1100,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1079 goto out_close; 1100 goto out_close;
1080 } 1101 }
1081 info_buf->Attributes = cpu_to_le32(dosattr); 1102 info_buf->Attributes = cpu_to_le32(dosattr);
1082 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid, 1103 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid,
1083 current->tgid); 1104 current->tgid);
1084 /* although we would like to mark the file hidden 1105 /* although we would like to mark the file hidden
1085 if that fails we will still try to rename it */ 1106 if that fails we will still try to rename it */
@@ -1090,7 +1111,8 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1090 } 1111 }
1091 1112
1092 /* rename the file */ 1113 /* rename the file */
1093 rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls, 1114 rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, NULL,
1115 cifs_sb->local_nls,
1094 cifs_sb->mnt_cifs_flags & 1116 cifs_sb->mnt_cifs_flags &
1095 CIFS_MOUNT_MAP_SPECIAL_CHR); 1117 CIFS_MOUNT_MAP_SPECIAL_CHR);
1096 if (rc != 0) { 1118 if (rc != 0) {
@@ -1100,7 +1122,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1100 1122
1101 /* try to set DELETE_ON_CLOSE */ 1123 /* try to set DELETE_ON_CLOSE */
1102 if (!cifsInode->delete_pending) { 1124 if (!cifsInode->delete_pending) {
1103 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid, 1125 rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid,
1104 current->tgid); 1126 current->tgid);
1105 /* 1127 /*
1106 * some samba versions return -ENOENT when we try to set the 1128 * some samba versions return -ENOENT when we try to set the
@@ -1120,7 +1142,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1120 } 1142 }
1121 1143
1122out_close: 1144out_close:
1123 CIFSSMBClose(xid, tcon, netfid); 1145 CIFSSMBClose(xid, tcon, fid.netfid);
1124out: 1146out:
1125 kfree(info_buf); 1147 kfree(info_buf);
1126 cifs_put_tlink(tlink); 1148 cifs_put_tlink(tlink);
@@ -1132,13 +1154,13 @@ out:
1132 * them anyway. 1154 * them anyway.
1133 */ 1155 */
1134undo_rename: 1156undo_rename:
1135 CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name, 1157 CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, dentry->d_name.name,
1136 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 1158 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1137 CIFS_MOUNT_MAP_SPECIAL_CHR); 1159 CIFS_MOUNT_MAP_SPECIAL_CHR);
1138undo_setattr: 1160undo_setattr:
1139 if (dosattr != origattr) { 1161 if (dosattr != origattr) {
1140 info_buf->Attributes = cpu_to_le32(origattr); 1162 info_buf->Attributes = cpu_to_le32(origattr);
1141 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid, 1163 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid,
1142 current->tgid)) 1164 current->tgid))
1143 cifsInode->cifsAttrs = origattr; 1165 cifsInode->cifsAttrs = origattr;
1144 } 1166 }
@@ -1549,7 +1571,8 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
1549 struct tcon_link *tlink; 1571 struct tcon_link *tlink;
1550 struct cifs_tcon *tcon; 1572 struct cifs_tcon *tcon;
1551 struct TCP_Server_Info *server; 1573 struct TCP_Server_Info *server;
1552 __u16 srcfid; 1574 struct cifs_fid fid;
1575 struct cifs_open_parms oparms;
1553 int oplock, rc; 1576 int oplock, rc;
1554 1577
1555 tlink = cifs_sb_tlink(cifs_sb); 1578 tlink = cifs_sb_tlink(cifs_sb);
@@ -1576,17 +1599,23 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
1576 if (to_dentry->d_parent != from_dentry->d_parent) 1599 if (to_dentry->d_parent != from_dentry->d_parent)
1577 goto do_rename_exit; 1600 goto do_rename_exit;
1578 1601
1602 oparms.tcon = tcon;
1603 oparms.cifs_sb = cifs_sb;
1579 /* open the file to be renamed -- we need DELETE perms */ 1604 /* open the file to be renamed -- we need DELETE perms */
1580 rc = CIFSSMBOpen(xid, tcon, from_path, FILE_OPEN, DELETE, 1605 oparms.desired_access = DELETE;
1581 CREATE_NOT_DIR, &srcfid, &oplock, NULL, 1606 oparms.create_options = CREATE_NOT_DIR;
1582 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 1607 oparms.disposition = FILE_OPEN;
1583 CIFS_MOUNT_MAP_SPECIAL_CHR); 1608 oparms.path = from_path;
1609 oparms.fid = &fid;
1610 oparms.reconnect = false;
1611
1612 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1584 if (rc == 0) { 1613 if (rc == 0) {
1585 rc = CIFSSMBRenameOpenFile(xid, tcon, srcfid, 1614 rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid,
1586 (const char *) to_dentry->d_name.name, 1615 (const char *) to_dentry->d_name.name,
1587 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 1616 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1588 CIFS_MOUNT_MAP_SPECIAL_CHR); 1617 CIFS_MOUNT_MAP_SPECIAL_CHR);
1589 CIFSSMBClose(xid, tcon, srcfid); 1618 CIFSSMBClose(xid, tcon, fid.netfid);
1590 } 1619 }
1591do_rename_exit: 1620do_rename_exit:
1592 cifs_put_tlink(tlink); 1621 cifs_put_tlink(tlink);