Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

backing-file: clean up the API

- Pass iocb to ctx->end_write() instead of file + pos

- Get rid of ctx->user_file, which is redundant most of the time

- Instead pass iocb to backing_file_splice_read and
backing_file_splice_write

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>

authored by

Miklos Szeredi and committed by
Amir Goldstein
48b50624 3b6b99ef

+53 -47
+17 -18
fs/backing-file.c
··· 80 80 refcount_t ref; 81 81 struct kiocb *orig_iocb; 82 82 /* used for aio completion */ 83 - void (*end_write)(struct file *, loff_t, ssize_t); 83 + void (*end_write)(struct kiocb *iocb, ssize_t); 84 84 struct work_struct work; 85 85 long res; 86 86 }; ··· 108 108 struct kiocb *iocb = &aio->iocb; 109 109 struct kiocb *orig_iocb = aio->orig_iocb; 110 110 111 - if (aio->end_write) 112 - aio->end_write(orig_iocb->ki_filp, iocb->ki_pos, res); 113 - 114 111 orig_iocb->ki_pos = iocb->ki_pos; 112 + if (aio->end_write) 113 + aio->end_write(orig_iocb, res); 114 + 115 115 backing_aio_put(aio); 116 116 } 117 117 ··· 200 200 revert_creds(old_cred); 201 201 202 202 if (ctx->accessed) 203 - ctx->accessed(ctx->user_file); 203 + ctx->accessed(iocb->ki_filp); 204 204 205 205 return ret; 206 206 } ··· 219 219 if (!iov_iter_count(iter)) 220 220 return 0; 221 221 222 - ret = file_remove_privs(ctx->user_file); 222 + ret = file_remove_privs(iocb->ki_filp); 223 223 if (ret) 224 224 return ret; 225 225 ··· 239 239 240 240 ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf); 241 241 if (ctx->end_write) 242 - ctx->end_write(ctx->user_file, iocb->ki_pos, ret); 242 + ctx->end_write(iocb, ret); 243 243 } else { 244 244 struct backing_aio *aio; 245 245 ··· 270 270 } 271 271 EXPORT_SYMBOL_GPL(backing_file_write_iter); 272 272 273 - ssize_t backing_file_splice_read(struct file *in, loff_t *ppos, 273 + ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb, 274 274 struct pipe_inode_info *pipe, size_t len, 275 275 unsigned int flags, 276 276 struct backing_file_ctx *ctx) ··· 282 282 return -EIO; 283 283 284 284 old_cred = override_creds(ctx->cred); 285 - ret = vfs_splice_read(in, ppos, pipe, len, flags); 285 + ret = vfs_splice_read(in, &iocb->ki_pos, pipe, len, flags); 286 286 revert_creds(old_cred); 287 287 288 288 if (ctx->accessed) 289 - ctx->accessed(ctx->user_file); 289 + ctx->accessed(iocb->ki_filp); 290 290 291 291 return ret; 292 292 } 293 293 EXPORT_SYMBOL_GPL(backing_file_splice_read); 294 294 295 295 ssize_t backing_file_splice_write(struct pipe_inode_info *pipe, 296 - struct file *out, loff_t *ppos, size_t len, 297 - unsigned int flags, 296 + struct file *out, struct kiocb *iocb, 297 + size_t len, unsigned int flags, 298 298 struct backing_file_ctx *ctx) 299 299 { 300 300 const struct cred *old_cred; ··· 306 306 if (!out->f_op->splice_write) 307 307 return -EINVAL; 308 308 309 - ret = file_remove_privs(ctx->user_file); 309 + ret = file_remove_privs(iocb->ki_filp); 310 310 if (ret) 311 311 return ret; 312 312 313 313 old_cred = override_creds(ctx->cred); 314 314 file_start_write(out); 315 - ret = out->f_op->splice_write(pipe, out, ppos, len, flags); 315 + ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags); 316 316 file_end_write(out); 317 317 revert_creds(old_cred); 318 318 319 319 if (ctx->end_write) 320 - ctx->end_write(ctx->user_file, ppos ? *ppos : 0, ret); 320 + ctx->end_write(iocb, ret); 321 321 322 322 return ret; 323 323 } ··· 329 329 const struct cred *old_cred; 330 330 int ret; 331 331 332 - if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)) || 333 - WARN_ON_ONCE(ctx->user_file != vma->vm_file)) 332 + if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING))) 334 333 return -EIO; 335 334 336 335 if (!file->f_op->mmap) ··· 342 343 revert_creds(old_cred); 343 344 344 345 if (ctx->accessed) 345 - ctx->accessed(ctx->user_file); 346 + ctx->accessed(vma->vm_file); 346 347 347 348 return ret; 348 349 }
+18 -14
fs/fuse/passthrough.c
··· 18 18 fuse_invalidate_atime(inode); 19 19 } 20 20 21 - static void fuse_passthrough_end_write(struct file *file, loff_t pos, ssize_t ret) 21 + static void fuse_passthrough_end_write(struct kiocb *iocb, ssize_t ret) 22 22 { 23 - struct inode *inode = file_inode(file); 23 + struct inode *inode = file_inode(iocb->ki_filp); 24 24 25 - fuse_write_update_attr(inode, pos, ret); 25 + fuse_write_update_attr(inode, iocb->ki_pos, ret); 26 26 } 27 27 28 28 ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter) ··· 34 34 ssize_t ret; 35 35 struct backing_file_ctx ctx = { 36 36 .cred = ff->cred, 37 - .user_file = file, 38 37 .accessed = fuse_file_accessed, 39 38 }; 40 39 ··· 61 62 ssize_t ret; 62 63 struct backing_file_ctx ctx = { 63 64 .cred = ff->cred, 64 - .user_file = file, 65 65 .end_write = fuse_passthrough_end_write, 66 66 }; 67 67 ··· 86 88 struct file *backing_file = fuse_file_passthrough(ff); 87 89 struct backing_file_ctx ctx = { 88 90 .cred = ff->cred, 89 - .user_file = in, 90 91 .accessed = fuse_file_accessed, 91 92 }; 93 + struct kiocb iocb; 94 + ssize_t ret; 92 95 93 96 pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu, flags=0x%x\n", __func__, 94 - backing_file, ppos ? *ppos : 0, len, flags); 97 + backing_file, *ppos, len, flags); 95 98 96 - return backing_file_splice_read(backing_file, ppos, pipe, len, flags, 97 - &ctx); 99 + init_sync_kiocb(&iocb, in); 100 + iocb.ki_pos = *ppos; 101 + ret = backing_file_splice_read(backing_file, &iocb, pipe, len, flags, &ctx); 102 + *ppos = iocb.ki_pos; 103 + 104 + return ret; 98 105 } 99 106 100 107 ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe, ··· 112 109 ssize_t ret; 113 110 struct backing_file_ctx ctx = { 114 111 .cred = ff->cred, 115 - .user_file = out, 116 112 .end_write = fuse_passthrough_end_write, 117 113 }; 114 + struct kiocb iocb; 118 115 119 116 pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu, flags=0x%x\n", __func__, 120 - backing_file, ppos ? *ppos : 0, len, flags); 117 + backing_file, *ppos, len, flags); 121 118 122 119 inode_lock(inode); 123 - ret = backing_file_splice_write(pipe, backing_file, ppos, len, flags, 124 - &ctx); 120 + init_sync_kiocb(&iocb, out); 121 + iocb.ki_pos = *ppos; 122 + ret = backing_file_splice_write(pipe, backing_file, &iocb, len, flags, &ctx); 123 + *ppos = iocb.ki_pos; 125 124 inode_unlock(inode); 126 125 127 126 return ret; ··· 135 130 struct file *backing_file = fuse_file_passthrough(ff); 136 131 struct backing_file_ctx ctx = { 137 132 .cred = ff->cred, 138 - .user_file = file, 139 133 .accessed = fuse_file_accessed, 140 134 }; 141 135
+13 -9
fs/overlayfs/file.c
··· 231 231 ovl_copyattr(file_inode(file)); 232 232 } 233 233 234 - static void ovl_file_end_write(struct file *file, loff_t pos, ssize_t ret) 234 + static void ovl_file_end_write(struct kiocb *iocb, ssize_t ret) 235 235 { 236 - ovl_file_modified(file); 236 + ovl_file_modified(iocb->ki_filp); 237 237 } 238 238 239 239 static void ovl_file_accessed(struct file *file) ··· 271 271 ssize_t ret; 272 272 struct backing_file_ctx ctx = { 273 273 .cred = ovl_creds(file_inode(file)->i_sb), 274 - .user_file = file, 275 274 .accessed = ovl_file_accessed, 276 275 }; 277 276 ··· 297 298 int ifl = iocb->ki_flags; 298 299 struct backing_file_ctx ctx = { 299 300 .cred = ovl_creds(inode->i_sb), 300 - .user_file = file, 301 301 .end_write = ovl_file_end_write, 302 302 }; 303 303 ··· 336 338 ssize_t ret; 337 339 struct backing_file_ctx ctx = { 338 340 .cred = ovl_creds(file_inode(in)->i_sb), 339 - .user_file = in, 340 341 .accessed = ovl_file_accessed, 341 342 }; 343 + struct kiocb iocb; 342 344 343 345 ret = ovl_real_fdget(in, &real); 344 346 if (ret) 345 347 return ret; 346 348 347 - ret = backing_file_splice_read(fd_file(real), ppos, pipe, len, flags, &ctx); 349 + init_sync_kiocb(&iocb, in); 350 + iocb.ki_pos = *ppos; 351 + ret = backing_file_splice_read(fd_file(real), &iocb, pipe, len, flags, &ctx); 352 + *ppos = iocb.ki_pos; 348 353 fdput(real); 349 354 350 355 return ret; ··· 369 368 ssize_t ret; 370 369 struct backing_file_ctx ctx = { 371 370 .cred = ovl_creds(inode->i_sb), 372 - .user_file = out, 373 371 .end_write = ovl_file_end_write, 374 372 }; 373 + struct kiocb iocb; 375 374 376 375 inode_lock(inode); 377 376 /* Update mode */ ··· 381 380 if (ret) 382 381 goto out_unlock; 383 382 384 - ret = backing_file_splice_write(pipe, fd_file(real), ppos, len, flags, &ctx); 383 + init_sync_kiocb(&iocb, out); 384 + iocb.ki_pos = *ppos; 385 + ret = backing_file_splice_write(pipe, fd_file(real), &iocb, len, flags, &ctx); 386 + *ppos = iocb.ki_pos; 385 387 fdput(real); 388 + 386 389 387 390 out_unlock: 388 391 inode_unlock(inode); ··· 425 420 struct file *realfile = file->private_data; 426 421 struct backing_file_ctx ctx = { 427 422 .cred = ovl_creds(file_inode(file)->i_sb), 428 - .user_file = file, 429 423 .accessed = ovl_file_accessed, 430 424 }; 431 425
+5 -6
include/linux/backing-file.h
··· 14 14 15 15 struct backing_file_ctx { 16 16 const struct cred *cred; 17 - struct file *user_file; 18 - void (*accessed)(struct file *); 19 - void (*end_write)(struct file *, loff_t, ssize_t); 17 + void (*accessed)(struct file *file); 18 + void (*end_write)(struct kiocb *iocb, ssize_t); 20 19 }; 21 20 22 21 struct file *backing_file_open(const struct path *user_path, int flags, ··· 30 31 ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter, 31 32 struct kiocb *iocb, int flags, 32 33 struct backing_file_ctx *ctx); 33 - ssize_t backing_file_splice_read(struct file *in, loff_t *ppos, 34 + ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb, 34 35 struct pipe_inode_info *pipe, size_t len, 35 36 unsigned int flags, 36 37 struct backing_file_ctx *ctx); 37 38 ssize_t backing_file_splice_write(struct pipe_inode_info *pipe, 38 - struct file *out, loff_t *ppos, size_t len, 39 - unsigned int flags, 39 + struct file *out, struct kiocb *iocb, 40 + size_t len, unsigned int flags, 40 41 struct backing_file_ctx *ctx); 41 42 int backing_file_mmap(struct file *file, struct vm_area_struct *vma, 42 43 struct backing_file_ctx *ctx);