Skip to content

Commit 9b7e9e2

Browse files
committed
fs: factor out backing_file_splice_{read,write}() helpers
There is not much in those helpers, but it makes sense to have them logically next to the backing_file_{read,write}_iter() helpers as they may grow more common logic in the future. Signed-off-by: Amir Goldstein <amir73il@gmail.com>
1 parent a6293b3 commit 9b7e9e2

3 files changed

Lines changed: 72 additions & 20 deletions

File tree

fs/backing-file.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/fs.h>
1212
#include <linux/backing-file.h>
13+
#include <linux/splice.h>
1314

1415
#include "internal.h"
1516

@@ -245,6 +246,56 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
245246
}
246247
EXPORT_SYMBOL_GPL(backing_file_write_iter);
247248

249+
ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
250+
struct pipe_inode_info *pipe, size_t len,
251+
unsigned int flags,
252+
struct backing_file_ctx *ctx)
253+
{
254+
const struct cred *old_cred;
255+
ssize_t ret;
256+
257+
if (WARN_ON_ONCE(!(in->f_mode & FMODE_BACKING)))
258+
return -EIO;
259+
260+
old_cred = override_creds(ctx->cred);
261+
ret = vfs_splice_read(in, ppos, pipe, len, flags);
262+
revert_creds(old_cred);
263+
264+
if (ctx->accessed)
265+
ctx->accessed(ctx->user_file);
266+
267+
return ret;
268+
}
269+
EXPORT_SYMBOL_GPL(backing_file_splice_read);
270+
271+
ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
272+
struct file *out, loff_t *ppos, size_t len,
273+
unsigned int flags,
274+
struct backing_file_ctx *ctx)
275+
{
276+
const struct cred *old_cred;
277+
ssize_t ret;
278+
279+
if (WARN_ON_ONCE(!(out->f_mode & FMODE_BACKING)))
280+
return -EIO;
281+
282+
ret = file_remove_privs(ctx->user_file);
283+
if (ret)
284+
return ret;
285+
286+
old_cred = override_creds(ctx->cred);
287+
file_start_write(out);
288+
ret = iter_file_splice_write(pipe, out, ppos, len, flags);
289+
file_end_write(out);
290+
revert_creds(old_cred);
291+
292+
if (ctx->end_write)
293+
ctx->end_write(ctx->user_file);
294+
295+
return ret;
296+
}
297+
EXPORT_SYMBOL_GPL(backing_file_splice_write);
298+
248299
static int __init backing_aio_init(void)
249300
{
250301
backing_aio_cachep = kmem_cache_create("backing_aio",

fs/overlayfs/file.c

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <linux/xattr.h>
1010
#include <linux/uio.h>
1111
#include <linux/uaccess.h>
12-
#include <linux/splice.h>
1312
#include <linux/security.h>
1413
#include <linux/mm.h>
1514
#include <linux/fs.h>
@@ -332,20 +331,21 @@ static ssize_t ovl_splice_read(struct file *in, loff_t *ppos,
332331
struct pipe_inode_info *pipe, size_t len,
333332
unsigned int flags)
334333
{
335-
const struct cred *old_cred;
336334
struct fd real;
337335
ssize_t ret;
336+
struct backing_file_ctx ctx = {
337+
.cred = ovl_creds(file_inode(in)->i_sb),
338+
.user_file = in,
339+
.accessed = ovl_file_accessed,
340+
};
338341

339342
ret = ovl_real_fdget(in, &real);
340343
if (ret)
341344
return ret;
342345

343-
old_cred = ovl_override_creds(file_inode(in)->i_sb);
344-
ret = vfs_splice_read(real.file, ppos, pipe, len, flags);
345-
revert_creds(old_cred);
346-
ovl_file_accessed(in);
347-
346+
ret = backing_file_splice_read(real.file, ppos, pipe, len, flags, &ctx);
348347
fdput(real);
348+
349349
return ret;
350350
}
351351

@@ -361,30 +361,23 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
361361
loff_t *ppos, size_t len, unsigned int flags)
362362
{
363363
struct fd real;
364-
const struct cred *old_cred;
365364
struct inode *inode = file_inode(out);
366365
ssize_t ret;
366+
struct backing_file_ctx ctx = {
367+
.cred = ovl_creds(inode->i_sb),
368+
.user_file = out,
369+
.end_write = ovl_file_modified,
370+
};
367371

368372
inode_lock(inode);
369373
/* Update mode */
370374
ovl_copyattr(inode);
371-
ret = file_remove_privs(out);
372-
if (ret)
373-
goto out_unlock;
374375

375376
ret = ovl_real_fdget(out, &real);
376377
if (ret)
377378
goto out_unlock;
378379

379-
old_cred = ovl_override_creds(inode->i_sb);
380-
file_start_write(real.file);
381-
382-
ret = iter_file_splice_write(pipe, real.file, ppos, len, flags);
383-
384-
file_end_write(real.file);
385-
/* Update size */
386-
ovl_file_modified(out);
387-
revert_creds(old_cred);
380+
ret = backing_file_splice_write(pipe, real.file, ppos, len, flags, &ctx);
388381
fdput(real);
389382

390383
out_unlock:

include/linux/backing-file.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,13 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
2828
ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
2929
struct kiocb *iocb, int flags,
3030
struct backing_file_ctx *ctx);
31+
ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
32+
struct pipe_inode_info *pipe, size_t len,
33+
unsigned int flags,
34+
struct backing_file_ctx *ctx);
35+
ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
36+
struct file *out, loff_t *ppos, size_t len,
37+
unsigned int flags,
38+
struct backing_file_ctx *ctx);
3139

3240
#endif /* _LINUX_BACKING_FILE_H */

0 commit comments

Comments
 (0)