aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-07-07 15:03:58 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 01:44:17 -0400
commita4464dbc0ca6a3ab8e9d1206bc05059dae2a559d (patch)
treed3c9332ab72cf5a4eba483ba1ff83c54ca4c42a0
parente3c3d9c838d48c0341c40ea45ee087e3d8c8ea39 (diff)
Make ->d_sb assign-once and always non-NULL
New helper (non-exported, fs/internal.h-only): __d_alloc(sb, name). Allocates dentry, sets its ->d_sb to given superblock and sets ->d_op accordingly. Old d_alloc(NULL, name) callers are converted to that (all of them know what superblock they want). d_alloc() itself is left only for parent != NULl case; uses __d_alloc(), inserts result into the list of parent's children. Note that now ->d_sb is assign-once and never NULL *and* ->d_parent is never NULL either. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/dcache.c75
-rw-r--r--fs/internal.h5
-rw-r--r--fs/libfs.c6
3 files changed, 47 insertions, 39 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index d3902139b533..c61edd0318c3 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1275,8 +1275,8 @@ static struct shrinker dcache_shrinker = {
1275}; 1275};
1276 1276
1277/** 1277/**
1278 * d_alloc - allocate a dcache entry 1278 * __d_alloc - allocate a dcache entry
1279 * @parent: parent of entry to allocate 1279 * @sb: filesystem it will belong to
1280 * @name: qstr of the name 1280 * @name: qstr of the name
1281 * 1281 *
1282 * Allocates a dentry. It returns %NULL if there is insufficient memory 1282 * Allocates a dentry. It returns %NULL if there is insufficient memory
@@ -1284,7 +1284,7 @@ static struct shrinker dcache_shrinker = {
1284 * copied and the copy passed in may be reused after this call. 1284 * copied and the copy passed in may be reused after this call.
1285 */ 1285 */
1286 1286
1287struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) 1287struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
1288{ 1288{
1289 struct dentry *dentry; 1289 struct dentry *dentry;
1290 char *dname; 1290 char *dname;
@@ -1314,8 +1314,8 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
1314 spin_lock_init(&dentry->d_lock); 1314 spin_lock_init(&dentry->d_lock);
1315 seqcount_init(&dentry->d_seq); 1315 seqcount_init(&dentry->d_seq);
1316 dentry->d_inode = NULL; 1316 dentry->d_inode = NULL;
1317 dentry->d_parent = NULL; 1317 dentry->d_parent = dentry;
1318 dentry->d_sb = NULL; 1318 dentry->d_sb = sb;
1319 dentry->d_op = NULL; 1319 dentry->d_op = NULL;
1320 dentry->d_fsdata = NULL; 1320 dentry->d_fsdata = NULL;
1321 INIT_HLIST_BL_NODE(&dentry->d_hash); 1321 INIT_HLIST_BL_NODE(&dentry->d_hash);
@@ -1323,36 +1323,47 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
1323 INIT_LIST_HEAD(&dentry->d_subdirs); 1323 INIT_LIST_HEAD(&dentry->d_subdirs);
1324 INIT_LIST_HEAD(&dentry->d_alias); 1324 INIT_LIST_HEAD(&dentry->d_alias);
1325 INIT_LIST_HEAD(&dentry->d_u.d_child); 1325 INIT_LIST_HEAD(&dentry->d_u.d_child);
1326 1326 d_set_d_op(dentry, dentry->d_sb->s_d_op);
1327 if (parent) {
1328 spin_lock(&parent->d_lock);
1329 /*
1330 * don't need child lock because it is not subject
1331 * to concurrency here
1332 */
1333 __dget_dlock(parent);
1334 dentry->d_parent = parent;
1335 dentry->d_sb = parent->d_sb;
1336 d_set_d_op(dentry, dentry->d_sb->s_d_op);
1337 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
1338 spin_unlock(&parent->d_lock);
1339 }
1340 1327
1341 this_cpu_inc(nr_dentry); 1328 this_cpu_inc(nr_dentry);
1342 1329
1343 return dentry; 1330 return dentry;
1344} 1331}
1332
1333/**
1334 * d_alloc - allocate a dcache entry
1335 * @parent: parent of entry to allocate
1336 * @name: qstr of the name
1337 *
1338 * Allocates a dentry. It returns %NULL if there is insufficient memory
1339 * available. On a success the dentry is returned. The name passed in is
1340 * copied and the copy passed in may be reused after this call.
1341 */
1342struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
1343{
1344 struct dentry *dentry = __d_alloc(parent->d_sb, name);
1345 if (!dentry)
1346 return NULL;
1347
1348 spin_lock(&parent->d_lock);
1349 /*
1350 * don't need child lock because it is not subject
1351 * to concurrency here
1352 */
1353 __dget_dlock(parent);
1354 dentry->d_parent = parent;
1355 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
1356 spin_unlock(&parent->d_lock);
1357
1358 return dentry;
1359}
1345EXPORT_SYMBOL(d_alloc); 1360EXPORT_SYMBOL(d_alloc);
1346 1361
1347struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name) 1362struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name)
1348{ 1363{
1349 struct dentry *dentry = d_alloc(NULL, name); 1364 struct dentry *dentry = __d_alloc(sb, name);
1350 if (dentry) { 1365 if (dentry)
1351 dentry->d_sb = sb;
1352 d_set_d_op(dentry, dentry->d_sb->s_d_op);
1353 dentry->d_parent = dentry;
1354 dentry->d_flags |= DCACHE_DISCONNECTED; 1366 dentry->d_flags |= DCACHE_DISCONNECTED;
1355 }
1356 return dentry; 1367 return dentry;
1357} 1368}
1358EXPORT_SYMBOL(d_alloc_pseudo); 1369EXPORT_SYMBOL(d_alloc_pseudo);
@@ -1522,13 +1533,9 @@ struct dentry * d_alloc_root(struct inode * root_inode)
1522 if (root_inode) { 1533 if (root_inode) {
1523 static const struct qstr name = { .name = "/", .len = 1 }; 1534 static const struct qstr name = { .name = "/", .len = 1 };
1524 1535
1525 res = d_alloc(NULL, &name); 1536 res = __d_alloc(root_inode->i_sb, &name);
1526 if (res) { 1537 if (res)
1527 res->d_sb = root_inode->i_sb;
1528 d_set_d_op(res, res->d_sb->s_d_op);
1529 res->d_parent = res;
1530 d_instantiate(res, root_inode); 1538 d_instantiate(res, root_inode);
1531 }
1532 } 1539 }
1533 return res; 1540 return res;
1534} 1541}
@@ -1589,13 +1596,11 @@ struct dentry *d_obtain_alias(struct inode *inode)
1589 if (res) 1596 if (res)
1590 goto out_iput; 1597 goto out_iput;
1591 1598
1592 tmp = d_alloc(NULL, &anonstring); 1599 tmp = __d_alloc(inode->i_sb, &anonstring);
1593 if (!tmp) { 1600 if (!tmp) {
1594 res = ERR_PTR(-ENOMEM); 1601 res = ERR_PTR(-ENOMEM);
1595 goto out_iput; 1602 goto out_iput;
1596 } 1603 }
1597 tmp->d_parent = tmp; /* make sure dput doesn't croak */
1598
1599 1604
1600 spin_lock(&inode->i_lock); 1605 spin_lock(&inode->i_lock);
1601 res = __d_find_any_alias(inode); 1606 res = __d_find_any_alias(inode);
@@ -1607,8 +1612,6 @@ struct dentry *d_obtain_alias(struct inode *inode)
1607 1612
1608 /* attach a disconnected dentry */ 1613 /* attach a disconnected dentry */
1609 spin_lock(&tmp->d_lock); 1614 spin_lock(&tmp->d_lock);
1610 tmp->d_sb = inode->i_sb;
1611 d_set_d_op(tmp, tmp->d_sb->s_d_op);
1612 tmp->d_inode = inode; 1615 tmp->d_inode = inode;
1613 tmp->d_flags |= DCACHE_DISCONNECTED; 1616 tmp->d_flags |= DCACHE_DISCONNECTED;
1614 list_add(&tmp->d_alias, &inode->i_dentry); 1617 list_add(&tmp->d_alias, &inode->i_dentry);
diff --git a/fs/internal.h b/fs/internal.h
index b29c46e4e32f..ae47c48bedde 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -135,3 +135,8 @@ extern void inode_wb_list_del(struct inode *inode);
135extern int get_nr_dirty_inodes(void); 135extern int get_nr_dirty_inodes(void);
136extern void evict_inodes(struct super_block *); 136extern void evict_inodes(struct super_block *);
137extern int invalidate_inodes(struct super_block *, bool); 137extern int invalidate_inodes(struct super_block *, bool);
138
139/*
140 * dcache.c
141 */
142extern struct dentry *__d_alloc(struct super_block *, const struct qstr *);
diff --git a/fs/libfs.c b/fs/libfs.c
index 275ca4749a2e..bd50b11f92da 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -16,6 +16,8 @@
16 16
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18 18
19#include "internal.h"
20
19static inline int simple_positive(struct dentry *dentry) 21static inline int simple_positive(struct dentry *dentry)
20{ 22{
21 return dentry->d_inode && !d_unhashed(dentry); 23 return dentry->d_inode && !d_unhashed(dentry);
@@ -246,13 +248,11 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
246 root->i_ino = 1; 248 root->i_ino = 1;
247 root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; 249 root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
248 root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; 250 root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
249 dentry = d_alloc(NULL, &d_name); 251 dentry = __d_alloc(s, &d_name);
250 if (!dentry) { 252 if (!dentry) {
251 iput(root); 253 iput(root);
252 goto Enomem; 254 goto Enomem;
253 } 255 }
254 dentry->d_sb = s;
255 dentry->d_parent = dentry;
256 d_instantiate(dentry, root); 256 d_instantiate(dentry, root);
257 s->s_root = dentry; 257 s->s_root = dentry;
258 s->s_d_op = dops; 258 s->s_d_op = dops;