diff options
Diffstat (limited to 'fs/ecryptfs/file.c')
-rw-r--r-- | fs/ecryptfs/file.c | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index a7abbea2c096..992cf95830b5 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -49,7 +49,7 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb, | |||
49 | unsigned long nr_segs, loff_t pos) | 49 | unsigned long nr_segs, loff_t pos) |
50 | { | 50 | { |
51 | ssize_t rc; | 51 | ssize_t rc; |
52 | struct path lower; | 52 | struct path *path; |
53 | struct file *file = iocb->ki_filp; | 53 | struct file *file = iocb->ki_filp; |
54 | 54 | ||
55 | rc = generic_file_aio_read(iocb, iov, nr_segs, pos); | 55 | rc = generic_file_aio_read(iocb, iov, nr_segs, pos); |
@@ -60,17 +60,16 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb, | |||
60 | if (-EIOCBQUEUED == rc) | 60 | if (-EIOCBQUEUED == rc) |
61 | rc = wait_on_sync_kiocb(iocb); | 61 | rc = wait_on_sync_kiocb(iocb); |
62 | if (rc >= 0) { | 62 | if (rc >= 0) { |
63 | lower.dentry = ecryptfs_dentry_to_lower(file->f_path.dentry); | 63 | path = ecryptfs_dentry_to_lower_path(file->f_path.dentry); |
64 | lower.mnt = ecryptfs_dentry_to_lower_mnt(file->f_path.dentry); | 64 | touch_atime(path); |
65 | touch_atime(&lower); | ||
66 | } | 65 | } |
67 | return rc; | 66 | return rc; |
68 | } | 67 | } |
69 | 68 | ||
70 | struct ecryptfs_getdents_callback { | 69 | struct ecryptfs_getdents_callback { |
71 | void *dirent; | 70 | struct dir_context ctx; |
72 | struct dentry *dentry; | 71 | struct dir_context *caller; |
73 | filldir_t filldir; | 72 | struct super_block *sb; |
74 | int filldir_called; | 73 | int filldir_called; |
75 | int entries_written; | 74 | int entries_written; |
76 | }; | 75 | }; |
@@ -88,7 +87,7 @@ ecryptfs_filldir(void *dirent, const char *lower_name, int lower_namelen, | |||
88 | 87 | ||
89 | buf->filldir_called++; | 88 | buf->filldir_called++; |
90 | rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size, | 89 | rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size, |
91 | buf->dentry, lower_name, | 90 | buf->sb, lower_name, |
92 | lower_namelen); | 91 | lower_namelen); |
93 | if (rc) { | 92 | if (rc) { |
94 | printk(KERN_ERR "%s: Error attempting to decode and decrypt " | 93 | printk(KERN_ERR "%s: Error attempting to decode and decrypt " |
@@ -96,9 +95,10 @@ ecryptfs_filldir(void *dirent, const char *lower_name, int lower_namelen, | |||
96 | rc); | 95 | rc); |
97 | goto out; | 96 | goto out; |
98 | } | 97 | } |
99 | rc = buf->filldir(buf->dirent, name, name_size, offset, ino, d_type); | 98 | buf->caller->pos = buf->ctx.pos; |
99 | rc = !dir_emit(buf->caller, name, name_size, ino, d_type); | ||
100 | kfree(name); | 100 | kfree(name); |
101 | if (rc >= 0) | 101 | if (!rc) |
102 | buf->entries_written++; | 102 | buf->entries_written++; |
103 | out: | 103 | out: |
104 | return rc; | 104 | return rc; |
@@ -107,27 +107,22 @@ out: | |||
107 | /** | 107 | /** |
108 | * ecryptfs_readdir | 108 | * ecryptfs_readdir |
109 | * @file: The eCryptfs directory file | 109 | * @file: The eCryptfs directory file |
110 | * @dirent: Directory entry handle | 110 | * @ctx: The actor to feed the entries to |
111 | * @filldir: The filldir callback function | ||
112 | */ | 111 | */ |
113 | static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) | 112 | static int ecryptfs_readdir(struct file *file, struct dir_context *ctx) |
114 | { | 113 | { |
115 | int rc; | 114 | int rc; |
116 | struct file *lower_file; | 115 | struct file *lower_file; |
117 | struct inode *inode; | 116 | struct inode *inode = file_inode(file); |
118 | struct ecryptfs_getdents_callback buf; | 117 | struct ecryptfs_getdents_callback buf = { |
119 | 118 | .ctx.actor = ecryptfs_filldir, | |
119 | .caller = ctx, | ||
120 | .sb = inode->i_sb, | ||
121 | }; | ||
120 | lower_file = ecryptfs_file_to_lower(file); | 122 | lower_file = ecryptfs_file_to_lower(file); |
121 | lower_file->f_pos = file->f_pos; | 123 | lower_file->f_pos = ctx->pos; |
122 | inode = file_inode(file); | 124 | rc = iterate_dir(lower_file, &buf.ctx); |
123 | memset(&buf, 0, sizeof(buf)); | 125 | ctx->pos = buf.ctx.pos; |
124 | buf.dirent = dirent; | ||
125 | buf.dentry = file->f_path.dentry; | ||
126 | buf.filldir = filldir; | ||
127 | buf.filldir_called = 0; | ||
128 | buf.entries_written = 0; | ||
129 | rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf); | ||
130 | file->f_pos = lower_file->f_pos; | ||
131 | if (rc < 0) | 126 | if (rc < 0) |
132 | goto out; | 127 | goto out; |
133 | if (buf.filldir_called && !buf.entries_written) | 128 | if (buf.filldir_called && !buf.entries_written) |
@@ -344,7 +339,7 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
344 | #endif | 339 | #endif |
345 | 340 | ||
346 | const struct file_operations ecryptfs_dir_fops = { | 341 | const struct file_operations ecryptfs_dir_fops = { |
347 | .readdir = ecryptfs_readdir, | 342 | .iterate = ecryptfs_readdir, |
348 | .read = generic_read_dir, | 343 | .read = generic_read_dir, |
349 | .unlocked_ioctl = ecryptfs_unlocked_ioctl, | 344 | .unlocked_ioctl = ecryptfs_unlocked_ioctl, |
350 | #ifdef CONFIG_COMPAT | 345 | #ifdef CONFIG_COMPAT |
@@ -365,7 +360,7 @@ const struct file_operations ecryptfs_main_fops = { | |||
365 | .aio_read = ecryptfs_read_update_atime, | 360 | .aio_read = ecryptfs_read_update_atime, |
366 | .write = do_sync_write, | 361 | .write = do_sync_write, |
367 | .aio_write = generic_file_aio_write, | 362 | .aio_write = generic_file_aio_write, |
368 | .readdir = ecryptfs_readdir, | 363 | .iterate = ecryptfs_readdir, |
369 | .unlocked_ioctl = ecryptfs_unlocked_ioctl, | 364 | .unlocked_ioctl = ecryptfs_unlocked_ioctl, |
370 | #ifdef CONFIG_COMPAT | 365 | #ifdef CONFIG_COMPAT |
371 | .compat_ioctl = ecryptfs_compat_ioctl, | 366 | .compat_ioctl = ecryptfs_compat_ioctl, |