Skip to content

Commit f721d24

Browse files
committed
Merge tag 'pull-tmpfile' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs tmpfile updates from Al Viro: "Miklos' ->tmpfile() signature change; pass an unopened struct file to it, let it open the damn thing. Allows to add tmpfile support to FUSE" * tag 'pull-tmpfile' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fuse: implement ->tmpfile() vfs: open inside ->tmpfile() vfs: move open right after ->tmpfile() vfs: make vfs_tmpfile() static ovl: use vfs_tmpfile_open() helper cachefiles: use vfs_tmpfile_open() helper cachefiles: only pass inode to *mark_inode_inuse() helpers cachefiles: tmpfile error handling cleanup hugetlbfs: cleanup mknod and tmpfile vfs: add vfs_tmpfile_open() helper
2 parents 27bc50f + 7d37539 commit f721d24

File tree

26 files changed

+301
-238
lines changed

26 files changed

+301
-238
lines changed

Documentation/filesystems/locking.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ prototypes::
7979
int (*atomic_open)(struct inode *, struct dentry *,
8080
struct file *, unsigned open_flag,
8181
umode_t create_mode);
82-
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
82+
int (*tmpfile) (struct user_namespace *, struct inode *,
83+
struct file *, umode_t);
8384
int (*fileattr_set)(struct user_namespace *mnt_userns,
8485
struct dentry *dentry, struct fileattr *fa);
8586
int (*fileattr_get)(struct dentry *dentry, struct fileattr *fa);

Documentation/filesystems/porting.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,3 +933,13 @@ to) and true - "keep going" (as 0 in old calling conventions). Rationale:
933933
callers never looked at specific -E... values anyway. ->iterate() and
934934
->iterate_shared() instance require no changes at all, all filldir_t ones in
935935
the tree converted.
936+
937+
---
938+
939+
**mandatory**
940+
941+
Calling conventions for ->tmpfile() have changed. It now takes a struct
942+
file pointer instead of struct dentry pointer. d_tmpfile() is similarly
943+
changed to simplify callers. The passed file is in a non-open state and on
944+
success must be opened before returning (e.g. by calling
945+
finish_open_simple()).

Documentation/filesystems/vfs.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ As of kernel 2.6.22, the following members are defined:
442442
void (*update_time)(struct inode *, struct timespec *, int);
443443
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
444444
unsigned open_flag, umode_t create_mode);
445-
int (*tmpfile) (struct user_namespace *, struct inode *, struct dentry *, umode_t);
445+
int (*tmpfile) (struct user_namespace *, struct inode *, struct file *, umode_t);
446446
int (*set_acl)(struct user_namespace *, struct inode *, struct posix_acl *, int);
447447
int (*fileattr_set)(struct user_namespace *mnt_userns,
448448
struct dentry *dentry, struct fileattr *fa);
@@ -592,7 +592,9 @@ otherwise noted.
592592
``tmpfile``
593593
called in the end of O_TMPFILE open(). Optional, equivalent to
594594
atomically creating, opening and unlinking a file in given
595-
directory.
595+
directory. On success needs to return with the file already
596+
open; this can be done by calling finish_open_simple() right at
597+
the end.
596598

597599
``fileattr_get``
598600
called on ioctl(FS_IOC_GETFLAGS) and ioctl(FS_IOC_FSGETXATTR) to

fs/bad_inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry,
147147
}
148148

149149
static int bad_inode_tmpfile(struct user_namespace *mnt_userns,
150-
struct inode *inode, struct dentry *dentry,
150+
struct inode *inode, struct file *file,
151151
umode_t mode)
152152
{
153153
return -EIO;

fs/btrfs/inode.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10018,15 +10018,15 @@ static int btrfs_permission(struct user_namespace *mnt_userns,
1001810018
}
1001910019

1002010020
static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
10021-
struct dentry *dentry, umode_t mode)
10021+
struct file *file, umode_t mode)
1002210022
{
1002310023
struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
1002410024
struct btrfs_trans_handle *trans;
1002510025
struct btrfs_root *root = BTRFS_I(dir)->root;
1002610026
struct inode *inode;
1002710027
struct btrfs_new_inode_args new_inode_args = {
1002810028
.dir = dir,
10029-
.dentry = dentry,
10029+
.dentry = file->f_path.dentry,
1003010030
.orphan = true,
1003110031
};
1003210032
unsigned int trans_num_items;
@@ -10063,7 +10063,7 @@ static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
1006310063
set_nlink(inode, 1);
1006410064

1006510065
if (!ret) {
10066-
d_tmpfile(dentry, inode);
10066+
d_tmpfile(file, inode);
1006710067
unlock_new_inode(inode);
1006810068
mark_inode_dirty(inode);
1006910069
}
@@ -10075,7 +10075,7 @@ static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
1007510075
out_inode:
1007610076
if (ret)
1007710077
iput(inode);
10078-
return ret;
10078+
return finish_open_simple(file, ret);
1007910079
}
1008010080

1008110081
void btrfs_set_range_writeback(struct btrfs_inode *inode, u64 start, u64 end)

fs/cachefiles/namei.c

Lines changed: 52 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515
* file or directory. The caller must hold the inode lock.
1616
*/
1717
static bool __cachefiles_mark_inode_in_use(struct cachefiles_object *object,
18-
struct dentry *dentry)
18+
struct inode *inode)
1919
{
20-
struct inode *inode = d_backing_inode(dentry);
2120
bool can_use = false;
2221

2322
if (!(inode->i_flags & S_KERNEL_FILE)) {
@@ -26,21 +25,18 @@ static bool __cachefiles_mark_inode_in_use(struct cachefiles_object *object,
2625
can_use = true;
2726
} else {
2827
trace_cachefiles_mark_failed(object, inode);
29-
pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n",
30-
dentry, inode->i_ino);
3128
}
3229

3330
return can_use;
3431
}
3532

3633
static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object,
37-
struct dentry *dentry)
34+
struct inode *inode)
3835
{
39-
struct inode *inode = d_backing_inode(dentry);
4036
bool can_use;
4137

4238
inode_lock(inode);
43-
can_use = __cachefiles_mark_inode_in_use(object, dentry);
39+
can_use = __cachefiles_mark_inode_in_use(object, inode);
4440
inode_unlock(inode);
4541
return can_use;
4642
}
@@ -49,21 +45,17 @@ static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object,
4945
* Unmark a backing inode. The caller must hold the inode lock.
5046
*/
5147
static void __cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
52-
struct dentry *dentry)
48+
struct inode *inode)
5349
{
54-
struct inode *inode = d_backing_inode(dentry);
55-
5650
inode->i_flags &= ~S_KERNEL_FILE;
5751
trace_cachefiles_mark_inactive(object, inode);
5852
}
5953

6054
static void cachefiles_do_unmark_inode_in_use(struct cachefiles_object *object,
61-
struct dentry *dentry)
55+
struct inode *inode)
6256
{
63-
struct inode *inode = d_backing_inode(dentry);
64-
6557
inode_lock(inode);
66-
__cachefiles_unmark_inode_in_use(object, dentry);
58+
__cachefiles_unmark_inode_in_use(object, inode);
6759
inode_unlock(inode);
6860
}
6961

@@ -77,14 +69,12 @@ void cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
7769
struct cachefiles_cache *cache = object->volume->cache;
7870
struct inode *inode = file_inode(file);
7971

80-
if (inode) {
81-
cachefiles_do_unmark_inode_in_use(object, file->f_path.dentry);
72+
cachefiles_do_unmark_inode_in_use(object, inode);
8273

83-
if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
84-
atomic_long_add(inode->i_blocks, &cache->b_released);
85-
if (atomic_inc_return(&cache->f_released))
86-
cachefiles_state_changed(cache);
87-
}
74+
if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
75+
atomic_long_add(inode->i_blocks, &cache->b_released);
76+
if (atomic_inc_return(&cache->f_released))
77+
cachefiles_state_changed(cache);
8878
}
8979
}
9080

@@ -164,8 +154,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
164154
inode_lock(d_inode(subdir));
165155
inode_unlock(d_inode(dir));
166156

167-
if (!__cachefiles_mark_inode_in_use(NULL, subdir))
157+
if (!__cachefiles_mark_inode_in_use(NULL, d_inode(subdir))) {
158+
pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n",
159+
subdir, d_inode(subdir)->i_ino);
168160
goto mark_error;
161+
}
169162

170163
inode_unlock(d_inode(subdir));
171164

@@ -224,9 +217,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
224217
void cachefiles_put_directory(struct dentry *dir)
225218
{
226219
if (dir) {
227-
inode_lock(dir->d_inode);
228-
__cachefiles_unmark_inode_in_use(NULL, dir);
229-
inode_unlock(dir->d_inode);
220+
cachefiles_do_unmark_inode_in_use(NULL, d_inode(dir));
230221
dput(dir);
231222
}
232223
}
@@ -410,7 +401,7 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
410401
"Rename failed with error %d", ret);
411402
}
412403

413-
__cachefiles_unmark_inode_in_use(object, rep);
404+
__cachefiles_unmark_inode_in_use(object, d_inode(rep));
414405
unlock_rename(cache->graveyard, dir);
415406
dput(grave);
416407
_leave(" = 0");
@@ -451,84 +442,72 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object)
451442
const struct cred *saved_cred;
452443
struct dentry *fan = volume->fanout[(u8)object->cookie->key_hash];
453444
struct file *file;
454-
struct path path;
445+
const struct path parentpath = { .mnt = cache->mnt, .dentry = fan };
455446
uint64_t ni_size;
456447
long ret;
457448

458449

459450
cachefiles_begin_secure(cache, &saved_cred);
460451

461-
path.mnt = cache->mnt;
462452
ret = cachefiles_inject_write_error();
463-
if (ret == 0)
464-
path.dentry = vfs_tmpfile(&init_user_ns, fan, S_IFREG, O_RDWR);
465-
else
466-
path.dentry = ERR_PTR(ret);
467-
if (IS_ERR(path.dentry)) {
468-
trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(path.dentry),
453+
if (ret == 0) {
454+
file = vfs_tmpfile_open(&init_user_ns, &parentpath, S_IFREG,
455+
O_RDWR | O_LARGEFILE | O_DIRECT,
456+
cache->cache_cred);
457+
ret = PTR_ERR_OR_ZERO(file);
458+
}
459+
if (ret) {
460+
trace_cachefiles_vfs_error(object, d_inode(fan), ret,
469461
cachefiles_trace_tmpfile_error);
470-
if (PTR_ERR(path.dentry) == -EIO)
462+
if (ret == -EIO)
471463
cachefiles_io_error_obj(object, "Failed to create tmpfile");
472-
file = ERR_CAST(path.dentry);
473-
goto out;
464+
goto err;
474465
}
475466

476-
trace_cachefiles_tmpfile(object, d_backing_inode(path.dentry));
467+
trace_cachefiles_tmpfile(object, file_inode(file));
477468

478-
if (!cachefiles_mark_inode_in_use(object, path.dentry)) {
479-
file = ERR_PTR(-EBUSY);
480-
goto out_dput;
481-
}
469+
/* This is a newly created file with no other possible user */
470+
if (!cachefiles_mark_inode_in_use(object, file_inode(file)))
471+
WARN_ON(1);
482472

483473
ret = cachefiles_ondemand_init_object(object);
484-
if (ret < 0) {
485-
file = ERR_PTR(ret);
486-
goto out_unuse;
487-
}
474+
if (ret < 0)
475+
goto err_unuse;
488476

489477
ni_size = object->cookie->object_size;
490478
ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE);
491479

492480
if (ni_size > 0) {
493-
trace_cachefiles_trunc(object, d_backing_inode(path.dentry), 0, ni_size,
481+
trace_cachefiles_trunc(object, file_inode(file), 0, ni_size,
494482
cachefiles_trunc_expand_tmpfile);
495483
ret = cachefiles_inject_write_error();
496484
if (ret == 0)
497-
ret = vfs_truncate(&path, ni_size);
485+
ret = vfs_truncate(&file->f_path, ni_size);
498486
if (ret < 0) {
499487
trace_cachefiles_vfs_error(
500-
object, d_backing_inode(path.dentry), ret,
488+
object, file_inode(file), ret,
501489
cachefiles_trace_trunc_error);
502-
file = ERR_PTR(ret);
503-
goto out_unuse;
490+
goto err_unuse;
504491
}
505492
}
506493

507-
file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT,
508-
d_backing_inode(path.dentry), cache->cache_cred);
509-
if (IS_ERR(file)) {
510-
trace_cachefiles_vfs_error(object, d_backing_inode(path.dentry),
511-
PTR_ERR(file),
512-
cachefiles_trace_open_error);
513-
goto out_unuse;
514-
}
494+
ret = -EINVAL;
515495
if (unlikely(!file->f_op->read_iter) ||
516496
unlikely(!file->f_op->write_iter)) {
517497
fput(file);
518498
pr_notice("Cache does not support read_iter and write_iter\n");
519-
file = ERR_PTR(-EINVAL);
520-
goto out_unuse;
499+
goto err_unuse;
521500
}
522-
523-
goto out_dput;
524-
525-
out_unuse:
526-
cachefiles_do_unmark_inode_in_use(object, path.dentry);
527-
out_dput:
528-
dput(path.dentry);
529501
out:
530502
cachefiles_end_secure(cache, saved_cred);
531503
return file;
504+
505+
err_unuse:
506+
cachefiles_do_unmark_inode_in_use(object, file_inode(file));
507+
fput(file);
508+
err:
509+
file = ERR_PTR(ret);
510+
goto out;
532511
}
533512

534513
/*
@@ -569,8 +548,11 @@ static bool cachefiles_open_file(struct cachefiles_object *object,
569548

570549
_enter("%pd", dentry);
571550

572-
if (!cachefiles_mark_inode_in_use(object, dentry))
551+
if (!cachefiles_mark_inode_in_use(object, d_inode(dentry))) {
552+
pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n",
553+
dentry, d_inode(dentry)->i_ino);
573554
return false;
555+
}
574556

575557
/* We need to open a file interface onto a data file now as we can't do
576558
* it on demand because writeback called from do_exit() sees
@@ -624,7 +606,7 @@ static bool cachefiles_open_file(struct cachefiles_object *object,
624606
error_fput:
625607
fput(file);
626608
error:
627-
cachefiles_do_unmark_inode_in_use(object, dentry);
609+
cachefiles_do_unmark_inode_in_use(object, d_inode(dentry));
628610
dput(dentry);
629611
return false;
630612
}

fs/dcache.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3249,8 +3249,10 @@ void d_genocide(struct dentry *parent)
32493249

32503250
EXPORT_SYMBOL(d_genocide);
32513251

3252-
void d_tmpfile(struct dentry *dentry, struct inode *inode)
3252+
void d_tmpfile(struct file *file, struct inode *inode)
32533253
{
3254+
struct dentry *dentry = file->f_path.dentry;
3255+
32543256
inode_dec_link_count(inode);
32553257
BUG_ON(dentry->d_name.name != dentry->d_iname ||
32563258
!hlist_unhashed(&dentry->d_u.d_alias) ||

fs/ext2/namei.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,17 @@ static int ext2_create (struct user_namespace * mnt_userns,
120120
}
121121

122122
static int ext2_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
123-
struct dentry *dentry, umode_t mode)
123+
struct file *file, umode_t mode)
124124
{
125125
struct inode *inode = ext2_new_inode(dir, mode, NULL);
126126
if (IS_ERR(inode))
127127
return PTR_ERR(inode);
128128

129129
ext2_set_file_ops(inode);
130130
mark_inode_dirty(inode);
131-
d_tmpfile(dentry, inode);
131+
d_tmpfile(file, inode);
132132
unlock_new_inode(inode);
133-
return 0;
133+
return finish_open_simple(file, 0);
134134
}
135135

136136
static int ext2_mknod (struct user_namespace * mnt_userns, struct inode * dir,

fs/ext4/namei.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2854,7 +2854,7 @@ static int ext4_mknod(struct user_namespace *mnt_userns, struct inode *dir,
28542854
}
28552855

28562856
static int ext4_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
2857-
struct dentry *dentry, umode_t mode)
2857+
struct file *file, umode_t mode)
28582858
{
28592859
handle_t *handle;
28602860
struct inode *inode;
@@ -2876,7 +2876,7 @@ static int ext4_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
28762876
inode->i_op = &ext4_file_inode_operations;
28772877
inode->i_fop = &ext4_file_operations;
28782878
ext4_set_aops(inode);
2879-
d_tmpfile(dentry, inode);
2879+
d_tmpfile(file, inode);
28802880
err = ext4_orphan_add(handle, inode);
28812881
if (err)
28822882
goto err_unlock_inode;
@@ -2887,7 +2887,7 @@ static int ext4_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
28872887
ext4_journal_stop(handle);
28882888
if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
28892889
goto retry;
2890-
return err;
2890+
return finish_open_simple(file, err);
28912891
err_unlock_inode:
28922892
ext4_journal_stop(handle);
28932893
unlock_new_inode(inode);

0 commit comments

Comments
 (0)