]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nfsd/nfs4state.c
[PATCH] ARM SMP: TLB implementations only affect local CPU
[linux-2.6-omap-h63xx.git] / fs / nfsd / nfs4state.c
index 6b9d23c39afe0107de9c5641c89eba1b868afd16..89e36526d7f289f32873fe856bd9421d89288311 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/nfs4.h>
 #include <linux/nfsd/state.h>
 #include <linux/nfsd/xdr4.h>
+#include <linux/namei.h>
 
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
@@ -71,7 +72,8 @@ static stateid_t onestateid;              /* bits all 1 */
 static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
 static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
 static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
-extern char recovery_dirname[];
+static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
+static void nfs4_set_recdir(char *recdir);
 
 /* Locking:
  *
@@ -905,6 +907,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
                        conf = find_confirmed_client_by_str(unconf->cl_recdir,
                                                                        hash);
                        if (conf) {
+                               nfsd4_remove_clid_dir(conf);
                                expire_client(conf);
                        }
                        move_to_confirmed(unconf);
@@ -1691,6 +1694,7 @@ nfs4_set_claim_prev(struct nfsd4_open *open, int *status)
                        *status = nfserr_reclaim_bad;
                else {
                        open->op_stateowner->so_confirmed = 1;
+                       open->op_stateowner->so_client->cl_firststate = 1;
                        open->op_stateowner->so_seqid--;
                }
        }
@@ -1903,6 +1907,7 @@ static void
 end_grace(void)
 {
        dprintk("NFSD: end of grace period\n");
+       nfsd4_recdir_purge_old();
        in_grace = 0;
 }
 
@@ -1932,6 +1937,7 @@ nfs4_laundromat(void)
                }
                dprintk("NFSD: purging unused client (clientid %08x)\n",
                        clp->cl_clientid.cl_id);
+               nfsd4_remove_clid_dir(clp);
                expire_client(clp);
        }
        INIT_LIST_HEAD(&reaplist);
@@ -2320,6 +2326,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
                         stp->st_stateid.si_stateownerid,
                         stp->st_stateid.si_fileid,
                         stp->st_stateid.si_generation);
+
+       nfsd4_create_clid_dir(sop->so_client);
 out:
        if (oc->oc_stateowner)
                nfs4_get_stateowner(oc->oc_stateowner);
@@ -3089,6 +3097,16 @@ alloc_reclaim(void)
        return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
 }
 
+int
+nfs4_has_reclaimed_state(const char *name)
+{
+       unsigned int strhashval = clientstr_hashval(name);
+       struct nfs4_client *clp;
+
+       clp = find_confirmed_client_by_str(name, strhashval);
+       return clp ? 1 : 0;
+}
+
 /*
  * failure => all reset bets are off, nfserr_no_grace...
  */
@@ -3208,8 +3226,10 @@ nfsd4_load_reboot_recovery_data(void)
 {
        int status;
 
-       nfsd4_init_recdir(recovery_dirname);
+       nfs4_lock_state();
+       nfsd4_init_recdir(user_recovery_dirname);
        status = nfsd4_recdir_load();
+       nfs4_unlock_state();
        if (status)
                printk("NFSD: Failure reading reboot recovery data\n");
 }
@@ -3313,6 +3333,35 @@ nfs4_state_shutdown(void)
        nfs4_unlock_state();
 }
 
+static void
+nfs4_set_recdir(char *recdir)
+{
+       nfs4_lock_state();
+       strcpy(user_recovery_dirname, recdir);
+       nfs4_unlock_state();
+}
+
+/*
+ * Change the NFSv4 recovery directory to recdir.
+ */
+int
+nfs4_reset_recoverydir(char *recdir)
+{
+       int status;
+       struct nameidata nd;
+
+       status = path_lookup(recdir, LOOKUP_FOLLOW, &nd);
+       if (status)
+               return status;
+       status = -ENOTDIR;
+       if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
+               nfs4_set_recdir(recdir);
+               status = 0;
+       }
+       path_release(&nd);
+       return status;
+}
+
 /*
  * Called when leasetime is changed.
  *