#include <linux/nfs4.h>
#include <linux/nfsd/state.h>
#include <linux/nfsd/xdr4.h>
+#include <linux/namei.h>
#define NFSDDBG_FACILITY NFSDDBG_PROC
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:
*
conf = find_confirmed_client_by_str(unconf->cl_recdir,
hash);
if (conf) {
+ nfsd4_remove_clid_dir(conf);
expire_client(conf);
}
move_to_confirmed(unconf);
*status = nfserr_reclaim_bad;
else {
open->op_stateowner->so_confirmed = 1;
+ open->op_stateowner->so_client->cl_firststate = 1;
open->op_stateowner->so_seqid--;
}
}
end_grace(void)
{
dprintk("NFSD: end of grace period\n");
+ nfsd4_recdir_purge_old();
in_grace = 0;
}
}
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);
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);
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...
*/
{
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");
}
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.
*