return 0;
}
-static int ll_set_dd(struct dentry *de)
+int ll_d_init(struct dentry *de)
{
LASSERT(de != NULL);
OBD_ALLOC_PTR(lld);
if (likely(lld != NULL)) {
spin_lock(&de->d_lock);
- if (likely(de->d_fsdata == NULL))
+ if (likely(de->d_fsdata == NULL)) {
de->d_fsdata = lld;
- else
+ __d_lustre_invalidate(de);
+ } else {
OBD_FREE_PTR(lld);
+ }
spin_unlock(&de->d_lock);
} else {
return -ENOMEM;
}
}
+ LASSERT(de->d_op == &ll_d_ops);
return 0;
}
-int ll_dops_init(struct dentry *de, int block, int init_sa)
-{
- struct ll_dentry_data *lld = ll_d2d(de);
- int rc = 0;
-
- if (lld == NULL && block != 0) {
- rc = ll_set_dd(de);
- if (rc)
- return rc;
-
- lld = ll_d2d(de);
- }
-
- if (lld != NULL && init_sa != 0)
- lld->lld_sa_generation = 0;
-
- /* kernel >= 2.6.38 d_op is set in d_alloc() */
- LASSERT(de->d_op == &ll_d_ops);
- return rc;
-}
-
void ll_intent_drop_lock(struct lookup_intent *it)
{
if (it->it_op && it->d.lustre.it_lock_mode) {
CDEBUG(D_VFSTRACE, "VFS Op:name=%s,intent=%s\n", de->d_name.name,
LL_IT2STR(it));
+ LASSERT(de != de->d_sb->s_root);
+
if (de->d_inode == NULL) {
__u64 ibits;
if (d_mountpoint(de))
GOTO(out_sa, rc = 1);
- /* need to get attributes in case root got changed from other client */
- if (de == de->d_sb->s_root) {
- rc = __ll_inode_revalidate_it(de, it, MDS_INODELOCK_LOOKUP);
- if (rc == 0)
- rc = 1;
- GOTO(out_sa, rc);
- }
-
exp = ll_i2mdexp(de->d_inode);
OBD_FAIL_TIMEOUT(OBD_FAIL_MDC_REVALIDATE_PAUSE, 5);
/* llite/dcache.c */
-int ll_dops_init(struct dentry *de, int block, int init_sa);
+int ll_d_init(struct dentry *de);
extern struct dentry_operations ll_d_ops;
void ll_intent_drop_lock(struct lookup_intent *);
void ll_intent_release(struct lookup_intent *);
if (lli->lli_opendir_pid != current_pid())
return;
- if (sai != NULL && ldd != NULL)
+ LASSERT(ldd != NULL);
+ if (sai != NULL)
ldd->lld_sa_generation = sai->sai_generation;
}
}
}
-static struct dentry_operations ll_d_root_ops = {
- .d_compare = ll_dcompare,
- .d_revalidate = ll_revalidate_nd,
-};
-
static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
struct vfsmount *mnt)
{
GOTO(out_root, err = -ENOMEM);
}
- /* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */
- d_set_d_op(sb->s_root, &ll_d_root_ops);
- sb->s_d_op = &ll_d_ops;
-
sbi->ll_sdev_orig = sb->s_dev;
/* We set sb->s_dev equal on all lustre clients in order to support
GOTO(out_free, err);
sb->s_bdi = &lsi->lsi_bdi;
+ /* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */
+ sb->s_d_op = &ll_d_ops;
/* Generate a string unique to this super, in case some joker tries
to mount the same fs at two mount points.
}
result = d_obtain_alias(inode);
- if (IS_ERR(result))
+ if (IS_ERR(result)) {
+ iput(inode);
return result;
-
- ll_dops_init(result, 1, 0);
+ }
return result;
}
struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de)
{
struct dentry *new;
+ int rc;
if (inode) {
new = ll_find_alias(inode, de);
if (new) {
- ll_dops_init(new, 1, 1);
+ rc = ll_d_init(new);
+ if (rc < 0) {
+ dput(new);
+ return ERR_PTR(rc);
+ }
d_move(new, de);
iput(inode);
CDEBUG(D_DENTRY,
return new;
}
}
- ll_dops_init(de, 1, 1);
- __d_lustre_invalidate(de);
+ rc = ll_d_init(de);
+ if (rc < 0)
+ return ERR_PTR(rc);
d_add(de, inode);
CDEBUG(D_DENTRY, "Add dentry %p inode %p refc %d flags %#x\n",
de, de->d_inode, d_count(de), de->d_flags);
/* Only hash *de if it is unhashed (new dentry).
* Atoimc_open may passin hashed dentries for open.
*/
- if (d_unhashed(*de))
+ if (d_unhashed(*de)) {
*de = ll_splice_alias(inode, *de);
+ if (IS_ERR(*de))
+ return PTR_ERR(*de);
+ }
if (!it_disposition(it, DISP_LOOKUP_NEG)) {
/* we have lookup look - unhide dentry */
ll_frob_intent(&it, &lookup_it);
- /* As do_lookup is called before follow_mount, root dentry may be left
- * not valid, revalidate it here. */
- if (parent->i_sb->s_root && (parent->i_sb->s_root->d_inode == parent) &&
- (it->it_op & (IT_OPEN | IT_CREAT))) {
- rc = ll_inode_revalidate_it(parent->i_sb->s_root, it,
- MDS_INODELOCK_LOOKUP);
- if (rc)
- return ERR_PTR(rc);
- }
-
if (it->it_op == IT_GETATTR) {
rc = ll_statahead_enter(parent, &dentry, 0);
if (rc == 1) {
/* Optimize away (CREATE && !OPEN). Let .create handle the race. */
if ((flags & LOOKUP_CREATE ) && !(flags & LOOKUP_OPEN)) {
- ll_dops_init(dentry, 1, 1);
__d_lustre_invalidate(dentry);
d_add(dentry, NULL);
return NULL;
if (d_mountpoint(dentry))
return 1;
- if (unlikely(dentry == dentry->d_sb->s_root))
- return 1;
-
entry->se_inode = igrab(inode);
rc = md_revalidate_lock(ll_i2mdexp(dir), &it, ll_inode2fid(inode),NULL);
if (rc == 1) {
if ((*dentryp)->d_inode == NULL) {
*dentryp = ll_splice_alias(inode,
*dentryp);
+ if (IS_ERR(*dentryp)) {
+ ll_sai_unplug(sai, entry);
+ return PTR_ERR(*dentryp);
+ }
} else if ((*dentryp)->d_inode != inode) {
/* revalidate, but inode is recreated */
CDEBUG(D_READA,