#include <linux/obd_support.h>
#include <linux/lustre_lite.h>
#include <linux/lustre_dlm.h>
+#include <linux/lustre_version.h>
#include "llite_internal.h"
/* methods */
last_ino = md->body->ino;
last_gen = md->body->generation;
CDEBUG(D_VFSTRACE,
- "comparing inode %p ino %lu/%u to body %u/%u\n",
+ "comparing inode %p ino %lu/%u/%u to body %u/%u/%u\n",
inode, inode->i_ino, inode->i_generation,
- md->body->ino, md->body->generation);
+ ll_i2info(inode)->lli_mds,
+ md->body->ino, md->body->generation,
+ md->body->mds);
}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+ if (inode->i_ino != md->body->ino)
+ return 0;
+#endif
if (inode->i_generation != md->body->generation)
return 0;
+ if (ll_i2info(inode)->lli_mds != md->body->mds)
+ return 0;
+
/* Apply the attributes in 'opaque' to this inode */
- ll_update_inode(inode, md->body, md->lsm);
+ ll_update_inode(inode, md);
return 1;
}
ll_read_inode2(inode, opaque);
return 0;
}
+
struct inode *ll_iget(struct super_block *sb, ino_t hash,
struct lustre_md *md)
{
break;
case LDLM_CB_CANCELING: {
struct inode *inode = ll_inode_from_lock(lock);
+ __u64 bits = lock->l_policy_data.l_inodebits.bits;
- /* Invalidate all dentries associated with this inode */
+ /* For lookup locks: Invalidate all dentries associated with
+ this inode, for UPDATE locks - invalidate directory pages */
if (inode == NULL)
break;
- clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK,
- &(ll_i2info(inode)->lli_flags));
+ if (bits & MDS_INODELOCK_UPDATE)
+ clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK,
+ &(ll_i2info(inode)->lli_flags));
+
if (lock->l_resource->lr_name.name[0] != inode->i_ino ||
lock->l_resource->lr_name.name[1] != inode->i_generation) {
LDLM_ERROR(lock, "data mismatch with ino %lu/%u",
inode->i_ino, inode->i_generation);
}
- if (S_ISDIR(inode->i_mode)) {
+
+ /* If lookup lock is cancelled, we just drop the dentry and
+ this will cause us to reget data from MDS when we'd want to
+ access this dentry/inode again. If this is lock on
+ other parts of inode that is cancelled, we do not need to do
+ much (but need to discard data from readdir, if any), since
+ abscence of lock will cause ll_revalidate_it (called from
+ stat() and similar functions) to renew the data anyway */
+ if (S_ISDIR(inode->i_mode) &&
+ (bits & MDS_INODELOCK_UPDATE)) {
CDEBUG(D_INODE, "invalidating inode %lu\n",
inode->i_ino);
- ll_invalidate_inode_pages(inode);
+ truncate_inode_pages(inode->i_mapping, 0);
}
if (inode->i_sb->s_root &&
- inode != inode->i_sb->s_root->d_inode)
+ inode != inode->i_sb->s_root->d_inode &&
+ (bits & MDS_INODELOCK_LOOKUP))
ll_unhash_aliases(inode);
iput(inode);
break;
{ .name = {inode->i_ino, inode->i_generation} };
struct obd_device *obddev = class_conn2obd(conn);
ENTRY;
+
RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, &res_id, flags,
opaque));
}
-
-void ll_prepare_mdc_op_data(struct mdc_op_data *data, struct inode *i1,
- struct inode *i2, const char *name, int namelen,
- int mode)
-{
- LASSERT(i1);
-
- ll_i2uctxt(&data->ctxt, i1, i2);
- ll_inode2fid(&data->fid1, i1);
-
- if (i2)
- ll_inode2fid(&data->fid2, i2);
-
- data->name = name;
- data->namelen = namelen;
- data->create_mode = mode;
- data->mod_time = LTIME_S(CURRENT_TIME);
-}
-
/* Search "inode"'s alias list for a dentry that has the same name and parent as
* de. If found, return it. If not found, return de. */
struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
atomic_inc(&dentry->d_count);
iput(inode);
dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
+ CDEBUG(D_DENTRY, "alias dentry %*s (%p) parent %p inode %p "
+ "refc %d\n", de->d_name.len, de->d_name.name, de,
+ de->d_parent, de->d_inode, atomic_read(&de->d_count));
return dentry;
}
if (!it_disposition(it, DISP_LOOKUP_NEG)) {
ENTRY;
- rc = ll_prep_inode(sbi->ll_osc_exp, &inode, request, offset,
- dentry->d_sb);
+ rc = ll_prep_inode(sbi->ll_osc_exp, sbi->ll_mdc_exp,
+ &inode, request, offset, dentry->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);
+ mdc_set_lock_data(NULL, &it->d.lustre.it_lock_handle, inode);
+
/* If this is a stat, get the authoritative file size */
if (it->it_op == IT_GETATTR && S_ISREG(inode->i_mode) &&
ll_i2info(inode)->lli_smd != NULL) {
- struct ldlm_extent extent = {0, OBD_OBJECT_EOF};
- struct lustre_handle lockh = {0};
struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
+ struct ost_lvb lvb;
ldlm_error_t rc;
LASSERT(lsm->lsm_object_id != 0);
- rc = ll_extent_lock(NULL, inode, lsm, LCK_PR, &extent,
- &lockh);
- if (rc != ELDLM_OK) {
+ /* bug 2334: drop MDS lock before acquiring OST lock */
+ ll_intent_drop_lock(it);
+
+ rc = ll_glimpse_size(inode, &lvb);
+ if (rc) {
iput(inode);
- RETURN(-EIO);
+ RETURN(rc);
}
- ll_extent_unlock(NULL, inode, lsm, LCK_PR, &lockh);
+ inode->i_size = lvb.lvb_size;
}
dentry = *de = ll_find_alias(inode, dentry);
dentry->d_op = &ll_d_ops;
ll_set_dd(dentry);
- if (dentry == saved)
+ if (dentry == saved) {
d_add(dentry, inode);
+ }
RETURN(0);
}
static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
+ struct nameidata *nd,
struct lookup_intent *it, int flags)
{
struct dentry *save = dentry, *retval;
if (d_mountpoint(dentry))
CERROR("Tell Peter, lookup on mtpt, it %s\n", LL_IT2STR(it));
+ if (nd != NULL)
+ nd->mnt->mnt_last_used = jiffies;
+
ll_frob_intent(&it, &lookup_it);
icbd.icbd_childp = &dentry;
ll_inode2fid(&pfid, parent);
ll_i2uctxt(&ctxt, parent, NULL);
- rc = mdc_intent_lock(ll_i2mdcexp(parent), &ctxt, &pfid,
- dentry->d_name.name, dentry->d_name.len, NULL, 0,
- NULL, it, flags, &req, ll_mdc_blocking_ast);
+ rc = md_intent_lock(ll_i2mdcexp(parent), &ctxt, &pfid,
+ dentry->d_name.name, dentry->d_name.len, NULL, 0,
+ NULL, it, flags, &req, ll_mdc_blocking_ast);
if (rc < 0)
GOTO(out, retval = ERR_PTR(rc));
ll_lookup_finish_locks(it, dentry);
+ if (nd &&
+ dentry->d_inode != NULL && dentry->d_inode->i_mode & S_ISUID &&
+ S_ISDIR(dentry->d_inode->i_mode) &&
+ (flags & LOOKUP_CONTINUE || (it->it_op & (IT_CHDIR | IT_OPEN))))
+ ll_dir_process_mount_object(dentry, nd->mnt);
+
if (dentry == save)
GOTO(out, retval = NULL);
else
out:
if (req)
ptlrpc_req_finished(req);
+ if (dentry->d_inode)
+ CDEBUG(D_INODE, "lookup 0x%p in %lu/%lu: %*s -> %lu/%lu\n",
+ dentry,
+ (unsigned long) parent->i_ino,
+ (unsigned long) parent->i_generation,
+ dentry->d_name.len, dentry->d_name.name,
+ (unsigned long) dentry->d_inode->i_ino,
+ (unsigned long) dentry->d_inode->i_generation);
+ else
+ CDEBUG(D_INODE, "lookup 0x%p in %lu/%lu: %*s -> ??\n",
+ dentry,
+ (unsigned long) parent->i_ino,
+ (unsigned long) parent->i_generation,
+ dentry->d_name.len, dentry->d_name.name);
return retval;
}
struct dentry *de;
ENTRY;
- if (nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
- de = ll_lookup_it(parent, dentry, &nd->intent, nd->flags);
+ if (nd && nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
+ de = ll_lookup_it(parent, dentry, nd, &nd->intent, nd->flags);
else
- de = ll_lookup_it(parent, dentry, NULL, 0);
+ de = ll_lookup_it(parent, dentry, nd, NULL, 0);
RETURN(de);
}
LASSERT(it && it->d.lustre.it_disposition);
request = it->d.lustre.it_data;
- rc = ll_prep_inode(sbi->ll_osc_exp, &inode, request, 1, dir->i_sb);
+ rc = ll_prep_inode(sbi->ll_osc_exp, sbi->ll_mdc_exp,
+ &inode, request, 1, dir->i_sb);
if (rc)
GOTO(out, inode = ERR_PTR(rc));
* 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);
- mdc_set_lock_data(&it->d.lustre.it_lock_handle, inode);
+ mdc_set_lock_data(NULL, &it->d.lustre.it_lock_handle, inode);
EXIT;
out:
ptlrpc_req_finished(request);
{
struct inode *inode;
struct ptlrpc_request *request = it->d.lustre.it_data;
+ struct obd_export *mdc_exp = ll_i2mdcexp(dir);
int rc = 0;
ENTRY;
if (rc)
RETURN(rc);
- mdc_store_inode_generation(request, 2, 1);
+ mdc_store_inode_generation(mdc_exp, request, 2, 1);
inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
NULL, 0, mode, 0, it);
if (IS_ERR(inode)) {
case S_IFIFO:
case S_IFSOCK:
ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
- err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
- current->fsuid, current->fsgid,
- rdev, &request);
+ err = md_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
+ current->fsuid, current->fsgid, rdev, &request);
ptlrpc_req_finished(request);
break;
case S_IFDIR:
case S_IFIFO:
case S_IFSOCK:
ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
- err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
- current->fsuid, current->fsgid,
- rdev, &request);
- err = ll_prep_inode(sbi->ll_osc_exp, &inode, request, 0,
- child->d_sb);
+ err = md_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
+ current->fsuid, current->fsgid, rdev, &request);
+ err = ll_prep_inode(sbi->ll_osc_exp, sbi->ll_mdc_exp,
+ &inode, request, 0, child->d_sb);
if (err)
GOTO(out_err, err);
break;
RETURN(err);
ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
- err = mdc_create(sbi->ll_mdc_exp, &op_data,
- tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
- current->fsuid, current->fsgid, 0, &request);
+ err = md_create(sbi->ll_mdc_exp, &op_data,
+ tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
+ current->fsuid, current->fsgid, 0, &request);
ptlrpc_req_finished(request);
RETURN(err);
}
dir->i_ino, dir->i_generation, dir, name);
ll_prepare_mdc_op_data(&op_data, src, dir, name, len, 0);
- err = mdc_link(sbi->ll_mdc_exp, &op_data, &request);
+ err = md_link(sbi->ll_mdc_exp, &op_data, &request);
ptlrpc_req_finished(request);
RETURN(err);
CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p)\n",
name, dir->i_ino, dir->i_generation, dir);
- if (dir->i_nlink >= EXT3_LINK_MAX)
- RETURN(err);
-
mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
- err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
- current->fsuid, current->fsgid, 0, &request);
+ err = md_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
+ current->fsuid, current->fsgid, 0, &request);
ptlrpc_req_finished(request);
RETURN(err);
}
name, dir->i_ino, dir->i_generation, dir);
ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, S_IFDIR);
- rc = mdc_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
+ rc = md_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
ptlrpc_req_finished(request);
RETURN(rc);
}
GOTO(out_free_memmd, rc = -ENOMEM);
oa->o_id = lsm->lsm_object_id;
+ oa->o_gr = lsm->lsm_object_gr;
oa->o_mode = body->mode & S_IFMT;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
+ oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP;
if (body->valid & OBD_MD_FLCOOKIE) {
oa->o_valid |= OBD_MD_FLCOOKIE;
name, dir->i_ino, dir->i_generation, dir);
ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
- rc = mdc_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
+ rc = md_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
if (rc)
GOTO(out, rc);
src, newname, tgt->i_ino, tgt->i_generation, tgt);
ll_prepare_mdc_op_data(&op_data, src, tgt, NULL, 0, 0);
- err = mdc_rename(sbi->ll_mdc_exp, &op_data,
- oldname, oldlen, newname, newlen, &request);
+ err = md_rename(sbi->ll_mdc_exp, &op_data,
+ oldname, oldlen, newname, newlen, &request);
if (!err) {
err = ll_objects_destroy(request, src);
}
}
struct inode_operations ll_dir_inode_operations = {
- 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,
- mknod: ll_mknod,
- rename_raw: ll_rename_raw,
- setattr: ll_setattr,
- setattr_raw: ll_setattr_raw,
+ .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,
+ .mknod = ll_mknod,
+ .rename_raw = ll_rename_raw,
+ .setattr = ll_setattr,
+ .setattr_raw = ll_setattr_raw,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- create_it: ll_create_it,
- lookup_it: ll_lookup_it,
- revalidate_it: ll_inode_revalidate_it,
+ .create_it = ll_create_it,
+ .lookup_it = ll_lookup_it,
+ .revalidate_it = ll_inode_revalidate_it,
#else
- lookup: ll_lookup_nd,
- create: ll_create_nd,
- getattr_it: ll_getattr,
+ .lookup = ll_lookup_nd,
+ .create = ll_create_nd,
+ .getattr_it = ll_getattr,
#endif
};