if (!ll_d_setup(de, true))
RETURN(-ENOMEM);
d_lustre_revalidate(de);
- if (S_ISDIR(inode->i_mode))
- ll_update_dir_depth_dmv(de->d_parent->d_inode, de);
+ if (S_ISDIR(inode->i_mode)) {
+ struct dentry *parent = dget_parent(de);
+
+ ll_update_dir_depth_dmv(d_inode(parent), de);
+ dput(parent);
+ }
}
RETURN(rc);
static int ll_revalidate_dentry(struct dentry *dentry,
unsigned int lookup_flags)
{
- struct inode *dir = dentry->d_parent->d_inode;
+ struct dentry *parent;
+ struct inode *dir;
int rc;
CDEBUG(D_VFSTRACE, "VFS Op:name=%s, flags=%u\n",
* to this dentry, then its lock has not been revoked and the
* path component is valid. */
if (lookup_flags & (LOOKUP_CONTINUE | LOOKUP_PARENT)) {
- if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
- ll_update_dir_depth_dmv(dir, dentry);
+ if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
+ parent = dget_parent(dentry);
+ ll_update_dir_depth_dmv(d_inode(parent), dentry);
+ dput(parent);
+ }
return 1;
}
if (lookup_flags & LOOKUP_RCU)
return -ECHILD;
+ parent = dget_parent(dentry);
+ dir = d_inode(parent);
if (dentry_may_statahead(dir, dentry))
ll_revalidate_statahead(dir, &dentry, dentry->d_inode == NULL);
if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
ll_update_dir_depth_dmv(dir, dentry);
+ dput(parent);
return 1;
}
GOTO(out, rc = 0);
if (unlikely(ll_dir_striped(inode))) {
+ struct dentry *parent = dget_parent(file_dentry(filp));
+ struct inode *i_dir = d_inode(parent);
+
/* Only needed for striped dir to fill ..see lmv_read_page() */
- if (file_dentry(filp)->d_parent != NULL &&
- file_dentry(filp)->d_parent->d_inode != NULL) {
+ if (i_dir) {
+ struct obd_export *exp = ll_i2mdexp(i_dir);
__u64 ibits = MDS_INODELOCK_LOOKUP;
- struct inode *parent =
- file_dentry(filp)->d_parent->d_inode;
- if (ll_have_md_lock(ll_i2mdexp(parent), parent, &ibits,
- LCK_MINMODE))
- pfid = *ll_inode2fid(parent);
+ if (ll_have_md_lock(exp, i_dir, &ibits, LCK_MINMODE))
+ pfid = *ll_inode2fid(i_dir);
}
+ dput(parent);
/* If it can not find in cache, do lookup .. on the master
* object */
struct lookup_intent *itp)
{
struct ll_sb_info *sbi = ll_i2sbi(de->d_inode);
- struct dentry *parent = de->d_parent;
+ struct dentry *parent = dget_parent(de);
char *name = NULL;
int len = 0;
struct md_op_data *op_data;
len = de->d_name.len;
name = kmalloc(len + 1, GFP_NOFS);
if (!name)
- RETURN(-ENOMEM);
+ GOTO(out_put, rc = -ENOMEM);
/* race here */
spin_lock(&de->d_lock);
if (!lu_name_is_valid_2(name, len)) {
kfree(name);
- RETURN(-ESTALE);
+ GOTO(out_put, rc = -ESTALE);
}
}
name, len, 0, LUSTRE_OPC_OPEN, NULL);
if (IS_ERR(op_data)) {
kfree(name);
- RETURN(PTR_ERR(op_data));
+ GOTO(out_put, rc = PTR_ERR(op_data));
}
op_data->op_data = lmm;
op_data->op_data_size = lmmsize;
*/
if (rc == -ENOENT)
rc = -ESTALE;
-
+out_put:
+ dput(parent);
RETURN(rc);
}
static int ll_inode_revalidate(struct dentry *dentry, enum ldlm_intent_flags op)
{
- struct inode *parent;
+ struct dentry *parent = NULL;
+ struct inode *dir;
struct inode *inode = dentry->d_inode;
struct obd_export *exp = ll_i2mdexp(inode);
struct lookup_intent oit = {
PFID(ll_inode2fid(inode)), inode, dentry->d_name.name);
if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID) {
- parent = dentry->d_parent->d_inode;
+ parent = dget_parent(dentry);
+ dir = d_inode(parent);
name = dentry->d_name.name;
namelen = dentry->d_name.len;
} else {
- parent = inode;
+ dir = inode;
}
- op_data = ll_prep_md_op_data(NULL, parent, inode, name, namelen, 0,
+ op_data = ll_prep_md_op_data(NULL, dir, inode, name, namelen, 0,
LUSTRE_OPC_ANY, NULL);
+ if (parent)
+ dput(parent);
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
struct inode *inode = de->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ll_inode_info *lli = ll_i2info(inode);
- struct inode *dir = de->d_parent->d_inode;
+ struct dentry *parent;
+ struct inode *dir;
bool need_glimpse = true;
ktime_t kstart = ktime_get();
int rc;
request_mask & STATX_MTIME))
need_glimpse = false;
+ parent = dget_parent(de);
+ dir = d_inode(parent);
ll_statahead_enter(dir, de);
if (dentry_may_statahead(dir, de))
ll_start_statahead(dir, de, need_glimpse &&
!(flags & AT_STATX_DONT_SYNC));
+ dput(parent);
if (flags & AT_STATX_DONT_SYNC)
GOTO(fill_attr, rc = 0);
static int pcc_inode_remove(struct inode *inode, struct dentry *pcc_dentry)
{
+ struct dentry *parent = dget_parent(pcc_dentry);
int rc;
- rc = vfs_unlink(&nop_mnt_idmap,
- pcc_dentry->d_parent->d_inode, pcc_dentry);
+ rc = vfs_unlink(&nop_mnt_idmap, d_inode(parent), pcc_dentry);
if (rc)
CWARN("%s: failed to unlink PCC file %pd, rc = %d\n",
ll_i2sbi(inode)->ll_fsname, pcc_dentry, rc);
+ dput(parent);
return rc;
}
return;
if (pca->pca_dentry) {
+ struct dentry *parent;
+ struct inode *i_dir;
const struct cred *old_cred;
int rc;
old_cred = override_creds(pcc_super_cred(sb));
- rc = vfs_unlink(&nop_mnt_idmap,
- pca->pca_dentry->d_parent->d_inode,
- pca->pca_dentry);
+ parent = dget_parent(pca->pca_dentry);
+ i_dir = d_inode(parent);
+ rc = vfs_unlink(&nop_mnt_idmap, i_dir, pca->pca_dentry);
+ dput(parent);
if (rc)
CWARN("%s: failed to unlink PCC file %pd: rc = %d\n",
ll_s2sbi(sb)->ll_fsname, pca->pca_dentry, rc);
struct ll_inode_info *lli = ll_i2info(dir);
struct ll_statahead_info *sai = NULL;
struct ll_statahead_context *ctx = NULL;
- struct dentry *parent = dentry->d_parent;
+ struct dentry *parent;
struct task_struct *task;
- struct ll_sb_info *sbi = ll_i2sbi(parent->d_inode);
+ struct ll_sb_info *sbi;
int first = LS_FIRST_DE;
int rc = 0;
if (sa_pattern_detect(dir, dentry, &first) == false)
RETURN(0);
+ parent = dget_parent(dentry);
+ sbi = ll_i2sbi(d_inode(parent));
if (unlikely(atomic_inc_return(&sbi->ll_sa_running) >
sbi->ll_sa_running_max)) {
CDEBUG(D_READA,
"Too many concurrent statahead instances, avoid new statahead instance temporarily.\n");
+ dput(parent);
GOTO(out, rc = -EMFILE);
}
+ /* on success ll_sai_alloc holds a ref on parent */
sai = ll_sai_alloc(parent);
+ dput(parent);
if (!sai)
GOTO(out, rc = -ENOMEM);
*/
if (xh && xh->flags == XATTR_TRUSTED_T &&
strcmp(xattr_name, XATTR_NAME_PROJID) == 0) {
- struct inode *dir = d_inode(dentry->d_parent);
+ struct dentry *parent = dget_parent(dentry);
+ struct inode *dir = d_inode(parent);
if ((ll_i2info(inode)->lli_projid ==
ll_i2info(dir)->lli_projid) &&
test_bit(LLIF_PROJECT_INHERIT,
&ll_i2info(dir)->lli_flags))
hide_xattr = true;
+ dput(parent);
} else if (xh && xh->flags == XATTR_SECURITY_T &&
strcmp(xattr_name, "security.c") == 0) {
/* Listing xattrs should not expose encryption