diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/ecryptfs/file.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'fs/ecryptfs/file.c')
-rw-r--r-- | fs/ecryptfs/file.c | 109 |
1 files changed, 57 insertions, 52 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index d45ba456812..d3f95f941c4 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -48,7 +48,8 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb, | |||
48 | unsigned long nr_segs, loff_t pos) | 48 | unsigned long nr_segs, loff_t pos) |
49 | { | 49 | { |
50 | ssize_t rc; | 50 | ssize_t rc; |
51 | struct path lower; | 51 | struct dentry *lower_dentry; |
52 | struct vfsmount *lower_vfsmount; | ||
52 | struct file *file = iocb->ki_filp; | 53 | struct file *file = iocb->ki_filp; |
53 | 54 | ||
54 | rc = generic_file_aio_read(iocb, iov, nr_segs, pos); | 55 | rc = generic_file_aio_read(iocb, iov, nr_segs, pos); |
@@ -59,9 +60,9 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb, | |||
59 | if (-EIOCBQUEUED == rc) | 60 | if (-EIOCBQUEUED == rc) |
60 | rc = wait_on_sync_kiocb(iocb); | 61 | rc = wait_on_sync_kiocb(iocb); |
61 | if (rc >= 0) { | 62 | if (rc >= 0) { |
62 | lower.dentry = ecryptfs_dentry_to_lower(file->f_path.dentry); | 63 | lower_dentry = ecryptfs_dentry_to_lower(file->f_path.dentry); |
63 | lower.mnt = ecryptfs_dentry_to_lower_mnt(file->f_path.dentry); | 64 | lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_path.dentry); |
64 | touch_atime(&lower); | 65 | touch_atime(lower_vfsmount, lower_dentry); |
65 | } | 66 | } |
66 | return rc; | 67 | return rc; |
67 | } | 68 | } |
@@ -138,50 +139,29 @@ out: | |||
138 | return rc; | 139 | return rc; |
139 | } | 140 | } |
140 | 141 | ||
141 | struct kmem_cache *ecryptfs_file_info_cache; | 142 | static void ecryptfs_vma_close(struct vm_area_struct *vma) |
142 | |||
143 | static int read_or_initialize_metadata(struct dentry *dentry) | ||
144 | { | 143 | { |
145 | struct inode *inode = dentry->d_inode; | 144 | filemap_write_and_wait(vma->vm_file->f_mapping); |
146 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | 145 | } |
147 | struct ecryptfs_crypt_stat *crypt_stat; | ||
148 | int rc; | ||
149 | 146 | ||
150 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 147 | static const struct vm_operations_struct ecryptfs_file_vm_ops = { |
151 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 148 | .close = ecryptfs_vma_close, |
152 | inode->i_sb)->mount_crypt_stat; | 149 | .fault = filemap_fault, |
153 | mutex_lock(&crypt_stat->cs_mutex); | 150 | }; |
154 | 151 | ||
155 | if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && | 152 | static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma) |
156 | crypt_stat->flags & ECRYPTFS_KEY_VALID) { | 153 | { |
157 | rc = 0; | 154 | int rc; |
158 | goto out; | ||
159 | } | ||
160 | 155 | ||
161 | rc = ecryptfs_read_metadata(dentry); | 156 | rc = generic_file_mmap(file, vma); |
162 | if (!rc) | 157 | if (!rc) |
163 | goto out; | 158 | vma->vm_ops = &ecryptfs_file_vm_ops; |
164 | 159 | ||
165 | if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) { | ||
166 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
167 | | ECRYPTFS_ENCRYPTED); | ||
168 | rc = 0; | ||
169 | goto out; | ||
170 | } | ||
171 | |||
172 | if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) && | ||
173 | !i_size_read(ecryptfs_inode_to_lower(inode))) { | ||
174 | rc = ecryptfs_initialize_file(dentry, inode); | ||
175 | if (!rc) | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | rc = -EIO; | ||
180 | out: | ||
181 | mutex_unlock(&crypt_stat->cs_mutex); | ||
182 | return rc; | 160 | return rc; |
183 | } | 161 | } |
184 | 162 | ||
163 | struct kmem_cache *ecryptfs_file_info_cache; | ||
164 | |||
185 | /** | 165 | /** |
186 | * ecryptfs_open | 166 | * ecryptfs_open |
187 | * @inode: inode speciying file to open | 167 | * @inode: inode speciying file to open |
@@ -257,9 +237,32 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
257 | rc = 0; | 237 | rc = 0; |
258 | goto out; | 238 | goto out; |
259 | } | 239 | } |
260 | rc = read_or_initialize_metadata(ecryptfs_dentry); | 240 | mutex_lock(&crypt_stat->cs_mutex); |
261 | if (rc) | 241 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) |
262 | goto out_put; | 242 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { |
243 | rc = ecryptfs_read_metadata(ecryptfs_dentry); | ||
244 | if (rc) { | ||
245 | ecryptfs_printk(KERN_DEBUG, | ||
246 | "Valid headers not found\n"); | ||
247 | if (!(mount_crypt_stat->flags | ||
248 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
249 | rc = -EIO; | ||
250 | printk(KERN_WARNING "Either the lower file " | ||
251 | "is not in a valid eCryptfs format, " | ||
252 | "or the key could not be retrieved. " | ||
253 | "Plaintext passthrough mode is not " | ||
254 | "enabled; returning -EIO\n"); | ||
255 | mutex_unlock(&crypt_stat->cs_mutex); | ||
256 | goto out_put; | ||
257 | } | ||
258 | rc = 0; | ||
259 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
260 | | ECRYPTFS_ENCRYPTED); | ||
261 | mutex_unlock(&crypt_stat->cs_mutex); | ||
262 | goto out; | ||
263 | } | ||
264 | } | ||
265 | mutex_unlock(&crypt_stat->cs_mutex); | ||
263 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " | 266 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " |
264 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, | 267 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, |
265 | (unsigned long long)i_size_read(inode)); | 268 | (unsigned long long)i_size_read(inode)); |
@@ -275,14 +278,8 @@ out: | |||
275 | 278 | ||
276 | static int ecryptfs_flush(struct file *file, fl_owner_t td) | 279 | static int ecryptfs_flush(struct file *file, fl_owner_t td) |
277 | { | 280 | { |
278 | struct file *lower_file = ecryptfs_file_to_lower(file); | 281 | return file->f_mode & FMODE_WRITE |
279 | 282 | ? filemap_write_and_wait(file->f_mapping) : 0; | |
280 | if (lower_file->f_op && lower_file->f_op->flush) { | ||
281 | filemap_write_and_wait(file->f_mapping); | ||
282 | return lower_file->f_op->flush(lower_file, td); | ||
283 | } | ||
284 | |||
285 | return 0; | ||
286 | } | 283 | } |
287 | 284 | ||
288 | static int ecryptfs_release(struct inode *inode, struct file *file) | 285 | static int ecryptfs_release(struct inode *inode, struct file *file) |
@@ -296,7 +293,15 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
296 | static int | 293 | static int |
297 | ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | 294 | ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
298 | { | 295 | { |
299 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); | 296 | int rc = 0; |
297 | |||
298 | rc = generic_file_fsync(file, start, end, datasync); | ||
299 | if (rc) | ||
300 | goto out; | ||
301 | rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end, | ||
302 | datasync); | ||
303 | out: | ||
304 | return rc; | ||
300 | } | 305 | } |
301 | 306 | ||
302 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | 307 | static int ecryptfs_fasync(int fd, struct file *file, int flag) |
@@ -365,7 +370,7 @@ const struct file_operations ecryptfs_main_fops = { | |||
365 | #ifdef CONFIG_COMPAT | 370 | #ifdef CONFIG_COMPAT |
366 | .compat_ioctl = ecryptfs_compat_ioctl, | 371 | .compat_ioctl = ecryptfs_compat_ioctl, |
367 | #endif | 372 | #endif |
368 | .mmap = generic_file_mmap, | 373 | .mmap = ecryptfs_file_mmap, |
369 | .open = ecryptfs_open, | 374 | .open = ecryptfs_open, |
370 | .flush = ecryptfs_flush, | 375 | .flush = ecryptfs_flush, |
371 | .release = ecryptfs_release, | 376 | .release = ecryptfs_release, |