Commit d4998115 authored by Linus Torvalds's avatar Linus Torvalds

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.
parents 392b8e47 28d57d43
...@@ -4796,6 +4796,29 @@ static int ocfs2_split_and_insert(struct inode *inode, ...@@ -4796,6 +4796,29 @@ static int ocfs2_split_and_insert(struct inode *inode,
return ret; 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 * Mark part or all of the extent record at split_index in the leaf
* pointed to by path as written. This removes the unwritten * pointed to by path as written. This removes the unwritten
...@@ -4885,7 +4908,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode, ...@@ -4885,7 +4908,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
if (ctxt.c_contig_type == CONTIG_NONE) { if (ctxt.c_contig_type == CONTIG_NONE) {
if (ctxt.c_split_covers_rec) 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 else
ret = ocfs2_split_and_insert(inode, handle, path, et, ret = ocfs2_split_and_insert(inode, handle, path, et,
&last_eb_bh, split_index, &last_eb_bh, split_index,
......
...@@ -1849,12 +1849,12 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, ...@@ -1849,12 +1849,12 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
if (!mle) { if (!mle) {
if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN && if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN &&
res->owner != assert->node_idx) { res->owner != assert->node_idx) {
mlog(ML_ERROR, "assert_master from " mlog(ML_ERROR, "DIE! Mastery assert from %u, "
"%u, but current owner is " "but current owner is %u! (%.*s)\n",
"%u! (%.*s)\n", assert->node_idx, res->owner, namelen,
assert->node_idx, res->owner, name);
namelen, name); __dlm_print_one_lock_resource(res);
goto kill; BUG();
} }
} else if (mle->type != DLM_MLE_MIGRATION) { } else if (mle->type != DLM_MLE_MIGRATION) {
if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) { if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) {
......
...@@ -181,8 +181,7 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, ...@@ -181,8 +181,7 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm,
spin_lock(&res->spinlock); spin_lock(&res->spinlock);
/* This ensures that clear refmap is sent after the set */ /* This ensures that clear refmap is sent after the set */
__dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
DLM_LOCK_RES_MIGRATING));
spin_unlock(&res->spinlock); spin_unlock(&res->spinlock);
/* clear our bit from the master's refmap, ignore errors */ /* clear our bit from the master's refmap, ignore errors */
......
...@@ -117,11 +117,11 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, ...@@ -117,11 +117,11 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
else else
BUG_ON(res->owner == dlm->node_num); 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 /* We want to be sure that we're not freeing a lock
* that still has AST's pending... */ * that still has AST's pending... */
in_use = !list_empty(&lock->ast_list); in_use = !list_empty(&lock->ast_list);
spin_unlock(&dlm->spinlock); spin_unlock(&dlm->ast_lock);
if (in_use) { if (in_use) {
mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock " mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock "
"while waiting for an ast!", res->lockname.len, "while waiting for an ast!", res->lockname.len,
......
...@@ -320,9 +320,14 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, ...@@ -320,9 +320,14 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb,
struct ocfs2_lock_res *lockres); struct ocfs2_lock_res *lockres);
static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
int convert); int convert);
#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ #define ocfs2_log_dlm_error(_func, _err, _lockres) do { \
mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ if ((_lockres)->l_type != OCFS2_LOCK_TYPE_DENTRY) \
_err, _func, _lockres->l_name); \ 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) } while (0)
static int ocfs2_downconvert_thread(void *arg); static int ocfs2_downconvert_thread(void *arg);
static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb,
......
...@@ -341,6 +341,9 @@ struct ocfs2_super ...@@ -341,6 +341,9 @@ struct ocfs2_super
struct ocfs2_node_map osb_recovering_orphan_dirs; struct ocfs2_node_map osb_recovering_orphan_dirs;
unsigned int *osb_orphan_wipes; unsigned int *osb_orphan_wipes;
wait_queue_head_t osb_wipe_event; 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) #define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
......
...@@ -1537,6 +1537,13 @@ static int ocfs2_get_sector(struct super_block *sb, ...@@ -1537,6 +1537,13 @@ static int ocfs2_get_sector(struct super_block *sb,
unlock_buffer(*bh); unlock_buffer(*bh);
ll_rw_block(READ, 1, bh); ll_rw_block(READ, 1, bh);
wait_on_buffer(*bh); wait_on_buffer(*bh);
if (!buffer_uptodate(*bh)) {
mlog_errno(-EIO);
brelse(*bh);
*bh = NULL;
return -EIO;
}
return 0; return 0;
} }
...@@ -1747,6 +1754,7 @@ static int ocfs2_initialize_super(struct super_block *sb, ...@@ -1747,6 +1754,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
INIT_LIST_HEAD(&osb->blocked_lock_list); INIT_LIST_HEAD(&osb->blocked_lock_list);
osb->blocked_lock_count = 0; osb->blocked_lock_count = 0;
spin_lock_init(&osb->osb_lock); spin_lock_init(&osb->osb_lock);
spin_lock_init(&osb->osb_xattr_lock);
ocfs2_init_inode_steal_slot(osb); ocfs2_init_inode_steal_slot(osb);
atomic_set(&osb->alloc_stats.moves, 0); atomic_set(&osb->alloc_stats.moves, 0);
......
...@@ -82,13 +82,14 @@ struct ocfs2_xattr_set_ctxt { ...@@ -82,13 +82,14 @@ struct ocfs2_xattr_set_ctxt {
#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
#define OCFS2_XATTR_INLINE_SIZE 80 #define OCFS2_XATTR_INLINE_SIZE 80
#define OCFS2_XATTR_HEADER_GAP 4
#define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \
- sizeof(struct ocfs2_xattr_header) \ - sizeof(struct ocfs2_xattr_header) \
- sizeof(__u32)) - OCFS2_XATTR_HEADER_GAP)
#define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \
- sizeof(struct ocfs2_xattr_block) \ - sizeof(struct ocfs2_xattr_block) \
- sizeof(struct ocfs2_xattr_header) \ - sizeof(struct ocfs2_xattr_header) \
- sizeof(__u32)) - OCFS2_XATTR_HEADER_GAP)
static struct ocfs2_xattr_def_value_root def_xv = { static struct ocfs2_xattr_def_value_root def_xv = {
.xv.xr_list.l_count = cpu_to_le16(1), .xv.xr_list.l_count = cpu_to_le16(1),
...@@ -274,10 +275,12 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket, ...@@ -274,10 +275,12 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
bucket->bu_blocks, bucket->bu_bhs, 0, bucket->bu_blocks, bucket->bu_bhs, 0,
NULL); NULL);
if (!rc) { 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, rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb,
bucket->bu_bhs, bucket->bu_bhs,
bucket->bu_blocks, bucket->bu_blocks,
&bucket_xh(bucket)->xh_check); &bucket_xh(bucket)->xh_check);
spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
if (rc) if (rc)
mlog_errno(rc); mlog_errno(rc);
} }
...@@ -310,9 +313,11 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle, ...@@ -310,9 +313,11 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle,
{ {
int i; int i;
spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb, ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb,
bucket->bu_bhs, bucket->bu_blocks, bucket->bu_bhs, bucket->bu_blocks,
&bucket_xh(bucket)->xh_check); &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++) for (i = 0; i < bucket->bu_blocks; i++)
ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); ocfs2_journal_dirty(handle, bucket->bu_bhs[i]);
...@@ -1507,7 +1512,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, ...@@ -1507,7 +1512,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
last += 1; 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) if (free < 0)
return -EIO; return -EIO;
...@@ -2190,7 +2195,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode, ...@@ -2190,7 +2195,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
last += 1; 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) if (free < 0)
return 0; return 0;
...@@ -2592,8 +2597,9 @@ static int __ocfs2_xattr_set_handle(struct inode *inode, ...@@ -2592,8 +2597,9 @@ static int __ocfs2_xattr_set_handle(struct inode *inode,
if (!ret) { if (!ret) {
/* Update inode ctime. */ /* Update inode ctime. */
ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh, ret = ocfs2_journal_access_di(ctxt->handle, inode,
OCFS2_JOURNAL_ACCESS_WRITE); xis->inode_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
...@@ -5060,8 +5066,8 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, ...@@ -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); xh_free_start = le16_to_cpu(xh->xh_free_start);
header_size = sizeof(struct ocfs2_xattr_header) + header_size = sizeof(struct ocfs2_xattr_header) +
count * sizeof(struct ocfs2_xattr_entry); count * sizeof(struct ocfs2_xattr_entry);
max_free = OCFS2_XATTR_BUCKET_SIZE - max_free = OCFS2_XATTR_BUCKET_SIZE - header_size -
le16_to_cpu(xh->xh_name_value_len) - 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 " mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size "
"of %u which exceed block size\n", "of %u which exceed block size\n",
...@@ -5094,7 +5100,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, ...@@ -5094,7 +5100,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
need = 0; 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 * We need to make sure the new name/value pair
* can exist in the same block. * can exist in the same block.
...@@ -5127,7 +5133,8 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, ...@@ -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); 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) if (xh_free_start % blocksize < need)
free -= xh_free_start % blocksize; free -= xh_free_start % blocksize;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment