Merge commit 'v3.17' into next
[firefly-linux-kernel-4.4.55.git] / fs / cifs / cifsacl.c
index 8f9b4f710d4a31ea651f64586fa2469edd92c2fa..6d00c419cbae0b54016ba997f55baf1ac7c54956 100644 (file)
@@ -84,7 +84,6 @@ static struct key_type cifs_idmap_key_type = {
        .instantiate = cifs_idmap_key_instantiate,
        .destroy     = cifs_idmap_key_destroy,
        .describe    = user_describe,
-       .match       = user_match,
 };
 
 static char *
@@ -865,8 +864,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
        return rc;
 }
 
-static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
-               __u16 fid, u32 *pacllen)
+struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
+               const struct cifs_fid *cifsfid, u32 *pacllen)
 {
        struct cifs_ntsd *pntsd = NULL;
        unsigned int xid;
@@ -877,7 +876,8 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
                return ERR_CAST(tlink);
 
        xid = get_xid();
-       rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
+       rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
+                               pacllen);
        free_xid(xid);
 
        cifs_put_tlink(tlink);
@@ -946,7 +946,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
        if (!open_file)
                return get_cifs_acl_by_path(cifs_sb, path, pacllen);
 
-       pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
+       pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
        cifsFileInfo_put(open_file);
        return pntsd;
 }
@@ -1006,19 +1006,31 @@ out:
 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
 int
 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
-                 struct inode *inode, const char *path, const __u16 *pfid)
+                 struct inode *inode, const char *path,
+                 const struct cifs_fid *pfid)
 {
        struct cifs_ntsd *pntsd = NULL;
        u32 acllen = 0;
        int rc = 0;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+       struct cifs_tcon *tcon;
 
        cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
 
-       if (pfid)
-               pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
-       else
-               pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
+       if (IS_ERR(tlink))
+               return PTR_ERR(tlink);
+       tcon = tlink_tcon(tlink);
 
+       if (pfid && (tcon->ses->server->ops->get_acl_by_fid))
+               pntsd = tcon->ses->server->ops->get_acl_by_fid(cifs_sb, pfid,
+                                                         &acllen);
+       else if (tcon->ses->server->ops->get_acl)
+               pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path,
+                                                       &acllen);
+       else {
+               cifs_put_tlink(tlink);
+               return -EOPNOTSUPP;
+       }
        /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
        if (IS_ERR(pntsd)) {
                rc = PTR_ERR(pntsd);
@@ -1030,6 +1042,8 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
                        cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
        }
 
+       cifs_put_tlink(tlink);
+
        return rc;
 }
 
@@ -1043,15 +1057,30 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
        __u32 secdesclen = 0;
        struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
        struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+       struct cifs_tcon *tcon;
+
+       if (IS_ERR(tlink))
+               return PTR_ERR(tlink);
+       tcon = tlink_tcon(tlink);
 
        cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
 
        /* Get the security descriptor */
-       pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
+
+       if (tcon->ses->server->ops->get_acl == NULL) {
+               cifs_put_tlink(tlink);
+               return -EOPNOTSUPP;
+       }
+
+       pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path,
+                                               &secdesclen);
        if (IS_ERR(pntsd)) {
                rc = PTR_ERR(pntsd);
                cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
-               goto out;
+               cifs_put_tlink(tlink);
+               return rc;
        }
 
        /*
@@ -1064,6 +1093,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
        pnntsd = kmalloc(secdesclen, GFP_KERNEL);
        if (!pnntsd) {
                kfree(pntsd);
+               cifs_put_tlink(tlink);
                return -ENOMEM;
        }
 
@@ -1072,14 +1102,18 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
 
        cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
 
+       if (tcon->ses->server->ops->set_acl == NULL)
+               rc = -EOPNOTSUPP;
+
        if (!rc) {
                /* Set the security descriptor */
-               rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag);
+               rc = tcon->ses->server->ops->set_acl(pnntsd, secdesclen, inode,
+                                                    path, aclflag);
                cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
        }
+       cifs_put_tlink(tlink);
 
        kfree(pnntsd);
        kfree(pntsd);
-out:
        return rc;
 }