]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/ubifs/file.c
Merge branch 'parisc-4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[linux.git] / fs / ubifs / file.c
index 60e789a9cac85f142d093b472a51aeee7cbf08c4..b0d783774c963c97f32df7649feeb8fb7e4e3e4f 100644 (file)
@@ -78,6 +78,13 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
                goto dump;
 
        dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
+
+       if (ubifs_crypt_is_encrypted(inode)) {
+               err = ubifs_decrypt(inode, dn, &dlen, block);
+               if (err)
+                       goto dump;
+       }
+
        out_len = UBIFS_BLOCK_SIZE;
        err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
                               le16_to_cpu(dn->compr_type));
@@ -650,6 +657,13 @@ static int populate_page(struct ubifs_info *c, struct page *page,
 
                        dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
                        out_len = UBIFS_BLOCK_SIZE;
+
+                       if (ubifs_crypt_is_encrypted(inode)) {
+                               err = ubifs_decrypt(inode, dn, &dlen, page_block);
+                               if (err)
+                                       goto out_err;
+                       }
+
                        err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len,
                                               le16_to_cpu(dn->compr_type));
                        if (err || len != out_len)
@@ -1643,6 +1657,59 @@ static int ubifs_file_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
+static const char *ubifs_get_link(struct dentry *dentry,
+                                           struct inode *inode,
+                                           struct delayed_call *done)
+{
+       int err;
+       struct fscrypt_symlink_data *sd;
+       struct ubifs_inode *ui = ubifs_inode(inode);
+       struct fscrypt_str cstr;
+       struct fscrypt_str pstr;
+
+       if (!ubifs_crypt_is_encrypted(inode))
+               return ui->data;
+
+       if (!dentry)
+               return ERR_PTR(-ECHILD);
+
+       err = fscrypt_get_encryption_info(inode);
+       if (err)
+               return ERR_PTR(err);
+
+       sd = (struct fscrypt_symlink_data *)ui->data;
+       cstr.name = sd->encrypted_path;
+       cstr.len = le16_to_cpu(sd->len);
+
+       if (cstr.len == 0)
+               return ERR_PTR(-ENOENT);
+
+       if ((cstr.len + sizeof(struct fscrypt_symlink_data) - 1) > ui->data_len)
+               return ERR_PTR(-EIO);
+
+       err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr);
+       if (err)
+               return ERR_PTR(err);
+
+       err = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr);
+       if (err) {
+               fscrypt_fname_free_buffer(&pstr);
+               return ERR_PTR(err);
+       }
+
+       pstr.name[pstr.len] = '\0';
+
+       // XXX this probably won't happen anymore...
+       if (pstr.name[0] == '\0') {
+               fscrypt_fname_free_buffer(&pstr);
+               return ERR_PTR(-ENOENT);
+       }
+
+       set_delayed_call(done, kfree_link, pstr.name);
+       return pstr.name;
+}
+
+
 const struct address_space_operations ubifs_file_address_operations = {
        .readpage       = ubifs_readpage,
        .writepage      = ubifs_writepage,
@@ -1666,8 +1733,7 @@ const struct inode_operations ubifs_file_inode_operations = {
 };
 
 const struct inode_operations ubifs_symlink_inode_operations = {
-       .readlink    = generic_readlink,
-       .get_link    = simple_get_link,
+       .get_link    = ubifs_get_link,
        .setattr     = ubifs_setattr,
        .getattr     = ubifs_getattr,
        .listxattr   = ubifs_listxattr,