[GFS2] Reorganize function gfs2_glmutex_lock
[pandora-kernel.git] / fs / nfsd / nfs4state.c
index 3f55970..31673cd 100644 (file)
@@ -358,9 +358,22 @@ alloc_client(struct xdr_netobj name)
        return clp;
 }
 
+static void
+shutdown_callback_client(struct nfs4_client *clp)
+{
+       struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+
+       /* shutdown rpc client, ending any outstanding recall rpcs */
+       if (clnt) {
+               clp->cl_callback.cb_client = NULL;
+               rpc_shutdown_client(clnt);
+       }
+}
+
 static inline void
 free_client(struct nfs4_client *clp)
 {
+       shutdown_callback_client(clp);
        if (clp->cl_cred.cr_group_info)
                put_group_info(clp->cl_cred.cr_group_info);
        kfree(clp->cl_name.data);
@@ -374,18 +387,6 @@ put_nfs4_client(struct nfs4_client *clp)
                free_client(clp);
 }
 
-static void
-shutdown_callback_client(struct nfs4_client *clp)
-{
-       struct rpc_clnt *clnt = clp->cl_callback.cb_client;
-
-       /* shutdown rpc client, ending any outstanding recall rpcs */
-       if (clnt) {
-               clp->cl_callback.cb_client = NULL;
-               rpc_shutdown_client(clnt);
-       }
-}
-
 static void
 expire_client(struct nfs4_client *clp)
 {
@@ -396,8 +397,6 @@ expire_client(struct nfs4_client *clp)
        dprintk("NFSD: expire_client cl_count %d\n",
                            atomic_read(&clp->cl_count));
 
-       shutdown_callback_client(clp);
-
        INIT_LIST_HEAD(&reaplist);
        spin_lock(&recall_lock);
        while (!list_empty(&clp->cl_delegations)) {
@@ -462,26 +461,28 @@ copy_cred(struct svc_cred *target, struct svc_cred *source) {
 }
 
 static inline int
-same_name(const char *n1, const char *n2) {
+same_name(const char *n1, const char *n2)
+{
        return 0 == memcmp(n1, n2, HEXDIR_LEN);
 }
 
 static int
-cmp_verf(nfs4_verifier *v1, nfs4_verifier *v2) {
-       return(!memcmp(v1->data,v2->data,sizeof(v1->data)));
+same_verf(nfs4_verifier *v1, nfs4_verifier *v2)
+{
+       return 0 == memcmp(v1->data, v2->data, sizeof(v1->data));
 }
 
 static int
-cmp_clid(clientid_t * cl1, clientid_t * cl2) {
-       return((cl1->cl_boot == cl2->cl_boot) &&
-               (cl1->cl_id == cl2->cl_id));
+same_clid(clientid_t *cl1, clientid_t *cl2)
+{
+       return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id);
 }
 
 /* XXX what about NGROUP */
 static int
-cmp_creds(struct svc_cred *cr1, struct svc_cred *cr2){
-       return(cr1->cr_uid == cr2->cr_uid);
-
+same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
+{
+       return cr1->cr_uid == cr2->cr_uid;
 }
 
 static void
@@ -507,7 +508,7 @@ check_name(struct xdr_netobj name) {
        if (name.len == 0) 
                return 0;
        if (name.len > NFS4_OPAQUE_LIMIT) {
-               printk("NFSD: check_name: name too long(%d)!\n", name.len);
+               dprintk("NFSD: check_name: name too long(%d)!\n", name.len);
                return 0;
        }
        return 1;
@@ -546,7 +547,7 @@ find_confirmed_client(clientid_t *clid)
        unsigned int idhashval = clientid_hashval(clid->cl_id);
 
        list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
-               if (cmp_clid(&clp->cl_clientid, clid))
+               if (same_clid(&clp->cl_clientid, clid))
                        return clp;
        }
        return NULL;
@@ -559,7 +560,7 @@ find_unconfirmed_client(clientid_t *clid)
        unsigned int idhashval = clientid_hashval(clid->cl_id);
 
        list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
-               if (cmp_clid(&clp->cl_clientid, clid))
+               if (same_clid(&clp->cl_clientid, clid))
                        return clp;
        }
        return NULL;
@@ -753,7 +754,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                 * or different ip_address
                 */
                status = nfserr_clid_inuse;
-               if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred)
+               if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)
                                || conf->cl_addr != sin->sin_addr.s_addr) {
                        dprintk("NFSD: setclientid: string in use by client"
                                "at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr));
@@ -772,14 +773,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                new = create_client(clname, dname);
                if (new == NULL)
                        goto out;
-               copy_verf(new, &clverifier);
-               new->cl_addr = sin->sin_addr.s_addr;
-               copy_cred(&new->cl_cred,&rqstp->rq_cred);
                gen_clid(new);
-               gen_confirm(new);
-               gen_callback(new, setclid);
-               add_to_unconfirmed(new, strhashval);
-       } else if (cmp_verf(&conf->cl_verifier, &clverifier)) {
+       } else if (same_verf(&conf->cl_verifier, &clverifier)) {
                /*
                 * CASE 1:
                 * cl_name match, confirmed, principal match
@@ -804,13 +799,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                new = create_client(clname, dname);
                if (new == NULL)
                        goto out;
-               copy_verf(new,&conf->cl_verifier);
-               new->cl_addr = sin->sin_addr.s_addr;
-               copy_cred(&new->cl_cred,&rqstp->rq_cred);
                copy_clid(new, conf);
-               gen_confirm(new);
-               gen_callback(new, setclid);
-               add_to_unconfirmed(new,strhashval);
        } else if (!unconf) {
                /*
                 * CASE 2:
@@ -823,14 +812,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                new = create_client(clname, dname);
                if (new == NULL)
                        goto out;
-               copy_verf(new,&clverifier);
-               new->cl_addr = sin->sin_addr.s_addr;
-               copy_cred(&new->cl_cred,&rqstp->rq_cred);
                gen_clid(new);
-               gen_confirm(new);
-               gen_callback(new, setclid);
-               add_to_unconfirmed(new, strhashval);
-       } else if (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
+       } else if (!same_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
                /*      
                 * CASE3:
                 * confirmed found (name, principal match)
@@ -850,19 +833,19 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                new = create_client(clname, dname);
                if (new == NULL)
                        goto out;
-               copy_verf(new,&clverifier);
-               new->cl_addr = sin->sin_addr.s_addr;
-               copy_cred(&new->cl_cred,&rqstp->rq_cred);
                gen_clid(new);
-               gen_confirm(new);
-               gen_callback(new, setclid);
-               add_to_unconfirmed(new, strhashval);
        } else {
                /* No cases hit !!! */
                status = nfserr_inval;
                goto out;
 
        }
+       copy_verf(new, &clverifier);
+       new->cl_addr = sin->sin_addr.s_addr;
+       copy_cred(&new->cl_cred, &rqstp->rq_cred);
+       gen_confirm(new);
+       gen_callback(new, setclid);
+       add_to_unconfirmed(new, strhashval);
        setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
        setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
        memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
@@ -910,16 +893,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                goto out;
 
        if ((conf && unconf) && 
-           (cmp_verf(&unconf->cl_confirm, &confirm)) &&
-           (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
+           (same_verf(&unconf->cl_confirm, &confirm)) &&
+           (same_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
            (same_name(conf->cl_recdir,unconf->cl_recdir))  &&
-           (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
+           (!same_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
                /* CASE 1:
                * unconf record that matches input clientid and input confirm.
                * conf record that matches input clientid.
                * conf and unconf records match names, verifiers
                */
-               if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred)) 
+               if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
                        status = nfserr_clid_inuse;
                else {
                        /* XXX: We just turn off callbacks until we can handle
@@ -933,7 +916,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                }
        } else if ((conf && !unconf) ||
            ((conf && unconf) && 
-            (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
+            (!same_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
              !same_name(conf->cl_recdir, unconf->cl_recdir)))) {
                /* CASE 2:
                 * conf record that matches input clientid.
@@ -941,18 +924,18 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                 * unconf->cl_name or unconf->cl_verifier don't match the
                 * conf record.
                 */
-               if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred))
+               if (!same_creds(&conf->cl_cred, &rqstp->rq_cred))
                        status = nfserr_clid_inuse;
                else
                        status = nfs_ok;
        } else if (!conf && unconf
-                       && cmp_verf(&unconf->cl_confirm, &confirm)) {
+                       && same_verf(&unconf->cl_confirm, &confirm)) {
                /* CASE 3:
                 * conf record not found.
                 * unconf record found.
                 * unconf->cl_confirm matches input confirm
                 */
-               if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
+               if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
                        status = nfserr_clid_inuse;
                } else {
                        unsigned int hash =
@@ -967,8 +950,8 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                        conf = unconf;
                        status = nfs_ok;
                }
-       } else if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm)))
-           && (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm,
+       } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm)))
+           && (!unconf || (unconf && !same_verf(&unconf->cl_confirm,
                                                                &confirm)))) {
                /* CASE 4:
                 * conf record not found, or if conf, conf->cl_confirm does not
@@ -1019,7 +1002,7 @@ nfsd4_free_slab(struct kmem_cache **slab)
        *slab = NULL;
 }
 
-static void
+void
 nfsd4_free_slabs(void)
 {
        nfsd4_free_slab(&stateowner_slab);
@@ -1207,10 +1190,12 @@ move_to_close_lru(struct nfs4_stateowner *sop)
 }
 
 static int
-cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
-       return ((sop->so_owner.len == owner->len) && 
-        !memcmp(sop->so_owner.data, owner->data, owner->len) && 
-         (sop->so_client->cl_clientid.cl_id == clid->cl_id));
+same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner,
+                                                       clientid_t *clid)
+{
+       return (sop->so_owner.len == owner->len) &&
+               0 == memcmp(sop->so_owner.data, owner->data, owner->len) &&
+               (sop->so_client->cl_clientid.cl_id == clid->cl_id);
 }
 
 static struct nfs4_stateowner *
@@ -1219,7 +1204,7 @@ find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open)
        struct nfs4_stateowner *so = NULL;
 
        list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) {
-               if (cmp_owner_str(so, &open->op_owner, &open->op_clientid))
+               if (same_owner_str(so, &open->op_owner, &open->op_clientid))
                        return so;
        }
        return NULL;
@@ -1360,6 +1345,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
         * lock) we know the server hasn't removed the lease yet, we know
         * it's safe to take a reference: */
        atomic_inc(&dp->dl_count);
+       atomic_inc(&dp->dl_client->cl_count);
 
        spin_lock(&recall_lock);
        list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
@@ -1368,8 +1354,12 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
        /* only place dl_time is set. protected by lock_kernel*/
        dp->dl_time = get_seconds();
 
-       /* XXX need to merge NFSD_LEASE_TIME with fs/locks.c:lease_break_time */
-       fl->fl_break_time = jiffies + NFSD_LEASE_TIME * HZ;
+       /*
+        * We don't want the locks code to timeout the lease for us;
+        * we'll remove it ourself if the delegation isn't returned
+        * in time.
+        */
+       fl->fl_break_time = 0;
 
        t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall");
        if (IS_ERR(t)) {
@@ -1378,6 +1368,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
                printk(KERN_INFO "NFSD: Callback thread failed for "
                        "for client (clientid %08x/%08x)\n",
                        clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
+               put_nfs4_client(dp->dl_client);
                nfs4_put_delegation(dp);
        }
 }
@@ -1738,7 +1729,7 @@ out:
        if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
                        && flag == NFS4_OPEN_DELEGATE_NONE
                        && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
-               printk("NFSD: WARNING: refusing delegation reclaim\n");
+               dprintk("NFSD: WARNING: refusing delegation reclaim\n");
        open->op_delegate_type = flag;
 }
 
@@ -2044,7 +2035,7 @@ static inline int
 io_during_grace_disallowed(struct inode *inode, int flags)
 {
        return nfs4_in_grace() && (flags & (RD_STATE | WR_STATE))
-               && MANDATORY_LOCK(inode);
+               && mandatory_lock(inode);
 }
 
 /*
@@ -2147,7 +2138,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
        *sopp = NULL;
 
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
-               printk("NFSD: preprocess_seqid_op: magic stateid!\n");
+               dprintk("NFSD: preprocess_seqid_op: magic stateid!\n");
                return nfserr_bad_stateid;
        }
 
@@ -2181,25 +2172,24 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
                lkflg = setlkflg(lock->lk_type);
 
                if (lock->lk_is_new) {
-                       if (!sop->so_is_open_owner)
-                              return nfserr_bad_stateid;
-                       if (!cmp_clid(&clp->cl_clientid, lockclid))
+                       if (!sop->so_is_open_owner)
+                               return nfserr_bad_stateid;
+                       if (!same_clid(&clp->cl_clientid, lockclid))
                               return nfserr_bad_stateid;
-                       /* stp is the open stateid */
-                       status = nfs4_check_openmode(stp, lkflg);
-                       if (status)
-                              return status;
-               } else {
-                       /* stp is the lock stateid */
-                       status = nfs4_check_openmode(stp->st_openstp, lkflg);
-                       if (status)
-                              return status;
+                       /* stp is the open stateid */
+                       status = nfs4_check_openmode(stp, lkflg);
+                       if (status)
+                               return status;
+               } else {
+                       /* stp is the lock stateid */
+                       status = nfs4_check_openmode(stp->st_openstp, lkflg);
+                       if (status)
+                               return status;
                }
-
        }
 
        if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
-               printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
+               dprintk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
                return nfserr_bad_stateid;
        }
 
@@ -2215,22 +2205,22 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
                goto check_replay;
 
        if (sop->so_confirmed && flags & CONFIRM) {
-               printk("NFSD: preprocess_seqid_op: expected"
+               dprintk("NFSD: preprocess_seqid_op: expected"
                                " unconfirmed stateowner!\n");
                return nfserr_bad_stateid;
        }
        if (!sop->so_confirmed && !(flags & CONFIRM)) {
-               printk("NFSD: preprocess_seqid_op: stateowner not"
+               dprintk("NFSD: preprocess_seqid_op: stateowner not"
                                " confirmed yet!\n");
                return nfserr_bad_stateid;
        }
        if (stateid->si_generation > stp->st_stateid.si_generation) {
-               printk("NFSD: preprocess_seqid_op: future stateid?!\n");
+               dprintk("NFSD: preprocess_seqid_op: future stateid?!\n");
                return nfserr_bad_stateid;
        }
 
        if (stateid->si_generation < stp->st_stateid.si_generation) {
-               printk("NFSD: preprocess_seqid_op: old stateid!\n");
+               dprintk("NFSD: preprocess_seqid_op: old stateid!\n");
                return nfserr_old_stateid;
        }
        renew_client(sop->so_client);
@@ -2242,7 +2232,7 @@ check_replay:
                /* indicate replay to calling function */
                return nfserr_replay_me;
        }
-       printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
+       dprintk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
                        sop->so_seqid, seqid);
        *sopp = NULL;
        return nfserr_bad_seqid;
@@ -2561,7 +2551,7 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid,
        struct nfs4_stateowner *op;
 
        list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) {
-               if (cmp_owner_str(op, owner, clid))
+               if (same_owner_str(op, owner, clid))
                        return op;
        }
        return NULL;
@@ -2855,7 +2845,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        file_lock.fl_type = F_WRLCK;
                break;
                default:
-                       printk("NFSD: nfs4_lockt: bad lock type!\n");
+                       dprintk("NFSD: nfs4_lockt: bad lock type!\n");
                        status = nfserr_inval;
                goto out;
        }
@@ -3025,7 +3015,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
        INIT_LIST_HEAD(&matches);
        for (i = 0; i < LOCK_HASH_SIZE; i++) {
                list_for_each_entry(sop, &lock_ownerid_hashtbl[i], so_idhash) {
-                       if (!cmp_owner_str(sop, owner, clid))
+                       if (!same_owner_str(sop, owner, clid))
                                continue;
                        list_for_each_entry(stp, &sop->so_stateids,
                                        st_perstateowner) {
@@ -3149,11 +3139,14 @@ nfs4_check_open_reclaim(clientid_t *clid)
 
 /* initialization to perform at module load time: */
 
-void
+int
 nfs4_state_init(void)
 {
-       int i;
+       int i, status;
 
+       status = nfsd4_init_slabs();
+       if (status)
+               return status;
        for (i = 0; i < CLIENT_HASH_SIZE; i++) {
                INIT_LIST_HEAD(&conf_id_hashtbl[i]);
                INIT_LIST_HEAD(&conf_str_hashtbl[i]);
@@ -3182,6 +3175,7 @@ nfs4_state_init(void)
        for (i = 0; i < CLIENT_HASH_SIZE; i++)
                INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
        reclaim_str_hashtbl_size = 0;
+       return 0;
 }
 
 static void
@@ -3242,20 +3236,15 @@ __nfs4_state_start(void)
        set_max_delegations();
 }
 
-int
+void
 nfs4_state_start(void)
 {
-       int status;
-
        if (nfs4_init)
-               return 0;
-       status = nfsd4_init_slabs();
-       if (status)
-               return status;
+               return;
        nfsd4_load_reboot_recovery_data();
        __nfs4_state_start();
        nfs4_init = 1;
-       return 0;
+       return;
 }
 
 int
@@ -3313,7 +3302,6 @@ nfs4_state_shutdown(void)
        nfs4_lock_state();
        nfs4_release_reclaim();
        __nfs4_state_shutdown();
-       nfsd4_free_slabs();
        nfs4_unlock_state();
 }