diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 5699d4c027cb..2a6bd9a4ae97 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -176,6 +176,7 @@ static void d_free(struct dentry *dentry) | |||
176 | 176 | ||
177 | /** | 177 | /** |
178 | * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups | 178 | * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups |
179 | * @dentry: the target dentry | ||
179 | * After this call, in-progress rcu-walk path lookup will fail. This | 180 | * After this call, in-progress rcu-walk path lookup will fail. This |
180 | * should be called after unhashing, and after changing d_inode (if | 181 | * should be called after unhashing, and after changing d_inode (if |
181 | * the dentry has not already been unhashed). | 182 | * the dentry has not already been unhashed). |
@@ -281,6 +282,7 @@ static void dentry_lru_move_tail(struct dentry *dentry) | |||
281 | /** | 282 | /** |
282 | * d_kill - kill dentry and return parent | 283 | * d_kill - kill dentry and return parent |
283 | * @dentry: dentry to kill | 284 | * @dentry: dentry to kill |
285 | * @parent: parent dentry | ||
284 | * | 286 | * |
285 | * The dentry must already be unhashed and removed from the LRU. | 287 | * The dentry must already be unhashed and removed from the LRU. |
286 | * | 288 | * |
@@ -1320,6 +1322,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
1320 | __dget_dlock(parent); | 1322 | __dget_dlock(parent); |
1321 | dentry->d_parent = parent; | 1323 | dentry->d_parent = parent; |
1322 | dentry->d_sb = parent->d_sb; | 1324 | dentry->d_sb = parent->d_sb; |
1325 | d_set_d_op(dentry, dentry->d_sb->s_d_op); | ||
1323 | list_add(&dentry->d_u.d_child, &parent->d_subdirs); | 1326 | list_add(&dentry->d_u.d_child, &parent->d_subdirs); |
1324 | spin_unlock(&parent->d_lock); | 1327 | spin_unlock(&parent->d_lock); |
1325 | } | 1328 | } |
@@ -1335,6 +1338,7 @@ struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name) | |||
1335 | struct dentry *dentry = d_alloc(NULL, name); | 1338 | struct dentry *dentry = d_alloc(NULL, name); |
1336 | if (dentry) { | 1339 | if (dentry) { |
1337 | dentry->d_sb = sb; | 1340 | dentry->d_sb = sb; |
1341 | d_set_d_op(dentry, dentry->d_sb->s_d_op); | ||
1338 | dentry->d_parent = dentry; | 1342 | dentry->d_parent = dentry; |
1339 | dentry->d_flags |= DCACHE_DISCONNECTED; | 1343 | dentry->d_flags |= DCACHE_DISCONNECTED; |
1340 | } | 1344 | } |
@@ -1355,8 +1359,8 @@ EXPORT_SYMBOL(d_alloc_name); | |||
1355 | 1359 | ||
1356 | void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) | 1360 | void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) |
1357 | { | 1361 | { |
1358 | BUG_ON(dentry->d_op); | 1362 | WARN_ON_ONCE(dentry->d_op); |
1359 | BUG_ON(dentry->d_flags & (DCACHE_OP_HASH | | 1363 | WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH | |
1360 | DCACHE_OP_COMPARE | | 1364 | DCACHE_OP_COMPARE | |
1361 | DCACHE_OP_REVALIDATE | | 1365 | DCACHE_OP_REVALIDATE | |
1362 | DCACHE_OP_DELETE )); | 1366 | DCACHE_OP_DELETE )); |
@@ -1378,8 +1382,11 @@ EXPORT_SYMBOL(d_set_d_op); | |||
1378 | static void __d_instantiate(struct dentry *dentry, struct inode *inode) | 1382 | static void __d_instantiate(struct dentry *dentry, struct inode *inode) |
1379 | { | 1383 | { |
1380 | spin_lock(&dentry->d_lock); | 1384 | spin_lock(&dentry->d_lock); |
1381 | if (inode) | 1385 | if (inode) { |
1386 | if (unlikely(IS_AUTOMOUNT(inode))) | ||
1387 | dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; | ||
1382 | list_add(&dentry->d_alias, &inode->i_dentry); | 1388 | list_add(&dentry->d_alias, &inode->i_dentry); |
1389 | } | ||
1383 | dentry->d_inode = inode; | 1390 | dentry->d_inode = inode; |
1384 | dentry_rcuwalk_barrier(dentry); | 1391 | dentry_rcuwalk_barrier(dentry); |
1385 | spin_unlock(&dentry->d_lock); | 1392 | spin_unlock(&dentry->d_lock); |
@@ -1507,6 +1514,7 @@ struct dentry * d_alloc_root(struct inode * root_inode) | |||
1507 | res = d_alloc(NULL, &name); | 1514 | res = d_alloc(NULL, &name); |
1508 | if (res) { | 1515 | if (res) { |
1509 | res->d_sb = root_inode->i_sb; | 1516 | res->d_sb = root_inode->i_sb; |
1517 | d_set_d_op(res, res->d_sb->s_d_op); | ||
1510 | res->d_parent = res; | 1518 | res->d_parent = res; |
1511 | d_instantiate(res, root_inode); | 1519 | d_instantiate(res, root_inode); |
1512 | } | 1520 | } |
@@ -1567,6 +1575,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1567 | /* attach a disconnected dentry */ | 1575 | /* attach a disconnected dentry */ |
1568 | spin_lock(&tmp->d_lock); | 1576 | spin_lock(&tmp->d_lock); |
1569 | tmp->d_sb = inode->i_sb; | 1577 | tmp->d_sb = inode->i_sb; |
1578 | d_set_d_op(tmp, tmp->d_sb->s_d_op); | ||
1570 | tmp->d_inode = inode; | 1579 | tmp->d_inode = inode; |
1571 | tmp->d_flags |= DCACHE_DISCONNECTED; | 1580 | tmp->d_flags |= DCACHE_DISCONNECTED; |
1572 | list_add(&tmp->d_alias, &inode->i_dentry); | 1581 | list_add(&tmp->d_alias, &inode->i_dentry); |
@@ -2449,8 +2458,7 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
2449 | } | 2458 | } |
2450 | 2459 | ||
2451 | /** | 2460 | /** |
2452 | * Prepend path string to a buffer | 2461 | * prepend_path - Prepend path string to a buffer |
2453 | * | ||
2454 | * @path: the dentry/vfsmount to report | 2462 | * @path: the dentry/vfsmount to report |
2455 | * @root: root vfsmnt/dentry (may be modified by this function) | 2463 | * @root: root vfsmnt/dentry (may be modified by this function) |
2456 | * @buffer: pointer to the end of the buffer | 2464 | * @buffer: pointer to the end of the buffer |