* 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.
*/
/*
#include <linux/quotaops.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
-#include <linux/dcache.h>
-#include <linux/buffer_head.h>
#define DEBUG_SUBSYSTEM S_LLITE
{
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);
}
break;
case LDLM_CB_CANCELING: {
struct inode *inode = ll_inode_from_lock(lock);
+ 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_md_real_close(inode, flags);
}
+ lli = ll_i2info(inode);
if (bits & MDS_INODELOCK_UPDATE)
- ll_i2info(inode)->lli_flags &= ~LLIF_MDS_SIZE_LOCK;
+ lli->lli_flags &= ~LLIF_MDS_SIZE_LOCK;
if (S_ISDIR(inode->i_mode) &&
(bits & MDS_INODELOCK_UPDATE)) {
__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);
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,
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;
}
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;
- }
+ 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);
+ (*de)->d_flags &= ~DCACHE_LUSTRE_INVALID;
unlock_dentry(*de);
}
} else {
/* 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));
}
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;
} 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);
RETURN(de);
}
-#endif
-
-/**
- * check new allocated inode, new inode shld not have any valid alias
- */
-static void ll_validate_new_inode(struct inode *new)
-{
- struct list_head *lp;
- struct dentry * dentry;
- int need_inval = 0;
- int in_recheck = 0;
-
- if (list_empty(&new->i_dentry))
- return;
-recheck:
- spin_lock(&dcache_lock);
- list_for_each(lp, &new->i_dentry) {
- dentry = list_entry(lp, struct dentry, d_alias);
- if (!d_unhashed(dentry) && !(dentry->d_flags & DCACHE_LUSTRE_INVALID)){
- ll_dump_inode(new);
- if (in_recheck)
- LBUG();
- }
- need_inval = 1;
- }
- spin_unlock(&dcache_lock);
-
- if (need_inval && !in_recheck) {
- /* kill all old inode's data pages */
- truncate_inode_pages(new->i_mapping, 0);
-
- /* invalidate all dirent and recheck inode */
- ll_unhash_aliases(new);
- in_recheck = 1;
- goto recheck;
- }
-}
/* 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,
if (rc)
GOTO(out, inode = ERR_PTR(rc));
- ll_validate_new_inode(inode);
+ LASSERT(list_empty(&inode->i_dentry));
/* We asked for a lock on the directory, but were granted a
* lock on the inode. Since we finally have an inode pointer,
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));
- }
- /* it might been set during parent dir revalidation */
- dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
d_instantiate(dentry, inode);
/* Negative dentry may be unhashed if parent does not have UPDATE lock,
* but some callers, e.g. do_coredump, expect dentry to be hashed after
&RMF_MDT_BODY);
LASSERT(body);
- /* mtime is always updated with ctime, but can be set in past.
- As write and utime(2) may happen within 1 second, and utime's
- mtime has a priority over write's one, so take mtime from mds
- for the same ctimes. */
+ if (body->valid & OBD_MD_FLMTIME &&
+ body->mtime > LTIME_S(inode->i_mtime)) {
+ CDEBUG(D_INODE, "setting ino %lu mtime from %lu to "LPU64"\n",
+ inode->i_ino, LTIME_S(inode->i_mtime), body->mtime);
+ LTIME_S(inode->i_mtime) = body->mtime;
+ }
if (body->valid & OBD_MD_FLCTIME &&
- body->ctime >= LTIME_S(inode->i_ctime)) {
+ body->ctime > LTIME_S(inode->i_ctime))
LTIME_S(inode->i_ctime) = body->ctime;
-
- if (body->valid & OBD_MD_FLMTIME) {
- CDEBUG(D_INODE, "setting ino %lu mtime from %lu "
- "to "LPU64"\n", inode->i_ino,
- LTIME_S(inode->i_mtime), body->mtime);
- LTIME_S(inode->i_mtime) = body->mtime;
- }
- }
}
static int ll_new_node(struct inode *dir, struct qstr *name,
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)
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);
}
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);
oa->o_id = lsm->lsm_object_id;
- oa->o_gr = lsm->lsm_object_gr;
+ oa->o_seq = lsm->lsm_object_seq;
oa->o_mode = body->mode & S_IFMT;
oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP;
return rc;
}
+/* ll_unlink_generic() doesn't update the inode with the new link count.
+ * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there
+ * is any lock existing. They will recycle dentries and inodes based upon locks
+ * too. b=20433 */
static int ll_unlink_generic(struct inode *dir, struct dentry *dparent,
struct dentry *dchild, struct qstr *name)
{
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,