Blame view
fs/ecryptfs/inode.c
32.2 KB
237fead61 [PATCH] ecryptfs:... |
1 2 3 4 5 |
/** * eCryptfs: Linux filesystem encryption layer * * Copyright (C) 1997-2004 Erez Zadok * Copyright (C) 2001-2004 Stony Brook University |
dd2a3b7ad [PATCH] eCryptfs:... |
6 |
* Copyright (C) 2004-2007 International Business Machines Corp. |
237fead61 [PATCH] ecryptfs:... |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
* Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> * Michael C. Thompsion <mcthomps@us.ibm.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include <linux/file.h> #include <linux/vmalloc.h> #include <linux/pagemap.h> #include <linux/dcache.h> #include <linux/namei.h> #include <linux/mount.h> |
0cc72dc7f [PATCH] eCryptfs:... |
32 |
#include <linux/fs_stack.h> |
5a0e3ad6a include cleanup: ... |
33 |
#include <linux/slab.h> |
48b512e68 ecryptfs: call vf... |
34 |
#include <linux/xattr.h> |
0a688ad71 ecryptfs: inode.c... |
35 |
#include <asm/unaligned.h> |
237fead61 [PATCH] ecryptfs:... |
36 37 38 39 40 |
#include "ecryptfs_kernel.h" static struct dentry *lock_parent(struct dentry *dentry) { struct dentry *dir; |
8dc4e3736 ecryptfs: clean u... |
41 |
dir = dget_parent(dentry); |
5955102c9 wrappers for ->i_... |
42 |
inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); |
237fead61 [PATCH] ecryptfs:... |
43 44 |
return dir; } |
237fead61 [PATCH] ecryptfs:... |
45 46 |
static void unlock_dir(struct dentry *dir) { |
5955102c9 wrappers for ->i_... |
47 |
inode_unlock(d_inode(dir)); |
237fead61 [PATCH] ecryptfs:... |
48 49 |
dput(dir); } |
c4f790736 eCryptfs: Consoli... |
50 51 |
static int ecryptfs_inode_test(struct inode *inode, void *lower_inode) { |
c4cf3ba4f ecryptfs: Drop cast |
52 |
return ecryptfs_inode_to_lower(inode) == lower_inode; |
c4f790736 eCryptfs: Consoli... |
53 |
} |
5ccf92037 eCryptfs: Cleanup... |
54 |
static int ecryptfs_inode_set(struct inode *inode, void *opaque) |
c4f790736 eCryptfs: Consoli... |
55 |
{ |
5ccf92037 eCryptfs: Cleanup... |
56 57 58 59 60 61 62 |
struct inode *lower_inode = opaque; ecryptfs_set_inode_lower(inode, lower_inode); fsstack_copy_attr_all(inode, lower_inode); /* i_size will be overwritten for encrypted regular files */ fsstack_copy_inode_size(inode, lower_inode); inode->i_ino = lower_inode->i_ino; |
c4f790736 eCryptfs: Consoli... |
63 |
inode->i_version++; |
c4f790736 eCryptfs: Consoli... |
64 |
inode->i_mapping->a_ops = &ecryptfs_aops; |
5ccf92037 eCryptfs: Cleanup... |
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
if (S_ISLNK(inode->i_mode)) inode->i_op = &ecryptfs_symlink_iops; else if (S_ISDIR(inode->i_mode)) inode->i_op = &ecryptfs_dir_iops; else inode->i_op = &ecryptfs_main_iops; if (S_ISDIR(inode->i_mode)) inode->i_fop = &ecryptfs_dir_fops; else if (special_file(inode->i_mode)) init_special_inode(inode, inode->i_mode, inode->i_rdev); else inode->i_fop = &ecryptfs_main_fops; |
c4f790736 eCryptfs: Consoli... |
79 80 |
return 0; } |
5ccf92037 eCryptfs: Cleanup... |
81 82 |
static struct inode *__ecryptfs_get_inode(struct inode *lower_inode, struct super_block *sb) |
c4f790736 eCryptfs: Consoli... |
83 84 |
{ struct inode *inode; |
c4f790736 eCryptfs: Consoli... |
85 |
|
5ccf92037 eCryptfs: Cleanup... |
86 87 88 89 |
if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) return ERR_PTR(-EXDEV); if (!igrab(lower_inode)) return ERR_PTR(-ESTALE); |
c4f790736 eCryptfs: Consoli... |
90 91 92 93 |
inode = iget5_locked(sb, (unsigned long)lower_inode, ecryptfs_inode_test, ecryptfs_inode_set, lower_inode); if (!inode) { |
c4f790736 eCryptfs: Consoli... |
94 |
iput(lower_inode); |
5ccf92037 eCryptfs: Cleanup... |
95 |
return ERR_PTR(-EACCES); |
c4f790736 eCryptfs: Consoli... |
96 |
} |
5ccf92037 eCryptfs: Cleanup... |
97 |
if (!(inode->i_state & I_NEW)) |
c4f790736 eCryptfs: Consoli... |
98 |
iput(lower_inode); |
5ccf92037 eCryptfs: Cleanup... |
99 100 101 102 103 104 105 106 107 108 109 |
return inode; } struct inode *ecryptfs_get_inode(struct inode *lower_inode, struct super_block *sb) { struct inode *inode = __ecryptfs_get_inode(lower_inode, sb); if (!IS_ERR(inode) && (inode->i_state & I_NEW)) unlock_new_inode(inode); |
c4f790736 eCryptfs: Consoli... |
110 |
return inode; |
c4f790736 eCryptfs: Consoli... |
111 |
} |
c4f790736 eCryptfs: Consoli... |
112 113 114 115 116 |
/** * ecryptfs_interpose * @lower_dentry: Existing dentry in the lower filesystem * @dentry: ecryptfs' dentry * @sb: ecryptfs's super_block |
c4f790736 eCryptfs: Consoli... |
117 118 119 120 121 122 |
* * Interposes upper and lower dentries. * * Returns zero on success; non-zero otherwise */ static int ecryptfs_interpose(struct dentry *lower_dentry, |
5ccf92037 eCryptfs: Cleanup... |
123 |
struct dentry *dentry, struct super_block *sb) |
c4f790736 eCryptfs: Consoli... |
124 |
{ |
2b0143b5c VFS: normal files... |
125 |
struct inode *inode = ecryptfs_get_inode(d_inode(lower_dentry), sb); |
5ccf92037 eCryptfs: Cleanup... |
126 |
|
c4f790736 eCryptfs: Consoli... |
127 128 |
if (IS_ERR(inode)) return PTR_ERR(inode); |
5ccf92037 eCryptfs: Cleanup... |
129 |
d_instantiate(dentry, inode); |
c4f790736 eCryptfs: Consoli... |
130 131 |
return 0; } |
8bc2d3cf6 eCryptfs: Unlink ... |
132 133 134 135 136 137 138 139 140 141 |
static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, struct inode *inode) { struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); struct dentry *lower_dir_dentry; int rc; dget(lower_dentry); lower_dir_dentry = lock_parent(lower_dentry); |
b21996e36 locks: break dele... |
142 |
rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL); |
8bc2d3cf6 eCryptfs: Unlink ... |
143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
if (rc) { printk(KERN_ERR "Error in vfs_unlink; rc = [%d] ", rc); goto out_unlock; } fsstack_copy_attr_times(dir, lower_dir_inode); set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); inode->i_ctime = dir->i_ctime; d_drop(dentry); out_unlock: unlock_dir(lower_dir_dentry); dput(lower_dentry); return rc; } |
237fead61 [PATCH] ecryptfs:... |
157 |
/** |
237fead61 [PATCH] ecryptfs:... |
158 159 160 161 |
* ecryptfs_do_create * @directory_inode: inode of the new file's dentry's parent in ecryptfs * @ecryptfs_dentry: New file's dentry in ecryptfs * @mode: The mode of the new file |
237fead61 [PATCH] ecryptfs:... |
162 163 164 165 166 |
* * Creates the underlying file and the eCryptfs inode which will link to * it. It will also update the eCryptfs directory inode to mimic the * stat of the lower directory inode. * |
b59db43ad eCryptfs: Prevent... |
167 |
* Returns the new eCryptfs inode on success; an ERR_PTR on error condition |
237fead61 [PATCH] ecryptfs:... |
168 |
*/ |
b59db43ad eCryptfs: Prevent... |
169 |
static struct inode * |
237fead61 [PATCH] ecryptfs:... |
170 |
ecryptfs_do_create(struct inode *directory_inode, |
175a4eb7e fs: propagate umo... |
171 |
struct dentry *ecryptfs_dentry, umode_t mode) |
237fead61 [PATCH] ecryptfs:... |
172 173 174 175 |
{ int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; |
b59db43ad eCryptfs: Prevent... |
176 |
struct inode *inode; |
237fead61 [PATCH] ecryptfs:... |
177 178 179 |
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); lower_dir_dentry = lock_parent(lower_dentry); |
2b0143b5c VFS: normal files... |
180 |
rc = vfs_create(d_inode(lower_dir_dentry), lower_dentry, mode, true); |
4981e081c eCryptfs: set up ... |
181 |
if (rc) { |
caeeeecfd eCryptfs: fix den... |
182 |
printk(KERN_ERR "%s: Failure to create dentry in lower fs; " |
18d1dbf1d ecryptfs: replace... |
183 184 |
"rc = [%d] ", __func__, rc); |
b59db43ad eCryptfs: Prevent... |
185 |
inode = ERR_PTR(rc); |
caeeeecfd eCryptfs: fix den... |
186 |
goto out_lock; |
237fead61 [PATCH] ecryptfs:... |
187 |
} |
2b0143b5c VFS: normal files... |
188 |
inode = __ecryptfs_get_inode(d_inode(lower_dentry), |
b59db43ad eCryptfs: Prevent... |
189 |
directory_inode->i_sb); |
8bc2d3cf6 eCryptfs: Unlink ... |
190 |
if (IS_ERR(inode)) { |
2b0143b5c VFS: normal files... |
191 |
vfs_unlink(d_inode(lower_dir_dentry), lower_dentry, NULL); |
237fead61 [PATCH] ecryptfs:... |
192 |
goto out_lock; |
8bc2d3cf6 eCryptfs: Unlink ... |
193 |
} |
2b0143b5c VFS: normal files... |
194 195 |
fsstack_copy_attr_times(directory_inode, d_inode(lower_dir_dentry)); fsstack_copy_inode_size(directory_inode, d_inode(lower_dir_dentry)); |
237fead61 [PATCH] ecryptfs:... |
196 197 |
out_lock: unlock_dir(lower_dir_dentry); |
b59db43ad eCryptfs: Prevent... |
198 |
return inode; |
237fead61 [PATCH] ecryptfs:... |
199 200 201 |
} /** |
237fead61 [PATCH] ecryptfs:... |
202 203 204 205 206 207 208 |
* ecryptfs_initialize_file * * Cause the file to be changed from a basic empty file to an ecryptfs * file with a header and first data page. * * Returns zero on success */ |
e3ccaa976 eCryptfs: Initial... |
209 210 |
int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, struct inode *ecryptfs_inode) |
237fead61 [PATCH] ecryptfs:... |
211 |
{ |
d7cdc5feb eCryptfs: update ... |
212 |
struct ecryptfs_crypt_stat *crypt_stat = |
b59db43ad eCryptfs: Prevent... |
213 |
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
237fead61 [PATCH] ecryptfs:... |
214 |
int rc = 0; |
237fead61 [PATCH] ecryptfs:... |
215 |
|
b59db43ad eCryptfs: Prevent... |
216 |
if (S_ISDIR(ecryptfs_inode->i_mode)) { |
237fead61 [PATCH] ecryptfs:... |
217 218 |
ecryptfs_printk(KERN_DEBUG, "This is a directory "); |
e2bd99ec5 [PATCH] eCryptfs:... |
219 |
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
d7cdc5feb eCryptfs: update ... |
220 |
goto out; |
237fead61 [PATCH] ecryptfs:... |
221 |
} |
237fead61 [PATCH] ecryptfs:... |
222 223 |
ecryptfs_printk(KERN_DEBUG, "Initializing crypto context "); |
b59db43ad eCryptfs: Prevent... |
224 |
rc = ecryptfs_new_file_context(ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
225 |
if (rc) { |
d7cdc5feb eCryptfs: update ... |
226 227 228 229 |
ecryptfs_printk(KERN_ERR, "Error creating new file " "context; rc = [%d] ", rc); goto out; |
237fead61 [PATCH] ecryptfs:... |
230 |
} |
b59db43ad eCryptfs: Prevent... |
231 |
rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode); |
27992890b ecryptfs: test lo... |
232 233 |
if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " |
332ab16f8 eCryptfs: Add ref... |
234 |
"the lower file for the dentry with name " |
9e78d14a9 Use %pd in eCryptFS |
235 236 237 |
"[%pd]; rc = [%d] ", __func__, ecryptfs_dentry, rc); |
27992890b ecryptfs: test lo... |
238 |
goto out; |
391b52f98 eCryptfs: Make al... |
239 |
} |
b59db43ad eCryptfs: Prevent... |
240 |
rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode); |
332ab16f8 eCryptfs: Add ref... |
241 |
if (rc) |
d7cdc5feb eCryptfs: update ... |
242 243 |
printk(KERN_ERR "Error writing headers; rc = [%d] ", rc); |
b59db43ad eCryptfs: Prevent... |
244 |
ecryptfs_put_lower_file(ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
245 246 247 248 249 250 251 252 253 |
out: return rc; } /** * ecryptfs_create * @dir: The inode of the directory in which to create the file. * @dentry: The eCryptfs dentry * @mode: The mode of the new file. |
237fead61 [PATCH] ecryptfs:... |
254 255 256 257 258 259 260 |
* * Creates a new file. * * Returns zero on success; non-zero on error condition */ static int ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, |
ebfc3b49a don't pass nameid... |
261 |
umode_t mode, bool excl) |
237fead61 [PATCH] ecryptfs:... |
262 |
{ |
b59db43ad eCryptfs: Prevent... |
263 |
struct inode *ecryptfs_inode; |
237fead61 [PATCH] ecryptfs:... |
264 |
int rc; |
b59db43ad eCryptfs: Prevent... |
265 266 |
ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode); |
a1c83681d fs: Drop unlikely... |
267 |
if (IS_ERR(ecryptfs_inode)) { |
237fead61 [PATCH] ecryptfs:... |
268 269 270 |
ecryptfs_printk(KERN_WARNING, "Failed to create file in" "lower filesystem "); |
b59db43ad eCryptfs: Prevent... |
271 |
rc = PTR_ERR(ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
272 273 274 275 |
goto out; } /* At this point, a file exists on "disk"; we need to make sure * that this on disk file is prepared to be an ecryptfs file */ |
b59db43ad eCryptfs: Prevent... |
276 277 |
rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); if (rc) { |
8bc2d3cf6 eCryptfs: Unlink ... |
278 279 |
ecryptfs_do_unlink(directory_inode, ecryptfs_dentry, ecryptfs_inode); |
0e81ba231 don't opencode ig... |
280 |
iget_failed(ecryptfs_inode); |
b59db43ad eCryptfs: Prevent... |
281 282 |
goto out; } |
f440ea85d do d_instantiate/... |
283 |
d_instantiate_new(ecryptfs_dentry, ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
284 285 286 |
out: return rc; } |
778aeb42a eCryptfs: Cleanup... |
287 288 289 290 291 292 293 294 295 |
static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode) { struct ecryptfs_crypt_stat *crypt_stat; int rc; rc = ecryptfs_get_lower_file(dentry, inode); if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the lower file for the dentry with name " |
9e78d14a9 Use %pd in eCryptFS |
296 297 298 |
"[%pd]; rc = [%d] ", __func__, dentry, rc); |
778aeb42a eCryptfs: Cleanup... |
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
return rc; } crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; /* TODO: lock for crypt_stat comparison */ if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) ecryptfs_set_default_sizes(crypt_stat); rc = ecryptfs_read_and_validate_header_region(inode); ecryptfs_put_lower_file(inode); if (rc) { rc = ecryptfs_read_and_validate_xattr_region(dentry, inode); if (!rc) crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; } /* Must return 0 to allow non-eCryptfs files to be looked up, too */ return 0; } |
237fead61 [PATCH] ecryptfs:... |
318 |
/** |
5ccf92037 eCryptfs: Cleanup... |
319 |
* ecryptfs_lookup_interpose - Dentry interposition for a lookup |
237fead61 [PATCH] ecryptfs:... |
320 |
*/ |
b1168a928 ecryptfs: avoid m... |
321 322 |
static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry, struct dentry *lower_dentry) |
237fead61 [PATCH] ecryptfs:... |
323 |
{ |
2b0143b5c VFS: normal files... |
324 |
struct inode *inode, *lower_inode = d_inode(lower_dentry); |
778aeb42a eCryptfs: Cleanup... |
325 |
struct ecryptfs_dentry_info *dentry_info; |
237fead61 [PATCH] ecryptfs:... |
326 |
struct vfsmount *lower_mnt; |
778aeb42a eCryptfs: Cleanup... |
327 |
int rc = 0; |
778aeb42a eCryptfs: Cleanup... |
328 |
dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); |
778aeb42a eCryptfs: Cleanup... |
329 |
if (!dentry_info) { |
addd65ad8 eCryptfs: Filenam... |
330 331 332 333 |
printk(KERN_ERR "%s: Out of memory whilst attempting " "to allocate ecryptfs_dentry_info struct ", __func__); |
778aeb42a eCryptfs: Cleanup... |
334 |
dput(lower_dentry); |
b1168a928 ecryptfs: avoid m... |
335 |
return ERR_PTR(-ENOMEM); |
237fead61 [PATCH] ecryptfs:... |
336 |
} |
0b1d90119 ecryptfs_lookup_i... |
337 338 |
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); |
b1168a928 ecryptfs: avoid m... |
339 340 |
fsstack_copy_attr_atime(d_inode(dentry->d_parent), d_inode(lower_dentry->d_parent)); |
84d08fa88 helper for readin... |
341 |
BUG_ON(!d_count(lower_dentry)); |
0b1d90119 ecryptfs_lookup_i... |
342 343 |
ecryptfs_set_dentry_private(dentry, dentry_info); |
92dd12303 ecryptfs: get rid... |
344 345 |
dentry_info->lower_path.mnt = lower_mnt; dentry_info->lower_path.dentry = lower_dentry; |
778aeb42a eCryptfs: Cleanup... |
346 |
|
2b0143b5c VFS: normal files... |
347 |
if (d_really_is_negative(lower_dentry)) { |
237fead61 [PATCH] ecryptfs:... |
348 |
/* We want to add because we couldn't find in lower */ |
778aeb42a eCryptfs: Cleanup... |
349 |
d_add(dentry, NULL); |
b1168a928 ecryptfs: avoid m... |
350 |
return NULL; |
237fead61 [PATCH] ecryptfs:... |
351 |
} |
b1168a928 ecryptfs: avoid m... |
352 |
inode = __ecryptfs_get_inode(lower_inode, dentry->d_sb); |
5ccf92037 eCryptfs: Cleanup... |
353 |
if (IS_ERR(inode)) { |
778aeb42a eCryptfs: Cleanup... |
354 355 356 |
printk(KERN_ERR "%s: Error interposing; rc = [%ld] ", __func__, PTR_ERR(inode)); |
b1168a928 ecryptfs: avoid m... |
357 |
return ERR_CAST(inode); |
391b52f98 eCryptfs: Make al... |
358 |
} |
778aeb42a eCryptfs: Cleanup... |
359 360 |
if (S_ISREG(inode->i_mode)) { rc = ecryptfs_i_size_read(dentry, inode); |
dd2a3b7ad [PATCH] eCryptfs:... |
361 |
if (rc) { |
778aeb42a eCryptfs: Cleanup... |
362 |
make_bad_inode(inode); |
b1168a928 ecryptfs: avoid m... |
363 |
return ERR_PTR(rc); |
237fead61 [PATCH] ecryptfs:... |
364 |
} |
237fead61 [PATCH] ecryptfs:... |
365 |
} |
778aeb42a eCryptfs: Cleanup... |
366 |
|
3b06b3ebf eCryptfs: Fix new... |
367 368 |
if (inode->i_state & I_NEW) unlock_new_inode(inode); |
b1168a928 ecryptfs: avoid m... |
369 |
return d_splice_alias(inode, dentry); |
addd65ad8 eCryptfs: Filenam... |
370 371 372 373 374 375 |
} /** * ecryptfs_lookup * @ecryptfs_dir_inode: The eCryptfs directory inode * @ecryptfs_dentry: The eCryptfs dentry that we are looking up |
89076bc31 get rid of assort... |
376 |
* @flags: lookup flags |
addd65ad8 eCryptfs: Filenam... |
377 378 379 380 381 382 |
* * Find a file on disk. If the file does not exist, then we'll add it to the * dentry cache and continue on to read it from the disk. */ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, struct dentry *ecryptfs_dentry, |
00cd8dd3b stop passing name... |
383 |
unsigned int flags) |
addd65ad8 eCryptfs: Filenam... |
384 385 |
{ char *encrypted_and_encoded_name = NULL; |
88ae4ab98 ecryptfs_lookup()... |
386 |
struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
addd65ad8 eCryptfs: Filenam... |
387 |
struct dentry *lower_dir_dentry, *lower_dentry; |
88ae4ab98 ecryptfs_lookup()... |
388 389 |
const char *name = ecryptfs_dentry->d_name.name; size_t len = ecryptfs_dentry->d_name.len; |
b1168a928 ecryptfs: avoid m... |
390 |
struct dentry *res; |
addd65ad8 eCryptfs: Filenam... |
391 |
int rc = 0; |
addd65ad8 eCryptfs: Filenam... |
392 |
lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
88ae4ab98 ecryptfs_lookup()... |
393 |
|
2aac0cf88 eCryptfs: NULL cr... |
394 395 |
mount_crypt_stat = &ecryptfs_superblock_to_private( ecryptfs_dentry->d_sb)->mount_crypt_stat; |
88ae4ab98 ecryptfs_lookup()... |
396 397 398 399 400 401 402 403 404 405 406 407 |
if (mount_crypt_stat && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) { rc = ecryptfs_encrypt_and_encode_filename( &encrypted_and_encoded_name, &len, mount_crypt_stat, name, len); if (rc) { printk(KERN_ERR "%s: Error attempting to encrypt and encode " "filename; rc = [%d] ", __func__, rc); return ERR_PTR(rc); } name = encrypted_and_encoded_name; |
addd65ad8 eCryptfs: Filenam... |
408 |
} |
88ae4ab98 ecryptfs_lookup()... |
409 410 |
lower_dentry = lookup_one_len_unlocked(name, lower_dir_dentry, len); |
addd65ad8 eCryptfs: Filenam... |
411 |
if (IS_ERR(lower_dentry)) { |
8787c7a3e eCryptfs: Revert ... |
412 |
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
b1168a928 ecryptfs: avoid m... |
413 414 415 |
"[%ld] on lower_dentry = [%s] ", __func__, PTR_ERR(lower_dentry), |
88ae4ab98 ecryptfs_lookup()... |
416 |
name); |
b1168a928 ecryptfs: avoid m... |
417 |
res = ERR_CAST(lower_dentry); |
88ae4ab98 ecryptfs_lookup()... |
418 419 |
} else { res = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry); |
addd65ad8 eCryptfs: Filenam... |
420 |
} |
addd65ad8 eCryptfs: Filenam... |
421 |
kfree(encrypted_and_encoded_name); |
b1168a928 ecryptfs: avoid m... |
422 |
return res; |
237fead61 [PATCH] ecryptfs:... |
423 424 425 426 427 428 429 430 431 432 |
} static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { struct dentry *lower_old_dentry; struct dentry *lower_new_dentry; struct dentry *lower_dir_dentry; u64 file_size_save; int rc; |
2b0143b5c VFS: normal files... |
433 |
file_size_save = i_size_read(d_inode(old_dentry)); |
237fead61 [PATCH] ecryptfs:... |
434 435 436 437 438 |
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_dir_dentry = lock_parent(lower_new_dentry); |
2b0143b5c VFS: normal files... |
439 |
rc = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry), |
146a8595c locks: break dele... |
440 |
lower_new_dentry, NULL); |
2b0143b5c VFS: normal files... |
441 |
if (rc || d_really_is_negative(lower_new_dentry)) |
237fead61 [PATCH] ecryptfs:... |
442 |
goto out_lock; |
5ccf92037 eCryptfs: Cleanup... |
443 |
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
444 445 |
if (rc) goto out_lock; |
2b0143b5c VFS: normal files... |
446 447 448 449 450 |
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); set_nlink(d_inode(old_dentry), ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink); i_size_write(d_inode(new_dentry), file_size_save); |
237fead61 [PATCH] ecryptfs:... |
451 452 453 454 |
out_lock: unlock_dir(lower_dir_dentry); dput(lower_new_dentry); dput(lower_old_dentry); |
237fead61 [PATCH] ecryptfs:... |
455 456 457 458 459 |
return rc; } static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) { |
2b0143b5c VFS: normal files... |
460 |
return ecryptfs_do_unlink(dir, dentry, d_inode(dentry)); |
237fead61 [PATCH] ecryptfs:... |
461 462 463 464 465 466 467 468 |
} static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; |
237fead61 [PATCH] ecryptfs:... |
469 |
char *encoded_symname; |
addd65ad8 eCryptfs: Filenam... |
470 471 |
size_t encoded_symlen; struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
237fead61 [PATCH] ecryptfs:... |
472 473 474 475 |
lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(lower_dentry); lower_dir_dentry = lock_parent(lower_dentry); |
addd65ad8 eCryptfs: Filenam... |
476 477 478 479 |
mount_crypt_stat = &ecryptfs_superblock_to_private( dir->i_sb)->mount_crypt_stat; rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, &encoded_symlen, |
addd65ad8 eCryptfs: Filenam... |
480 481 482 |
mount_crypt_stat, symname, strlen(symname)); if (rc) |
237fead61 [PATCH] ecryptfs:... |
483 |
goto out_lock; |
2b0143b5c VFS: normal files... |
484 |
rc = vfs_symlink(d_inode(lower_dir_dentry), lower_dentry, |
db2e747b1 [patch 5/5] vfs: ... |
485 |
encoded_symname); |
237fead61 [PATCH] ecryptfs:... |
486 |
kfree(encoded_symname); |
2b0143b5c VFS: normal files... |
487 |
if (rc || d_really_is_negative(lower_dentry)) |
237fead61 [PATCH] ecryptfs:... |
488 |
goto out_lock; |
5ccf92037 eCryptfs: Cleanup... |
489 |
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
490 491 |
if (rc) goto out_lock; |
2b0143b5c VFS: normal files... |
492 493 |
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); |
237fead61 [PATCH] ecryptfs:... |
494 495 496 |
out_lock: unlock_dir(lower_dir_dentry); dput(lower_dentry); |
2b0143b5c VFS: normal files... |
497 |
if (d_really_is_negative(dentry)) |
237fead61 [PATCH] ecryptfs:... |
498 499 500 |
d_drop(dentry); return rc; } |
18bb1db3e switch vfs_mkdir(... |
501 |
static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
237fead61 [PATCH] ecryptfs:... |
502 503 504 505 506 507 508 |
{ int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); lower_dir_dentry = lock_parent(lower_dentry); |
2b0143b5c VFS: normal files... |
509 510 |
rc = vfs_mkdir(d_inode(lower_dir_dentry), lower_dentry, mode); if (rc || d_really_is_negative(lower_dentry)) |
237fead61 [PATCH] ecryptfs:... |
511 |
goto out; |
5ccf92037 eCryptfs: Cleanup... |
512 |
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
513 514 |
if (rc) goto out; |
2b0143b5c VFS: normal files... |
515 516 517 |
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); |
237fead61 [PATCH] ecryptfs:... |
518 519 |
out: unlock_dir(lower_dir_dentry); |
2b0143b5c VFS: normal files... |
520 |
if (d_really_is_negative(dentry)) |
237fead61 [PATCH] ecryptfs:... |
521 522 523 524 525 526 |
d_drop(dentry); return rc; } static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) { |
237fead61 [PATCH] ecryptfs:... |
527 |
struct dentry *lower_dentry; |
237fead61 [PATCH] ecryptfs:... |
528 |
struct dentry *lower_dir_dentry; |
45ec4abab [PATCH] eCryptfs:... |
529 |
int rc; |
237fead61 [PATCH] ecryptfs:... |
530 531 |
lower_dentry = ecryptfs_dentry_to_lower(dentry); |
45ec4abab [PATCH] eCryptfs:... |
532 |
dget(dentry); |
237fead61 [PATCH] ecryptfs:... |
533 |
lower_dir_dentry = lock_parent(lower_dentry); |
45ec4abab [PATCH] eCryptfs:... |
534 |
dget(lower_dentry); |
2b0143b5c VFS: normal files... |
535 |
rc = vfs_rmdir(d_inode(lower_dir_dentry), lower_dentry); |
45ec4abab [PATCH] eCryptfs:... |
536 |
dput(lower_dentry); |
2b0143b5c VFS: normal files... |
537 538 539 540 |
if (!rc && d_really_is_positive(dentry)) clear_nlink(d_inode(dentry)); fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); |
237fead61 [PATCH] ecryptfs:... |
541 542 543 |
unlock_dir(lower_dir_dentry); if (!rc) d_drop(dentry); |
45ec4abab [PATCH] eCryptfs:... |
544 |
dput(dentry); |
237fead61 [PATCH] ecryptfs:... |
545 546 547 548 |
return rc; } static int |
1a67aafb5 switch ->mknod() ... |
549 |
ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) |
237fead61 [PATCH] ecryptfs:... |
550 551 552 553 554 555 556 |
{ int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); lower_dir_dentry = lock_parent(lower_dentry); |
2b0143b5c VFS: normal files... |
557 558 |
rc = vfs_mknod(d_inode(lower_dir_dentry), lower_dentry, mode, dev); if (rc || d_really_is_negative(lower_dentry)) |
237fead61 [PATCH] ecryptfs:... |
559 |
goto out; |
5ccf92037 eCryptfs: Cleanup... |
560 |
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
561 562 |
if (rc) goto out; |
2b0143b5c VFS: normal files... |
563 564 |
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); |
237fead61 [PATCH] ecryptfs:... |
565 566 |
out: unlock_dir(lower_dir_dentry); |
2b0143b5c VFS: normal files... |
567 |
if (d_really_is_negative(dentry)) |
237fead61 [PATCH] ecryptfs:... |
568 569 570 571 572 573 |
d_drop(dentry); return rc; } static int ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
1cd66c93b fs: make remainin... |
574 575 |
struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) |
237fead61 [PATCH] ecryptfs:... |
576 577 578 579 580 581 |
{ int rc; struct dentry *lower_old_dentry; struct dentry *lower_new_dentry; struct dentry *lower_old_dir_dentry; struct dentry *lower_new_dir_dentry; |
0d132f736 ecryptfs: don't i... |
582 |
struct dentry *trap = NULL; |
8335eafc2 eCryptfs: Copy up... |
583 |
struct inode *target_inode; |
237fead61 [PATCH] ecryptfs:... |
584 |
|
1cd66c93b fs: make remainin... |
585 586 |
if (flags) return -EINVAL; |
237fead61 [PATCH] ecryptfs:... |
587 588 589 590 591 592 |
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_old_dir_dentry = dget_parent(lower_old_dentry); lower_new_dir_dentry = dget_parent(lower_new_dentry); |
2b0143b5c VFS: normal files... |
593 |
target_inode = d_inode(new_dentry); |
0d132f736 ecryptfs: don't i... |
594 595 596 597 598 599 600 601 602 603 604 |
trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); /* source should not be ancestor of target */ if (trap == lower_old_dentry) { rc = -EINVAL; goto out_lock; } /* target should not be ancestor of source */ if (trap == lower_new_dentry) { rc = -ENOTEMPTY; goto out_lock; } |
2b0143b5c VFS: normal files... |
605 606 |
rc = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry, d_inode(lower_new_dir_dentry), lower_new_dentry, |
520c8b165 vfs: add renameat... |
607 |
NULL, 0); |
237fead61 [PATCH] ecryptfs:... |
608 609 |
if (rc) goto out_lock; |
8335eafc2 eCryptfs: Copy up... |
610 611 612 |
if (target_inode) fsstack_copy_attr_all(target_inode, ecryptfs_inode_to_lower(target_inode)); |
2b0143b5c VFS: normal files... |
613 |
fsstack_copy_attr_all(new_dir, d_inode(lower_new_dir_dentry)); |
237fead61 [PATCH] ecryptfs:... |
614 |
if (new_dir != old_dir) |
2b0143b5c VFS: normal files... |
615 |
fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry)); |
237fead61 [PATCH] ecryptfs:... |
616 617 |
out_lock: unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
dd55c8985 eCryptfs: dput de... |
618 619 |
dput(lower_new_dir_dentry); dput(lower_old_dir_dentry); |
237fead61 [PATCH] ecryptfs:... |
620 621 622 623 |
dput(lower_new_dentry); dput(lower_old_dentry); return rc; } |
b22e8fedc ecryptfs: fix fai... |
624 |
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz) |
237fead61 [PATCH] ecryptfs:... |
625 |
{ |
6c988f575 ecryptfs: use vfs... |
626 |
DEFINE_DELAYED_CALL(done); |
3a60a1686 eCryptfs: Decrypt... |
627 |
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
6c988f575 ecryptfs: use vfs... |
628 |
const char *link; |
b22e8fedc ecryptfs: fix fai... |
629 |
char *buf; |
addd65ad8 eCryptfs: Filenam... |
630 |
int rc; |
237fead61 [PATCH] ecryptfs:... |
631 |
|
6c988f575 ecryptfs: use vfs... |
632 633 634 |
link = vfs_get_link(lower_dentry, &done); if (IS_ERR(link)) return ERR_CAST(link); |
b22e8fedc ecryptfs: fix fai... |
635 |
rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb, |
6c988f575 ecryptfs: use vfs... |
636 637 638 639 640 641 |
link, strlen(link)); do_delayed_call(&done); if (rc) return ERR_PTR(rc); return buf; |
3a60a1686 eCryptfs: Decrypt... |
642 |
} |
6b2553918 replace ->follow_... |
643 |
static const char *ecryptfs_get_link(struct dentry *dentry, |
fceef393a switch ->get_link... |
644 645 |
struct inode *inode, struct delayed_call *done) |
3a60a1686 eCryptfs: Decrypt... |
646 |
{ |
b22e8fedc ecryptfs: fix fai... |
647 |
size_t len; |
6b2553918 replace ->follow_... |
648 649 650 651 652 653 |
char *buf; if (!dentry) return ERR_PTR(-ECHILD); buf = ecryptfs_readlink_lower(dentry, &len); |
b22e8fedc ecryptfs: fix fai... |
654 |
if (IS_ERR(buf)) |
680baacbc new ->follow_link... |
655 |
return buf; |
2b0143b5c VFS: normal files... |
656 657 |
fsstack_copy_attr_atime(d_inode(dentry), d_inode(ecryptfs_dentry_to_lower(dentry))); |
408bd629b get rid of pointl... |
658 |
buf[len] = '\0'; |
fceef393a switch ->get_link... |
659 660 |
set_delayed_call(done, kfree_link, buf); return buf; |
237fead61 [PATCH] ecryptfs:... |
661 |
} |
237fead61 [PATCH] ecryptfs:... |
662 663 664 665 666 |
/** * upper_size_to_lower_size * @crypt_stat: Crypt_stat associated with file * @upper_size: Size of the upper file * |
cc11beffd eCryptfs: track h... |
667 |
* Calculate the required size of the lower file based on the |
237fead61 [PATCH] ecryptfs:... |
668 669 670 671 672 673 674 675 676 677 |
* specified size of the upper file. This calculation is based on the * number of headers in the underlying file and the extent size. * * Returns Calculated size of the lower file. */ static loff_t upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, loff_t upper_size) { loff_t lower_size; |
157f10713 eCryptfs: Fix met... |
678 |
lower_size = ecryptfs_lower_header_size(crypt_stat); |
237fead61 [PATCH] ecryptfs:... |
679 680 681 682 683 684 685 686 687 688 689 690 |
if (upper_size != 0) { loff_t num_extents; num_extents = upper_size >> crypt_stat->extent_shift; if (upper_size & ~crypt_stat->extent_mask) num_extents++; lower_size += (num_extents * crypt_stat->extent_size); } return lower_size; } /** |
5f3ef64f4 eCryptfs: Use not... |
691 |
* truncate_upper |
237fead61 [PATCH] ecryptfs:... |
692 |
* @dentry: The ecryptfs layer dentry |
5f3ef64f4 eCryptfs: Use not... |
693 694 |
* @ia: Address of the ecryptfs inode's attributes * @lower_ia: Address of the lower inode's attributes |
237fead61 [PATCH] ecryptfs:... |
695 696 697 |
* * Function to handle truncations modifying the size of the file. Note * that the file sizes are interpolated. When expanding, we are simply |
5f3ef64f4 eCryptfs: Use not... |
698 699 700 701 702 |
* writing strings of 0's out. When truncating, we truncate the upper * inode and update the lower_ia according to the page index * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return, * the caller must use lower_ia in a call to notify_change() to perform * the truncation of the lower inode. |
237fead61 [PATCH] ecryptfs:... |
703 704 705 |
* * Returns zero on success; non-zero otherwise */ |
5f3ef64f4 eCryptfs: Use not... |
706 707 |
static int truncate_upper(struct dentry *dentry, struct iattr *ia, struct iattr *lower_ia) |
237fead61 [PATCH] ecryptfs:... |
708 709 |
{ int rc = 0; |
2b0143b5c VFS: normal files... |
710 |
struct inode *inode = d_inode(dentry); |
237fead61 [PATCH] ecryptfs:... |
711 712 713 714 |
struct ecryptfs_crypt_stat *crypt_stat; loff_t i_size = i_size_read(inode); loff_t lower_size_before_truncate; loff_t lower_size_after_truncate; |
5f3ef64f4 eCryptfs: Use not... |
715 716 |
if (unlikely((ia->ia_size == i_size))) { lower_ia->ia_valid &= ~ATTR_SIZE; |
332ab16f8 eCryptfs: Add ref... |
717 |
return 0; |
5f3ef64f4 eCryptfs: Use not... |
718 |
} |
3b06b3ebf eCryptfs: Fix new... |
719 |
rc = ecryptfs_get_lower_file(dentry, inode); |
332ab16f8 eCryptfs: Add ref... |
720 721 |
if (rc) return rc; |
2b0143b5c VFS: normal files... |
722 |
crypt_stat = &ecryptfs_inode_to_private(d_inode(dentry))->crypt_stat; |
237fead61 [PATCH] ecryptfs:... |
723 |
/* Switch on growing or shrinking file */ |
5f3ef64f4 eCryptfs: Use not... |
724 |
if (ia->ia_size > i_size) { |
2ed92554a eCryptfs: make op... |
725 |
char zero[] = { 0x00 }; |
5f3ef64f4 eCryptfs: Use not... |
726 |
lower_ia->ia_valid &= ~ATTR_SIZE; |
2ed92554a eCryptfs: make op... |
727 728 729 730 |
/* Write a single 0 at the last position of the file; * this triggers code that will fill in 0's throughout * the intermediate portion of the previous end of the * file and the new and of the file */ |
48c1e44ac switch ecryptfs_w... |
731 |
rc = ecryptfs_write(inode, zero, |
5f3ef64f4 eCryptfs: Use not... |
732 733 734 735 |
(ia->ia_size - 1), 1); } else { /* ia->ia_size < i_size_read(inode) */ /* We're chopping off all the pages down to the page * in which ia->ia_size is located. Fill in the end of |
ea1754a08 mm, fs: remove re... |
736 737 |
* that page from (ia->ia_size & ~PAGE_MASK) to * PAGE_SIZE with zeros. */ |
09cbfeaf1 mm, fs: get rid o... |
738 739 |
size_t num_zeros = (PAGE_SIZE - (ia->ia_size & ~PAGE_MASK)); |
2ed92554a eCryptfs: make op... |
740 |
|
13a791b4e eCryptfs: Fix dat... |
741 |
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
2c27c65ed check ATTR_SIZE c... |
742 |
truncate_setsize(inode, ia->ia_size); |
5f3ef64f4 eCryptfs: Use not... |
743 744 |
lower_ia->ia_size = ia->ia_size; lower_ia->ia_valid |= ATTR_SIZE; |
48c1e44ac switch ecryptfs_w... |
745 |
goto out; |
13a791b4e eCryptfs: Fix dat... |
746 |
} |
2ed92554a eCryptfs: make op... |
747 748 749 750 751 752 |
if (num_zeros) { char *zeros_virt; zeros_virt = kzalloc(num_zeros, GFP_KERNEL); if (!zeros_virt) { rc = -ENOMEM; |
48c1e44ac switch ecryptfs_w... |
753 |
goto out; |
2ed92554a eCryptfs: make op... |
754 |
} |
48c1e44ac switch ecryptfs_w... |
755 |
rc = ecryptfs_write(inode, zeros_virt, |
5f3ef64f4 eCryptfs: Use not... |
756 |
ia->ia_size, num_zeros); |
2ed92554a eCryptfs: make op... |
757 |
kfree(zeros_virt); |
5dda6992a eCryptfs: remove ... |
758 |
if (rc) { |
240e2df5c eCryptfs: fix wri... |
759 760 761 762 |
printk(KERN_ERR "Error attempting to zero out " "the remainder of the end page on " "reducing truncate; rc = [%d] ", rc); |
48c1e44ac switch ecryptfs_w... |
763 |
goto out; |
240e2df5c eCryptfs: fix wri... |
764 765 |
} } |
2c27c65ed check ATTR_SIZE c... |
766 |
truncate_setsize(inode, ia->ia_size); |
0216f7f79 eCryptfs: replace... |
767 |
rc = ecryptfs_write_inode_size_to_metadata(inode); |
dd2a3b7ad [PATCH] eCryptfs:... |
768 769 770 771 772 |
if (rc) { printk(KERN_ERR "Problem with " "ecryptfs_write_inode_size_to_metadata; " "rc = [%d] ", rc); |
48c1e44ac switch ecryptfs_w... |
773 |
goto out; |
dd2a3b7ad [PATCH] eCryptfs:... |
774 |
} |
237fead61 [PATCH] ecryptfs:... |
775 776 777 778 779 |
/* We are reducing the size of the ecryptfs file, and need to * know if we need to reduce the size of the lower file. */ lower_size_before_truncate = upper_size_to_lower_size(crypt_stat, i_size); lower_size_after_truncate = |
5f3ef64f4 eCryptfs: Use not... |
780 781 782 783 784 785 |
upper_size_to_lower_size(crypt_stat, ia->ia_size); if (lower_size_after_truncate < lower_size_before_truncate) { lower_ia->ia_size = lower_size_after_truncate; lower_ia->ia_valid |= ATTR_SIZE; } else lower_ia->ia_valid &= ~ATTR_SIZE; |
237fead61 [PATCH] ecryptfs:... |
786 |
} |
237fead61 [PATCH] ecryptfs:... |
787 |
out: |
332ab16f8 eCryptfs: Add ref... |
788 |
ecryptfs_put_lower_file(inode); |
237fead61 [PATCH] ecryptfs:... |
789 790 |
return rc; } |
a261a0390 eCryptfs: Check i... |
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 |
static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset) { struct ecryptfs_crypt_stat *crypt_stat; loff_t lower_oldsize, lower_newsize; crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; lower_oldsize = upper_size_to_lower_size(crypt_stat, i_size_read(inode)); lower_newsize = upper_size_to_lower_size(crypt_stat, offset); if (lower_newsize > lower_oldsize) { /* * The eCryptfs inode and the new *lower* size are mixed here * because we may not have the lower i_mutex held and/or it may * not be appropriate to call inode_newsize_ok() with inodes * from other filesystems. */ return inode_newsize_ok(inode, lower_newsize); } return 0; } |
5f3ef64f4 eCryptfs: Use not... |
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
/** * ecryptfs_truncate * @dentry: The ecryptfs layer dentry * @new_length: The length to expand the file to * * Simple function that handles the truncation of an eCryptfs inode and * its corresponding lower inode. * * Returns zero on success; non-zero otherwise */ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) { struct iattr ia = { .ia_valid = ATTR_SIZE, .ia_size = new_length }; struct iattr lower_ia = { .ia_valid = 0 }; int rc; |
2b0143b5c VFS: normal files... |
827 |
rc = ecryptfs_inode_newsize_ok(d_inode(dentry), new_length); |
a261a0390 eCryptfs: Check i... |
828 829 |
if (rc) return rc; |
5f3ef64f4 eCryptfs: Use not... |
830 831 832 |
rc = truncate_upper(dentry, &ia, &lower_ia); if (!rc && lower_ia.ia_valid & ATTR_SIZE) { struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
5955102c9 wrappers for ->i_... |
833 |
inode_lock(d_inode(lower_dentry)); |
27ac0ffea locks: break dele... |
834 |
rc = notify_change(lower_dentry, &lower_ia, NULL); |
5955102c9 wrappers for ->i_... |
835 |
inode_unlock(d_inode(lower_dentry)); |
5f3ef64f4 eCryptfs: Use not... |
836 837 838 |
} return rc; } |
237fead61 [PATCH] ecryptfs:... |
839 |
static int |
10556cb21 ->permission() sa... |
840 |
ecryptfs_permission(struct inode *inode, int mask) |
237fead61 [PATCH] ecryptfs:... |
841 |
{ |
f419a2e3b [PATCH] kill name... |
842 |
return inode_permission(ecryptfs_inode_to_lower(inode), mask); |
237fead61 [PATCH] ecryptfs:... |
843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 |
} /** * ecryptfs_setattr * @dentry: dentry handle to the inode to modify * @ia: Structure with flags of what to change and values * * Updates the metadata of an inode. If the update is to the size * i.e. truncation, then ecryptfs_truncate will handle the size modification * of both the ecryptfs inode and the lower inode. * * All other metadata changes will be passed right to the lower filesystem, * and we will just update our inode to look like the lower. */ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) { int rc = 0; struct dentry *lower_dentry; |
5f3ef64f4 eCryptfs: Use not... |
861 |
struct iattr lower_ia; |
237fead61 [PATCH] ecryptfs:... |
862 863 864 |
struct inode *inode; struct inode *lower_inode; struct ecryptfs_crypt_stat *crypt_stat; |
2b0143b5c VFS: normal files... |
865 |
crypt_stat = &ecryptfs_inode_to_private(d_inode(dentry))->crypt_stat; |
e81f3340b eCryptfs: Do not ... |
866 867 868 869 870 |
if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) { rc = ecryptfs_init_crypt_stat(crypt_stat); if (rc) return rc; } |
2b0143b5c VFS: normal files... |
871 |
inode = d_inode(dentry); |
237fead61 [PATCH] ecryptfs:... |
872 |
lower_inode = ecryptfs_inode_to_lower(inode); |
e10f281bc eCryptfs: initial... |
873 874 |
lower_dentry = ecryptfs_dentry_to_lower(dentry); mutex_lock(&crypt_stat->cs_mutex); |
e36cb0b89 VFS: (Scripted) C... |
875 |
if (d_is_dir(dentry)) |
e10f281bc eCryptfs: initial... |
876 |
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
e36cb0b89 VFS: (Scripted) C... |
877 |
else if (d_is_reg(dentry) |
64ee4808a eCryptfs: ecryptf... |
878 879 |
&& (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) { |
e10f281bc eCryptfs: initial... |
880 |
struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
e10f281bc eCryptfs: initial... |
881 |
|
e10f281bc eCryptfs: initial... |
882 883 |
mount_crypt_stat = &ecryptfs_superblock_to_private( dentry->d_sb)->mount_crypt_stat; |
3b06b3ebf eCryptfs: Fix new... |
884 |
rc = ecryptfs_get_lower_file(dentry, inode); |
332ab16f8 eCryptfs: Add ref... |
885 886 887 888 |
if (rc) { mutex_unlock(&crypt_stat->cs_mutex); goto out; } |
d7cdc5feb eCryptfs: update ... |
889 |
rc = ecryptfs_read_metadata(dentry); |
332ab16f8 eCryptfs: Add ref... |
890 |
ecryptfs_put_lower_file(inode); |
5dda6992a eCryptfs: remove ... |
891 |
if (rc) { |
e10f281bc eCryptfs: initial... |
892 893 894 |
if (!(mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { rc = -EIO; |
25bd81740 eCryptfs: Minor f... |
895 |
printk(KERN_WARNING "Either the lower file " |
e10f281bc eCryptfs: initial... |
896 |
"is not in a valid eCryptfs format, " |
25bd81740 eCryptfs: Minor f... |
897 898 |
"or the key could not be retrieved. " "Plaintext passthrough mode is not " |
e10f281bc eCryptfs: initial... |
899 900 |
"enabled; returning -EIO "); |
e10f281bc eCryptfs: initial... |
901 |
mutex_unlock(&crypt_stat->cs_mutex); |
e10f281bc eCryptfs: initial... |
902 903 904 |
goto out; } rc = 0; |
3aeb86ea4 eCryptfs: Handle ... |
905 906 |
crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ECRYPTFS_ENCRYPTED); |
e10f281bc eCryptfs: initial... |
907 |
} |
e10f281bc eCryptfs: initial... |
908 909 |
} mutex_unlock(&crypt_stat->cs_mutex); |
a261a0390 eCryptfs: Check i... |
910 |
|
31051c85b fs: Give dentry t... |
911 |
rc = setattr_prepare(dentry, ia); |
a261a0390 eCryptfs: Check i... |
912 913 914 915 916 917 918 |
if (rc) goto out; if (ia->ia_valid & ATTR_SIZE) { rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size); if (rc) goto out; } |
5f3ef64f4 eCryptfs: Use not... |
919 920 921 |
memcpy(&lower_ia, ia, sizeof(lower_ia)); if (ia->ia_valid & ATTR_FILE) lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |
237fead61 [PATCH] ecryptfs:... |
922 |
if (ia->ia_valid & ATTR_SIZE) { |
5f3ef64f4 eCryptfs: Use not... |
923 |
rc = truncate_upper(dentry, ia, &lower_ia); |
237fead61 [PATCH] ecryptfs:... |
924 925 926 |
if (rc < 0) goto out; } |
1ac564eca ecryptfs: allow l... |
927 928 929 930 931 |
/* * mode change is for clearing setuid/setgid bits. Allow lower fs * to interpret this in its own way. */ |
5f3ef64f4 eCryptfs: Use not... |
932 933 |
if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) lower_ia.ia_valid &= ~ATTR_MODE; |
1ac564eca ecryptfs: allow l... |
934 |
|
5955102c9 wrappers for ->i_... |
935 |
inode_lock(d_inode(lower_dentry)); |
27ac0ffea locks: break dele... |
936 |
rc = notify_change(lower_dentry, &lower_ia, NULL); |
5955102c9 wrappers for ->i_... |
937 |
inode_unlock(d_inode(lower_dentry)); |
237fead61 [PATCH] ecryptfs:... |
938 |
out: |
9afa2fb6c fsstack/ecryptfs:... |
939 |
fsstack_copy_attr_all(inode, lower_inode); |
237fead61 [PATCH] ecryptfs:... |
940 941 |
return rc; } |
a528d35e8 statx: Add a syst... |
942 943 |
static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) |
3a60a1686 eCryptfs: Decrypt... |
944 |
{ |
a528d35e8 statx: Add a syst... |
945 |
struct dentry *dentry = path->dentry; |
3a60a1686 eCryptfs: Decrypt... |
946 947 948 949 950 |
struct ecryptfs_mount_crypt_stat *mount_crypt_stat; int rc = 0; mount_crypt_stat = &ecryptfs_superblock_to_private( dentry->d_sb)->mount_crypt_stat; |
2b0143b5c VFS: normal files... |
951 |
generic_fillattr(d_inode(dentry), stat); |
3a60a1686 eCryptfs: Decrypt... |
952 953 954 |
if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { char *target; size_t targetsiz; |
b22e8fedc ecryptfs: fix fai... |
955 956 |
target = ecryptfs_readlink_lower(dentry, &targetsiz); if (!IS_ERR(target)) { |
3a60a1686 eCryptfs: Decrypt... |
957 958 |
kfree(target); stat->size = targetsiz; |
b22e8fedc ecryptfs: fix fai... |
959 960 |
} else { rc = PTR_ERR(target); |
3a60a1686 eCryptfs: Decrypt... |
961 962 963 964 |
} } return rc; } |
a528d35e8 statx: Add a syst... |
965 966 |
static int ecryptfs_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) |
f8f484d1b eCryptfs: Add get... |
967 |
{ |
a528d35e8 statx: Add a syst... |
968 |
struct dentry *dentry = path->dentry; |
f8f484d1b eCryptfs: Add get... |
969 970 |
struct kstat lower_stat; int rc; |
a528d35e8 statx: Add a syst... |
971 972 |
rc = vfs_getattr(ecryptfs_dentry_to_lower_path(dentry), &lower_stat, request_mask, flags); |
f8f484d1b eCryptfs: Add get... |
973 |
if (!rc) { |
2b0143b5c VFS: normal files... |
974 975 976 |
fsstack_copy_attr_all(d_inode(dentry), ecryptfs_inode_to_lower(d_inode(dentry))); generic_fillattr(d_inode(dentry), stat); |
f8f484d1b eCryptfs: Add get... |
977 978 979 980 |
stat->blocks = lower_stat.blocks; } return rc; } |
dd2a3b7ad [PATCH] eCryptfs:... |
981 |
int |
3767e255b switch ->setxattr... |
982 983 |
ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, const void *value, |
237fead61 [PATCH] ecryptfs:... |
984 985 |
size_t size, int flags) { |
5d6c31910 xattr: Add __vfs_... |
986 |
int rc; |
237fead61 [PATCH] ecryptfs:... |
987 988 989 |
struct dentry *lower_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); |
5d6c31910 xattr: Add __vfs_... |
990 |
if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) { |
cfce08c6b ecryptfs: fix err... |
991 |
rc = -EOPNOTSUPP; |
237fead61 [PATCH] ecryptfs:... |
992 993 |
goto out; } |
48b512e68 ecryptfs: call vf... |
994 |
rc = vfs_setxattr(lower_dentry, name, value, size, flags); |
3767e255b switch ->setxattr... |
995 996 |
if (!rc && inode) fsstack_copy_attr_all(inode, d_inode(lower_dentry)); |
237fead61 [PATCH] ecryptfs:... |
997 998 999 |
out: return rc; } |
dd2a3b7ad [PATCH] eCryptfs:... |
1000 |
ssize_t |
ce23e6401 ->getxattr(): pas... |
1001 1002 |
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode, const char *name, void *value, size_t size) |
d7cdc5feb eCryptfs: update ... |
1003 |
{ |
5d6c31910 xattr: Add __vfs_... |
1004 |
int rc; |
d7cdc5feb eCryptfs: update ... |
1005 |
|
5d6c31910 xattr: Add __vfs_... |
1006 |
if (!(lower_inode->i_opflags & IOP_XATTR)) { |
cfce08c6b ecryptfs: fix err... |
1007 |
rc = -EOPNOTSUPP; |
d7cdc5feb eCryptfs: update ... |
1008 1009 |
goto out; } |
ce23e6401 ->getxattr(): pas... |
1010 |
inode_lock(lower_inode); |
5d6c31910 xattr: Add __vfs_... |
1011 |
rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size); |
ce23e6401 ->getxattr(): pas... |
1012 |
inode_unlock(lower_inode); |
d7cdc5feb eCryptfs: update ... |
1013 1014 1015 |
out: return rc; } |
7896b6318 fs/ecryptfs/: pos... |
1016 |
static ssize_t |
ce23e6401 ->getxattr(): pas... |
1017 1018 |
ecryptfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size) |
237fead61 [PATCH] ecryptfs:... |
1019 |
{ |
ce23e6401 ->getxattr(): pas... |
1020 1021 1022 |
return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), ecryptfs_inode_to_lower(inode), name, value, size); |
237fead61 [PATCH] ecryptfs:... |
1023 1024 1025 1026 1027 1028 1029 1030 1031 |
} static ssize_t ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) { int rc = 0; struct dentry *lower_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); |
2b0143b5c VFS: normal files... |
1032 |
if (!d_inode(lower_dentry)->i_op->listxattr) { |
cfce08c6b ecryptfs: fix err... |
1033 |
rc = -EOPNOTSUPP; |
237fead61 [PATCH] ecryptfs:... |
1034 1035 |
goto out; } |
5955102c9 wrappers for ->i_... |
1036 |
inode_lock(d_inode(lower_dentry)); |
2b0143b5c VFS: normal files... |
1037 |
rc = d_inode(lower_dentry)->i_op->listxattr(lower_dentry, list, size); |
5955102c9 wrappers for ->i_... |
1038 |
inode_unlock(d_inode(lower_dentry)); |
237fead61 [PATCH] ecryptfs:... |
1039 1040 1041 |
out: return rc; } |
4b899da50 ecryptfs: Switch ... |
1042 1043 |
static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode, const char *name) |
237fead61 [PATCH] ecryptfs:... |
1044 |
{ |
5d6c31910 xattr: Add __vfs_... |
1045 |
int rc; |
237fead61 [PATCH] ecryptfs:... |
1046 |
struct dentry *lower_dentry; |
4b899da50 ecryptfs: Switch ... |
1047 |
struct inode *lower_inode; |
237fead61 [PATCH] ecryptfs:... |
1048 1049 |
lower_dentry = ecryptfs_dentry_to_lower(dentry); |
4b899da50 ecryptfs: Switch ... |
1050 |
lower_inode = ecryptfs_inode_to_lower(inode); |
5d6c31910 xattr: Add __vfs_... |
1051 |
if (!(lower_inode->i_opflags & IOP_XATTR)) { |
cfce08c6b ecryptfs: fix err... |
1052 |
rc = -EOPNOTSUPP; |
237fead61 [PATCH] ecryptfs:... |
1053 1054 |
goto out; } |
4b899da50 ecryptfs: Switch ... |
1055 |
inode_lock(lower_inode); |
5d6c31910 xattr: Add __vfs_... |
1056 |
rc = __vfs_removexattr(lower_dentry, name); |
4b899da50 ecryptfs: Switch ... |
1057 |
inode_unlock(lower_inode); |
237fead61 [PATCH] ecryptfs:... |
1058 1059 1060 |
out: return rc; } |
754661f14 [PATCH] mark stru... |
1061 |
const struct inode_operations ecryptfs_symlink_iops = { |
6b2553918 replace ->follow_... |
1062 |
.get_link = ecryptfs_get_link, |
237fead61 [PATCH] ecryptfs:... |
1063 1064 |
.permission = ecryptfs_permission, .setattr = ecryptfs_setattr, |
3a60a1686 eCryptfs: Decrypt... |
1065 |
.getattr = ecryptfs_getattr_link, |
237fead61 [PATCH] ecryptfs:... |
1066 |
.listxattr = ecryptfs_listxattr, |
237fead61 [PATCH] ecryptfs:... |
1067 |
}; |
754661f14 [PATCH] mark stru... |
1068 |
const struct inode_operations ecryptfs_dir_iops = { |
237fead61 [PATCH] ecryptfs:... |
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 |
.create = ecryptfs_create, .lookup = ecryptfs_lookup, .link = ecryptfs_link, .unlink = ecryptfs_unlink, .symlink = ecryptfs_symlink, .mkdir = ecryptfs_mkdir, .rmdir = ecryptfs_rmdir, .mknod = ecryptfs_mknod, .rename = ecryptfs_rename, .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, |
237fead61 [PATCH] ecryptfs:... |
1080 |
.listxattr = ecryptfs_listxattr, |
237fead61 [PATCH] ecryptfs:... |
1081 |
}; |
754661f14 [PATCH] mark stru... |
1082 |
const struct inode_operations ecryptfs_main_iops = { |
237fead61 [PATCH] ecryptfs:... |
1083 1084 |
.permission = ecryptfs_permission, .setattr = ecryptfs_setattr, |
f8f484d1b eCryptfs: Add get... |
1085 |
.getattr = ecryptfs_getattr, |
237fead61 [PATCH] ecryptfs:... |
1086 |
.listxattr = ecryptfs_listxattr, |
4b899da50 ecryptfs: Switch ... |
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 |
}; static int ecryptfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size) { return ecryptfs_getxattr(dentry, inode, name, buffer, size); } static int ecryptfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) { if (value) return ecryptfs_setxattr(dentry, inode, name, value, size, flags); else { BUG_ON(flags != XATTR_REPLACE); return ecryptfs_removexattr(dentry, inode, name); } } const struct xattr_handler ecryptfs_xattr_handler = { .prefix = "", /* match anything */ .get = ecryptfs_xattr_get, .set = ecryptfs_xattr_set, }; const struct xattr_handler *ecryptfs_xattr_handlers[] = { &ecryptfs_xattr_handler, NULL |
237fead61 [PATCH] ecryptfs:... |
1118 |
}; |