Merge tag 'ovl-update-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs

Pull overlayfs updates from Miklos Szeredi:

- Add tmpfile support

- Clean up include

* tag 'ovl-update-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs:
ovl: remove duplicate included header
ovl: remove upper umask handling from ovl_create_upper()
ovl: implement tmpfile

+165 -29
+23
fs/backing-file.c
··· 52 52 } 53 53 EXPORT_SYMBOL_GPL(backing_file_open); 54 54 55 + struct file *backing_tmpfile_open(const struct path *user_path, int flags, 56 + const struct path *real_parentpath, 57 + umode_t mode, const struct cred *cred) 58 + { 59 + struct mnt_idmap *real_idmap = mnt_idmap(real_parentpath->mnt); 60 + struct file *f; 61 + int error; 62 + 63 + f = alloc_empty_backing_file(flags, cred); 64 + if (IS_ERR(f)) 65 + return f; 66 + 67 + path_get(user_path); 68 + *backing_file_user_path(f) = *user_path; 69 + error = vfs_tmpfile(real_idmap, real_parentpath, f, mode); 70 + if (error) { 71 + fput(f); 72 + f = ERR_PTR(error); 73 + } 74 + return f; 75 + } 76 + EXPORT_SYMBOL(backing_tmpfile_open); 77 + 55 78 struct backing_aio { 56 79 struct kiocb iocb; 57 80 refcount_t ref;
+3
fs/internal.h
··· 62 62 int do_symlinkat(struct filename *from, int newdfd, struct filename *to); 63 63 int do_linkat(int olddfd, struct filename *old, int newdfd, 64 64 struct filename *new, int flags); 65 + int vfs_tmpfile(struct mnt_idmap *idmap, 66 + const struct path *parentpath, 67 + struct file *file, umode_t mode); 65 68 66 69 /* 67 70 * namespace.c
+3 -3
fs/namei.c
··· 3676 3676 * On non-idmapped mounts or if permission checking is to be performed on the 3677 3677 * raw inode simply pass @nop_mnt_idmap. 3678 3678 */ 3679 - static int vfs_tmpfile(struct mnt_idmap *idmap, 3680 - const struct path *parentpath, 3681 - struct file *file, umode_t mode) 3679 + int vfs_tmpfile(struct mnt_idmap *idmap, 3680 + const struct path *parentpath, 3681 + struct file *file, umode_t mode) 3682 3682 { 3683 3683 struct dentry *child; 3684 3684 struct inode *dir = d_inode(parentpath->dentry);
+130 -22
fs/overlayfs/dir.c
··· 14 14 #include <linux/posix_acl_xattr.h> 15 15 #include <linux/atomic.h> 16 16 #include <linux/ratelimit.h> 17 + #include <linux/backing-file.h> 17 18 #include "overlayfs.h" 18 19 19 20 static unsigned short ovl_redirect_max = 256; ··· 261 260 * may not use to instantiate the new dentry. 262 261 */ 263 262 static int ovl_instantiate(struct dentry *dentry, struct inode *inode, 264 - struct dentry *newdentry, bool hardlink) 263 + struct dentry *newdentry, bool hardlink, struct file *tmpfile) 265 264 { 266 265 struct ovl_inode_params oip = { 267 266 .upperdentry = newdentry, 268 267 .newinode = inode, 269 268 }; 270 269 271 - ovl_dir_modified(dentry->d_parent, false); 272 270 ovl_dentry_set_upper_alias(dentry); 273 271 ovl_dentry_init_reval(dentry, newdentry, NULL); 274 272 ··· 294 294 dput(newdentry); 295 295 inc_nlink(inode); 296 296 } 297 + 298 + if (tmpfile) 299 + d_mark_tmpfile(tmpfile, inode); 297 300 298 301 d_instantiate(dentry, inode); 299 302 if (inode != oip.newinode) { ··· 330 327 struct dentry *newdentry; 331 328 int err; 332 329 333 - if (!attr->hardlink && !IS_POSIXACL(udir)) 334 - attr->mode &= ~current_umask(); 335 - 336 330 inode_lock_nested(udir, I_MUTEX_PARENT); 337 331 newdentry = ovl_create_real(ofs, udir, 338 332 ovl_lookup_upper(ofs, dentry->d_name.name, ··· 345 345 ovl_set_opaque(dentry, newdentry); 346 346 } 347 347 348 - err = ovl_instantiate(dentry, inode, newdentry, !!attr->hardlink); 348 + ovl_dir_modified(dentry->d_parent, false); 349 + err = ovl_instantiate(dentry, inode, newdentry, !!attr->hardlink, NULL); 349 350 if (err) 350 351 goto out_cleanup; 351 352 out_unlock: ··· 530 529 if (err) 531 530 goto out_cleanup; 532 531 } 533 - err = ovl_instantiate(dentry, inode, newdentry, hardlink); 532 + ovl_dir_modified(dentry->d_parent, false); 533 + err = ovl_instantiate(dentry, inode, newdentry, hardlink, NULL); 534 534 if (err) { 535 535 ovl_cleanup(ofs, udir, newdentry); 536 536 dput(newdentry); ··· 553 551 goto out_dput; 554 552 } 555 553 554 + static int ovl_setup_cred_for_create(struct dentry *dentry, struct inode *inode, 555 + umode_t mode, const struct cred *old_cred) 556 + { 557 + int err; 558 + struct cred *override_cred; 559 + 560 + override_cred = prepare_creds(); 561 + if (!override_cred) 562 + return -ENOMEM; 563 + 564 + override_cred->fsuid = inode->i_uid; 565 + override_cred->fsgid = inode->i_gid; 566 + err = security_dentry_create_files_as(dentry, mode, &dentry->d_name, 567 + old_cred, override_cred); 568 + if (err) { 569 + put_cred(override_cred); 570 + return err; 571 + } 572 + put_cred(override_creds(override_cred)); 573 + put_cred(override_cred); 574 + 575 + return 0; 576 + } 577 + 556 578 static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, 557 579 struct ovl_cattr *attr, bool origin) 558 580 { 559 581 int err; 560 582 const struct cred *old_cred; 561 - struct cred *override_cred; 562 583 struct dentry *parent = dentry->d_parent; 563 584 564 585 old_cred = ovl_override_creds(dentry->d_sb); ··· 597 572 } 598 573 599 574 if (!attr->hardlink) { 600 - err = -ENOMEM; 601 - override_cred = prepare_creds(); 602 - if (!override_cred) 603 - goto out_revert_creds; 604 575 /* 605 576 * In the creation cases(create, mkdir, mknod, symlink), 606 577 * ovl should transfer current's fs{u,g}id to underlying ··· 610 589 * create a new inode, so just use the ovl mounter's 611 590 * fs{u,g}id. 612 591 */ 613 - override_cred->fsuid = inode->i_uid; 614 - override_cred->fsgid = inode->i_gid; 615 - err = security_dentry_create_files_as(dentry, 616 - attr->mode, &dentry->d_name, old_cred, 617 - override_cred); 618 - if (err) { 619 - put_cred(override_cred); 592 + err = ovl_setup_cred_for_create(dentry, inode, attr->mode, old_cred); 593 + if (err) 620 594 goto out_revert_creds; 621 - } 622 - put_cred(override_creds(override_cred)); 623 - put_cred(override_cred); 624 595 } 625 596 626 597 if (!ovl_dentry_is_whiteout(dentry)) ··· 1303 1290 return err; 1304 1291 } 1305 1292 1293 + static int ovl_create_tmpfile(struct file *file, struct dentry *dentry, 1294 + struct inode *inode, umode_t mode) 1295 + { 1296 + const struct cred *old_cred; 1297 + struct path realparentpath; 1298 + struct file *realfile; 1299 + struct dentry *newdentry; 1300 + /* It's okay to set O_NOATIME, since the owner will be current fsuid */ 1301 + int flags = file->f_flags | OVL_OPEN_FLAGS; 1302 + int err; 1303 + 1304 + err = ovl_copy_up(dentry->d_parent); 1305 + if (err) 1306 + return err; 1307 + 1308 + old_cred = ovl_override_creds(dentry->d_sb); 1309 + err = ovl_setup_cred_for_create(dentry, inode, mode, old_cred); 1310 + if (err) 1311 + goto out_revert_creds; 1312 + 1313 + ovl_path_upper(dentry->d_parent, &realparentpath); 1314 + realfile = backing_tmpfile_open(&file->f_path, flags, &realparentpath, 1315 + mode, current_cred()); 1316 + err = PTR_ERR_OR_ZERO(realfile); 1317 + pr_debug("tmpfile/open(%pd2, 0%o) = %i\n", realparentpath.dentry, mode, err); 1318 + if (err) 1319 + goto out_revert_creds; 1320 + 1321 + /* ovl_instantiate() consumes the newdentry reference on success */ 1322 + newdentry = dget(realfile->f_path.dentry); 1323 + err = ovl_instantiate(dentry, inode, newdentry, false, file); 1324 + if (!err) { 1325 + file->private_data = realfile; 1326 + } else { 1327 + dput(newdentry); 1328 + fput(realfile); 1329 + } 1330 + out_revert_creds: 1331 + revert_creds(old_cred); 1332 + return err; 1333 + } 1334 + 1335 + static int ovl_dummy_open(struct inode *inode, struct file *file) 1336 + { 1337 + return 0; 1338 + } 1339 + 1340 + static int ovl_tmpfile(struct mnt_idmap *idmap, struct inode *dir, 1341 + struct file *file, umode_t mode) 1342 + { 1343 + int err; 1344 + struct dentry *dentry = file->f_path.dentry; 1345 + struct inode *inode; 1346 + 1347 + if (!OVL_FS(dentry->d_sb)->tmpfile) 1348 + return -EOPNOTSUPP; 1349 + 1350 + err = ovl_want_write(dentry); 1351 + if (err) 1352 + return err; 1353 + 1354 + err = -ENOMEM; 1355 + inode = ovl_new_inode(dentry->d_sb, mode, 0); 1356 + if (!inode) 1357 + goto drop_write; 1358 + 1359 + inode_init_owner(&nop_mnt_idmap, inode, dir, mode); 1360 + err = ovl_create_tmpfile(file, dentry, inode, inode->i_mode); 1361 + if (err) 1362 + goto put_inode; 1363 + 1364 + /* 1365 + * Check if the preallocated inode was actually used. Having something 1366 + * else assigned to the dentry shouldn't happen as that would indicate 1367 + * that the backing tmpfile "leaked" out of overlayfs. 1368 + */ 1369 + err = -EIO; 1370 + if (WARN_ON(inode != d_inode(dentry))) 1371 + goto put_realfile; 1372 + 1373 + /* inode reference was transferred to dentry */ 1374 + inode = NULL; 1375 + err = finish_open(file, dentry, ovl_dummy_open); 1376 + put_realfile: 1377 + /* Without FMODE_OPENED ->release() won't be called on @file */ 1378 + if (!(file->f_mode & FMODE_OPENED)) 1379 + fput(file->private_data); 1380 + put_inode: 1381 + iput(inode); 1382 + drop_write: 1383 + ovl_drop_write(dentry); 1384 + return err; 1385 + } 1386 + 1306 1387 const struct inode_operations ovl_dir_inode_operations = { 1307 1388 .lookup = ovl_lookup, 1308 1389 .mkdir = ovl_mkdir, ··· 1417 1310 .update_time = ovl_update_time, 1418 1311 .fileattr_get = ovl_fileattr_get, 1419 1312 .fileattr_set = ovl_fileattr_set, 1313 + .tmpfile = ovl_tmpfile, 1420 1314 };
-3
fs/overlayfs/file.c
··· 24 24 return 'm'; 25 25 } 26 26 27 - /* No atime modification on underlying */ 28 - #define OVL_OPEN_FLAGS (O_NOATIME) 29 - 30 27 static struct file *ovl_open_realfile(const struct file *file, 31 28 const struct path *realpath) 32 29 {
-1
fs/overlayfs/inode.c
··· 8 8 #include <linux/slab.h> 9 9 #include <linux/cred.h> 10 10 #include <linux/xattr.h> 11 - #include <linux/posix_acl.h> 12 11 #include <linux/ratelimit.h> 13 12 #include <linux/fiemap.h> 14 13 #include <linux/fileattr.h>
+3
fs/overlayfs/overlayfs.h
··· 175 175 return (int)metacopy->len - OVL_METACOPY_MIN_SIZE; 176 176 } 177 177 178 + /* No atime modification on underlying */ 179 + #define OVL_OPEN_FLAGS (O_NOATIME) 180 + 178 181 extern const char *const ovl_xattr_table[][2]; 179 182 static inline const char *ovl_xattr(struct ovl_fs *ofs, enum ovl_xattr ox) 180 183 {
+3
include/linux/backing-file.h
··· 22 22 struct file *backing_file_open(const struct path *user_path, int flags, 23 23 const struct path *real_path, 24 24 const struct cred *cred); 25 + struct file *backing_tmpfile_open(const struct path *user_path, int flags, 26 + const struct path *real_parentpath, 27 + umode_t mode, const struct cred *cred); 25 28 ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter, 26 29 struct kiocb *iocb, int flags, 27 30 struct backing_file_ctx *ctx);