[PATCH] knfsd: hide use of lockd's h_monitored flag
[pandora-kernel.git] / fs / lockd / clntproc.c
index 5980c45..5436be6 100644 (file)
@@ -100,7 +100,7 @@ static struct nlm_lockowner *nlm_find_lockowner(struct nlm_host *host, fl_owner_
        res = __nlm_find_lockowner(host, owner);
        if (res == NULL) {
                spin_unlock(&host->h_lock);
-               new = (struct nlm_lockowner *)kmalloc(sizeof(*new), GFP_KERNEL);
+               new = kmalloc(sizeof(*new), GFP_KERNEL);
                spin_lock(&host->h_lock);
                res = __nlm_find_lockowner(host, owner);
                if (res == NULL && new != NULL) {
@@ -129,11 +129,11 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
        nlmclnt_next_cookie(&argp->cookie);
        argp->state   = nsm_local_state;
        memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
-       lock->caller  = system_utsname.nodename;
+       lock->caller  = utsname()->nodename;
        lock->oh.data = req->a_owner;
        lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
                                (unsigned int)fl->fl_u.nfs_fl.owner->pid,
-                               system_utsname.nodename);
+                               utsname()->nodename);
        lock->svid = fl->fl_u.nfs_fl.owner->pid;
        lock->fl.fl_start = fl->fl_start;
        lock->fl.fl_end = fl->fl_end;
@@ -151,11 +151,13 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req)
 int
 nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
 {
+       struct rpc_clnt         *client = NFS_CLIENT(inode);
+       struct sockaddr_in      addr;
        struct nlm_host         *host;
        struct nlm_rqst         *call;
        sigset_t                oldset;
        unsigned long           flags;
-       int                     status, proto, vers;
+       int                     status, vers;
 
        vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1;
        if (NFS_PROTO(inode)->version > 3) {
@@ -163,10 +165,8 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
                return -ENOLCK;
        }
 
-       /* Retrieve transport protocol from NFS client */
-       proto = NFS_CLIENT(inode)->cl_xprt->prot;
-
-       host = nlmclnt_lookup_host(NFS_ADDR(inode), proto, vers);
+       rpc_peeraddr(client, (struct sockaddr *) &addr, sizeof(addr));
+       host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers);
        if (host == NULL)
                return -ENOLCK;
 
@@ -454,7 +454,7 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho
        fl->fl_ops = &nlmclnt_lock_ops;
 }
 
-static void do_vfs_lock(struct file_lock *fl)
+static int do_vfs_lock(struct file_lock *fl)
 {
        int res = 0;
        switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
@@ -467,9 +467,7 @@ static void do_vfs_lock(struct file_lock *fl)
                default:
                        BUG();
        }
-       if (res < 0)
-               printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
-                               __FUNCTION__);
+       return res;
 }
 
 /*
@@ -498,13 +496,18 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
        struct nlm_host *host = req->a_host;
        struct nlm_res  *resp = &req->a_res;
        struct nlm_wait *block = NULL;
+       unsigned char fl_flags = fl->fl_flags;
        int status = -ENOLCK;
 
-       if (!host->h_monitored && nsm_monitor(host) < 0) {
+       if (nsm_monitor(host) < 0) {
                printk(KERN_NOTICE "lockd: failed to monitor %s\n",
                                        host->h_name);
                goto out;
        }
+       fl->fl_flags |= FL_ACCESS;
+       status = do_vfs_lock(fl);
+       if (status < 0)
+               goto out;
 
        block = nlmclnt_prepare_block(host, fl);
 again:
@@ -539,9 +542,10 @@ again:
                        up_read(&host->h_rwsem);
                        goto again;
                }
-               fl->fl_flags |= FL_SLEEP;
                /* Ensure the resulting lock will get added to granted list */
-               do_vfs_lock(fl);
+               fl->fl_flags = fl_flags | FL_SLEEP;
+               if (do_vfs_lock(fl) < 0)
+                       printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
                up_read(&host->h_rwsem);
        }
        status = nlm_stat_to_errno(resp->status);
@@ -552,6 +556,7 @@ out_unblock:
                nlmclnt_cancel(host, req->a_args.block, fl);
 out:
        nlm_release_call(req);
+       fl->fl_flags = fl_flags;
        return status;
 }
 
@@ -606,15 +611,19 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
 {
        struct nlm_host *host = req->a_host;
        struct nlm_res  *resp = &req->a_res;
-       int             status;
+       int status = 0;
 
        /*
         * Note: the server is supposed to either grant us the unlock
         * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either
         * case, we want to unlock.
         */
+       fl->fl_flags |= FL_EXISTS;
        down_read(&host->h_rwsem);
-       do_vfs_lock(fl);
+       if (do_vfs_lock(fl) == -ENOENT) {
+               up_read(&host->h_rwsem);
+               goto out;
+       }
        up_read(&host->h_rwsem);
 
        if (req->a_flags & RPC_TASK_ASYNC)
@@ -624,7 +633,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
        if (status < 0)
                goto out;
 
-       status = 0;
        if (resp->status == NLM_LCK_GRANTED)
                goto out;