static int ll_set_inode(struct inode *inode, void *opaque)
{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct mdt_body *body = ((struct lustre_md *)opaque)->body;
+
+ if (unlikely(!(body->valid & OBD_MD_FLID))) {
+ CERROR("MDS body missing FID\n");
+ return -EINVAL;
+ }
+
+ lli->lli_fid = body->fid1;
return 0;
}
struct inode *ll_iget(struct super_block *sb, ino_t hash,
struct lustre_md *md)
{
- struct ll_inode_info *lli;
struct inode *inode;
ENTRY;
inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);
if (inode) {
- lli = ll_i2info(inode);
if (inode->i_state & I_NEW) {
int rc;
{
struct dentry *dentry, *tmp_alias, *tmp_subdir;
- spin_lock(&ll_lookup_lock);
+ cfs_spin_lock(&ll_lookup_lock);
spin_lock(&dcache_lock);
restart:
list_for_each_entry_safe(dentry, tmp_alias,
}
}
spin_unlock(&dcache_lock);
- spin_unlock(&ll_lookup_lock);
+ cfs_spin_unlock(&ll_lookup_lock);
}
__u32 ll_i2suppgid(struct inode *i)
{
- if (in_group_p(i->i_gid))
+ if (cfs_curproc_is_in_groups(i->i_gid))
return (__u32)i->i_gid;
else
return (__u32)(-1);
struct dentry *dentry;
struct dentry *last_discon = NULL;
- spin_lock(&ll_lookup_lock);
+ cfs_spin_lock(&ll_lookup_lock);
spin_lock(&dcache_lock);
list_for_each(tmp, &inode->i_dentry) {
dentry = list_entry(tmp, struct dentry, d_alias);
dget_locked(dentry);
lock_dentry(dentry);
__d_drop(dentry);
-#ifdef DCACHE_LUSTRE_INVALID
- dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
-#endif
unlock_dentry(dentry);
ll_dops_init(dentry, 0);
d_rehash_cond(dentry, 0); /* avoid taking dcache_lock inside */
spin_unlock(&dcache_lock);
- spin_unlock(&ll_lookup_lock);
+ cfs_spin_unlock(&ll_lookup_lock);
iput(inode);
CDEBUG(D_DENTRY, "alias dentry %.*s (%p) parent %p inode %p "
"refc %d\n", de->d_name.len, de->d_name.name, de,
"refc %d\n", last_discon, last_discon->d_inode,
atomic_read(&last_discon->d_count));
dget_locked(last_discon);
+ lock_dentry(last_discon);
+ last_discon->d_flags |= DCACHE_LUSTRE_INVALID;
+ unlock_dentry(last_discon);
spin_unlock(&dcache_lock);
- spin_unlock(&ll_lookup_lock);
+ cfs_spin_unlock(&ll_lookup_lock);
ll_dops_init(last_discon, 1);
d_rehash(de);
d_move(last_discon, de);
iput(inode);
return last_discon;
}
-
+ lock_dentry(de);
+ de->d_flags |= DCACHE_LUSTRE_INVALID;
+ unlock_dentry(de);
ll_d_add(de, inode);
spin_unlock(&dcache_lock);
- spin_unlock(&ll_lookup_lock);
+ cfs_spin_unlock(&ll_lookup_lock);
return de;
}
+void ll_lookup_it_alias(struct dentry **de, struct inode *inode, __u32 bits)
+{
+ struct dentry *save = *de;
+ ENTRY;
+
+ ll_dops_init(*de, 1);
+ *de = ll_find_alias(inode, *de);
+ if (*de != save) {
+ struct ll_dentry_data *lld = ll_d2d(*de);
+
+ /* just make sure the ll_dentry_data is ready */
+ if (unlikely(lld == NULL)) {
+ ll_set_dd(*de);
+ lld = ll_d2d(*de);
+ if (likely(lld != NULL))
+ lld->lld_sa_generation = 0;
+ }
+ }
+ /* we have lookup look - unhide dentry */
+ if (bits & MDS_INODELOCK_LOOKUP) {
+ lock_dentry(*de);
+ (*de)->d_flags &= ~DCACHE_LUSTRE_INVALID;
+ unlock_dentry(*de);
+ }
+ EXIT;
+}
+
int ll_lookup_it_finish(struct ptlrpc_request *request,
- struct lookup_intent *it, void *data)
+ struct lookup_intent *it, void *data,
+ struct inode **alias)
{
struct it_cb_data *icbd = data;
struct dentry **de = icbd->icbd_childp;
/* NB 1 request reference will be taken away by ll_intent_lock()
* when I return */
if (!it_disposition(it, DISP_LOOKUP_NEG)) {
- struct dentry *save = *de;
+ __u32 bits;
rc = ll_prep_inode(&inode, request, (*de)->d_sb);
if (rc)
CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
inode, inode->i_ino, inode->i_generation);
md_set_lock_data(sbi->ll_md_exp,
- &it->d.lustre.it_lock_handle, inode);
+ &it->d.lustre.it_lock_handle, inode, &bits);
+
+ if (alias != NULL) {
+ *alias = inode;
+ RETURN(0);
+ }
/* We used to query real size from OSTs here, but actually
this is not needed. For stat() calls size would be updated
Everybody else who needs correct file size would call
cl_glimpse_size or some equivalent themselves anyway.
Also see bug 7198. */
-
- ll_dops_init(*de, 1);
- *de = ll_find_alias(inode, *de);
- if (*de != save) {
- struct ll_dentry_data *lld = ll_d2d(*de);
-
- /* just make sure the ll_dentry_data is ready */
- if (unlikely(lld == NULL)) {
- ll_set_dd(*de);
- lld = ll_d2d(*de);
- if (likely(lld != NULL))
- lld->lld_sa_generation = 0;
- }
- }
+ ll_lookup_it_alias(de, inode, bits);
} else {
ll_dops_init(*de, 1);
/* Check that parent has UPDATE lock. If there is none, we
ll_d_add(*de, NULL);
spin_unlock(&dcache_lock);
} else {
+ /* negative lookup - and don't have update lock to
+ * parent */
+ lock_dentry(*de);
+ (*de)->d_flags |= DCACHE_LUSTRE_INVALID;
+ unlock_dentry(*de);
+
(*de)->d_inode = NULL;
/* We do not want to hash the dentry if don`t have a
* lock, but if this dentry is later used in d_move,
if (it->it_op == IT_GETATTR) {
first = ll_statahead_enter(parent, &dentry, 1);
if (first >= 0) {
- ll_statahead_exit(dentry, first);
+ ll_statahead_exit(parent, dentry, first);
if (first == 1)
RETURN(retval = dentry);
}
if (rc < 0)
GOTO(out, retval = ERR_PTR(rc));
- rc = ll_lookup_it_finish(req, it, &icbd);
+ rc = ll_lookup_it_finish(req, it, &icbd, NULL);
if (rc != 0) {
ll_intent_release(it);
GOTO(out, retval = ERR_PTR(rc));
}
if (first == -EEXIST)
- ll_statahead_mark(dentry);
+ ll_statahead_mark(parent, dentry);
if ((it->it_op & IT_OPEN) && dentry->d_inode &&
!S_ISREG(dentry->d_inode->i_mode) &&
it = ll_d2d(dentry)->lld_it;
ll_d2d(dentry)->lld_it = NULL;
} else {
+ if ((nd->flags & LOOKUP_CREATE ) && !(nd->flags & LOOKUP_OPEN)) {
+ /* We are sure this is new dentry, so we need to create
+ our private data and set the dentry ops */
+ ll_dops_init(dentry, 1);
+ RETURN(NULL);
+ }
it = ll_convert_intent(&nd->intent.open, nd->flags);
if (IS_ERR(it))
RETURN((struct dentry *)it);
(struct ptlrpc_request *)
it->d.lustre.it_data);
} else {
- struct file *filp;
- nd->intent.open.file->private_data = it;
- filp =lookup_instantiate_filp(nd,dentry,
- NULL);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
/* 2.6.1[456] have a bug in open_namei() that forgets to check
* nd->intent.open.file for error, so we need to return it as lookup's result
* instead */
+ struct file *filp;
+ nd->intent.open.file->private_data = it;
+ filp =lookup_instantiate_filp(nd,dentry,
+ NULL);
if (IS_ERR(filp)) {
if (de)
dput(de);
de = (struct dentry *) filp;
}
+#else
+ nd->intent.open.file->private_data = it;
+ (void)lookup_instantiate_filp(nd,dentry,
+ NULL);
#endif
}
CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n",
inode, inode->i_ino, inode->i_generation);
md_set_lock_data(sbi->ll_md_exp,
- &it->d.lustre.it_lock_handle, inode);
+ &it->d.lustre.it_lock_handle, inode, NULL);
EXIT;
out:
ptlrpc_req_finished(request);
GOTO(err_exit, err = PTR_ERR(op_data));
err = md_create(sbi->ll_md_exp, op_data, tgt, tgt_len, mode,
- current->fsuid, current->fsgid,
+ cfs_curproc_fsuid(), cfs_curproc_fsgid(),
cfs_curproc_cap_pack(), rdev, &request);
ll_finish_md_op_data(op_data);
if (err)
}
LASSERT(rc >= sizeof(*lsm));
- rc = obd_checkmd(ll_i2dtexp(dir), ll_i2mdexp(dir), lsm);
- if (rc)
- GOTO(out_free_memmd, rc);
-
OBDO_ALLOC(oa);
if (oa == NULL)
GOTO(out_free_memmd, rc = -ENOMEM);