diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-05-27 09:34:43 -0400 |
---|---|---|
committer | Pavel Shilovsky <pshilovsky@samba.org> | 2012-07-24 13:55:07 -0400 |
commit | 1208ef1f76540b621f80e6130c4fb7bed8ece360 (patch) | |
tree | 65edaf646b06ba93ffe2a0ee4a98e7b9378bb59f /fs/cifs/inode.c | |
parent | 2503a0dba989486c59523a947a1dcb50ad90fee9 (diff) |
CIFS: Move query inode info code to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 93 |
1 files changed, 37 insertions, 56 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index af902864ac03..df071fb2567f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -600,61 +600,54 @@ cgfi_exit: | |||
600 | return rc; | 600 | return rc; |
601 | } | 601 | } |
602 | 602 | ||
603 | int cifs_get_inode_info(struct inode **pinode, | 603 | int |
604 | const unsigned char *full_path, FILE_ALL_INFO *pfindData, | 604 | cifs_get_inode_info(struct inode **inode, const char *full_path, |
605 | struct super_block *sb, unsigned int xid, const __u16 *pfid) | 605 | FILE_ALL_INFO *data, struct super_block *sb, int xid, |
606 | const __u16 *fid) | ||
606 | { | 607 | { |
607 | int rc = 0, tmprc; | 608 | int rc = 0, tmprc; |
608 | struct cifs_tcon *pTcon; | 609 | struct cifs_tcon *tcon; |
610 | struct TCP_Server_Info *server; | ||
609 | struct tcon_link *tlink; | 611 | struct tcon_link *tlink; |
610 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 612 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
611 | char *buf = NULL; | 613 | char *buf = NULL; |
612 | bool adjustTZ = false; | 614 | bool adjust_tz = false; |
613 | struct cifs_fattr fattr; | 615 | struct cifs_fattr fattr; |
614 | 616 | ||
615 | tlink = cifs_sb_tlink(cifs_sb); | 617 | tlink = cifs_sb_tlink(cifs_sb); |
616 | if (IS_ERR(tlink)) | 618 | if (IS_ERR(tlink)) |
617 | return PTR_ERR(tlink); | 619 | return PTR_ERR(tlink); |
618 | pTcon = tlink_tcon(tlink); | 620 | tcon = tlink_tcon(tlink); |
621 | server = tcon->ses->server; | ||
619 | 622 | ||
620 | cFYI(1, "Getting info on %s", full_path); | 623 | cFYI(1, "Getting info on %s", full_path); |
621 | 624 | ||
622 | if ((pfindData == NULL) && (*pinode != NULL)) { | 625 | if ((data == NULL) && (*inode != NULL)) { |
623 | if (CIFS_I(*pinode)->clientCanCacheRead) { | 626 | if (CIFS_I(*inode)->clientCanCacheRead) { |
624 | cFYI(1, "No need to revalidate cached inode sizes"); | 627 | cFYI(1, "No need to revalidate cached inode sizes"); |
625 | goto cgii_exit; | 628 | goto cgii_exit; |
626 | } | 629 | } |
627 | } | 630 | } |
628 | 631 | ||
629 | /* if file info not passed in then get it from server */ | 632 | /* if inode info is not passed, get it from server */ |
630 | if (pfindData == NULL) { | 633 | if (data == NULL) { |
634 | if (!server->ops->query_path_info) { | ||
635 | rc = -ENOSYS; | ||
636 | goto cgii_exit; | ||
637 | } | ||
631 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 638 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
632 | if (buf == NULL) { | 639 | if (buf == NULL) { |
633 | rc = -ENOMEM; | 640 | rc = -ENOMEM; |
634 | goto cgii_exit; | 641 | goto cgii_exit; |
635 | } | 642 | } |
636 | pfindData = (FILE_ALL_INFO *)buf; | 643 | data = (FILE_ALL_INFO *)buf; |
637 | 644 | rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, | |
638 | /* could do find first instead but this returns more info */ | 645 | data, &adjust_tz); |
639 | rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData, | ||
640 | 0 /* not legacy */, | ||
641 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
642 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
643 | /* BB optimize code so we do not make the above call | ||
644 | when server claims no NT SMB support and the above call | ||
645 | failed at least once - set flag in tcon or mount */ | ||
646 | if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { | ||
647 | rc = SMBQueryInformation(xid, pTcon, full_path, | ||
648 | pfindData, cifs_sb->local_nls, | ||
649 | cifs_sb->mnt_cifs_flags & | ||
650 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
651 | adjustTZ = true; | ||
652 | } | ||
653 | } | 646 | } |
654 | 647 | ||
655 | if (!rc) { | 648 | if (!rc) { |
656 | cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData, | 649 | cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *)data, cifs_sb, |
657 | cifs_sb, adjustTZ); | 650 | adjust_tz); |
658 | } else if (rc == -EREMOTE) { | 651 | } else if (rc == -EREMOTE) { |
659 | cifs_create_dfs_fattr(&fattr, sb); | 652 | cifs_create_dfs_fattr(&fattr, sb); |
660 | rc = 0; | 653 | rc = 0; |
@@ -668,28 +661,17 @@ int cifs_get_inode_info(struct inode **pinode, | |||
668 | * Is an i_ino of zero legal? Can we use that to check if the server | 661 | * Is an i_ino of zero legal? Can we use that to check if the server |
669 | * supports returning inode numbers? Are there other sanity checks we | 662 | * supports returning inode numbers? Are there other sanity checks we |
670 | * can use to ensure that the server is really filling in that field? | 663 | * can use to ensure that the server is really filling in that field? |
671 | * | ||
672 | * We can not use the IndexNumber field by default from Windows or | ||
673 | * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA | ||
674 | * CIFS spec claims that this value is unique within the scope of a | ||
675 | * share, and the windows docs hint that it's actually unique | ||
676 | * per-machine. | ||
677 | * | ||
678 | * There may be higher info levels that work but are there Windows | ||
679 | * server or network appliances for which IndexNumber field is not | ||
680 | * guaranteed unique? | ||
681 | */ | 664 | */ |
682 | if (*pinode == NULL) { | 665 | if (*inode == NULL) { |
683 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { | 666 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { |
684 | int rc1 = 0; | 667 | if (server->ops->get_srv_inum) |
685 | 668 | tmprc = server->ops->get_srv_inum(xid, tcon, | |
686 | rc1 = CIFSGetSrvInodeNumber(xid, pTcon, | 669 | cifs_sb, full_path, &fattr.cf_uniqueid, |
687 | full_path, &fattr.cf_uniqueid, | 670 | data); |
688 | cifs_sb->local_nls, | 671 | else |
689 | cifs_sb->mnt_cifs_flags & | 672 | tmprc = -ENOSYS; |
690 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 673 | if (tmprc || !fattr.cf_uniqueid) { |
691 | if (rc1 || !fattr.cf_uniqueid) { | 674 | cFYI(1, "GetSrvInodeNum rc %d", tmprc); |
692 | cFYI(1, "GetSrvInodeNum rc %d", rc1); | ||
693 | fattr.cf_uniqueid = iunique(sb, ROOT_I); | 675 | fattr.cf_uniqueid = iunique(sb, ROOT_I); |
694 | cifs_autodisable_serverino(cifs_sb); | 676 | cifs_autodisable_serverino(cifs_sb); |
695 | } | 677 | } |
@@ -697,7 +679,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
697 | fattr.cf_uniqueid = iunique(sb, ROOT_I); | 679 | fattr.cf_uniqueid = iunique(sb, ROOT_I); |
698 | } | 680 | } |
699 | } else { | 681 | } else { |
700 | fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid; | 682 | fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; |
701 | } | 683 | } |
702 | 684 | ||
703 | /* query for SFU type info if supported and needed */ | 685 | /* query for SFU type info if supported and needed */ |
@@ -711,8 +693,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
711 | #ifdef CONFIG_CIFS_ACL | 693 | #ifdef CONFIG_CIFS_ACL |
712 | /* fill in 0777 bits from ACL */ | 694 | /* fill in 0777 bits from ACL */ |
713 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 695 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
714 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, | 696 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, full_path, fid); |
715 | pfid); | ||
716 | if (rc) { | 697 | if (rc) { |
717 | cFYI(1, "%s: Getting ACL failed with error: %d", | 698 | cFYI(1, "%s: Getting ACL failed with error: %d", |
718 | __func__, rc); | 699 | __func__, rc); |
@@ -732,12 +713,12 @@ int cifs_get_inode_info(struct inode **pinode, | |||
732 | cFYI(1, "CIFSCheckMFSymlink: %d", tmprc); | 713 | cFYI(1, "CIFSCheckMFSymlink: %d", tmprc); |
733 | } | 714 | } |
734 | 715 | ||
735 | if (!*pinode) { | 716 | if (!*inode) { |
736 | *pinode = cifs_iget(sb, &fattr); | 717 | *inode = cifs_iget(sb, &fattr); |
737 | if (!*pinode) | 718 | if (!*inode) |
738 | rc = -ENOMEM; | 719 | rc = -ENOMEM; |
739 | } else { | 720 | } else { |
740 | cifs_fattr_to_inode(*pinode, &fattr); | 721 | cifs_fattr_to_inode(*inode, &fattr); |
741 | } | 722 | } |
742 | 723 | ||
743 | cgii_exit: | 724 | cgii_exit: |