Skip to content

Commit 16914e6

Browse files
author
Miklos Szeredi
committed
ovl: add ovl_read_iter()
Implement stacked reading. Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 2ef66b8 commit 16914e6

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

fs/overlayfs/file.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/cred.h>
1010
#include <linux/file.h>
1111
#include <linux/xattr.h>
12+
#include <linux/uio.h>
1213
#include "overlayfs.h"
1314

1415
static struct file *ovl_open_realfile(const struct file *file)
@@ -129,8 +130,74 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
129130
i_size_read(realinode));
130131
}
131132

133+
static void ovl_file_accessed(struct file *file)
134+
{
135+
struct inode *inode, *upperinode;
136+
137+
if (file->f_flags & O_NOATIME)
138+
return;
139+
140+
inode = file_inode(file);
141+
upperinode = ovl_inode_upper(inode);
142+
143+
if (!upperinode)
144+
return;
145+
146+
if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) ||
147+
!timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) {
148+
inode->i_mtime = upperinode->i_mtime;
149+
inode->i_ctime = upperinode->i_ctime;
150+
}
151+
152+
touch_atime(&file->f_path);
153+
}
154+
155+
static rwf_t ovl_iocb_to_rwf(struct kiocb *iocb)
156+
{
157+
int ifl = iocb->ki_flags;
158+
rwf_t flags = 0;
159+
160+
if (ifl & IOCB_NOWAIT)
161+
flags |= RWF_NOWAIT;
162+
if (ifl & IOCB_HIPRI)
163+
flags |= RWF_HIPRI;
164+
if (ifl & IOCB_DSYNC)
165+
flags |= RWF_DSYNC;
166+
if (ifl & IOCB_SYNC)
167+
flags |= RWF_SYNC;
168+
169+
return flags;
170+
}
171+
172+
static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
173+
{
174+
struct file *file = iocb->ki_filp;
175+
struct fd real;
176+
const struct cred *old_cred;
177+
ssize_t ret;
178+
179+
if (!iov_iter_count(iter))
180+
return 0;
181+
182+
ret = ovl_real_fdget(file, &real);
183+
if (ret)
184+
return ret;
185+
186+
old_cred = ovl_override_creds(file_inode(file)->i_sb);
187+
ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
188+
ovl_iocb_to_rwf(iocb));
189+
revert_creds(old_cred);
190+
191+
ovl_file_accessed(file);
192+
193+
fdput(real);
194+
195+
return ret;
196+
}
197+
132198
const struct file_operations ovl_file_operations = {
133199
.open = ovl_open,
134200
.release = ovl_release,
135201
.llseek = ovl_llseek,
202+
.read_iter = ovl_read_iter,
136203
};

0 commit comments

Comments
 (0)