]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
lockd: stop abusing file_lock_list
authorChristoph Hellwig <hch@lst.de>
Mon, 20 Mar 2006 18:44:40 +0000 (13:44 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 20 Mar 2006 18:44:40 +0000 (13:44 -0500)
Currently lockd directly access the file_lock_list from fs/locks.c.
It does so to mark locks granted or reclaimable.  This is very
suboptimal, because a) lockd needs to poke into locks.c internals, and
b) it needs to iterate over all locks in the system for marking locks
granted or reclaimable.

This patch adds lists for granted and reclaimable locks to the nlm_host
structure instead, and adds locks to those.

nlmclnt_lock:
now adds the lock to h_granted instead of setting the
NFS_LCK_GRANTED, still O(1)

nlmclnt_mark_reclaim:
goes away completely, replaced by a list_splice_init.
Complexity reduced from O(locks in the system) to O(1)

reclaimer:
iterates over h_reclaim now, complexity reduced from
O(locks in the system) to O(locks per nlm_host)

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/host.c
fs/locks.c
include/linux/fs.h
include/linux/lockd/lockd.h
include/linux/nfs_fs_i.h

index 8ae79ae4b9987c819e3cc723f534695b406928b2..0fc0ee267b04f093132709f816980851295bb908 100644 (file)
@@ -154,34 +154,6 @@ u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock)
  * server crash.
  */
 
-/*
- * Mark the locks for reclaiming.
- * FIXME: In 2.5 we don't want to iterate through any global file_lock_list.
- *        Maintain NLM lock reclaiming lists in the nlm_host instead.
- */
-static
-void nlmclnt_mark_reclaim(struct nlm_host *host)
-{
-       struct file_lock *fl;
-       struct inode *inode;
-       struct list_head *tmp;
-
-       list_for_each(tmp, &file_lock_list) {
-               fl = list_entry(tmp, struct file_lock, fl_link);
-
-               inode = fl->fl_file->f_dentry->d_inode;
-               if (inode->i_sb->s_magic != NFS_SUPER_MAGIC)
-                       continue;
-               if (fl->fl_u.nfs_fl.owner == NULL)
-                       continue;
-               if (fl->fl_u.nfs_fl.owner->host != host)
-                       continue;
-               if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED))
-                       continue;
-               fl->fl_u.nfs_fl.flags |= NFS_LCK_RECLAIM;
-       }
-}
-
 /*
  * Someone has sent us an SM_NOTIFY. Ensure we bind to the new port number,
  * that we mark locks for reclaiming, and that we bump the pseudo NSM state.
@@ -194,7 +166,12 @@ void nlmclnt_prepare_reclaim(struct nlm_host *host, u32 newstate)
        host->h_state++;
        host->h_nextrebind = 0;
        nlm_rebind_host(host);
-       nlmclnt_mark_reclaim(host);
+
+       /*
+        * Mark the locks for reclaiming.
+        */
+       list_splice_init(&host->h_granted, &host->h_reclaim);
+
        dprintk("NLM: reclaiming locks for host %s", host->h_name);
 }
 
@@ -223,9 +200,7 @@ reclaimer(void *ptr)
 {
        struct nlm_host   *host = (struct nlm_host *) ptr;
        struct nlm_wait   *block;
-       struct list_head *tmp;
-       struct file_lock *fl;
-       struct inode *inode;
+       struct file_lock *fl, *next;
 
        daemonize("%s-reclaim", host->h_name);
        allow_signal(SIGKILL);
@@ -237,20 +212,9 @@ reclaimer(void *ptr)
 
        /* First, reclaim all locks that have been marked. */
 restart:
-       list_for_each(tmp, &file_lock_list) {
-               fl = list_entry(tmp, struct file_lock, fl_link);
-
-               inode = fl->fl_file->f_dentry->d_inode;
-               if (inode->i_sb->s_magic != NFS_SUPER_MAGIC)
-                       continue;
-               if (fl->fl_u.nfs_fl.owner == NULL)
-                       continue;
-               if (fl->fl_u.nfs_fl.owner->host != host)
-                       continue;
-               if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_RECLAIM))
-                       continue;
+       list_for_each_entry_safe(fl, next, &host->h_reclaim, fl_u.nfs_fl.list) {
+               list_del(&fl->fl_u.nfs_fl.list);
 
-               fl->fl_u.nfs_fl.flags &= ~NFS_LCK_RECLAIM;
                nlmclnt_reclaim(host, fl);
                if (signalled())
                        break;
index 80ae3127699f32c9c3ac92bd7682dd75843f9060..cb469431bd1d739c71c2b274da7e4e225b53b413 100644 (file)
@@ -465,7 +465,6 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho
 {
        BUG_ON(fl->fl_ops != NULL);
        fl->fl_u.nfs_fl.state = 0;
-       fl->fl_u.nfs_fl.flags = 0;
        fl->fl_u.nfs_fl.owner = nlm_find_lockowner(host, fl->fl_owner);
        fl->fl_ops = &nlmclnt_lock_ops;
 }
@@ -552,8 +551,8 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
 
        if (resp->status == NLM_LCK_GRANTED) {
                fl->fl_u.nfs_fl.state = host->h_state;
-               fl->fl_u.nfs_fl.flags |= NFS_LCK_GRANTED;
                fl->fl_flags |= FL_SLEEP;
+               list_add_tail(&fl->fl_u.nfs_fl.list, &host->h_granted);
                do_vfs_lock(fl);
        }
        status = nlm_stat_to_errno(resp->status);
@@ -619,9 +618,11 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
        struct nlm_res  *resp = &req->a_res;
        int             status;
 
-       /* Clean the GRANTED flag now so the lock doesn't get
-        * reclaimed while we're stuck in the unlock call. */
-       fl->fl_u.nfs_fl.flags &= ~NFS_LCK_GRANTED;
+       /*
+        * Remove from the granted list now so the lock doesn't get
+        * reclaimed while we're stuck in the unlock call.
+        */
+       list_del(&fl->fl_u.nfs_fl.list);
 
        /*
         * Note: the server is supposed to either grant us the unlock
index 100e78229700a03be65a7ffd6c737f598126b35b..f456f8ed9acdf95c88f4bca6684b25914bb1b1d3 100644 (file)
@@ -123,6 +123,8 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
        nlm_hosts[hash]    = host;
        INIT_LIST_HEAD(&host->h_lockowners);
        spin_lock_init(&host->h_lock);
+       INIT_LIST_HEAD(&host->h_granted);
+       INIT_LIST_HEAD(&host->h_reclaim);
 
        if (++nrhosts > NLM_HOST_MAX)
                next_gc = 0;
index c83b5dbe0ed9f573a1cbc8d34aadf00e921d24c1..56f996e98bbcd03459480ce9ea505e2663b46129 100644 (file)
@@ -139,10 +139,7 @@ int lease_break_time = 45;
 #define for_each_lock(inode, lockp) \
        for (lockp = &inode->i_flock; *lockp != NULL; lockp = &(*lockp)->fl_next)
 
-LIST_HEAD(file_lock_list);
-
-EXPORT_SYMBOL(file_lock_list);
-
+static LIST_HEAD(file_lock_list);
 static LIST_HEAD(blocked_list);
 
 static kmem_cache_t *filelock_cache;
index d2cffee8fc1183620a31761a1098dfb85b4f0ed5..5dc0fa288a4cee43ed09176b9c9124dfa4860ffe 100644 (file)
@@ -730,8 +730,6 @@ struct file_lock {
 #define OFFT_OFFSET_MAX        INT_LIMIT(off_t)
 #endif
 
-extern struct list_head file_lock_list;
-
 #include <linux/fcntl.h>
 
 extern int fcntl_getlk(struct file *, struct flock __user *);
index 860a93f6ce6d99f39bd70d8ebaf756928ef43d22..b0f63b6ab0d48202f2d1fb055d6fee13c74d739f 100644 (file)
@@ -59,6 +59,8 @@ struct nlm_host {
        unsigned long           h_expires;      /* eligible for GC */
        struct list_head        h_lockowners;   /* Lockowners for the client */
        spinlock_t              h_lock;
+       struct list_head        h_granted;      /* Locks in GRANTED state */
+       struct list_head        h_reclaim;      /* Locks in RECLAIM state */
 };
 
 /*
index e2c18dabff8624ba8c526ddaa1cc50a5530db0de..861730275ba0545feb6857c42f9d161d7f38d47c 100644 (file)
@@ -12,8 +12,8 @@ struct nlm_lockowner;
  */
 struct nfs_lock_info {
        u32             state;
-       u32             flags;
        struct nlm_lockowner *owner;
+       struct list_head list;
 };
 
 struct nfs4_lock_state;
@@ -21,10 +21,4 @@ struct nfs4_lock_info {
        struct nfs4_lock_state *owner;
 };
 
-/*
- * Lock flag values
- */
-#define NFS_LCK_GRANTED                0x0001          /* lock has been granted */
-#define NFS_LCK_RECLAIM                0x0002          /* lock marked for reclaiming */
-
 #endif