osd_th_alloced(oh);
memset(oti->oti_declare_ops, 0,
- sizeof(oti->oti_declare_ops));
- memset(oti->oti_declare_ops_rb, 0,
- sizeof(oti->oti_declare_ops_rb));
+ sizeof(oti->oti_declare_ops));
memset(oti->oti_declare_ops_cred, 0,
- sizeof(oti->oti_declare_ops_cred));
- oti->oti_rollback = false;
+ sizeof(oti->oti_declare_ops_cred));
+ memset(oti->oti_declare_ops_used, 0,
+ sizeof(oti->oti_declare_ops_used));
}
RETURN(th);
}
+void osd_trans_dump_creds(const struct lu_env *env, struct thandle *th)
+{
+ struct osd_thread_info *oti = osd_oti_get(env);
+ struct osd_thandle *oh;
+
+ oh = container_of0(th, struct osd_thandle, ot_super);
+ LASSERT(oh != NULL);
+
+ CWARN(" create: %u/%u/%u, destroy: %u/%u/%u\n",
+ oti->oti_declare_ops[OSD_OT_CREATE],
+ oti->oti_declare_ops_cred[OSD_OT_CREATE],
+ oti->oti_declare_ops_used[OSD_OT_CREATE],
+ oti->oti_declare_ops[OSD_OT_DESTROY],
+ oti->oti_declare_ops_cred[OSD_OT_DESTROY],
+ oti->oti_declare_ops_used[OSD_OT_DESTROY]);
+ CWARN(" attr_set: %u/%u/%u, xattr_set: %u/%u/%u\n",
+ oti->oti_declare_ops[OSD_OT_ATTR_SET],
+ oti->oti_declare_ops_cred[OSD_OT_ATTR_SET],
+ oti->oti_declare_ops_used[OSD_OT_ATTR_SET],
+ oti->oti_declare_ops[OSD_OT_XATTR_SET],
+ oti->oti_declare_ops_cred[OSD_OT_XATTR_SET],
+ oti->oti_declare_ops_used[OSD_OT_XATTR_SET]);
+ CWARN(" write: %u/%u/%u, punch: %u/%u/%u, quota %u/%u/%u\n",
+ oti->oti_declare_ops[OSD_OT_WRITE],
+ oti->oti_declare_ops_cred[OSD_OT_WRITE],
+ oti->oti_declare_ops_used[OSD_OT_WRITE],
+ oti->oti_declare_ops[OSD_OT_PUNCH],
+ oti->oti_declare_ops_cred[OSD_OT_PUNCH],
+ oti->oti_declare_ops_used[OSD_OT_PUNCH],
+ oti->oti_declare_ops[OSD_OT_QUOTA],
+ oti->oti_declare_ops_cred[OSD_OT_QUOTA],
+ oti->oti_declare_ops_used[OSD_OT_QUOTA]);
+ CWARN(" insert: %u/%u/%u, delete: %u/%u/%u\n",
+ oti->oti_declare_ops[OSD_OT_INSERT],
+ oti->oti_declare_ops_cred[OSD_OT_INSERT],
+ oti->oti_declare_ops_used[OSD_OT_INSERT],
+ oti->oti_declare_ops[OSD_OT_DELETE],
+ oti->oti_declare_ops_cred[OSD_OT_DELETE],
+ oti->oti_declare_ops_used[OSD_OT_DELETE]);
+ CWARN(" ref_add: %u/%u/%u, ref_del: %u/%u/%u\n",
+ oti->oti_declare_ops[OSD_OT_REF_ADD],
+ oti->oti_declare_ops_cred[OSD_OT_REF_ADD],
+ oti->oti_declare_ops_used[OSD_OT_REF_ADD],
+ oti->oti_declare_ops[OSD_OT_REF_DEL],
+ oti->oti_declare_ops_cred[OSD_OT_REF_DEL],
+ oti->oti_declare_ops_used[OSD_OT_REF_DEL]);
+}
+
/*
* Concurrency: shouldn't matter.
*/
LDISKFS_SB(osd_sb(dev))->s_es->s_volume_name,
oh->ot_credits,
osd_journal(dev)->j_max_transaction_buffers);
- CWARN(" create: %u/%u, destroy: %u/%u\n",
- oti->oti_declare_ops[OSD_OT_CREATE],
- oti->oti_declare_ops_cred[OSD_OT_CREATE],
- oti->oti_declare_ops[OSD_OT_DESTROY],
- oti->oti_declare_ops_cred[OSD_OT_DESTROY]);
- CWARN(" attr_set: %u/%u, xattr_set: %u/%u\n",
- oti->oti_declare_ops[OSD_OT_ATTR_SET],
- oti->oti_declare_ops_cred[OSD_OT_ATTR_SET],
- oti->oti_declare_ops[OSD_OT_XATTR_SET],
- oti->oti_declare_ops_cred[OSD_OT_XATTR_SET]);
- CWARN(" write: %u/%u, punch: %u/%u, quota %u/%u\n",
- oti->oti_declare_ops[OSD_OT_WRITE],
- oti->oti_declare_ops_cred[OSD_OT_WRITE],
- oti->oti_declare_ops[OSD_OT_PUNCH],
- oti->oti_declare_ops_cred[OSD_OT_PUNCH],
- oti->oti_declare_ops[OSD_OT_QUOTA],
- oti->oti_declare_ops_cred[OSD_OT_QUOTA]);
- CWARN(" insert: %u/%u, delete: %u/%u\n",
- oti->oti_declare_ops[OSD_OT_INSERT],
- oti->oti_declare_ops_cred[OSD_OT_INSERT],
- oti->oti_declare_ops[OSD_OT_DELETE],
- oti->oti_declare_ops_cred[OSD_OT_DELETE]);
- CWARN(" ref_add: %u/%u, ref_del: %u/%u\n",
- oti->oti_declare_ops[OSD_OT_REF_ADD],
- oti->oti_declare_ops_cred[OSD_OT_REF_ADD],
- oti->oti_declare_ops[OSD_OT_REF_DEL],
- oti->oti_declare_ops_cred[OSD_OT_REF_DEL]);
+
+ osd_trans_dump_creds(env, th);
if (last_credits != oh->ot_credits &&
time_after(jiffies, last_printed +
result = sb->s_op->statfs(sb->s_root, ksfs);
if (likely(result == 0)) { /* N.B. statfs can't really fail */
statfs_pack(sfs, ksfs);
- if (sb->s_flags & MS_RDONLY)
+ if (unlikely(sb->s_flags & MS_RDONLY))
sfs->os_state = OS_STATE_READONLY;
+ if (LDISKFS_HAS_INCOMPAT_FEATURE(sb,
+ LDISKFS_FEATURE_INCOMPAT_EXTENTS))
+ sfs->os_maxbytes = sb->s_maxbytes;
+ else
+ sfs->os_maxbytes = LDISKFS_SB(sb)->s_bitmap_maxbytes;
}
-
spin_unlock(&osd->od_osfs_lock);
if (unlikely(env == NULL))
param->ddp_max_nlink = LDISKFS_LINK_MAX;
param->ddp_block_shift = sb->s_blocksize_bits;
param->ddp_mount_type = LDD_MT_LDISKFS;
- param->ddp_maxbytes = sb->s_maxbytes;
+ if (LDISKFS_HAS_INCOMPAT_FEATURE(sb, LDISKFS_FEATURE_INCOMPAT_EXTENTS))
+ param->ddp_maxbytes = sb->s_maxbytes;
+ else
+ param->ddp_maxbytes = LDISKFS_SB(sb)->s_bitmap_maxbytes;
/* Overhead estimate should be fairly accurate, so we really take a tiny
* error margin which also avoids fragmenting the filesystem too much */
param->ddp_grant_reserved = 2; /* end up to be 1.9% after conversion */
if (!rc)
ll_dirty_inode(inode, I_DIRTY_DATASYNC);
+
+ osd_trans_exec_check(env, handle, OSD_OT_ATTR_SET);
+
return rc;
}
oth = container_of(th, struct osd_thandle, ot_super);
LASSERT(oth->ot_handle->h_transaction != NULL);
- if (hint && hint->dah_parent)
- parent = hint->dah_parent;
+ if (hint != NULL && hint->dah_parent != NULL &&
+ !dt_object_remote(hint->dah_parent))
+ parent = hint->dah_parent;
inode = ldiskfs_create_inode(oth->ot_handle,
parent ? osd_dt_obj(parent)->oo_inode :
int result;
__u32 umask;
+ osd_trans_exec_op(info->oti_env, th, OSD_OT_CREATE);
+
/* we drop umask so that permissions we pass are not affected */
umask = current->fs->umask;
current->fs->umask = 0;
/* restore previous umask value */
current->fs->umask = umask;
+ osd_trans_exec_check(info->oti_env, th, OSD_OT_CREATE);
+
return result;
}
struct osd_inode_id *id = &info->oti_id;
struct osd_device *osd = osd_obj2dev(obj);
struct osd_thandle *oh;
+ int rc;
LASSERT(obj->oo_inode != NULL);
oh = container_of0(th, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle);
+ osd_trans_exec_op(env, th, OSD_OT_INSERT);
osd_id_gen(id, obj->oo_inode->i_ino, obj->oo_inode->i_generation);
- return osd_oi_insert(info, osd, fid, id, oh->ot_handle, OI_CHECK_FLD);
+ rc = osd_oi_insert(info, osd, fid, id, oh->ot_handle, OI_CHECK_FLD);
+ osd_trans_exec_check(env, th, OSD_OT_INSERT);
+
+ return rc;
}
int osd_fld_lookup(const struct lu_env *env, struct osd_device *osd,
oh = container_of0(handle, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle == NULL);
+ /* EA object consumes more credits than regular object: osd_mk_index
+ * vs. osd_mkreg: osd_mk_index will create 2 blocks for root_node and
+ * leaf_node, could involves the block, block bitmap, groups, GDT
+ * change for each block, so add 4 * 2 credits in that case. */
osd_trans_declare_op(env, oh, OSD_OT_CREATE,
- osd_dto_credits_noquota[DTO_OBJECT_CREATE]);
+ osd_dto_credits_noquota[DTO_OBJECT_CREATE] +
+ (dof->dof_type == DFT_INDEX) ? 4 * 2 : 0);
/* Reuse idle OI block may cause additional one OI block
* to be changed. */
osd_trans_declare_op(env, oh, OSD_OT_INSERT,
osd_dto_credits_noquota[DTO_INDEX_INSERT] + 1);
- /* If this is directory, then we expect . and .. to be inserted as
- * well. The one directory block always needs to be created for the
- * directory, so we could use DTO_WRITE_BASE here (GDT, block bitmap,
- * block), there is no danger of needing a tree for the first block.
- */
- if (attr && S_ISDIR(attr->la_mode)) {
- osd_trans_declare_op(env, oh, OSD_OT_INSERT,
- osd_dto_credits_noquota[DTO_WRITE_BASE]);
- osd_trans_declare_op(env, oh, OSD_OT_INSERT, 0);
- }
-
if (!attr)
RETURN(0);
* 'tune2fs -O quota' will take care of creating them */
RETURN(-EPERM);
- osd_trans_exec_op(env, th, OSD_OT_CREATE);
- osd_trans_declare_rb(env, th, OSD_OT_REF_ADD);
-
- result = __osd_object_create(info, obj, attr, hint, dof, th);
- if (result == 0)
- result = __osd_oi_insert(env, obj, fid, th);
-
+ result = __osd_object_create(info, obj, attr, hint, dof, th);
+ if (result == 0) {
+ result = __osd_oi_insert(env, obj, fid, th);
+ if (obj->oo_dt.do_body_ops == &osd_body_ops_new)
+ obj->oo_dt.do_body_ops = &osd_body_ops;
+ }
LASSERT(ergo(result == 0,
- dt_object_exists(dt) && !dt_object_remote(dt)));
+ dt_object_exists(dt) && !dt_object_remote(dt)));
- LASSERT(osd_invariant(obj));
- RETURN(result);
+ LASSERT(osd_invariant(obj));
+ RETURN(result);
}
/**
result = osd_oi_delete(osd_oti_get(env), osd, fid, oh->ot_handle,
OI_CHECK_FLD);
- /* XXX: add to ext3 orphan list */
- /* rc = ext3_orphan_add(handle_t *handle, struct inode *inode) */
+ osd_trans_exec_check(env, th, OSD_OT_DESTROY);
+ /* XXX: add to ext3 orphan list */
+ /* rc = ext3_orphan_add(handle_t *handle, struct inode *inode) */
- /* not needed in the cache anymore */
- set_bit(LU_OBJECT_HEARD_BANSHEE, &dt->do_lu.lo_header->loh_flags);
+ /* not needed in the cache anymore */
+ set_bit(LU_OBJECT_HEARD_BANSHEE, &dt->do_lu.lo_header->loh_flags);
+ obj->oo_destroyed = 1;
- RETURN(0);
+ RETURN(0);
}
/**
dot_ldp = (struct ldiskfs_dentry_param *)info->oti_ldp;
dot_ldp->edp_magic = 0;
+
return ldiskfs_add_dot_dotdot(oth->ot_handle, parent_dir,
- dir, dot_ldp, dot_dot_ldp);
+ dir, dot_ldp, dot_dot_ldp);
}
/**
* 'tune2fs -O quota' will take care of creating them */
RETURN(-EPERM);
- osd_trans_exec_op(env, th, OSD_OT_CREATE);
- osd_trans_declare_rb(env, th, OSD_OT_REF_ADD);
-
result = __osd_object_create(info, obj, attr, hint, dof, th);
if (result == 0) {
if (fid_is_idif(fid) &&
fid, OI_CHECK_FLD) ?
LMAC_FID_ON_OST : 0, 0);
}
+ if (obj->oo_dt.do_body_ops == &osd_body_ops_new)
+ obj->oo_dt.do_body_ops = &osd_body_ops;
}
if (result == 0)
ll_dirty_inode(inode, I_DIRTY_DATASYNC);
LINVRNT(osd_invariant(obj));
+ osd_trans_exec_check(env, th, OSD_OT_REF_ADD);
+
return rc;
}
ll_dirty_inode(inode, I_DIRTY_DATASYNC);
LINVRNT(osd_invariant(obj));
+ osd_trans_exec_check(env, th, OSD_OT_REF_DEL);
+
return 0;
}
oh = container_of0(handle, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle == NULL);
- /* optimistic optimization: LMA is set first and usually fit inode */
if (strcmp(name, XATTR_NAME_LMA) == 0) {
- if (dt_object_exists(dt))
+ /* For non-upgrading case, the LMA is set first and
+ * usually fit inode. But for upgrade case, the LMA
+ * may be in another separated EA block. */
+ if (!dt_object_exists(dt))
credits = 0;
- else
+ else if (fl == LU_XATTR_REPLACE)
credits = 1;
+ else
+ goto upgrade;
} else if (strcmp(name, XATTR_NAME_VERSION) == 0) {
credits = 1;
} else {
+upgrade:
credits = osd_dto_credits_noquota[DTO_XATTR_SET];
if (buf && buf->lb_len > sb->s_blocksize) {
credits *= (buf->lb_len + sb->s_blocksize - 1) >>
* xattr set may involve inode quota change, reserve credits for
* dquot_initialize()
*/
- oh->ot_credits += LDISKFS_MAXQUOTAS_INIT_BLOCKS(sb);
+ credits += LDISKFS_MAXQUOTAS_INIT_BLOCKS(sb);
}
osd_trans_declare_op(env, oh, OSD_OT_XATTR_SET, credits);
struct inode *inode = obj->oo_inode;
struct osd_thread_info *info = osd_oti_get(env);
int fs_flags = 0;
+ int rc;
ENTRY;
LASSERT(handle != NULL);
strcmp(name, XATTR_NAME_LINK) == 0)
return -ENOSPC;
- return __osd_xattr_set(info, inode, name, buf->lb_buf, buf->lb_len,
+ rc = __osd_xattr_set(info, inode, name, buf->lb_buf, buf->lb_len,
fs_flags);
+ osd_trans_exec_check(env, handle, OSD_OT_XATTR_SET);
+
+ return rc;
}
/*
dentry->d_inode = inode;
dentry->d_sb = inode->i_sb;
rc = inode->i_op->removexattr(dentry, name);
+ osd_trans_exec_check(env, handle, OSD_OT_XATTR_SET);
return rc;
}
rc = iam_delete(oh->ot_handle, bag, (const struct iam_key *)key, ipd);
osd_ipd_put(env, bag, ipd);
LINVRNT(osd_invariant(obj));
+ osd_trans_exec_check(env, handle, OSD_OT_DELETE);
RETURN(rc);
}
oh = container_of0(handle, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle == NULL);
+ /* due to DNE we may need to remove an agent inode */
osd_trans_declare_op(env, oh, OSD_OT_DELETE,
- osd_dto_credits_noquota[DTO_INDEX_DELETE]);
+ osd_dto_credits_noquota[DTO_INDEX_DELETE] +
+ osd_dto_credits_noquota[DTO_OBJECT_DELETE]);
inode = osd_dt_obj(dt)->oo_inode;
LASSERT(inode);
out:
LASSERT(osd_invariant(obj));
+ osd_trans_exec_check(env, handle, OSD_OT_DELETE);
RETURN(rc);
}
iam_rec, ipd);
osd_ipd_put(env, bag, ipd);
LINVRNT(osd_invariant(obj));
+ osd_trans_exec_check(env, th, OSD_OT_INSERT);
RETURN(rc);
}
dir->oo_compat_dotdot_created = 1;
}
- /* ldiskfs_init_new_dir() doesn't call ldiskfs_mark_inode_dirty()
- * this seem as an optimization as usually it's called
- * later to refresh mtime of the parent. Lustre does not
- * update mtime in few cases (e.g. PENDING, .lustre)
- * we still need to transfer i_size/etc to the buffer cache */
- ldiskfs_mark_inode_dirty(oth->ot_handle, dir->oo_inode);
-
return result;
}
struct osd_thandle *oh;
struct osd_device *osd = osd_dev(dt->do_lu.lo_dev);
struct lu_fid *fid = (struct lu_fid *)rec;
- int rc;
+ int credits, rc = 0;
ENTRY;
LASSERT(!dt_object_remote(dt));
oh = container_of0(handle, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle == NULL);
- osd_trans_declare_op(env, oh, OSD_OT_INSERT,
- osd_dto_credits_noquota[DTO_INDEX_INSERT]);
+ credits = osd_dto_credits_noquota[DTO_INDEX_INSERT];
+ if (fid != NULL) {
+ rc = osd_remote_fid(env, osd, fid);
+ if (unlikely(rc < 0))
+ RETURN(rc);
+ if (rc > 0) {
+ /* a reference to remote inode is represented by an
+ * agent inode which we have to create */
+ credits += osd_dto_credits_noquota[DTO_OBJECT_CREATE];
+ credits += osd_dto_credits_noquota[DTO_INDEX_INSERT];
+ }
+ rc = 0;
+ }
+
+ osd_trans_declare_op(env, oh, OSD_OT_INSERT, credits);
if (osd_dt_obj(dt)->oo_inode != NULL) {
struct inode *inode = osd_dt_obj(dt)->oo_inode;
osd_dt_obj(dt), true, NULL, false);
}
- if (fid == NULL)
- RETURN(0);
-
- rc = osd_remote_fid(env, osd, fid);
- if (rc <= 0)
- RETURN(rc);
-
- rc = 0;
-
- osd_trans_declare_op(env, oh, OSD_OT_CREATE,
- osd_dto_credits_noquota[DTO_OBJECT_CREATE]);
- osd_trans_declare_op(env, oh, OSD_OT_INSERT,
- osd_dto_credits_noquota[DTO_INDEX_INSERT] + 1);
- osd_trans_declare_op(env, oh, OSD_OT_INSERT,
- osd_dto_credits_noquota[DTO_INDEX_INSERT] + 1);
-
RETURN(rc);
}
if (child != NULL)
osd_object_put(env, child);
LASSERT(osd_invariant(obj));
+ osd_trans_exec_check(env, th, OSD_OT_INSERT);
RETURN(rc);
}
struct dentry *obj_dentry;
ENTRY;
- if (!dt_object_exists(dt))
+ if (!dt_object_exists(dt) || obj->oo_destroyed)
RETURN(ERR_PTR(-ENOENT));
OBD_SLAB_ALLOC_PTR_GFP(oie, osd_itea_cachep, GFP_NOFS);
} else {
attr &= ~LU_DIRENT_ATTRS_MASK;
if (!fid_is_sane(fid)) {
+ bool is_dotdot = false;
if (it->oie_dirent->oied_namelen == 2 &&
it->oie_dirent->oied_name[0] == '.' &&
- it->oie_dirent->oied_name[1] == '.') {
- /* If the parent is on remote MDT, and there
- * is no FID-in-dirent, then we have to get
- * the parent FID from the linkEA. */
- if (ino == osd_remote_parent_ino(dev))
- rc = osd_get_pfid_from_linkea(env, obj,
- fid);
+ it->oie_dirent->oied_name[1] == '.')
+ is_dotdot = true;
+ /* If the parent is on remote MDT, and there
+ * is no FID-in-dirent, then we have to get
+ * the parent FID from the linkEA. */
+ if (ino == osd_remote_parent_ino(dev) && is_dotdot) {
+ rc = osd_get_pfid_from_linkea(env, obj, fid);
} else {
- if (OBD_FAIL_CHECK(OBD_FAIL_FID_LOOKUP))
+ if (is_dotdot == false &&
+ OBD_FAIL_CHECK(OBD_FAIL_FID_LOOKUP))
RETURN(-ENOENT);
rc = osd_ea_fid_get(env, obj, ino, fid, id);
if (opts != NULL && strstr(opts, "force_over_128tb") != NULL)
force_over_128tb = 1;
- OBD_PAGE_ALLOC(__page, GFP_IOFS);
+ __page = alloc_page(GFP_IOFS);
if (__page == NULL)
GOTO(out, rc = -ENOMEM);
page = (unsigned long)page_address(__page);
out:
if (__page)
- OBD_PAGE_FREE(__page);
+ __free_page(__page);
return rc;
}
GOTO(out, rc);
}
- if (server_name_is_ost(o->od_svname))
+ o->od_index = -1; /* -1 means index is invalid */
+ rc = server_name2index(o->od_svname, &o->od_index, NULL);
+ if (rc == LDD_F_SV_TYPE_OST)
o->od_is_ost = 1;
o->od_full_scrub_ratio = OFSR_DEFAULT;