Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] Backport patches to ocfs2 1.4 tree from mainline
Found 15 patches (out of 162) that appeared relevant to ocfs2 1.4. Please review. Sunil
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 01/15] ocfs2: Fix check of return value of ocfs2_start_trans()
From: Jan Kara <jack at suse.cz> Mainline commit fa38e92cb34e27e60d0faf1035934eb9b44aa1d4 On failure, ocfs2_start_trans() returns values like ERR_PTR(-ENOMEM). Thus checks for !handle are wrong. Fix them to use IS_ERR(). Signed-off-by: Jan Kara <jack at suse.cz> Signed-off-by: Joel Becker <joel.becker at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/file.c | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 6877dea..2871b45 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -252,8 +252,8 @@ int ocfs2_update_inode_atime(struct inode *inode, mlog_entry_void(); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); - if (handle == NULL) { - ret = -ENOMEM; + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); mlog_errno(ret); goto out; } @@ -317,8 +317,8 @@ static int ocfs2_simple_size_update(struct inode *inode, handle_t *handle = NULL; handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); - if (handle == NULL) { - ret = -ENOMEM; + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); mlog_errno(ret); goto out; } @@ -1212,8 +1212,8 @@ static int __ocfs2_write_remove_suid(struct inode *inode, (unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_mode); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); - if (handle == NULL) { - ret = -ENOMEM; + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); mlog_errno(ret); goto out; } @@ -1415,8 +1415,8 @@ static int __ocfs2_remove_inode_range(struct inode *inode, } handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); - if (handle == NULL) { - ret = -ENOMEM; + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); mlog_errno(ret); goto out; } @@ -1508,8 +1508,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, goto out; handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); - if (handle == NULL) { - ret = -ENOMEM; + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); mlog_errno(ret); goto out; } -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 02/15] ocfs2: Fix checking of return value of new_inode()
From: Jan Kara <jack at suse.cz> Mainline commit 87cfa004321c62aec681713ea48e0b846336d9f4 new_inode() does not return ERR_PTR() but NULL in case of failure. Correct checking of the return value. Signed-off-by: Jan Kara <jack at suse.cz> Signed-off-by: Joel Becker <joel.becker at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/namei.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 7d8bed4..0391f6e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -377,8 +377,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, } inode = new_inode(dir->i_sb); - if (IS_ERR(inode)) { - status = PTR_ERR(inode); + if (!inode) { + status = -ENOMEM; mlog(ML_ERROR, "new_inode failed!\n"); goto leave; } -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 03/15] ocfs2: Add helper clear_nlink()
Commit ce71ec36840368b877fb63bd14c8e67ab62d08b1 in mainline introduced helper clear_nlink(). This patch adds the helper in kapi-include. Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com> --- Makefile | 3 ++- configure.in | 5 +++++ kapi-compat/include/clear_nlink.h | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletions(-) create mode 100644 kapi-compat/include/clear_nlink.h diff --git a/Makefile b/Makefile index 8e959ff..d976201 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,8 @@ KAPI_COMPAT_FILES = \ kapi-compat/include/le16_add_cpu.h \ kapi-compat/include/le32_add_cpu.h \ kapi-compat/include/le64_add_cpu.h \ - kapi-compat/include/be32_add_cpu.h + kapi-compat/include/be32_add_cpu.h \ + kapi-compat/include/clear_nlink.h PATCH_FILES diff --git a/configure.in b/configure.in index a92110a..b7efa1b 100644 --- a/configure.in +++ b/configure.in @@ -480,6 +480,11 @@ OCFS2_CHECK_KERNEL([be32_add_cpu() in byteorder/generic.h], byteorder/generic.h, , be32_add_cpu_compat_header="be32_add_cpu.h", [^static inline void be32_add_cpu(]) KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS $be32_add_cpu_compat_header" +clear_nlink_compat_header="" +OCFS2_CHECK_KERNEL([clear_nlink() in fs.h], fs.h, + , clear_nlink_compat_header="clear_nlink.h", [^static inline void clear_nlink(]) +KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS $clear_nlink_compat_header" + # using -include has two advantages: # the source doesn't need to know to include compat headers # the compat header file names don't go through the search path diff --git a/kapi-compat/include/clear_nlink.h b/kapi-compat/include/clear_nlink.h new file mode 100644 index 0000000..ef43ff2 --- /dev/null +++ b/kapi-compat/include/clear_nlink.h @@ -0,0 +1,19 @@ +#ifndef KAPI_CLEAR_NLINK_H +#define KAPI_CLEAR_NLINK_H + +#include <linux/fs.h> + +/** + * clear_nlink - directly zero an inode's link count + * @inode: inode + * + * This is a low-level filesystem helper to replace any + * direct filesystem manipulation of i_nlink. See + * drop_nlink() for why we care about i_nlink hitting zero. + */ +static inline void clear_nlink(struct inode *inode) +{ + inode->i_nlink = 0; +} + +#endif -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 04/15] ocfs2: Let inode be really deleted when ocfs2_mknod_locked() fails
From: Jan Kara <jack at suse.cz> Mainline commit b99835c1684918b9975851d71455c5c007d1715b We forgot to set i_nlink to 0 when returning due to error from ocfs2_mknod_locked() and thus inode was not properly released via ocfs2_delete_inode() (e.g. claimed space was not released). Fix it. Signed-off-by: Jan Kara <jack at suse.cz> Signed-off-by: Joel Becker <joel.becker at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/namei.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 0391f6e..c8206f9 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -490,8 +490,10 @@ leave: brelse(*new_fe_bh); *new_fe_bh = NULL; } - if (inode) + if (inode) { + clear_nlink(inode); iput(inode); + } } mlog_exit(status); -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 05/15] ocfs2: return 0 in page_mkwrite to let VFS retry.
From: Tao Ma <tao.ma at oracle.com> Mainline commit 4c1bbf1ba631d7db61ce3462349a3f5d14ae3009 In ocfs2_page_mkwrite, we return -EINVAL when we found the page mapping isn't updated, and it will cause the user space program get SIGBUS and exit. The reason is that during race writeable mmap, we will do unmap_mapping_range in ocfs2_data_downconvert_worker. The good thing is that if we reuturn 0 in page_mkwrite, VFS will retry fault and then call page_mkwrite again, so it is safe to return 0 here. Signed-off-by: Tao Ma <tao.ma at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/mmap.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index ff5dc1d..4a07c4a 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c @@ -147,7 +147,11 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, * ocfs2_write_begin_nolock(). */ if (!PageUptodate(page) || page->mapping != inode->i_mapping) { - ret = -EINVAL; + /* + * the page has been umapped in ocfs2_data_downconvert_worker. + * So return 0 here and let VFS retry. + */ + ret = 0; goto out; } -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 06/15] ocfs2: truncate outstanding block after direct io failure
From: Dmitri Monakhov <dmonakhov at openvz.org> Mainline commit c435400140d24fbcb3da6b1e006be831f9056cb6 Signed-off-by: Dmitri Monakhov <dmonakhov at openvz.org> Cc: Jeff Moyer <jmoyer at redhat.com> Cc: Mark Fasheh <mark.fasheh at oracle.com> Cc: Joel Becker <Joel.Becker at oracle.com> Cc: Nick Piggin <nickpiggin at yahoo.com.au> Signed-off-by: Andrew Morton <akpm at linux-foundation.org> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/file.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 2871b45..0c8e03a 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2170,6 +2170,13 @@ relock: written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, ppos, count, ocount); if (written < 0) { + /* + * direct write may have instantiated a few + * blocks outside i_size. Trim these off again. + * Don't need i_size_read because we hold i_mutex. + */ + if (*ppos + count > inode->i_size) + vmtruncate(inode, inode->i_size); ret = written; goto out_dio; } -- 1.5.6.3
From: Coly Li <coyli at suse.de> Mainline commit 3b5da0189c93160e44b878d2c72e9552d642497c This patch fixes two typos in comments of ocfs2. Signed-off-by: Coly Li <coyli at suse.de> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/dlm/userdlm.h | 2 +- fs/ocfs2/ocfs2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/dlm/userdlm.h b/fs/ocfs2/dlm/userdlm.h index 39ec277..0c3cc03 100644 --- a/fs/ocfs2/dlm/userdlm.h +++ b/fs/ocfs2/dlm/userdlm.h @@ -33,7 +33,7 @@ #include <linux/workqueue.h> /* user_lock_res->l_flags flags. */ -#define USER_LOCK_ATTACHED (0x00000001) /* have we initialized +#define USER_LOCK_ATTACHED (0x00000001) /* we have initialized * the lvb */ #define USER_LOCK_BUSY (0x00000002) /* we are currently in * dlm_lock */ diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 7b2a9a8..83a30a0 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -83,7 +83,7 @@ enum ocfs2_unlock_action { }; /* ocfs2_lock_res->l_flags flags. */ -#define OCFS2_LOCK_ATTACHED (0x00000001) /* have we initialized +#define OCFS2_LOCK_ATTACHED (0x00000001) /* we have initialized * the lvb */ #define OCFS2_LOCK_BUSY (0x00000002) /* we are currently in * dlm_lock */ -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 08/15] ocfs2: fix wake_up in unlock_ast
From: David Teigland <teigland at redhat.com> Mainline commit 07f9eebcdfaeefc8f807fa1bcce1d7c3ae6661b1 In ocfs2_unlock_ast(), call wake_up() on lockres before releasing the spin lock on it. As soon as the spin lock is released, the lockres can be freed. Signed-off-by: David Teigland <teigland at redhat.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/dlmglue.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 7781ef1..fce142b 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -2756,9 +2756,8 @@ static void ocfs2_unlock_ast(void *opaque, enum dlm_status status) lockres_clear_flags(lockres, OCFS2_LOCK_BUSY); complete_unlock: lockres->l_unlock_action = OCFS2_UNLOCK_INVALID; - spin_unlock_irqrestore(&lockres->l_lock, flags); - wake_up(&lockres->l_event); + spin_unlock_irqrestore(&lockres->l_lock, flags); mlog_exit_void(); } -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 09/15] ocfs2/dlm: Fix a race between migrate request and exit domain
Mainline commit 2b83256407687613e906bee93d98a25339128a4d Patch address a racing migrate request message and an exit domain message. Instead of blocking exit domains for the duration of the migrate, we ignore failure to deliver that message. This is because an exiting domain should not have any active locks and thus has no role to play in the migration. Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/dlm/dlmmaster.c | 23 +++++++++++++++++++---- 1 files changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 9d3472e..d87556f 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2949,7 +2949,7 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm, struct dlm_node_iter *iter) { struct dlm_migrate_request migrate; - int ret, status = 0; + int ret, skip, status = 0; int nodenum; memset(&migrate, 0, sizeof(migrate)); @@ -2966,12 +2966,27 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm, nodenum == new_master) continue; + /* We could race exit domain. If exited, skip. */ + spin_lock(&dlm->spinlock); + skip = (!test_bit(nodenum, dlm->domain_map)); + spin_unlock(&dlm->spinlock); + if (skip) { + clear_bit(nodenum, iter->node_map); + continue; + } + ret = o2net_send_message(DLM_MIGRATE_REQUEST_MSG, dlm->key, &migrate, sizeof(migrate), nodenum, &status); - if (ret < 0) - mlog_errno(ret); - else if (status < 0) { + if (ret < 0) { + mlog(0, "migrate_request returned %d!\n", ret); + if (!dlm_is_host_down(ret)) { + mlog(ML_ERROR, "unhandled error=%d!\n", ret); + BUG(); + } + clear_bit(nodenum, iter->node_map); + ret = 0; + } else if (status < 0) { mlog(0, "migrate request (node %u) returned %d!\n", nodenum, status); ret = status; -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 10/15] ocfs2/dlm: Clean up errors in dlm_proxy_ast_handler()
Mainline commit 57dff2676eb68d805883a2204faaa5339ac44e03 Patch cleans printed errors in dlm_proxy_ast_handler(). The errors now includes the node number that sent the (b)ast. Also it reduces the number of endian swaps of the cookie. Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/dlm/dlmast.c | 52 +++++++++++++++++++++++++----------------------- 1 files changed, 27 insertions(+), 25 deletions(-) diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c index 644bee5..d07ddbe 100644 --- a/fs/ocfs2/dlm/dlmast.c +++ b/fs/ocfs2/dlm/dlmast.c @@ -275,6 +275,7 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, struct list_head *iter, *head=NULL; u64 cookie; u32 flags; + u8 node; if (!dlm_grab(dlm)) { dlm_error(DLM_REJECTED); @@ -286,18 +287,21 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, name = past->name; locklen = past->namelen; - cookie = be64_to_cpu(past->cookie); + cookie = past->cookie; flags = be32_to_cpu(past->flags); + node = past->node_idx; if (locklen > DLM_LOCKID_NAME_MAX) { ret = DLM_IVBUFLEN; - mlog(ML_ERROR, "Invalid name length in proxy ast handler!\n"); + mlog(ML_ERROR, "Invalid name length (%d) in proxy ast " + "handler!\n", locklen); goto leave; } if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) = (LKM_PUT_LVB|LKM_GET_LVB)) { - mlog(ML_ERROR, "both PUT and GET lvb specified\n"); + mlog(ML_ERROR, "Both PUT and GET lvb specified, (0x%x)\n", + flags); ret = DLM_BADARGS; goto leave; } @@ -310,22 +314,21 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, if (past->type != DLM_AST && past->type != DLM_BAST) { mlog(ML_ERROR, "Unknown ast type! %d, cookie=%u:%llu" - "name=%.*s\n", past->type, - dlm_get_lock_cookie_node(cookie), - dlm_get_lock_cookie_seq(cookie), - locklen, name); + "name=%.*s, node=%u\n", past->type, + dlm_get_lock_cookie_node(be64_to_cpu(cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), + locklen, name, node); ret = DLM_IVLOCKID; goto leave; } res = dlm_lookup_lockres(dlm, name, locklen); if (!res) { - mlog(0, "got %sast for unknown lockres! " - "cookie=%u:%llu, name=%.*s, namelen=%u\n", - past->type == DLM_AST ? "" : "b", - dlm_get_lock_cookie_node(cookie), - dlm_get_lock_cookie_seq(cookie), - locklen, name, locklen); + mlog(0, "Got %sast for unknown lockres! cookie=%u:%llu, " + "name=%.*s, node=%u\n", (past->type == DLM_AST ? "" : "b"), + dlm_get_lock_cookie_node(be64_to_cpu(cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), + locklen, name, node); ret = DLM_IVLOCKID; goto leave; } @@ -337,12 +340,12 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, spin_lock(&res->spinlock); if (res->state & DLM_LOCK_RES_RECOVERING) { - mlog(0, "responding with DLM_RECOVERING!\n"); + mlog(0, "Responding with DLM_RECOVERING!\n"); ret = DLM_RECOVERING; goto unlock_out; } if (res->state & DLM_LOCK_RES_MIGRATING) { - mlog(0, "responding with DLM_MIGRATING!\n"); + mlog(0, "Responding with DLM_MIGRATING!\n"); ret = DLM_MIGRATING; goto unlock_out; } @@ -351,7 +354,7 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, lock = NULL; list_for_each(iter, head) { lock = list_entry (iter, struct dlm_lock, list); - if (be64_to_cpu(lock->ml.cookie) == cookie) + if (lock->ml.cookie == cookie) goto do_ast; } @@ -363,15 +366,15 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, list_for_each(iter, head) { lock = list_entry (iter, struct dlm_lock, list); - if (be64_to_cpu(lock->ml.cookie) == cookie) + if (lock->ml.cookie == cookie) goto do_ast; } - mlog(0, "got %sast for unknown lock! cookie=%u:%llu, " - "name=%.*s, namelen=%u\n", past->type == DLM_AST ? "" : "b", - dlm_get_lock_cookie_node(cookie), - dlm_get_lock_cookie_seq(cookie), - locklen, name, locklen); + mlog(0, "Got %sast for unknown lock! cookie=%u:%llu, name=%.*s, " + "node=%u\n", past->type == DLM_AST ? "" : "b", + dlm_get_lock_cookie_node(be64_to_cpu(cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), + locklen, name, node); ret = DLM_NORMAL; unlock_out: @@ -383,8 +386,8 @@ do_ast: if (past->type == DLM_AST) { /* do not alter lock refcount. switching lists. */ list_move_tail(&lock->list, &res->granted); - mlog(0, "ast: adding to granted list... type=%d, " - "convert_type=%d\n", lock->ml.type, lock->ml.convert_type); + mlog(0, "ast: Adding to granted list... type=%d, " + "convert_type=%d\n", lock->ml.type, lock->ml.convert_type); if (lock->ml.convert_type != LKM_IVMODE) { lock->ml.type = lock->ml.convert_type; lock->ml.convert_type = LKM_IVMODE; @@ -408,7 +411,6 @@ do_ast: dlm_do_local_bast(dlm, res, lock, past->blocked_type); leave: - if (res) dlm_lockres_put(res); -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 11/15] ocfs2/dlm: Hold off sending lockres drop ref message while lockres is migrating
Mainline commit d4f7e650e55af6b235871126f747da88600e8040 During lockres purge, o2dlm sends a drop reference message to the lockres master. This patch delays the message if the lockres is being migrated. Fixes oss bugzilla#1012 http://oss.oracle.com/bugzilla/show_bug.cgi?id=1012 Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/dlm/dlmthread.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 4060bb3..d129520 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -181,7 +181,8 @@ 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_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG | + DLM_LOCK_RES_MIGRATING)); spin_unlock(&res->spinlock); /* clear our bit from the master's refmap, ignore errors */ -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 12/15] ocfs2/dlm: Fix race in adding/removing lockres' to/from the tracking list
Mainline commit b0d4f817ba5de8adb875ace594554a96d7737710 This patch adds a new lock, dlm->tracking_lock, to protect adding/removing lockres' to/from the dlm->tracking_list. We were previously using dlm->spinlock for the same, but that proved inadequate as we could be freeing a lockres from a context that did not hold that lock. As the new lock only protects this list, we can explicitly take it when removing the lockres from the tracking list. This bug was exposed when testing multiple processes concurrently flock() the same file. Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/dlm/dlmcommon.h | 3 ++ fs/ocfs2/dlm/dlmdebug.c | 53 ++++++++++++++++++++------------------------- fs/ocfs2/dlm/dlmdomain.c | 1 + fs/ocfs2/dlm/dlmmaster.c | 10 ++++++++ 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 9add88d..a7ecccc 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -140,6 +140,7 @@ struct dlm_ctxt unsigned int purge_count; spinlock_t spinlock; spinlock_t ast_lock; + spinlock_t track_lock; char *name; u8 node_num; u32 key; @@ -316,6 +317,8 @@ struct dlm_lock_resource * put on a list for the dlm thread to run. */ unsigned long last_used; + struct dlm_ctxt *dlm; + unsigned migration_pending:1; atomic_t asts_reserved; spinlock_t spinlock; diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index 1b81dcb..b32f60a 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c @@ -630,43 +630,38 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos) { struct debug_lockres *dl = m->private; struct dlm_ctxt *dlm = dl->dl_ctxt; + struct dlm_lock_resource *oldres = dl->dl_res; struct dlm_lock_resource *res = NULL; + struct list_head *track_list; - spin_lock(&dlm->spinlock); + spin_lock(&dlm->track_lock); + if (oldres) + track_list = &oldres->tracking; + else + track_list = &dlm->tracking_list; - if (dl->dl_res) { - list_for_each_entry(res, &dl->dl_res->tracking, tracking) { - if (dl->dl_res) { - dlm_lockres_put(dl->dl_res); - dl->dl_res = NULL; - } - if (&res->tracking == &dlm->tracking_list) { - mlog(0, "End of list found, %p\n", res); - dl = NULL; - break; - } + list_for_each_entry(res, track_list, tracking) { + if (&res->tracking == &dlm->tracking_list) + res = NULL; + else dlm_lockres_get(res); - dl->dl_res = res; - break; - } - } else { - if (!list_empty(&dlm->tracking_list)) { - list_for_each_entry(res, &dlm->tracking_list, tracking) - break; - dlm_lockres_get(res); - dl->dl_res = res; - } else - dl = NULL; + break; } + spin_unlock(&dlm->track_lock); - if (dl) { - spin_lock(&dl->dl_res->spinlock); - dump_lockres(dl->dl_res, dl->dl_buf, dl->dl_len - 1); - spin_unlock(&dl->dl_res->spinlock); - } + if (oldres) + dlm_lockres_put(oldres); - spin_unlock(&dlm->spinlock); + dl->dl_res = res; + + if (res) { + spin_lock(&res->spinlock); + dump_lockres(res, dl->dl_buf, dl->dl_len - 1); + spin_unlock(&res->spinlock); + } else + dl = NULL; + /* passed to seq_show */ return dl; } diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 2eff4a4..c2e192e 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -1550,6 +1550,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, spin_lock_init(&dlm->spinlock); spin_lock_init(&dlm->master_lock); spin_lock_init(&dlm->ast_lock); + spin_lock_init(&dlm->track_lock); INIT_LIST_HEAD(&dlm->list); INIT_LIST_HEAD(&dlm->dirty_list); INIT_LIST_HEAD(&dlm->reco.resources); diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index d87556f..ec52d90 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -505,8 +505,10 @@ void dlm_change_lockres_owner(struct dlm_ctxt *dlm, static void dlm_lockres_release(struct kref *kref) { struct dlm_lock_resource *res; + struct dlm_ctxt *dlm; res = container_of(kref, struct dlm_lock_resource, refs); + dlm = res->dlm; /* This should not happen -- all lockres' have a name * associated with them at init time. */ @@ -515,6 +517,7 @@ static void dlm_lockres_release(struct kref *kref) mlog(0, "destroying lockres %.*s\n", res->lockname.len, res->lockname.name); + spin_lock(&dlm->track_lock); if (!list_empty(&res->tracking)) list_del_init(&res->tracking); else { @@ -522,6 +525,9 @@ static void dlm_lockres_release(struct kref *kref) res->lockname.len, res->lockname.name); dlm_print_one_lock_resource(res); } + spin_unlock(&dlm->track_lock); + + dlm_put(dlm); if (!hlist_unhashed(&res->hash_node) || !list_empty(&res->granted) || @@ -595,6 +601,10 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, res->migration_pending = 0; res->inflight_locks = 0; + /* put in dlm_lockres_release */ + dlm_grab(dlm); + res->dlm = dlm; + kref_init(&res->refs); /* just for consistency */ -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 13/15] ocfs2/dlm: Fix race during lockres mastery
Mainline commit 7b791d68562e4ce5ab57cbacb10a1ad4ee33956e dlm_get_lock_resource() is supposed to return a lock resource with a proper master. If multiple concurrent threads attempt to lookup the lockres for the same lockid while the lock mastery in underway, one or more threads are likely to return a lockres without a proper master. This patch makes the threads wait in dlm_get_lock_resource() while the mastery is underway, ensuring all threads return the lockres with a proper master. This issue is known to be limited to users using the flock() syscall. For all other fs operations, the ocfs2 dlmglue layer serializes the dlm op for each lockid. Users encountering this bug will see flock() return EINVAL and dmesg have the following error: ERROR: Dlm error "DLM_BADARGS" while calling dlmlock on resource <LOCKID>: bad api args Reported-by: Coly Li <coyli at suse.de> Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com> Signed-off-by: Mark Fasheh <mfasheh at suse.com> --- fs/ocfs2/dlm/dlmmaster.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index ec52d90..b0ea529 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -732,14 +732,21 @@ lookup: if (tmpres) { int dropping_ref = 0; + spin_unlock(&dlm->spinlock); + spin_lock(&tmpres->spinlock); + /* We wait for the other thread that is mastering the resource */ + if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { + __dlm_wait_on_lockres(tmpres); + BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN); + } + if (tmpres->owner == dlm->node_num) { BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF); dlm_lockres_grab_inflight_ref(dlm, tmpres); } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) dropping_ref = 1; spin_unlock(&tmpres->spinlock); - spin_unlock(&dlm->spinlock); /* wait until done messaging the master, drop our ref to allow * the lockres to be purged, start over. */ -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 14/15] trivial: fix then -> than typos in comments and documentation
From: Frederik Schwarzer <schwarzerf at gmail.com> Mainline commit 025dfdafe77f20b3890981a394774baab7b9c827 - (better, more, bigger ...) then -> (...) than Signed-off-by: Frederik Schwarzer <schwarzerf at gmail.com> Signed-off-by: Jiri Kosina <jkosina at suse.cz> --- fs/ocfs2/cluster/heartbeat.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 999e7e5..3e52fa3 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -862,7 +862,7 @@ static int o2hb_thread(void *data) while (!kthread_should_stop() && !reg->hr_unclean_stop) { /* We track the time spent inside - * o2hb_do_disk_heartbeat so that we avoid more then + * o2hb_do_disk_heartbeat so that we avoid more than * hr_timeout_ms between disk writes. On busy systems * this should result in a heartbeat which is less * likely to time itself out. */ -- 1.5.6.3
Sunil Mushran
2009-Jan-14 01:47 UTC
[Ocfs2-devel] [PATCH 15/15] typos: fix similar typos to successfull
From: Coly Li <coyli at suse.de> Mainline commit 73ac36ea14fd18ea3dc057e41b16ff31a3c0bd5a When I review ocfs2 code, find there are 2 typos to "successfull". After doing grep "successfull " in kernel tree, 22 typos found totally -- great minds always think alike :) This patch fixes all the similar typos. Thanks for Randy's ack and comments. Signed-off-by: Coly Li <coyli at suse.de> Acked-by: Randy Dunlap <randy.dunlap at oracle.com> Acked-by: Roland Dreier <rolandd at cisco.com> Cc: Jeremy Kerr <jk at ozlabs.org> Cc: Jeff Garzik <jeff at garzik.org> Cc: Heiko Carstens <heiko.carstens at de.ibm.com> Cc: Martin Schwidefsky <schwidefsky at de.ibm.com> Cc: Theodore Ts'o <tytso at mit.edu> Cc: Mark Fasheh <mfasheh at suse.com> Cc: Vlad Yasevich <vladislav.yasevich at hp.com> Cc: Sridhar Samudrala <sri at us.ibm.com> Signed-off-by: Andrew Morton <akpm at linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org> --- fs/ocfs2/dlmglue.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index fce142b..7eceb0a 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -978,7 +978,7 @@ static int ocfs2_lock_create(struct ocfs2_super *osb, ocfs2_recover_from_dlm_error(lockres, 1); } - mlog(0, "lock %s, successfull return from dlmlock\n", lockres->l_name); + mlog(0, "lock %s, successful return from dlmlock\n", lockres->l_name); bail: mlog_exit(ret); @@ -1189,7 +1189,7 @@ again: goto out; } - mlog(0, "lock %s, successfull return from dlmlock\n", + mlog(0, "lock %s, successful return from dlmlock\n", lockres->l_name); /* At this point we've gone inside the dlm and need to @@ -2837,7 +2837,7 @@ static int ocfs2_drop_lock(struct ocfs2_super *osb, dlm_print_one_lock(lockres->l_lksb.lockid); BUG(); } - mlog(0, "lock %s, successfull return from dlmunlock\n", + mlog(0, "lock %s, successful return from dlmunlock\n", lockres->l_name); ocfs2_wait_on_busy_lock(lockres); -- 1.5.6.3