forked from luck/tmp_suning_uos_patched
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: ocfs2: add IO error check in ocfs2_get_sector() ocfs2: set gap to seperate entry and value when xattr in bucket ocfs2: lock the metaecc process for xattr bucket ocfs2: Use the right access_* method in ctime update of xattr. ocfs2/dlm: Make dlm_assert_master_handler() kill itself instead of the asserter ocfs2/dlm: Use ast_lock to protect ast_list ocfs2: Cleanup the lockname print in dlmglue.c ocfs2/dlm: Retract fix for race between purge and migrate ocfs2: Access and dirty the buffer_head in mark_written.
This commit is contained in:
commit
d499811503
@ -4796,6 +4796,29 @@ static int ocfs2_split_and_insert(struct inode *inode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ocfs2_replace_extent_rec(struct inode *inode,
|
||||
handle_t *handle,
|
||||
struct ocfs2_path *path,
|
||||
struct ocfs2_extent_list *el,
|
||||
int split_index,
|
||||
struct ocfs2_extent_rec *split_rec)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ocfs2_path_bh_journal_access(handle, inode, path,
|
||||
path_num_items(path) - 1);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
el->l_recs[split_index] = *split_rec;
|
||||
|
||||
ocfs2_journal_dirty(handle, path_leaf_bh(path));
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark part or all of the extent record at split_index in the leaf
|
||||
* pointed to by path as written. This removes the unwritten
|
||||
@ -4885,7 +4908,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
|
||||
|
||||
if (ctxt.c_contig_type == CONTIG_NONE) {
|
||||
if (ctxt.c_split_covers_rec)
|
||||
el->l_recs[split_index] = *split_rec;
|
||||
ret = ocfs2_replace_extent_rec(inode, handle,
|
||||
path, el,
|
||||
split_index, split_rec);
|
||||
else
|
||||
ret = ocfs2_split_and_insert(inode, handle, path, et,
|
||||
&last_eb_bh, split_index,
|
||||
|
@ -1849,12 +1849,12 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
if (!mle) {
|
||||
if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN &&
|
||||
res->owner != assert->node_idx) {
|
||||
mlog(ML_ERROR, "assert_master from "
|
||||
"%u, but current owner is "
|
||||
"%u! (%.*s)\n",
|
||||
assert->node_idx, res->owner,
|
||||
namelen, name);
|
||||
goto kill;
|
||||
mlog(ML_ERROR, "DIE! Mastery assert from %u, "
|
||||
"but current owner is %u! (%.*s)\n",
|
||||
assert->node_idx, res->owner, namelen,
|
||||
name);
|
||||
__dlm_print_one_lock_resource(res);
|
||||
BUG();
|
||||
}
|
||||
} else if (mle->type != DLM_MLE_MIGRATION) {
|
||||
if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) {
|
||||
|
@ -181,8 +181,7 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm,
|
||||
|
||||
spin_lock(&res->spinlock);
|
||||
/* This ensures that clear refmap is sent after the set */
|
||||
__dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG |
|
||||
DLM_LOCK_RES_MIGRATING));
|
||||
__dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
|
||||
spin_unlock(&res->spinlock);
|
||||
|
||||
/* clear our bit from the master's refmap, ignore errors */
|
||||
|
@ -117,11 +117,11 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
|
||||
else
|
||||
BUG_ON(res->owner == dlm->node_num);
|
||||
|
||||
spin_lock(&dlm->spinlock);
|
||||
spin_lock(&dlm->ast_lock);
|
||||
/* We want to be sure that we're not freeing a lock
|
||||
* that still has AST's pending... */
|
||||
in_use = !list_empty(&lock->ast_list);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
spin_unlock(&dlm->ast_lock);
|
||||
if (in_use) {
|
||||
mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock "
|
||||
"while waiting for an ast!", res->lockname.len,
|
||||
|
@ -320,9 +320,14 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb,
|
||||
struct ocfs2_lock_res *lockres);
|
||||
static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
|
||||
int convert);
|
||||
#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \
|
||||
mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \
|
||||
_err, _func, _lockres->l_name); \
|
||||
#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \
|
||||
if ((_lockres)->l_type != OCFS2_LOCK_TYPE_DENTRY) \
|
||||
mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \
|
||||
_err, _func, _lockres->l_name); \
|
||||
else \
|
||||
mlog(ML_ERROR, "DLM error %d while calling %s on resource %.*s%08x\n", \
|
||||
_err, _func, OCFS2_DENTRY_LOCK_INO_START - 1, (_lockres)->l_name, \
|
||||
(unsigned int)ocfs2_get_dentry_lock_ino(_lockres)); \
|
||||
} while (0)
|
||||
static int ocfs2_downconvert_thread(void *arg);
|
||||
static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb,
|
||||
|
@ -341,6 +341,9 @@ struct ocfs2_super
|
||||
struct ocfs2_node_map osb_recovering_orphan_dirs;
|
||||
unsigned int *osb_orphan_wipes;
|
||||
wait_queue_head_t osb_wipe_event;
|
||||
|
||||
/* used to protect metaecc calculation check of xattr. */
|
||||
spinlock_t osb_xattr_lock;
|
||||
};
|
||||
|
||||
#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
|
||||
|
@ -1537,6 +1537,13 @@ static int ocfs2_get_sector(struct super_block *sb,
|
||||
unlock_buffer(*bh);
|
||||
ll_rw_block(READ, 1, bh);
|
||||
wait_on_buffer(*bh);
|
||||
if (!buffer_uptodate(*bh)) {
|
||||
mlog_errno(-EIO);
|
||||
brelse(*bh);
|
||||
*bh = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1747,6 +1754,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
|
||||
INIT_LIST_HEAD(&osb->blocked_lock_list);
|
||||
osb->blocked_lock_count = 0;
|
||||
spin_lock_init(&osb->osb_lock);
|
||||
spin_lock_init(&osb->osb_xattr_lock);
|
||||
ocfs2_init_inode_steal_slot(osb);
|
||||
|
||||
atomic_set(&osb->alloc_stats.moves, 0);
|
||||
|
@ -82,13 +82,14 @@ struct ocfs2_xattr_set_ctxt {
|
||||
|
||||
#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
|
||||
#define OCFS2_XATTR_INLINE_SIZE 80
|
||||
#define OCFS2_XATTR_HEADER_GAP 4
|
||||
#define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \
|
||||
- sizeof(struct ocfs2_xattr_header) \
|
||||
- sizeof(__u32))
|
||||
- OCFS2_XATTR_HEADER_GAP)
|
||||
#define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \
|
||||
- sizeof(struct ocfs2_xattr_block) \
|
||||
- sizeof(struct ocfs2_xattr_header) \
|
||||
- sizeof(__u32))
|
||||
- OCFS2_XATTR_HEADER_GAP)
|
||||
|
||||
static struct ocfs2_xattr_def_value_root def_xv = {
|
||||
.xv.xr_list.l_count = cpu_to_le16(1),
|
||||
@ -274,10 +275,12 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
|
||||
bucket->bu_blocks, bucket->bu_bhs, 0,
|
||||
NULL);
|
||||
if (!rc) {
|
||||
spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb,
|
||||
bucket->bu_bhs,
|
||||
bucket->bu_blocks,
|
||||
&bucket_xh(bucket)->xh_check);
|
||||
spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
if (rc)
|
||||
mlog_errno(rc);
|
||||
}
|
||||
@ -310,9 +313,11 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle,
|
||||
{
|
||||
int i;
|
||||
|
||||
spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb,
|
||||
bucket->bu_bhs, bucket->bu_blocks,
|
||||
&bucket_xh(bucket)->xh_check);
|
||||
spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
|
||||
|
||||
for (i = 0; i < bucket->bu_blocks; i++)
|
||||
ocfs2_journal_dirty(handle, bucket->bu_bhs[i]);
|
||||
@ -1507,7 +1512,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
|
||||
last += 1;
|
||||
}
|
||||
|
||||
free = min_offs - ((void *)last - xs->base) - sizeof(__u32);
|
||||
free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
|
||||
if (free < 0)
|
||||
return -EIO;
|
||||
|
||||
@ -2190,7 +2195,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
|
||||
last += 1;
|
||||
}
|
||||
|
||||
free = min_offs - ((void *)last - xs->base) - sizeof(__u32);
|
||||
free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
|
||||
if (free < 0)
|
||||
return 0;
|
||||
|
||||
@ -2592,8 +2597,9 @@ static int __ocfs2_xattr_set_handle(struct inode *inode,
|
||||
|
||||
if (!ret) {
|
||||
/* Update inode ctime. */
|
||||
ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh,
|
||||
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||
ret = ocfs2_journal_access_di(ctxt->handle, inode,
|
||||
xis->inode_bh,
|
||||
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto out;
|
||||
@ -5060,8 +5066,8 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
|
||||
xh_free_start = le16_to_cpu(xh->xh_free_start);
|
||||
header_size = sizeof(struct ocfs2_xattr_header) +
|
||||
count * sizeof(struct ocfs2_xattr_entry);
|
||||
max_free = OCFS2_XATTR_BUCKET_SIZE -
|
||||
le16_to_cpu(xh->xh_name_value_len) - header_size;
|
||||
max_free = OCFS2_XATTR_BUCKET_SIZE - header_size -
|
||||
le16_to_cpu(xh->xh_name_value_len) - OCFS2_XATTR_HEADER_GAP;
|
||||
|
||||
mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size "
|
||||
"of %u which exceed block size\n",
|
||||
@ -5094,7 +5100,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
|
||||
need = 0;
|
||||
}
|
||||
|
||||
free = xh_free_start - header_size;
|
||||
free = xh_free_start - header_size - OCFS2_XATTR_HEADER_GAP;
|
||||
/*
|
||||
* We need to make sure the new name/value pair
|
||||
* can exist in the same block.
|
||||
@ -5127,7 +5133,8 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
|
||||
}
|
||||
|
||||
xh_free_start = le16_to_cpu(xh->xh_free_start);
|
||||
free = xh_free_start - header_size;
|
||||
free = xh_free_start - header_size
|
||||
- OCFS2_XATTR_HEADER_GAP;
|
||||
if (xh_free_start % blocksize < need)
|
||||
free -= xh_free_start % blocksize;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user