* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
struct ll_inode_info *lli;
__u64 bits = lock->l_policy_data.l_inodebits.bits;
struct lu_fid *fid;
+ ldlm_mode_t mode = lock->l_req_mode;
/* Invalidate all dentries associated with this inode */
if (inode == NULL)
break;
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))
+ 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))
+ 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))
+ ll_have_md_lock(inode, MDS_INODELOCK_OPEN, mode))
bits &= ~MDS_INODELOCK_OPEN;
fid = ll_inode2fid(inode);
ll_drop_negative_dentry(inode);
}
- if ((bits & MDS_INODELOCK_LOOKUP) &&
- !cfs_list_empty(&lli->lli_sa_dentry)) {
- struct ll_dentry_data *lld, *next;
-
- cfs_spin_lock(&lli->lli_sa_lock);
- cfs_list_for_each_entry_safe(lld, next,
- &lli->lli_sa_dentry,
- lld_sa_alias)
- cfs_list_del_init(&lld->lld_sa_alias);
- cfs_spin_unlock(&lli->lli_sa_lock);
- }
-
if (inode->i_sb->s_root &&
inode != inode->i_sb->s_root->d_inode &&
(bits & MDS_INODELOCK_LOOKUP))
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_dops_init(*de, 1);
- }
- /* 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)
{
/* 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);
md_set_lock_data(sbi->ll_md_exp,
&it->d.lustre.it_lock_handle, inode, &bits);
- if (icbd->bits != NULL)
- *icbd->bits = bits;
- if (icbd->icbd_alias != NULL) {
- *icbd->icbd_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
from subsequent do_revalidate()->ll_inode_revalidate_it() in
Everybody else who needs correct file size would call
cl_glimpse_size or some equivalent themselves anyway.
Also see bug 7198. */
- ll_lookup_it_alias(de, inode, bits);
+ 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_dops_init(*de, 1);
+ }
+ /* we have lookup look - unhide dentry */
+ if (bits & MDS_INODELOCK_LOOKUP) {
+ lock_dentry(*de);
+ (*de)->d_flags &= ~DCACHE_LUSTRE_INVALID;
+ unlock_dentry(*de);
+ }
} else {
ll_dops_init(*de, 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)) {
+ if (ll_have_md_lock(parent, MDS_INODELOCK_UPDATE, LCK_MINMODE)) {
spin_lock(&dcache_lock);
ll_d_add(*de, NULL);
spin_unlock(&dcache_lock);
* 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);
+ rc = ll_inode_revalidate_it(parent->i_sb->s_root, it,
+ MDS_INODELOCK_LOOKUP);
if (rc)
RETURN(ERR_PTR(rc));
}
icbd.icbd_childp = &dentry;
icbd.icbd_parent = parent;
- icbd.icbd_alias = NULL;
- icbd.bits = NULL;
if (it->it_op & IT_CREAT ||
(it->it_op & IT_OPEN && it->it_create_mode & O_CREAT))
if (IS_ERR(op_data))
RETURN((void *)op_data);
- it->it_create_mode &= ~current->fs->umask;
+ it->it_create_mode &= ~cfs_curproc_umask();
rc = md_intent_lock(ll_i2mdexp(parent), op_data, NULL, 0, it,
lookup_flags, &req, ll_md_blocking_ast, 0);
return retval;
}
-#ifdef HAVE_VFS_INTENT_PATCHES
-static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
- struct nameidata *nd)
-{
- struct dentry *de;
- ENTRY;
-
- if (nd && nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
- de = ll_lookup_it(parent, dentry, &nd->intent, nd->flags);
- else
- de = ll_lookup_it(parent, dentry, NULL, 0);
-
- RETURN(de);
-}
-#else
struct lookup_intent *ll_convert_intent(struct open_intent *oit,
int lookup_flags)
{
it->it_op = IT_OPEN;
if (lookup_flags & LOOKUP_CREATE)
it->it_op |= IT_CREAT;
- it->it_create_mode = oit->create_mode;
+ it->it_create_mode = (oit->create_mode & S_IALLUGO) | S_IFREG;
it->it_flags = oit->flags;
} else {
it->it_op = IT_GETATTR;
if (IS_ERR(nd->intent.open.file))
RETURN((struct dentry *)nd->intent.open.file);
#endif
-
if (ll_d2d(dentry) && ll_d2d(dentry)->lld_it) {
it = ll_d2d(dentry)->lld_it;
ll_d2d(dentry)->lld_it = NULL;
RETURN(de);
}
-#endif
/* We depend on "mode" being set with the proper file type/umask by now */
static struct inode *ll_create_node(struct inode *dir, const char *name,
inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
NULL, 0, mode, 0, it);
- if (IS_ERR(inode)) {
+ if (IS_ERR(inode))
RETURN(PTR_ERR(inode));
- }
d_instantiate(dentry, inode);
/* Negative dentry may be unhashed if parent does not have UPDATE lock,
d_drop(dchild);
d_instantiate(dchild, inode);
- EXIT;
}
+ EXIT;
err_exit:
ptlrpc_req_finished(request);
name->len, name->name, dir->i_ino, dir->i_generation, dir,
mode, rdev);
- mode &= ~current->fs->umask;
+ mode &= ~cfs_curproc_umask();
switch (mode & S_IFMT) {
case 0:
RETURN(err);
}
-#ifndef HAVE_VFS_INTENT_PATCHES
static int ll_create_nd(struct inode *dir, struct dentry *dentry,
int mode, struct nameidata *nd)
{
return rc;
}
-#else
-static int ll_create_nd(struct inode *dir, struct dentry *dentry,
- int mode, struct nameidata *nd)
-{
- if (!nd || !nd->intent.d.lustre.it_disposition)
- /* No saved request? Just mknod the file */
- return ll_mknod_generic(dir, &dentry->d_name, mode, 0, dentry);
-
- return ll_create_it(dir, dentry, mode, &nd->intent);
-}
-#endif
static int ll_symlink_generic(struct inode *dir, struct qstr *name,
const char *tgt, struct dentry *dchild)
CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
name->len, name->name, dir->i_ino, dir->i_generation, dir);
- mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
+ mode = (mode & (S_IRWXUGO|S_ISVTX) & ~cfs_curproc_umask()) | S_IFDIR;
err = ll_new_node(dir, name, NULL, mode, 0, dchild, LUSTRE_OPC_MKDIR);
RETURN(err);
RETURN(err);
}
-#ifdef HAVE_VFS_INTENT_PATCHES
-static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
-{
- return ll_mknod_generic(nd->dentry->d_inode, &nd->last, mode,rdev,NULL);
-}
-static int ll_rename_raw(struct nameidata *srcnd, struct nameidata *tgtnd)
-{
- return ll_rename_generic(srcnd->dentry->d_inode, srcnd->dentry,
- NULL, &srcnd->last,
- tgtnd->dentry->d_inode, tgtnd->dentry,
- NULL, &tgtnd->last);
-}
-static int ll_link_raw(struct nameidata *srcnd, struct nameidata *tgtnd)
-{
- return ll_link_generic(srcnd->dentry->d_inode, tgtnd->dentry->d_inode,
- &tgtnd->last, NULL);
-}
-static int ll_symlink_raw(struct nameidata *nd, const char *tgt)
-{
- return ll_symlink_generic(nd->dentry->d_inode, &nd->last, tgt, NULL);
-}
-static int ll_rmdir_raw(struct nameidata *nd)
-{
- return ll_rmdir_generic(nd->dentry->d_inode, nd->dentry, NULL,
- &nd->last);
-}
-static int ll_mkdir_raw(struct nameidata *nd, int mode)
-{
- return ll_mkdir_generic(nd->dentry->d_inode, &nd->last, mode, NULL);
-}
-static int ll_unlink_raw(struct nameidata *nd)
-{
- return ll_unlink_generic(nd->dentry->d_inode, nd->dentry, NULL,
- &nd->last);
-}
-#endif
-
static int ll_mknod(struct inode *dir, struct dentry *dchild, int mode,
ll_dev_t rdev)
{
}
struct inode_operations ll_dir_inode_operations = {
-#ifdef HAVE_VFS_INTENT_PATCHES
- .link_raw = ll_link_raw,
- .unlink_raw = ll_unlink_raw,
- .symlink_raw = ll_symlink_raw,
- .mkdir_raw = ll_mkdir_raw,
- .rmdir_raw = ll_rmdir_raw,
- .mknod_raw = ll_mknod_raw,
- .rename_raw = ll_rename_raw,
- .setattr = ll_setattr,
- .setattr_raw = ll_setattr_raw,
-#endif
.mknod = ll_mknod,
.lookup = ll_lookup_nd,
.create = ll_create_nd,
};
struct inode_operations ll_special_inode_operations = {
-#ifdef HAVE_VFS_INTENT_PATCHES
- .setattr_raw = ll_setattr_raw,
-#endif
.setattr = ll_setattr,
.getattr = ll_getattr,
.permission = ll_inode_permission,