Author: zbyniu                       Date: Wed Apr  4 13:40:45 2007 GMT
Module: SOURCES                       Tag: LINUX_2_6_20
---- Log message:
- gfs and dlm ported from 2.6.21rc5

---- Files affected:
SOURCES:
   linux-2.6-gfs2_dlm-2.6.21.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/linux-2.6-gfs2_dlm-2.6.21.patch
diff -u /dev/null SOURCES/linux-2.6-gfs2_dlm-2.6.21.patch:1.1.2.1
--- /dev/null   Wed Apr  4 15:40:45 2007
+++ SOURCES/linux-2.6-gfs2_dlm-2.6.21.patch     Wed Apr  4 15:40:40 2007
@@ -0,0 +1,4785 @@
+diff -uNrp 2.6.20/fs/dlm/Kconfig 2.6.21/fs/dlm/Kconfig
+--- 2.6.20/fs/dlm/Kconfig      2007-02-04 19:44:54.000000000 +0100
++++ 2.6.21/fs/dlm/Kconfig      2007-03-26 00:56:23.000000000 +0200
+@@ -3,21 +3,21 @@ menu "Distributed Lock Manager"
+ 
+ config DLM
+       tristate "Distributed Lock Manager (DLM)"
+-      depends on IPV6 || IPV6=n
++      depends on SYSFS && (IPV6 || IPV6=n)
+       select CONFIGFS_FS
+       select IP_SCTP if DLM_SCTP
+       help
+-      A general purpose distributed lock manager for kernel or userspace
+-      applications.
++        A general purpose distributed lock manager for kernel or userspace
++        applications.
+ 
+ choice
+       prompt "Select DLM communications protocol"
+       depends on DLM
+       default DLM_TCP
+       help
+-      The DLM Can use TCP or SCTP for it's network communications.
+-      SCTP supports multi-homed operations whereas TCP doesn't.
+-      However, SCTP seems to have stability problems at the moment.
++        The DLM Can use TCP or SCTP for it's network communications.
++        SCTP supports multi-homed operations whereas TCP doesn't.
++        However, SCTP seems to have stability problems at the moment.
+ 
+ config DLM_TCP
+       bool "TCP/IP"
+@@ -31,8 +31,8 @@ config DLM_DEBUG
+       bool "DLM debugging"
+       depends on DLM
+       help
+-      Under the debugfs mount point, the name of each lockspace will
+-      appear as a file in the "dlm" directory.  The output is the
+-      list of resource and locks the local node knows about.
++        Under the debugfs mount point, the name of each lockspace will
++        appear as a file in the "dlm" directory.  The output is the
++        list of resource and locks the local node knows about.
+ 
+ endmenu
+diff -uNrp 2.6.20/fs/dlm/config.c 2.6.21/fs/dlm/config.c
+--- 2.6.20/fs/dlm/config.c     2007-02-04 19:44:54.000000000 +0100
++++ 2.6.21/fs/dlm/config.c     2007-03-26 00:56:23.000000000 +0200
+@@ -54,6 +54,11 @@ static struct config_item *make_node(str
+ static void drop_node(struct config_group *, struct config_item *);
+ static void release_node(struct config_item *);
+ 
++static ssize_t show_cluster(struct config_item *i, struct configfs_attribute 
*a,
++                          char *buf);
++static ssize_t store_cluster(struct config_item *i,
++                           struct configfs_attribute *a,
++                           const char *buf, size_t len);
+ static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
+                        char *buf);
+ static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a,
+@@ -73,6 +78,101 @@ static ssize_t node_nodeid_write(struct 
+ static ssize_t node_weight_read(struct node *nd, char *buf);
+ static ssize_t node_weight_write(struct node *nd, const char *buf, size_t 
len);
+ 
++struct cluster {
++      struct config_group group;
++      unsigned int cl_tcp_port;
++      unsigned int cl_buffer_size;
++      unsigned int cl_rsbtbl_size;
++      unsigned int cl_lkbtbl_size;
++      unsigned int cl_dirtbl_size;
++      unsigned int cl_recover_timer;
++      unsigned int cl_toss_secs;
++      unsigned int cl_scan_secs;
++      unsigned int cl_log_debug;
++};
++
++enum {
++      CLUSTER_ATTR_TCP_PORT = 0,
++      CLUSTER_ATTR_BUFFER_SIZE,
++      CLUSTER_ATTR_RSBTBL_SIZE,
++      CLUSTER_ATTR_LKBTBL_SIZE,
++      CLUSTER_ATTR_DIRTBL_SIZE,
++      CLUSTER_ATTR_RECOVER_TIMER,
++      CLUSTER_ATTR_TOSS_SECS,
++      CLUSTER_ATTR_SCAN_SECS,
++      CLUSTER_ATTR_LOG_DEBUG,
++};
++
++struct cluster_attribute {
++      struct configfs_attribute attr;
++      ssize_t (*show)(struct cluster *, char *);
++      ssize_t (*store)(struct cluster *, const char *, size_t);
++};
++
++static ssize_t cluster_set(struct cluster *cl, unsigned int *cl_field,
++                         unsigned int *info_field, int check_zero,
++                         const char *buf, size_t len)
++{
++      unsigned int x;
++
++      if (!capable(CAP_SYS_ADMIN))
++              return -EACCES;
++
++      x = simple_strtoul(buf, NULL, 0);
++
++      if (check_zero && !x)
++              return -EINVAL;
++
++      *cl_field = x;
++      *info_field = x;
++
++      return len;
++}
++
++#define __CONFIGFS_ATTR(_name,_mode,_read,_write) {                           
\
++      .attr   = { .ca_name = __stringify(_name),                            \
++                  .ca_mode = _mode,                                         \
++                  .ca_owner = THIS_MODULE },                                \
++      .show   = _read,                                                      \
++      .store  = _write,                                                     \
++}
++
++#define CLUSTER_ATTR(name, check_zero)                                        
\
++static ssize_t name##_write(struct cluster *cl, const char *buf, size_t len)  
\
++{                                                                             
\
++      return cluster_set(cl, &cl->cl_##name, &dlm_config.ci_##name,         \
++                         check_zero, buf, len);                             \
++}                                                                             
\
++static ssize_t name##_read(struct cluster *cl, char *buf)                     
\
++{                                                                             
\
++      return snprintf(buf, PAGE_SIZE, "%u\n", cl->cl_##name);               \
++}                                                                             
\
++static struct cluster_attribute cluster_attr_##name =                         
\
++__CONFIGFS_ATTR(name, 0644, name##_read, name##_write)
++
++CLUSTER_ATTR(tcp_port, 1);
++CLUSTER_ATTR(buffer_size, 1);
++CLUSTER_ATTR(rsbtbl_size, 1);
++CLUSTER_ATTR(lkbtbl_size, 1);
++CLUSTER_ATTR(dirtbl_size, 1);
++CLUSTER_ATTR(recover_timer, 1);
++CLUSTER_ATTR(toss_secs, 1);
++CLUSTER_ATTR(scan_secs, 1);
++CLUSTER_ATTR(log_debug, 0);
++
++static struct configfs_attribute *cluster_attrs[] = {
++      [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
++      [CLUSTER_ATTR_BUFFER_SIZE] = &cluster_attr_buffer_size.attr,
++      [CLUSTER_ATTR_RSBTBL_SIZE] = &cluster_attr_rsbtbl_size.attr,
++      [CLUSTER_ATTR_LKBTBL_SIZE] = &cluster_attr_lkbtbl_size.attr,
++      [CLUSTER_ATTR_DIRTBL_SIZE] = &cluster_attr_dirtbl_size.attr,
++      [CLUSTER_ATTR_RECOVER_TIMER] = &cluster_attr_recover_timer.attr,
++      [CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs.attr,
++      [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr,
++      [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
++      NULL,
++};
++
+ enum {
+       COMM_ATTR_NODEID = 0,
+       COMM_ATTR_LOCAL,
+@@ -152,10 +252,6 @@ struct clusters {
+       struct configfs_subsystem subsys;
+ };
+ 
+-struct cluster {
+-      struct config_group group;
+-};
+-
+ struct spaces {
+       struct config_group ss_group;
+ };
+@@ -197,6 +293,8 @@ static struct configfs_group_operations 
+ 
+ static struct configfs_item_operations cluster_ops = {
+       .release = release_cluster,
++      .show_attribute = show_cluster,
++      .store_attribute = store_cluster,
+ };
+ 
+ static struct configfs_group_operations spaces_ops = {
+@@ -237,6 +335,7 @@ static struct config_item_type clusters_
+ 
+ static struct config_item_type cluster_type = {
+       .ct_item_ops = &cluster_ops,
++      .ct_attrs = cluster_attrs,
+       .ct_owner = THIS_MODULE,
+ };
+ 
+@@ -317,6 +416,16 @@ static struct config_group *make_cluster
+       cl->group.default_groups[1] = &cms->cs_group;
+       cl->group.default_groups[2] = NULL;
+ 
++      cl->cl_tcp_port = dlm_config.ci_tcp_port;
++      cl->cl_buffer_size = dlm_config.ci_buffer_size;
++      cl->cl_rsbtbl_size = dlm_config.ci_rsbtbl_size;
++      cl->cl_lkbtbl_size = dlm_config.ci_lkbtbl_size;
++      cl->cl_dirtbl_size = dlm_config.ci_dirtbl_size;
++      cl->cl_recover_timer = dlm_config.ci_recover_timer;
++      cl->cl_toss_secs = dlm_config.ci_toss_secs;
++      cl->cl_scan_secs = dlm_config.ci_scan_secs;
++      cl->cl_log_debug = dlm_config.ci_log_debug;
++
+       space_list = &sps->ss_group;
+       comm_list = &cms->cs_group;
+       return &cl->group;
+@@ -509,6 +618,25 @@ void dlm_config_exit(void)
+  * Functions for user space to read/write attributes
+  */
+ 
++static ssize_t show_cluster(struct config_item *i, struct configfs_attribute 
*a,
++                          char *buf)
++{
++      struct cluster *cl = to_cluster(i);
++      struct cluster_attribute *cla =
++                      container_of(a, struct cluster_attribute, attr);
++      return cla->show ? cla->show(cl, buf) : 0;
++}
++
++static ssize_t store_cluster(struct config_item *i,
++                           struct configfs_attribute *a,
++                           const char *buf, size_t len)
++{
++      struct cluster *cl = to_cluster(i);
++      struct cluster_attribute *cla =
++              container_of(a, struct cluster_attribute, attr);
++      return cla->store ? cla->store(cl, buf, len) : -EINVAL;
++}
++
+ static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
+                        char *buf)
+ {
+@@ -775,15 +903,17 @@ int dlm_our_addr(struct sockaddr_storage
+ #define DEFAULT_RECOVER_TIMER      5
+ #define DEFAULT_TOSS_SECS         10
+ #define DEFAULT_SCAN_SECS          5
++#define DEFAULT_LOG_DEBUG          0
+ 
+ struct dlm_config_info dlm_config = {
+-      .tcp_port = DEFAULT_TCP_PORT,
+-      .buffer_size = DEFAULT_BUFFER_SIZE,
+-      .rsbtbl_size = DEFAULT_RSBTBL_SIZE,
+-      .lkbtbl_size = DEFAULT_LKBTBL_SIZE,
+-      .dirtbl_size = DEFAULT_DIRTBL_SIZE,
+-      .recover_timer = DEFAULT_RECOVER_TIMER,
+-      .toss_secs = DEFAULT_TOSS_SECS,
+-      .scan_secs = DEFAULT_SCAN_SECS
++      .ci_tcp_port = DEFAULT_TCP_PORT,
++      .ci_buffer_size = DEFAULT_BUFFER_SIZE,
++      .ci_rsbtbl_size = DEFAULT_RSBTBL_SIZE,
++      .ci_lkbtbl_size = DEFAULT_LKBTBL_SIZE,
++      .ci_dirtbl_size = DEFAULT_DIRTBL_SIZE,
++      .ci_recover_timer = DEFAULT_RECOVER_TIMER,
++      .ci_toss_secs = DEFAULT_TOSS_SECS,
++      .ci_scan_secs = DEFAULT_SCAN_SECS,
++      .ci_log_debug = DEFAULT_LOG_DEBUG
+ };
+ 
+diff -uNrp 2.6.20/fs/dlm/config.h 2.6.21/fs/dlm/config.h
+--- 2.6.20/fs/dlm/config.h     2007-02-04 19:44:54.000000000 +0100
++++ 2.6.21/fs/dlm/config.h     2007-03-26 00:56:23.000000000 +0200
+@@ -17,14 +17,15 @@
+ #define DLM_MAX_ADDR_COUNT 3
+ 
+ struct dlm_config_info {
+-      int tcp_port;
+-      int buffer_size;
+-      int rsbtbl_size;
+-      int lkbtbl_size;
+-      int dirtbl_size;
+-      int recover_timer;
+-      int toss_secs;
+-      int scan_secs;
++      int ci_tcp_port;
++      int ci_buffer_size;
++      int ci_rsbtbl_size;
++      int ci_lkbtbl_size;
++      int ci_dirtbl_size;
++      int ci_recover_timer;
++      int ci_toss_secs;
++      int ci_scan_secs;
++      int ci_log_debug;
+ };
+ 
+ extern struct dlm_config_info dlm_config;
+diff -uNrp 2.6.20/fs/dlm/debug_fs.c 2.6.21/fs/dlm/debug_fs.c
+--- 2.6.20/fs/dlm/debug_fs.c   2007-02-04 19:44:54.000000000 +0100
++++ 2.6.21/fs/dlm/debug_fs.c   2007-03-26 00:56:23.000000000 +0200
+@@ -287,7 +287,7 @@ static int rsb_open(struct inode *inode,
+       return 0;
+ }
+ 
+-static struct file_operations rsb_fops = {
++static const struct file_operations rsb_fops = {
+       .owner   = THIS_MODULE,
+       .open    = rsb_open,
+       .read    = seq_read,
+@@ -331,7 +331,7 @@ static ssize_t waiters_read(struct file 
+       return rv;
+ }
+ 
+-static struct file_operations waiters_fops = {
++static const struct file_operations waiters_fops = {
+       .owner   = THIS_MODULE,
+       .open    = waiters_open,
+       .read    = waiters_read
+diff -uNrp 2.6.20/fs/dlm/dlm_internal.h 2.6.21/fs/dlm/dlm_internal.h
+--- 2.6.20/fs/dlm/dlm_internal.h       2007-02-04 19:44:54.000000000 +0100
++++ 2.6.21/fs/dlm/dlm_internal.h       2007-03-26 00:56:23.000000000 +0200
+@@ -41,6 +41,7 @@
+ #include <asm/uaccess.h>
+ 
+ #include <linux/dlm.h>
++#include "config.h"
+ 
+ #define DLM_LOCKSPACE_LEN     64
+ 
+@@ -69,12 +70,12 @@ struct dlm_mhandle;
+ #define log_error(ls, fmt, args...) \
+       printk(KERN_ERR "dlm: %s: " fmt "\n", (ls)->ls_name , ##args)
+ 
+-#define DLM_LOG_DEBUG
+-#ifdef DLM_LOG_DEBUG
+-#define log_debug(ls, fmt, args...) log_error(ls, fmt, ##args)
+-#else
+-#define log_debug(ls, fmt, args...)
+-#endif
++#define log_debug(ls, fmt, args...) \
++do { \
++      if (dlm_config.ci_log_debug) \
++              printk(KERN_DEBUG "dlm: %s: " fmt "\n", \
++                     (ls)->ls_name , ##args); \
++} while (0)
+ 
+ #define DLM_ASSERT(x, do) \
+ { \
+@@ -309,8 +310,8 @@ static inline int rsb_flag(struct dlm_rs
+ 
+ /* dlm_header is first element of all structs sent between nodes */
+ 
+-#define DLM_HEADER_MAJOR      0x00020000
+-#define DLM_HEADER_MINOR      0x00000001
++#define DLM_HEADER_MAJOR      0x00030000
++#define DLM_HEADER_MINOR      0x00000000
+ 
+ #define DLM_MSG                       1
+ #define DLM_RCOM              2
+@@ -386,6 +387,8 @@ struct dlm_rcom {
+       uint32_t                rc_type;        /* DLM_RCOM_ */
+       int                     rc_result;      /* multi-purpose */
+       uint64_t                rc_id;          /* match reply with request */
++      uint64_t                rc_seq;         /* sender's ls_recover_seq */
++      uint64_t                rc_seq_reply;   /* remote ls_recover_seq */
+       char                    rc_buf[0];
+ };
+ 
+@@ -523,6 +526,7 @@ struct dlm_user_proc {
+       spinlock_t              asts_spin;
+       struct list_head        locks;
+       spinlock_t              locks_spin;
++      struct list_head        unlocking;
+       wait_queue_head_t       wait;
+ };
+ 
+diff -uNrp 2.6.20/fs/dlm/lock.c 2.6.21/fs/dlm/lock.c
+--- 2.6.20/fs/dlm/lock.c       2007-02-04 19:44:54.000000000 +0100
++++ 2.6.21/fs/dlm/lock.c       2007-03-26 00:56:23.000000000 +0200
+@@ -754,6 +754,11 @@ static void add_to_waiters(struct dlm_lk
+       mutex_unlock(&ls->ls_waiters_mutex);
+ }
+ 
++/* We clear the RESEND flag because we might be taking an lkb off the waiters
++   list as part of process_requestqueue (e.g. a lookup that has an optimized
++   request reply on the requestqueue) between dlm_recover_waiters_pre() which
++   set RESEND and dlm_recover_waiters_post() */
++
+ static int _remove_from_waiters(struct dlm_lkb *lkb)
+ {
+       int error = 0;
+@@ -764,6 +769,7 @@ static int _remove_from_waiters(struct d
+               goto out;
+       }
+       lkb->lkb_wait_type = 0;
++      lkb->lkb_flags &= ~DLM_IFL_RESEND;
+       list_del(&lkb->lkb_wait_reply);
+       unhold_lkb(lkb);
+  out:
+@@ -810,7 +816,7 @@ static int shrink_bucket(struct dlm_ls *
+               list_for_each_entry_reverse(r, &ls->ls_rsbtbl[b].toss,
+                                           res_hashchain) {
+                       if (!time_after_eq(jiffies, r->res_toss_time +
+-                                         dlm_config.toss_secs * HZ))
++                                         dlm_config.ci_toss_secs * HZ))
+                               continue;
+                       found = 1;
+                       break;
+@@ -2144,12 +2150,24 @@ static void send_args(struct dlm_rsb *r,
+       if (lkb->lkb_astaddr)
+               ms->m_asts |= AST_COMP;
+ 
+-      if (ms->m_type == DLM_MSG_REQUEST || ms->m_type == DLM_MSG_LOOKUP)
+-              memcpy(ms->m_extra, r->res_name, r->res_length);
++      /* compare with switch in create_message; send_remove() doesn't
++         use send_args() */
+ 
+-      else if (lkb->lkb_lvbptr)
++      switch (ms->m_type) {
++      case DLM_MSG_REQUEST:
++      case DLM_MSG_LOOKUP:
++              memcpy(ms->m_extra, r->res_name, r->res_length);
++              break;
++      case DLM_MSG_CONVERT:
++      case DLM_MSG_UNLOCK:
++      case DLM_MSG_REQUEST_REPLY:
++      case DLM_MSG_CONVERT_REPLY:
++      case DLM_MSG_GRANT:
++              if (!lkb->lkb_lvbptr)
++                      break;
+               memcpy(ms->m_extra, lkb->lkb_lvbptr, r->res_ls->ls_lvblen);
+-
++              break;
++      }
+ }
+ 
+ static int send_common(struct dlm_rsb *r, struct dlm_lkb *lkb, int mstype)
+@@ -2418,8 +2436,12 @@ static int receive_request_args(struct d
+ 
+       DLM_ASSERT(is_master_copy(lkb), dlm_print_lkb(lkb););
+ 
+-      if (receive_lvb(ls, lkb, ms))
+-              return -ENOMEM;
++      if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
++              /* lkb was just created so there won't be an lvb yet */
++              lkb->lkb_lvbptr = allocate_lvb(ls);
++              if (!lkb->lkb_lvbptr)
++                      return -ENOMEM;
++      }
+ 
+       return 0;
+ }
+@@ -3002,7 +3024,7 @@ int dlm_receive_message(struct dlm_heade
+ {
+       struct dlm_message *ms = (struct dlm_message *) hd;
+       struct dlm_ls *ls;
+-      int error;
++      int error = 0;
+ 
+       if (!recovery)
+               dlm_message_in(ms);
+@@ -3119,7 +3141,7 @@ int dlm_receive_message(struct dlm_heade
+  out:
+       dlm_put_lockspace(ls);
+       dlm_astd_wake();
+-      return 0;
++      return error;
+ }
+ 
+ 
+@@ -3132,6 +3154,7 @@ static void recover_convert_waiter(struc
+       if (middle_conversion(lkb)) {
+               hold_lkb(lkb);
+               ls->ls_stub_ms.m_result = -EINPROGRESS;
++              ls->ls_stub_ms.m_flags = lkb->lkb_flags;
+               _remove_from_waiters(lkb);
+               _receive_convert_reply(lkb, &ls->ls_stub_ms);
+ 
+@@ -3205,6 +3228,7 @@ void dlm_recover_waiters_pre(struct dlm_
+               case DLM_MSG_UNLOCK:
+                       hold_lkb(lkb);
+                       ls->ls_stub_ms.m_result = -DLM_EUNLOCK;
++                      ls->ls_stub_ms.m_flags = lkb->lkb_flags;
+                       _remove_from_waiters(lkb);
+                       _receive_unlock_reply(lkb, &ls->ls_stub_ms);
+                       dlm_put_lkb(lkb);
+@@ -3213,6 +3237,7 @@ void dlm_recover_waiters_pre(struct dlm_
+               case DLM_MSG_CANCEL:
+                       hold_lkb(lkb);
+                       ls->ls_stub_ms.m_result = -DLM_ECANCEL;
++                      ls->ls_stub_ms.m_flags = lkb->lkb_flags;
+                       _remove_from_waiters(lkb);
+                       _receive_cancel_reply(lkb, &ls->ls_stub_ms);
+                       dlm_put_lkb(lkb);
+@@ -3571,6 +3596,14 @@ int dlm_recover_process_copy(struct dlm_
+       lock_rsb(r);
+ 
+       switch (error) {
++      case -EBADR:
++              /* There's a chance the new master received our lock before
++                 dlm_recover_master_reply(), this wouldn't happen if we did
++                 a barrier between recover_masters and recover_locks. */
++              log_debug(ls, "master copy not ready %x r %lx %s", lkb->lkb_id,
++                        (unsigned long)r, r->res_name);
++              dlm_send_rcom_lock(r, lkb);
++              goto out;
+       case -EEXIST:
+               log_debug(ls, "master copy exists %x", lkb->lkb_id);
+               /* fall through */
+@@ -3585,7 +3618,7 @@ int dlm_recover_process_copy(struct dlm_
+       /* an ack for dlm_recover_locks() which waits for replies from
+          all the locks it sends to new masters */
+       dlm_recovered_lock(r);
+-
++ out:
+       unlock_rsb(r);
+       put_rsb(r);
+       dlm_put_lkb(lkb);
+@@ -3610,7 +3643,7 @@ int dlm_user_request(struct dlm_ls *ls, 
+       }
+ 
+       if (flags & DLM_LKF_VALBLK) {
+-              ua->lksb.sb_lvbptr = kmalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
++              ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
+               if (!ua->lksb.sb_lvbptr) {
+                       kfree(ua);
+                       __put_lkb(ls, lkb);
+@@ -3679,7 +3712,7 @@ int dlm_user_convert(struct dlm_ls *ls, 
+       ua = (struct dlm_user_args *)lkb->lkb_astparam;
+ 
+       if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
+-              ua->lksb.sb_lvbptr = kmalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
++              ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
+               if (!ua->lksb.sb_lvbptr) {
+                       error = -ENOMEM;
+                       goto out_put;
+@@ -3745,12 +3778,10 @@ int dlm_user_unlock(struct dlm_ls *ls, s
+               goto out_put;
+ 
+       spin_lock(&ua->proc->locks_spin);
+-      list_del_init(&lkb->lkb_ownqueue);
++      /* dlm_user_add_ast() may have already taken lkb off the proc list */
++      if (!list_empty(&lkb->lkb_ownqueue))
++              list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking);
+       spin_unlock(&ua->proc->locks_spin);
+-
+-      /* this removes the reference for the proc->locks list added by
+-         dlm_user_request */
+-      unhold_lkb(lkb);
+  out_put:
+       dlm_put_lkb(lkb);
+  out:
+@@ -3790,9 +3821,8 @@ int dlm_user_cancel(struct dlm_ls *ls, s
+       /* this lkb was removed from the WAITING queue */
+       if (lkb->lkb_grmode == DLM_LOCK_IV) {
+               spin_lock(&ua->proc->locks_spin);
+-              list_del_init(&lkb->lkb_ownqueue);
++              list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking);
+               spin_unlock(&ua->proc->locks_spin);
+-              unhold_lkb(lkb);
+       }
+  out_put:
+       dlm_put_lkb(lkb);
+@@ -3853,11 +3883,6 @@ void dlm_clear_proc_locks(struct dlm_ls 
+       mutex_lock(&ls->ls_clear_proc_locks);
+ 
+       list_for_each_entry_safe(lkb, safe, &proc->locks, lkb_ownqueue) {
+-              if (lkb->lkb_ast_type) {
+-                      list_del(&lkb->lkb_astqueue);
+-                      unhold_lkb(lkb);
+-              }
+-
+               list_del_init(&lkb->lkb_ownqueue);
+ 
+               if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) {
+@@ -3874,6 +3899,20 @@ void dlm_clear_proc_locks(struct dlm_ls 
+ 
+               dlm_put_lkb(lkb);
+       }
++
++      /* in-progress unlocks */
++      list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
++              list_del_init(&lkb->lkb_ownqueue);
++              lkb->lkb_flags |= DLM_IFL_DEAD;
++              dlm_put_lkb(lkb);
++      }
++
++      list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) {
++              list_del(&lkb->lkb_astqueue);
++              dlm_put_lkb(lkb);
++      }
++
+       mutex_unlock(&ls->ls_clear_proc_locks);
+       unlock_recovery(ls);
+ }
++
+diff -uNrp 2.6.20/fs/dlm/lockspace.c 2.6.21/fs/dlm/lockspace.c
+--- 2.6.20/fs/dlm/lockspace.c  2007-02-04 19:44:54.000000000 +0100
++++ 2.6.21/fs/dlm/lockspace.c  2007-03-26 00:56:23.000000000 +0200
+@@ -236,7 +236,7 @@ static int dlm_scand(void *data)
+       while (!kthread_should_stop()) {
+               list_for_each_entry(ls, &lslist, ls_list)
+                       dlm_scan_rsbs(ls);
+-              schedule_timeout_interruptible(dlm_config.scan_secs * HZ);
<<Diff was trimmed, longer than 597 lines>>
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to