]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/gfs2/locking.c
Fix nfsd truncation of readdir results
[linux-2.6-omap-h63xx.git] / fs / gfs2 / locking.c
index fce2001e5e256a021c499de340ed167eaa472fb8..523243a13a2184a0fcbe02ecc10df012af3c77f8 100644 (file)
 #include <linux/kmod.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
-
-#include "lm_interface.h"
+#include <linux/lm_interface.h>
 
 struct lmh_wrapper {
        struct list_head lw_list;
-       struct lm_lockops *lw_ops;
+       const struct lm_lockops *lw_ops;
 };
 
+static int nolock_mount(char *table_name, char *host_data,
+                       lm_callback_t cb, void *cb_data,
+                       unsigned int min_lvb_size, int flags,
+                       struct lm_lockstruct *lockstruct,
+                       struct kobject *fskobj);
+
 /* List of registered low-level locking protocols.  A file system selects one
    of them by name at mount time, e.g. lock_nolock, lock_dlm. */
 
+static const struct lm_lockops nolock_ops = {
+       .lm_proto_name = "lock_nolock",
+       .lm_mount = nolock_mount,
+};
+
+static struct lmh_wrapper nolock_proto  = {
+       .lw_list = LIST_HEAD_INIT(nolock_proto.lw_list),
+       .lw_ops = &nolock_ops,
+};
+
 static LIST_HEAD(lmh_list);
 static DEFINE_MUTEX(lmh_lock);
 
+static int nolock_mount(char *table_name, char *host_data,
+                       lm_callback_t cb, void *cb_data,
+                       unsigned int min_lvb_size, int flags,
+                       struct lm_lockstruct *lockstruct,
+                       struct kobject *fskobj)
+{
+       char *c;
+       unsigned int jid;
+
+       c = strstr(host_data, "jid=");
+       if (!c)
+               jid = 0;
+       else {
+               c += 4;
+               sscanf(c, "%u", &jid);
+       }
+
+       lockstruct->ls_jid = jid;
+       lockstruct->ls_first = 1;
+       lockstruct->ls_lvb_size = min_lvb_size;
+       lockstruct->ls_ops = &nolock_ops;
+       lockstruct->ls_flags = LM_LSFLAG_LOCAL;
+
+       return 0;
+}
+
 /**
  * gfs2_register_lockproto - Register a low-level locking protocol
  * @proto: the protocol definition
@@ -37,7 +78,7 @@ static DEFINE_MUTEX(lmh_lock);
  * Returns: 0 on success, -EXXX on failure
  */
 
-int gfs2_register_lockproto(struct lm_lockops *proto)
+int gfs2_register_lockproto(const struct lm_lockops *proto)
 {
        struct lmh_wrapper *lw;
 
@@ -72,7 +113,7 @@ int gfs2_register_lockproto(struct lm_lockops *proto)
  *
  */
 
-void gfs2_unregister_lockproto(struct lm_lockops *proto)
+void gfs2_unregister_lockproto(const struct lm_lockops *proto)
 {
        struct lmh_wrapper *lw;
 
@@ -99,7 +140,7 @@ void gfs2_unregister_lockproto(struct lm_lockops *proto)
  * @table_name - the name of the lock space
  * @host_data - data specific to this host
  * @cb - the callback to the code using the lock module
- * @fsdata - data to pass back with the callback
+ * @sdp - The GFS2 superblock
  * @min_lvb_size - the mininum LVB size that the caller can deal with
  * @flags - LM_MFLAG_*
  * @lockstruct - a structure returned describing the mount
@@ -108,7 +149,7 @@ void gfs2_unregister_lockproto(struct lm_lockops *proto)
  */
 
 int gfs2_mount_lockproto(char *proto_name, char *table_name, char *host_data,
-                        lm_callback_t cb, lm_fsdata_t *fsdata,
+                        lm_callback_t cb, void *cb_data,
                         unsigned int min_lvb_size, int flags,
                         struct lm_lockstruct *lockstruct,
                         struct kobject *fskobj)
@@ -117,9 +158,13 @@ int gfs2_mount_lockproto(char *proto_name, char *table_name, char *host_data,
        int try = 0;
        int error, found;
 
+
 retry:
        mutex_lock(&lmh_lock);
 
+       if (list_empty(&nolock_proto.lw_list))
+               list_add(&nolock_proto.lw_list, &lmh_list);
+
        found = 0;
        list_for_each_entry(lw, &lmh_list, lw_list) {
                if (!strcmp(lw->lw_ops->lm_proto_name, proto_name)) {
@@ -140,14 +185,15 @@ retry:
                goto out;
        }
 
-       if (!try_module_get(lw->lw_ops->lm_owner)) {
+       if (lw->lw_ops->lm_owner &&
+           !try_module_get(lw->lw_ops->lm_owner)) {
                try = 0;
                mutex_unlock(&lmh_lock);
                msleep(1000);
                goto retry;
        }
 
-       error = lw->lw_ops->lm_mount(table_name, host_data, cb, fsdata,
+       error = lw->lw_ops->lm_mount(table_name, host_data, cb, cb_data,
                                     min_lvb_size, flags, lockstruct, fskobj);
        if (error)
                module_put(lw->lw_ops->lm_owner);
@@ -159,7 +205,8 @@ out:
 void gfs2_unmount_lockproto(struct lm_lockstruct *lockstruct)
 {
        mutex_lock(&lmh_lock);
-       lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace);
+       if (lockstruct->ls_ops->lm_unmount)
+               lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace);
        if (lockstruct->ls_ops->lm_owner)
                module_put(lockstruct->ls_ops->lm_owner);
        mutex_unlock(&lmh_lock);