/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011 Whamcloud, Inc.
+ *
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#include <linux/quotaops.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
+#include <linux/security.h>
#define DEBUG_SUBSYSTEM S_LLITE
#include <lustre_lite.h>
#include <lustre_dlm.h>
#include <lustre_ver.h>
-#include <lustre_mdc.h>
#include "llite_internal.h"
/*
if (inode) {
if (inode->i_state & I_NEW) {
- int rc;
+ int rc = 0;
ll_read_inode2(inode, md);
- rc = cl_inode_init(inode, md);
+ if (S_ISREG(inode->i_mode) &&
+ ll_i2info(inode)->lli_clob == NULL)
+ rc = cl_inode_init(inode, md);
if (rc != 0) {
md->lsm = NULL;
make_bad_inode(inode);
LASSERT(lock->l_flags & LDLM_FL_CANCELING);
/* For OPEN locks we differentiate between lock modes - CR, CW. PR - bug 22891 */
- if ((bits & MDS_INODELOCK_LOOKUP) &&
- ll_have_md_lock(inode, MDS_INODELOCK_LOOKUP, LCK_MINMODE))
- bits &= ~MDS_INODELOCK_LOOKUP;
- if ((bits & MDS_INODELOCK_UPDATE) &&
- ll_have_md_lock(inode, MDS_INODELOCK_UPDATE, LCK_MINMODE))
- bits &= ~MDS_INODELOCK_UPDATE;
- if ((bits & MDS_INODELOCK_OPEN) &&
- ll_have_md_lock(inode, MDS_INODELOCK_OPEN, mode))
- bits &= ~MDS_INODELOCK_OPEN;
+ if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE))
+ ll_have_md_lock(inode, &bits, LCK_MINMODE);
+
+ if (bits & MDS_INODELOCK_OPEN)
+ ll_have_md_lock(inode, &bits, mode);
fid = ll_inode2fid(inode);
if (lock->l_resource->lr_name.name[0] != fid_seq(fid) ||
if (inode)
list_add(&de->d_alias, &inode->i_dentry);
de->d_inode = inode;
+ /* d_instantiate() replacement code should initialize security
+ * context. */
+ security_d_instantiate(de, inode);
/* d_rehash */
if (!d_unhashed(de)) {
* in ll_revalidate_it. After revaliadate inode will be have hashed aliases
* and it triggers BUG_ON in d_instantiate_unique (bug #10954).
*/
-static struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
+struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
{
struct list_head *tmp;
struct dentry *dentry;
}
if (dentry->d_flags & DCACHE_DISCONNECTED) {
- LASSERT(last_discon == NULL);
+ /* LASSERT(last_discon == NULL); LU-405, bz 20055 */
last_discon = dentry;
continue;
}
continue;
dget_locked(dentry);
- lock_dentry(dentry);
- __d_drop(dentry);
- unlock_dentry(dentry);
ll_dops_init(dentry, 0, 1);
- d_rehash_cond(dentry, 0); /* avoid taking dcache_lock inside */
+ ll_dentry_rehash(dentry, 1);
spin_unlock(&dcache_lock);
cfs_spin_unlock(&ll_lookup_lock);
iput(inode);
struct it_cb_data *icbd = data;
struct dentry **de = icbd->icbd_childp;
struct inode *parent = icbd->icbd_parent;
- struct ll_sb_info *sbi = ll_i2sbi(parent);
struct inode *inode = NULL;
int rc;
ENTRY;
* when I return */
if (!it_disposition(it, DISP_LOOKUP_NEG)) {
struct dentry *save = *de;
- __u32 bits;
+ __u64 bits = 0;
rc = ll_prep_inode(&inode, request, (*de)->d_sb);
if (rc)
RETURN(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, &bits);
+ ll_set_lock_data(ll_i2sbi(parent)->ll_md_exp, inode, it, &bits);
/* We used to query real size from OSTs here, but actually
this is not needed. For stat() calls size would be updated
ll_dops_init(*de, 1, 1);
}
/* we have lookup look - unhide dentry */
- if (bits & MDS_INODELOCK_LOOKUP) {
- lock_dentry(*de);
- (*de)->d_flags &= ~DCACHE_LUSTRE_INVALID;
- unlock_dentry(*de);
- }
+ ll_dentry_reset_flags(*de, bits);
} else {
+ __u64 ibits;
+
ll_dops_init(*de, 1, 1);
/* Check that parent has UPDATE lock. If there is none, we
cannot afford to hash this dentry (done by ll_d_add) as it
might get picked up later when UPDATE lock will appear */
- if (ll_have_md_lock(parent, MDS_INODELOCK_UPDATE, LCK_MINMODE)) {
+ ibits = MDS_INODELOCK_UPDATE;
+ if (ll_have_md_lock(parent, &ibits, LCK_MINMODE)) {
spin_lock(&dcache_lock);
ll_d_add(*de, NULL);
spin_unlock(&dcache_lock);
struct md_op_data *op_data;
struct it_cb_data icbd;
__u32 opc;
- int rc, first = 0;
+ int rc;
ENTRY;
if (dentry->d_name.len > ll_i2sbi(parent)->ll_namelen)
}
if (it->it_op == IT_GETATTR) {
- first = ll_statahead_enter(parent, &dentry, 1);
- if (first >= 0) {
- ll_statahead_exit(parent, dentry, first);
- if (first == 1)
- RETURN(retval = dentry);
+ rc = ll_statahead_enter(parent, &dentry, 0);
+ if (rc == 1) {
+ if (dentry == save)
+ GOTO(out, retval = NULL);
+ GOTO(out, retval = dentry);
}
}
GOTO(out, retval = ERR_PTR(rc));
}
- if (first == -EEXIST)
- ll_statahead_mark(parent, dentry);
-
if ((it->it_op & IT_OPEN) && dentry->d_inode &&
!S_ISREG(dentry->d_inode->i_mode) &&
!S_ISDIR(dentry->d_inode->i_mode)) {
out:
if (req)
ptlrpc_req_finished(req);
+ if (it->it_op == IT_GETATTR && (retval == NULL || retval == dentry))
+ ll_statahead_mark(parent, dentry);
return retval;
}
* stuff it in the lock. */
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, NULL);
+ ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL);
EXIT;
out:
ptlrpc_req_finished(request);