Skip to content

Commit 658d132

Browse files
committed
Merge branch 'vfs-6.19.directory.locking' into base.vfs-6.19.ovl
Bring in the directory locking changes as they touch overlayfs in a pretty substantial way and we are about to change the credential override semantics quite substantially as well. Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents 2b21a62 + 523ac76 commit 658d132

31 files changed

Lines changed: 1298 additions & 835 deletions

File tree

Documentation/filesystems/porting.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,3 +1309,16 @@ a different length, use
13091309
vfs_parse_fs_qstr(fc, key, &QSTR_LEN(value, len))
13101310

13111311
instead.
1312+
1313+
---
1314+
1315+
**mandatory**
1316+
1317+
vfs_mkdir() now returns a dentry - the one returned by ->mkdir(). If
1318+
that dentry is different from the dentry passed in, including if it is
1319+
an IS_ERR() dentry pointer, the original dentry is dput().
1320+
1321+
When vfs_mkdir() returns an error, and so both dputs() the original
1322+
dentry and doesn't provide a replacement, it also unlocks the parent.
1323+
Consequently the return value from vfs_mkdir() can be passed to
1324+
end_creating() and the parent will be unlocked precisely when necessary.

fs/btrfs/ioctl.c

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -904,14 +904,9 @@ static noinline int btrfs_mksubvol(struct dentry *parent,
904904
struct fscrypt_str name_str = FSTR_INIT((char *)qname->name, qname->len);
905905
int ret;
906906

907-
ret = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT);
908-
if (ret == -EINTR)
909-
return ret;
910-
911-
dentry = lookup_one(idmap, qname, parent);
912-
ret = PTR_ERR(dentry);
907+
dentry = start_creating_killable(idmap, parent, qname);
913908
if (IS_ERR(dentry))
914-
goto out_unlock;
909+
return PTR_ERR(dentry);
915910

916911
ret = btrfs_may_create(idmap, dir, dentry);
917912
if (ret)
@@ -940,9 +935,7 @@ static noinline int btrfs_mksubvol(struct dentry *parent,
940935
out_up_read:
941936
up_read(&fs_info->subvol_sem);
942937
out_dput:
943-
dput(dentry);
944-
out_unlock:
945-
btrfs_inode_unlock(BTRFS_I(dir), 0);
938+
end_creating(dentry);
946939
return ret;
947940
}
948941

@@ -2417,18 +2410,10 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
24172410
goto free_subvol_name;
24182411
}
24192412

2420-
ret = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT);
2421-
if (ret == -EINTR)
2422-
goto free_subvol_name;
2423-
dentry = lookup_one(idmap, &QSTR(subvol_name), parent);
2413+
dentry = start_removing_killable(idmap, parent, &QSTR(subvol_name));
24242414
if (IS_ERR(dentry)) {
24252415
ret = PTR_ERR(dentry);
2426-
goto out_unlock_dir;
2427-
}
2428-
2429-
if (d_really_is_negative(dentry)) {
2430-
ret = -ENOENT;
2431-
goto out_dput;
2416+
goto out_end_removing;
24322417
}
24332418

24342419
inode = d_inode(dentry);
@@ -2449,7 +2434,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
24492434
*/
24502435
ret = -EPERM;
24512436
if (!btrfs_test_opt(fs_info, USER_SUBVOL_RM_ALLOWED))
2452-
goto out_dput;
2437+
goto out_end_removing;
24532438

24542439
/*
24552440
* Do not allow deletion if the parent dir is the same
@@ -2460,21 +2445,21 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
24602445
*/
24612446
ret = -EINVAL;
24622447
if (root == dest)
2463-
goto out_dput;
2448+
goto out_end_removing;
24642449

24652450
ret = inode_permission(idmap, inode, MAY_WRITE | MAY_EXEC);
24662451
if (ret)
2467-
goto out_dput;
2452+
goto out_end_removing;
24682453
}
24692454

24702455
/* check if subvolume may be deleted by a user */
24712456
ret = btrfs_may_delete(idmap, dir, dentry, 1);
24722457
if (ret)
2473-
goto out_dput;
2458+
goto out_end_removing;
24742459

24752460
if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) {
24762461
ret = -EINVAL;
2477-
goto out_dput;
2462+
goto out_end_removing;
24782463
}
24792464

24802465
btrfs_inode_lock(BTRFS_I(inode), 0);
@@ -2483,10 +2468,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
24832468
if (!ret)
24842469
d_delete_notify(dir, dentry);
24852470

2486-
out_dput:
2487-
dput(dentry);
2488-
out_unlock_dir:
2489-
btrfs_inode_unlock(BTRFS_I(dir), 0);
2471+
out_end_removing:
2472+
end_removing(dentry);
24902473
free_subvol_name:
24912474
kfree(subvol_name_ptr);
24922475
free_parent:

fs/cachefiles/interface.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/mount.h>
1010
#include <linux/xattr.h>
1111
#include <linux/file.h>
12+
#include <linux/namei.h>
1213
#include <linux/falloc.h>
1314
#include <trace/events/fscache.h>
1415
#include "internal.h"
@@ -428,11 +429,13 @@ static bool cachefiles_invalidate_cookie(struct fscache_cookie *cookie)
428429
if (!old_tmpfile) {
429430
struct cachefiles_volume *volume = object->volume;
430431
struct dentry *fan = volume->fanout[(u8)cookie->key_hash];
432+
struct dentry *obj;
431433

432-
inode_lock_nested(d_inode(fan), I_MUTEX_PARENT);
433-
cachefiles_bury_object(volume->cache, object, fan,
434-
old_file->f_path.dentry,
435-
FSCACHE_OBJECT_INVALIDATED);
434+
obj = start_removing_dentry(fan, old_file->f_path.dentry);
435+
if (!IS_ERR(obj))
436+
cachefiles_bury_object(volume->cache, object,
437+
fan, obj,
438+
FSCACHE_OBJECT_INVALIDATED);
436439
}
437440
fput(old_file);
438441
}

fs/cachefiles/namei.c

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
9393
_enter(",,%s", dirname);
9494

9595
/* search the current directory for the element name */
96-
inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
9796

9897
retry:
9998
ret = cachefiles_inject_read_error();
10099
if (ret == 0)
101-
subdir = lookup_one(&nop_mnt_idmap, &QSTR(dirname), dir);
100+
subdir = start_creating(&nop_mnt_idmap, dir, &QSTR(dirname));
102101
else
103102
subdir = ERR_PTR(ret);
104103
trace_cachefiles_lookup(NULL, dir, subdir);
@@ -129,10 +128,12 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
129128
if (ret < 0)
130129
goto mkdir_error;
131130
ret = cachefiles_inject_write_error();
132-
if (ret == 0)
131+
if (ret == 0) {
133132
subdir = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700);
134-
else
133+
} else {
134+
end_creating(subdir);
135135
subdir = ERR_PTR(ret);
136+
}
136137
if (IS_ERR(subdir)) {
137138
trace_cachefiles_vfs_error(NULL, d_inode(dir), ret,
138139
cachefiles_trace_mkdir_error);
@@ -141,7 +142,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
141142
trace_cachefiles_mkdir(dir, subdir);
142143

143144
if (unlikely(d_unhashed(subdir) || d_is_negative(subdir))) {
144-
dput(subdir);
145+
end_creating(subdir);
145146
goto retry;
146147
}
147148
ASSERT(d_backing_inode(subdir));
@@ -154,7 +155,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
154155

155156
/* Tell rmdir() it's not allowed to delete the subdir */
156157
inode_lock(d_inode(subdir));
157-
inode_unlock(d_inode(dir));
158+
end_creating_keep(subdir);
158159

159160
if (!__cachefiles_mark_inode_in_use(NULL, d_inode(subdir))) {
160161
pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n",
@@ -196,14 +197,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
196197
return ERR_PTR(-EBUSY);
197198

198199
mkdir_error:
199-
inode_unlock(d_inode(dir));
200-
if (!IS_ERR(subdir))
201-
dput(subdir);
200+
end_creating(subdir);
202201
pr_err("mkdir %s failed with error %d\n", dirname, ret);
203202
return ERR_PTR(ret);
204203

205204
lookup_error:
206-
inode_unlock(d_inode(dir));
207205
ret = PTR_ERR(subdir);
208206
pr_err("Lookup %s failed with error %d\n", dirname, ret);
209207
return ERR_PTR(ret);
@@ -263,6 +261,8 @@ static int cachefiles_unlink(struct cachefiles_cache *cache,
263261
* - File backed objects are unlinked
264262
* - Directory backed objects are stuffed into the graveyard for userspace to
265263
* delete
264+
* On entry dir must be locked. It will be unlocked on exit.
265+
* On entry there must be at least 2 refs on rep, one will be dropped on exit.
266266
*/
267267
int cachefiles_bury_object(struct cachefiles_cache *cache,
268268
struct cachefiles_object *object,
@@ -278,27 +278,23 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
278278
_enter(",'%pd','%pd'", dir, rep);
279279

280280
if (rep->d_parent != dir) {
281-
inode_unlock(d_inode(dir));
281+
end_removing(rep);
282282
_leave(" = -ESTALE");
283283
return -ESTALE;
284284
}
285285

286286
/* non-directories can just be unlinked */
287287
if (!d_is_dir(rep)) {
288-
dget(rep); /* Stop the dentry being negated if it's only pinned
289-
* by a file struct.
290-
*/
291288
ret = cachefiles_unlink(cache, object, dir, rep, why);
292-
dput(rep);
289+
end_removing(rep);
293290

294-
inode_unlock(d_inode(dir));
295291
_leave(" = %d", ret);
296292
return ret;
297293
}
298294

299295
/* directories have to be moved to the graveyard */
300296
_debug("move stale object to graveyard");
301-
inode_unlock(d_inode(dir));
297+
end_removing(rep);
302298

303299
try_again:
304300
/* first step is to make up a grave dentry in the graveyard */
@@ -425,13 +421,12 @@ int cachefiles_delete_object(struct cachefiles_object *object,
425421

426422
_enter(",OBJ%x{%pD}", object->debug_id, object->file);
427423

428-
/* Stop the dentry being negated if it's only pinned by a file struct. */
429-
dget(dentry);
430-
431-
inode_lock_nested(d_backing_inode(fan), I_MUTEX_PARENT);
432-
ret = cachefiles_unlink(volume->cache, object, fan, dentry, why);
433-
inode_unlock(d_backing_inode(fan));
434-
dput(dentry);
424+
dentry = start_removing_dentry(fan, dentry);
425+
if (IS_ERR(dentry))
426+
ret = PTR_ERR(dentry);
427+
else
428+
ret = cachefiles_unlink(volume->cache, object, fan, dentry, why);
429+
end_removing(dentry);
435430
return ret;
436431
}
437432

@@ -644,9 +639,13 @@ bool cachefiles_look_up_object(struct cachefiles_object *object)
644639

645640
if (!d_is_reg(dentry)) {
646641
pr_err("%pd is not a file\n", dentry);
647-
inode_lock_nested(d_inode(fan), I_MUTEX_PARENT);
648-
ret = cachefiles_bury_object(volume->cache, object, fan, dentry,
649-
FSCACHE_OBJECT_IS_WEIRD);
642+
struct dentry *de = start_removing_dentry(fan, dentry);
643+
if (IS_ERR(de))
644+
ret = PTR_ERR(de);
645+
else
646+
ret = cachefiles_bury_object(volume->cache, object,
647+
fan, de,
648+
FSCACHE_OBJECT_IS_WEIRD);
650649
dput(dentry);
651650
if (ret < 0)
652651
return false;
@@ -679,36 +678,41 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
679678

680679
_enter(",%pD", object->file);
681680

682-
inode_lock_nested(d_inode(fan), I_MUTEX_PARENT);
683681
ret = cachefiles_inject_read_error();
684682
if (ret == 0)
685-
dentry = lookup_one(&nop_mnt_idmap, &QSTR(object->d_name), fan);
683+
dentry = start_creating(&nop_mnt_idmap, fan, &QSTR(object->d_name));
686684
else
687685
dentry = ERR_PTR(ret);
688686
if (IS_ERR(dentry)) {
689687
trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry),
690688
cachefiles_trace_lookup_error);
691689
_debug("lookup fail %ld", PTR_ERR(dentry));
692-
goto out_unlock;
690+
goto out;
693691
}
694692

695-
if (!d_is_negative(dentry)) {
693+
/*
694+
* This loop will only execute more than once if some other thread
695+
* races to create the object we are trying to create.
696+
*/
697+
while (!d_is_negative(dentry)) {
696698
ret = cachefiles_unlink(volume->cache, object, fan, dentry,
697699
FSCACHE_OBJECT_IS_STALE);
698700
if (ret < 0)
699-
goto out_dput;
701+
goto out_end;
702+
703+
end_creating(dentry);
700704

701-
dput(dentry);
702705
ret = cachefiles_inject_read_error();
703706
if (ret == 0)
704-
dentry = lookup_one(&nop_mnt_idmap, &QSTR(object->d_name), fan);
707+
dentry = start_creating(&nop_mnt_idmap, fan,
708+
&QSTR(object->d_name));
705709
else
706710
dentry = ERR_PTR(ret);
707711
if (IS_ERR(dentry)) {
708712
trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry),
709713
cachefiles_trace_lookup_error);
710714
_debug("lookup fail %ld", PTR_ERR(dentry));
711-
goto out_unlock;
715+
goto out;
712716
}
713717
}
714718

@@ -729,10 +733,9 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
729733
success = true;
730734
}
731735

732-
out_dput:
733-
dput(dentry);
734-
out_unlock:
735-
inode_unlock(d_inode(fan));
736+
out_end:
737+
end_creating(dentry);
738+
out:
736739
_leave(" = %u", success);
737740
return success;
738741
}
@@ -748,26 +751,20 @@ static struct dentry *cachefiles_lookup_for_cull(struct cachefiles_cache *cache,
748751
struct dentry *victim;
749752
int ret = -ENOENT;
750753

751-
inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
754+
victim = start_removing(&nop_mnt_idmap, dir, &QSTR(filename));
752755

753-
victim = lookup_one(&nop_mnt_idmap, &QSTR(filename), dir);
754756
if (IS_ERR(victim))
755757
goto lookup_error;
756-
if (d_is_negative(victim))
757-
goto lookup_put;
758758
if (d_inode(victim)->i_flags & S_KERNEL_FILE)
759759
goto lookup_busy;
760760
return victim;
761761

762762
lookup_busy:
763763
ret = -EBUSY;
764-
lookup_put:
765-
inode_unlock(d_inode(dir));
766-
dput(victim);
764+
end_removing(victim);
767765
return ERR_PTR(ret);
768766

769767
lookup_error:
770-
inode_unlock(d_inode(dir));
771768
ret = PTR_ERR(victim);
772769
if (ret == -ENOENT)
773770
return ERR_PTR(-ESTALE); /* Probably got retired by the netfs */
@@ -815,18 +812,17 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
815812

816813
ret = cachefiles_bury_object(cache, NULL, dir, victim,
817814
FSCACHE_OBJECT_WAS_CULLED);
815+
dput(victim);
818816
if (ret < 0)
819817
goto error;
820818

821819
fscache_count_culled();
822-
dput(victim);
823820
_leave(" = 0");
824821
return 0;
825822

826823
error_unlock:
827-
inode_unlock(d_inode(dir));
824+
end_removing(victim);
828825
error:
829-
dput(victim);
830826
if (ret == -ENOENT)
831827
return -ESTALE; /* Probably got retired by the netfs */
832828

0 commit comments

Comments
 (0)