Skip to content

Commit fe64f32

Browse files
committed
Merge branch 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull more vfs updates from Al Viro: "Assorted cleanups and fixes. In the "trivial API change" department - ->d_compare() losing 'parent' argument" * 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: cachefiles: Fix race between inactivating and culling a cache object 9p: use clone_fid() 9p: fix braino introduced in "9p: new helper - v9fs_parent_fid()" vfs: make dentry_needs_remove_privs() internal vfs: remove file_needs_remove_privs() vfs: fix deadlock in file_remove_privs() on overlayfs get rid of 'parent' argument of ->d_compare() cifs, msdos, vfat, hfs+: don't bother with parent in ->d_compare() affs ->d_compare(): don't bother with ->d_inode fold _d_rehash() and __d_rehash() together fold dentry_rcuwalk_invalidate() into its only remaining caller
2 parents 0cbbc42 + db20a89 commit fe64f32

File tree

32 files changed

+82
-130
lines changed

32 files changed

+82
-130
lines changed

Documentation/filesystems/Locking

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ prototypes:
1212
int (*d_revalidate)(struct dentry *, unsigned int);
1313
int (*d_weak_revalidate)(struct dentry *, unsigned int);
1414
int (*d_hash)(const struct dentry *, struct qstr *);
15-
int (*d_compare)(const struct dentry *, const struct dentry *,
15+
int (*d_compare)(const struct dentry *,
1616
unsigned int, const char *, const struct qstr *);
1717
int (*d_delete)(struct dentry *);
1818
int (*d_init)(struct dentry *);

Documentation/filesystems/porting

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,3 +585,10 @@ in your dentry operations instead.
585585
in the instances. Rationale: !@#!@# security_d_instantiate() needs to be
586586
called before we attach dentry to inode and !@#!@##!@$!$#!@#$!@$!@$ smack
587587
->d_instantiate() uses not just ->getxattr() but ->setxattr() as well.
588+
--
589+
[mandatory]
590+
->d_compare() doesn't get parent as a separate argument anymore. If you
591+
used it for finding the struct super_block involved, dentry->d_sb will
592+
work just as well; if it's something more complicated, use dentry->d_parent.
593+
Just be careful not to assume that fetching it more than once will yield
594+
the same value - in RCU mode it could change under you.

Documentation/filesystems/vfs.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ struct dentry_operations {
931931
int (*d_revalidate)(struct dentry *, unsigned int);
932932
int (*d_weak_revalidate)(struct dentry *, unsigned int);
933933
int (*d_hash)(const struct dentry *, struct qstr *);
934-
int (*d_compare)(const struct dentry *, const struct dentry *,
934+
int (*d_compare)(const struct dentry *,
935935
unsigned int, const char *, const struct qstr *);
936936
int (*d_delete)(const struct dentry *);
937937
int (*d_init)(struct dentry *);

drivers/staging/lustre/lustre/llite/dcache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static void ll_release(struct dentry *de)
7878
* INVALID) so d_lookup() matches it, but we have no lock on it (so
7979
* lock_match() fails) and we spin around real_lookup().
8080
*/
81-
static int ll_dcompare(const struct dentry *parent, const struct dentry *dentry,
81+
static int ll_dcompare(const struct dentry *dentry,
8282
unsigned int len, const char *str,
8383
const struct qstr *name)
8484
{

fs/9p/fid.c

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -257,36 +257,12 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
257257
return v9fs_fid_lookup_with_uid(dentry, uid, any);
258258
}
259259

260-
struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
261-
{
262-
struct p9_fid *fid, *ret;
263-
264-
fid = v9fs_fid_lookup(dentry);
265-
if (IS_ERR(fid))
266-
return fid;
267-
268-
ret = p9_client_walk(fid, 0, NULL, 1);
269-
return ret;
270-
}
271-
272-
static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
273-
{
274-
struct p9_fid *fid, *ret;
275-
276-
fid = v9fs_fid_lookup_with_uid(dentry, uid, 0);
277-
if (IS_ERR(fid))
278-
return fid;
279-
280-
ret = p9_client_walk(fid, 0, NULL, 1);
281-
return ret;
282-
}
283-
284260
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
285261
{
286262
int err;
287263
struct p9_fid *fid;
288264

289-
fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
265+
fid = clone_fid(v9fs_fid_lookup_with_uid(dentry, GLOBAL_ROOT_UID, 0));
290266
if (IS_ERR(fid))
291267
goto error_out;
292268
/*

fs/9p/fid.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ static inline struct p9_fid *v9fs_parent_fid(struct dentry *dentry)
2828
{
2929
return v9fs_fid_lookup(dentry->d_parent);
3030
}
31-
struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
3231
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
3332
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
33+
static inline struct p9_fid *clone_fid(struct p9_fid *fid)
34+
{
35+
return IS_ERR(fid) ? fid : p9_client_walk(fid, 0, NULL, 1);
36+
}
37+
static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
38+
{
39+
return clone_fid(v9fs_fid_lookup(dentry));
40+
}
3441
#endif

fs/9p/vfs_inode.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
661661
}
662662

663663
/* clone a fid to use for creation */
664-
ofid = p9_client_walk(dfid, 0, NULL, 1);
664+
ofid = clone_fid(dfid);
665665
if (IS_ERR(ofid)) {
666666
err = PTR_ERR(ofid);
667667
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
@@ -975,13 +975,13 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
975975
if (IS_ERR(oldfid))
976976
return PTR_ERR(oldfid);
977977

978-
olddirfid = v9fs_parent_fid(old_dentry);
978+
olddirfid = clone_fid(v9fs_parent_fid(old_dentry));
979979
if (IS_ERR(olddirfid)) {
980980
retval = PTR_ERR(olddirfid);
981981
goto done;
982982
}
983983

984-
newdirfid = v9fs_parent_fid(new_dentry);
984+
newdirfid = clone_fid(v9fs_parent_fid(new_dentry));
985985
if (IS_ERR(newdirfid)) {
986986
retval = PTR_ERR(newdirfid);
987987
goto clunk_olddir;

fs/9p/vfs_inode_dotl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
281281
}
282282

283283
/* clone a fid to use for creation */
284-
ofid = p9_client_walk(dfid, 0, NULL, 1);
284+
ofid = clone_fid(dfid);
285285
if (IS_ERR(ofid)) {
286286
err = PTR_ERR(ofid);
287287
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);

fs/9p/xattr.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
9797
const void *value, size_t value_len, int flags)
9898
{
9999
struct p9_fid *fid = v9fs_fid_lookup(dentry);
100-
if (IS_ERR(fid))
101-
return PTR_ERR(fid);
102100
return v9fs_fid_xattr_set(fid, name, value, value_len, flags);
103101
}
104102

@@ -115,7 +113,7 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
115113
name, value_len, flags);
116114

117115
/* Clone it */
118-
fid = p9_client_walk(fid, 0, NULL, 1);
116+
fid = clone_fid(fid);
119117
if (IS_ERR(fid))
120118
return PTR_ERR(fid);
121119

fs/adfs/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ adfs_hash(const struct dentry *parent, struct qstr *qstr)
227227
* requirements of the underlying filesystem.
228228
*/
229229
static int
230-
adfs_compare(const struct dentry *parent, const struct dentry *dentry,
230+
adfs_compare(const struct dentry *dentry,
231231
unsigned int len, const char *str, const struct qstr *name)
232232
{
233233
int i;

fs/affs/amigaffs.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,7 @@ affs_warning(struct super_block *sb, const char *function, const char *fmt, ...)
472472
bool
473473
affs_nofilenametruncate(const struct dentry *dentry)
474474
{
475-
struct inode *inode = d_inode(dentry);
476-
477-
return affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_NO_TRUNCATE);
475+
return affs_test_opt(AFFS_SB(dentry->d_sb)->s_flags, SF_NO_TRUNCATE);
478476
}
479477

480478
/* Check if the name is valid for a affs object. */

fs/affs/namei.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ typedef int (*toupper_t)(int);
1414

1515
static int affs_toupper(int ch);
1616
static int affs_hash_dentry(const struct dentry *, struct qstr *);
17-
static int affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
17+
static int affs_compare_dentry(const struct dentry *dentry,
1818
unsigned int len, const char *str, const struct qstr *name);
1919
static int affs_intl_toupper(int ch);
2020
static int affs_intl_hash_dentry(const struct dentry *, struct qstr *);
21-
static int affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
21+
static int affs_intl_compare_dentry(const struct dentry *dentry,
2222
unsigned int len, const char *str, const struct qstr *name);
2323

2424
const struct dentry_operations affs_dentry_operations = {
@@ -131,20 +131,20 @@ static inline int __affs_compare_dentry(unsigned int len,
131131
}
132132

133133
static int
134-
affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
134+
affs_compare_dentry(const struct dentry *dentry,
135135
unsigned int len, const char *str, const struct qstr *name)
136136
{
137137

138138
return __affs_compare_dentry(len, str, name, affs_toupper,
139-
affs_nofilenametruncate(parent));
139+
affs_nofilenametruncate(dentry));
140140
}
141141

142142
static int
143-
affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
143+
affs_intl_compare_dentry(const struct dentry *dentry,
144144
unsigned int len, const char *str, const struct qstr *name)
145145
{
146146
return __affs_compare_dentry(len, str, name, affs_intl_toupper,
147-
affs_nofilenametruncate(parent));
147+
affs_nofilenametruncate(dentry));
148148

149149
}
150150

fs/cachefiles/namei.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
263263
void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
264264
struct cachefiles_object *object)
265265
{
266+
blkcnt_t i_blocks = d_backing_inode(object->dentry)->i_blocks;
267+
266268
write_lock(&cache->active_lock);
267269
rb_erase(&object->active_node, &cache->active_nodes);
268270
clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
@@ -273,8 +275,7 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
273275
/* This object can now be culled, so we need to let the daemon know
274276
* that there is something it can remove if it needs to.
275277
*/
276-
atomic_long_add(d_backing_inode(object->dentry)->i_blocks,
277-
&cache->b_released);
278+
atomic_long_add(i_blocks, &cache->b_released);
278279
if (atomic_inc_return(&cache->f_released))
279280
cachefiles_state_changed(cache);
280281
}

fs/cifs/dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -903,10 +903,10 @@ static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q)
903903
return 0;
904904
}
905905

906-
static int cifs_ci_compare(const struct dentry *parent, const struct dentry *dentry,
906+
static int cifs_ci_compare(const struct dentry *dentry,
907907
unsigned int len, const char *str, const struct qstr *name)
908908
{
909-
struct nls_table *codepage = CIFS_SB(parent->d_sb)->local_nls;
909+
struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
910910
wchar_t c1, c2;
911911
int i, l1, l2;
912912

fs/dcache.c

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -316,20 +316,6 @@ static void dentry_free(struct dentry *dentry)
316316
call_rcu(&dentry->d_u.d_rcu, __d_free);
317317
}
318318

319-
/**
320-
* dentry_rcuwalk_invalidate - invalidate in-progress rcu-walk lookups
321-
* @dentry: the target dentry
322-
* After this call, in-progress rcu-walk path lookup will fail. This
323-
* should be called after unhashing, and after changing d_inode (if
324-
* the dentry has not already been unhashed).
325-
*/
326-
static inline void dentry_rcuwalk_invalidate(struct dentry *dentry)
327-
{
328-
lockdep_assert_held(&dentry->d_lock);
329-
/* Go through am invalidation barrier */
330-
write_seqcount_invalidate(&dentry->d_seq);
331-
}
332-
333319
/*
334320
* Release the dentry's inode, using the filesystem
335321
* d_iput() operation if defined.
@@ -468,7 +454,8 @@ void __d_drop(struct dentry *dentry)
468454
__hlist_bl_del(&dentry->d_hash);
469455
dentry->d_hash.pprev = NULL;
470456
hlist_bl_unlock(b);
471-
dentry_rcuwalk_invalidate(dentry);
457+
/* After this call, in-progress rcu-walk path lookup will fail. */
458+
write_seqcount_invalidate(&dentry->d_seq);
472459
}
473460
}
474461
EXPORT_SYMBOL(__d_drop);
@@ -2060,7 +2047,7 @@ static inline bool d_same_name(const struct dentry *dentry,
20602047
return false;
20612048
return dentry_cmp(dentry, name->name, name->len) == 0;
20622049
}
2063-
return parent->d_op->d_compare(parent, dentry,
2050+
return parent->d_op->d_compare(dentry,
20642051
dentry->d_name.len, dentry->d_name.name,
20652052
name) == 0;
20662053
}
@@ -2163,7 +2150,7 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent,
21632150
cpu_relax();
21642151
goto seqretry;
21652152
}
2166-
if (parent->d_op->d_compare(parent, dentry,
2153+
if (parent->d_op->d_compare(dentry,
21672154
tlen, tname, name) != 0)
21682155
continue;
21692156
} else {
@@ -2352,19 +2339,15 @@ void d_delete(struct dentry * dentry)
23522339
}
23532340
EXPORT_SYMBOL(d_delete);
23542341

2355-
static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b)
2342+
static void __d_rehash(struct dentry *entry)
23562343
{
2344+
struct hlist_bl_head *b = d_hash(entry->d_name.hash);
23572345
BUG_ON(!d_unhashed(entry));
23582346
hlist_bl_lock(b);
23592347
hlist_bl_add_head_rcu(&entry->d_hash, b);
23602348
hlist_bl_unlock(b);
23612349
}
23622350

2363-
static void _d_rehash(struct dentry * entry)
2364-
{
2365-
__d_rehash(entry, d_hash(entry->d_name.hash));
2366-
}
2367-
23682351
/**
23692352
* d_rehash - add an entry back to the hash
23702353
* @entry: dentry to add to the hash
@@ -2375,7 +2358,7 @@ static void _d_rehash(struct dentry * entry)
23752358
void d_rehash(struct dentry * entry)
23762359
{
23772360
spin_lock(&entry->d_lock);
2378-
_d_rehash(entry);
2361+
__d_rehash(entry);
23792362
spin_unlock(&entry->d_lock);
23802363
}
23812364
EXPORT_SYMBOL(d_rehash);
@@ -2549,7 +2532,7 @@ static inline void __d_add(struct dentry *dentry, struct inode *inode)
25492532
raw_write_seqcount_end(&dentry->d_seq);
25502533
fsnotify_update_flags(dentry);
25512534
}
2552-
_d_rehash(dentry);
2535+
__d_rehash(dentry);
25532536
if (dir)
25542537
end_dir_add(dir, n);
25552538
spin_unlock(&dentry->d_lock);
@@ -2611,7 +2594,7 @@ struct dentry *d_exact_alias(struct dentry *entry, struct inode *inode)
26112594
alias = NULL;
26122595
} else {
26132596
__dget_dlock(alias);
2614-
_d_rehash(alias);
2597+
__d_rehash(alias);
26152598
spin_unlock(&alias->d_lock);
26162599
}
26172600
spin_unlock(&inode->i_lock);
@@ -2795,30 +2778,22 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
27952778
write_seqcount_begin(&dentry->d_seq);
27962779
write_seqcount_begin_nested(&target->d_seq, DENTRY_D_LOCK_NESTED);
27972780

2781+
/* unhash both */
27982782
/* __d_drop does write_seqcount_barrier, but they're OK to nest. */
2799-
2800-
/*
2801-
* Move the dentry to the target hash queue. Don't bother checking
2802-
* for the same hash queue because of how unlikely it is.
2803-
*/
28042783
__d_drop(dentry);
2805-
__d_rehash(dentry, d_hash(target->d_name.hash));
2806-
2807-
/*
2808-
* Unhash the target (d_delete() is not usable here). If exchanging
2809-
* the two dentries, then rehash onto the other's hash queue.
2810-
*/
28112784
__d_drop(target);
2812-
if (exchange) {
2813-
__d_rehash(target, d_hash(dentry->d_name.hash));
2814-
}
28152785

28162786
/* Switch the names.. */
28172787
if (exchange)
28182788
swap_names(dentry, target);
28192789
else
28202790
copy_name(dentry, target);
28212791

2792+
/* rehash in new place(s) */
2793+
__d_rehash(dentry);
2794+
if (exchange)
2795+
__d_rehash(target);
2796+
28222797
/* ... and switch them in the tree */
28232798
if (IS_ROOT(dentry)) {
28242799
/* splicing a tree */

fs/efivarfs/super.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ static struct super_block *efivarfs_sb;
4545
* So we need to perform a case-sensitive match on part 1 and a
4646
* case-insensitive match on part 2.
4747
*/
48-
static int efivarfs_d_compare(const struct dentry *parent,
49-
const struct dentry *dentry,
48+
static int efivarfs_d_compare(const struct dentry *dentry,
5049
unsigned int len, const char *str,
5150
const struct qstr *name)
5251
{

fs/fat/namei_msdos.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ static int msdos_hash(const struct dentry *dentry, struct qstr *qstr)
162162
* Compare two msdos names. If either of the names are invalid,
163163
* we fall back to doing the standard name comparison.
164164
*/
165-
static int msdos_cmp(const struct dentry *parent, const struct dentry *dentry,
165+
static int msdos_cmp(const struct dentry *dentry,
166166
unsigned int len, const char *str, const struct qstr *name)
167167
{
168-
struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options;
168+
struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
169169
unsigned char a_msdos_name[MSDOS_NAME], b_msdos_name[MSDOS_NAME];
170170
int error;
171171

0 commit comments

Comments
 (0)