]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/nfsd/nfs4state.c
Merge branch 'akpm-incoming-2'
[net-next-2.6.git] / fs / nfsd / nfs4state.c
index ce0412fd23ebac03609024b35eed6622fa0b42e6..56347e0ac88da33f1fd655809a90c1509f0cb389 100644 (file)
@@ -33,7 +33,7 @@
 */
 
 #include <linux/file.h>
-#include <linux/smp_lock.h>
+#include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/swap.h>
@@ -1628,33 +1628,25 @@ out:
        return status;
 }
 
-static struct nfsd4_conn *__nfsd4_find_conn(struct svc_rqst *r, struct nfsd4_session *s)
+static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_session *s)
 {
        struct nfsd4_conn *c;
 
        list_for_each_entry(c, &s->se_conns, cn_persession) {
-               if (c->cn_xprt == r->rq_xprt) {
+               if (c->cn_xprt == xpt) {
                        return c;
                }
        }
        return NULL;
 }
 
-static void nfsd4_sequence_check_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
+static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
 {
        struct nfs4_client *clp = ses->se_client;
-       struct nfsd4_conn *c, *new = NULL;
-
-       spin_lock(&clp->cl_lock);
-       c = __nfsd4_find_conn(rqstp, ses);
-       spin_unlock(&clp->cl_lock);
-       if (c)
-               return;
-
-       new = alloc_conn(rqstp, NFS4_CDFC4_FORE);
+       struct nfsd4_conn *c;
 
        spin_lock(&clp->cl_lock);
-       c = __nfsd4_find_conn(rqstp, ses);
+       c = __nfsd4_find_conn(new->cn_xprt, ses);
        if (c) {
                spin_unlock(&clp->cl_lock);
                free_conn(new);
@@ -1674,11 +1666,20 @@ nfsd4_sequence(struct svc_rqst *rqstp,
        struct nfsd4_compoundres *resp = rqstp->rq_resp;
        struct nfsd4_session *session;
        struct nfsd4_slot *slot;
+       struct nfsd4_conn *conn;
        int status;
 
        if (resp->opcnt != 1)
                return nfserr_sequence_pos;
 
+       /*
+        * Will be either used or freed by nfsd4_sequence_check_conn
+        * below.
+        */
+       conn = alloc_conn(rqstp, NFS4_CDFC4_FORE);
+       if (!conn)
+               return nfserr_jukebox;
+
        spin_lock(&client_lock);
        status = nfserr_badsession;
        session = find_in_sessionid_hashtbl(&seq->sessionid);
@@ -1710,7 +1711,8 @@ nfsd4_sequence(struct svc_rqst *rqstp,
        if (status)
                goto out;
 
-       nfsd4_sequence_check_conn(rqstp, session);
+       nfsd4_sequence_check_conn(conn, session);
+       conn = NULL;
 
        /* Success! bump slot seqid */
        slot->sl_inuse = true;
@@ -1726,6 +1728,7 @@ out:
                nfsd4_get_session(cstate->session);
                atomic_inc(&session->se_client->cl_refcount);
        }
+       kfree(conn);
        spin_unlock(&client_lock);
        dprintk("%s: return %d\n", __func__, ntohl(status));
        return status;
@@ -2611,7 +2614,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
        struct nfs4_delegation *dp;
        struct nfs4_stateowner *sop = stp->st_stateowner;
        int cb_up = atomic_read(&sop->so_client->cl_cb_set);
-       struct file_lock fl, *flp = &fl;
+       struct file_lock *fl;
        int status, flag = 0;
 
        flag = NFS4_OPEN_DELEGATE_NONE;
@@ -2645,20 +2648,24 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
                flag = NFS4_OPEN_DELEGATE_NONE;
                goto out;
        }
-       locks_init_lock(&fl);
-       fl.fl_lmops = &nfsd_lease_mng_ops;
-       fl.fl_flags = FL_LEASE;
-       fl.fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
-       fl.fl_end = OFFSET_MAX;
-       fl.fl_owner =  (fl_owner_t)dp;
-       fl.fl_file = find_readable_file(stp->st_file);
-       BUG_ON(!fl.fl_file);
-       fl.fl_pid = current->tgid;
+       status = -ENOMEM;
+       fl = locks_alloc_lock();
+       if (!fl)
+               goto out;
+       locks_init_lock(fl);
+       fl->fl_lmops = &nfsd_lease_mng_ops;
+       fl->fl_flags = FL_LEASE;
+       fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
+       fl->fl_end = OFFSET_MAX;
+       fl->fl_owner =  (fl_owner_t)dp;
+       fl->fl_file = find_readable_file(stp->st_file);
+       BUG_ON(!fl->fl_file);
+       fl->fl_pid = current->tgid;
 
        /* vfs_setlease checks to see if delegation should be handed out.
         * the lock_manager callbacks fl_mylease and fl_change are used
         */
-       if ((status = vfs_setlease(fl.fl_file, fl.fl_type, &flp))) {
+       if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
                dprintk("NFSD: setlease failed [%d], no delegation\n", status);
                unhash_delegation(dp);
                flag = NFS4_OPEN_DELEGATE_NONE;
@@ -4021,7 +4028,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner)
        struct inode *inode = filp->fi_inode;
        int status = 0;
 
-       lock_kernel();
+       lock_flocks();
        for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
                if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
                        status = 1;
@@ -4029,7 +4036,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner)
                }
        }
 out:
-       unlock_kernel();
+       unlock_flocks();
        return status;
 }