diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifsacl.c | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 7f8e6c46d116..1403b5d86a73 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -612,57 +612,61 @@ static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, | |||
612 | return pntsd; | 612 | return pntsd; |
613 | } | 613 | } |
614 | 614 | ||
615 | /* Set an ACL on the server */ | 615 | static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid, |
616 | static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | 616 | struct cifs_ntsd *pnntsd, u32 acllen) |
617 | struct inode *inode, const char *path) | ||
618 | { | 617 | { |
619 | struct cifsFileInfo *open_file; | 618 | int xid, rc; |
620 | bool unlock_file = false; | ||
621 | int xid; | ||
622 | int rc = -EIO; | ||
623 | __u16 fid; | ||
624 | struct super_block *sb; | ||
625 | struct cifs_sb_info *cifs_sb; | ||
626 | 619 | ||
627 | cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | 620 | xid = GetXid(); |
621 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | ||
622 | FreeXid(xid); | ||
628 | 623 | ||
629 | if (!inode) | 624 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); |
630 | return rc; | 625 | return rc; |
626 | } | ||
631 | 627 | ||
632 | sb = inode->i_sb; | 628 | static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, |
633 | if (sb == NULL) | 629 | struct cifs_ntsd *pnntsd, u32 acllen) |
634 | return rc; | 630 | { |
631 | int oplock = 0; | ||
632 | int xid, rc; | ||
633 | __u16 fid; | ||
635 | 634 | ||
636 | cifs_sb = CIFS_SB(sb); | ||
637 | xid = GetXid(); | 635 | xid = GetXid(); |
638 | 636 | ||
639 | open_file = find_readable_file(CIFS_I(inode)); | 637 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0, |
640 | if (open_file) { | 638 | &fid, &oplock, NULL, cifs_sb->local_nls, |
641 | unlock_file = true; | 639 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
642 | fid = open_file->netfid; | 640 | if (rc) { |
643 | } else { | 641 | cERROR(1, ("Unable to open file to set ACL")); |
644 | int oplock = 0; | 642 | goto out; |
645 | /* open file */ | ||
646 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
647 | WRITE_DAC, 0, &fid, &oplock, NULL, | ||
648 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
649 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
650 | if (rc != 0) { | ||
651 | cERROR(1, ("Unable to open file to set ACL")); | ||
652 | FreeXid(xid); | ||
653 | return rc; | ||
654 | } | ||
655 | } | 643 | } |
656 | 644 | ||
657 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | 645 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); |
658 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); | 646 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); |
659 | if (unlock_file) | ||
660 | atomic_dec(&open_file->wrtPending); | ||
661 | else | ||
662 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
663 | 647 | ||
648 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
649 | out: | ||
664 | FreeXid(xid); | 650 | FreeXid(xid); |
651 | return rc; | ||
652 | } | ||
665 | 653 | ||
654 | /* Set an ACL on the server */ | ||
655 | static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | ||
656 | struct inode *inode, const char *path) | ||
657 | { | ||
658 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
659 | struct cifsFileInfo *open_file; | ||
660 | int rc; | ||
661 | |||
662 | cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | ||
663 | |||
664 | open_file = find_readable_file(CIFS_I(inode)); | ||
665 | if (!open_file) | ||
666 | return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen); | ||
667 | |||
668 | rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen); | ||
669 | atomic_dec(&open_file->wrtPending); | ||
666 | return rc; | 670 | return rc; |
667 | } | 671 | } |
668 | 672 | ||