Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 114335
b: refs/heads/master
c: af558e3
h: refs/heads/master
i:
  114333: 7037d70
  114331: a6a2bb7
  114327: a500b36
  114319: 3a92718
  114303: eab0809
v: v3
  • Loading branch information
J. Bruce Fields committed Oct 3, 2008
1 parent 050ec4f commit 356c5fe
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 62 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d5b337b4877f7c4e1d761434ee04d045b0201e03
refs/heads/master: af558e33bedab672f5cfd3260bce7445e353fe21
2 changes: 1 addition & 1 deletion trunk/fs/lockd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
obj-$(CONFIG_LOCKD) += lockd.o

lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \
svcproc.o svcsubs.o mon.o xdr.o
svcproc.o svcsubs.o mon.o xdr.o grace.o
lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o
lockd-objs := $(lockd-objs-y)
59 changes: 59 additions & 0 deletions trunk/fs/lockd/grace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Common code for control of lockd and nfsv4 grace periods.
*/

#include <linux/module.h>
#include <linux/lockd/bind.h>

static LIST_HEAD(grace_list);
static DEFINE_SPINLOCK(grace_lock);

/**
* locks_start_grace
* @lm: who this grace period is for
*
* A grace period is a period during which locks should not be given
* out. Currently grace periods are only enforced by the two lock
* managers (lockd and nfsd), using the locks_in_grace() function to
* check when they are in a grace period.
*
* This function is called to start a grace period.
*/
void locks_start_grace(struct lock_manager *lm)
{
spin_lock(&grace_lock);
list_add(&lm->list, &grace_list);
spin_unlock(&grace_lock);
}
EXPORT_SYMBOL_GPL(locks_start_grace);

/**
* locks_end_grace
* @lm: who this grace period is for
*
* Call this function to state that the given lock manager is ready to
* resume regular locking. The grace period will not end until all lock
* managers that called locks_start_grace() also call locks_end_grace().
* Note that callers count on it being safe to call this more than once,
* and the second call should be a no-op.
*/
void locks_end_grace(struct lock_manager *lm)
{
spin_lock(&grace_lock);
list_del_init(&lm->list);
spin_unlock(&grace_lock);
}
EXPORT_SYMBOL_GPL(locks_end_grace);

/**
* locks_in_grace
*
* Lock managers call this function to determine when it is OK for them
* to answer ordinary lock requests, and when they should accept only
* lock reclaims.
*/
int locks_in_grace(void)
{
return !list_empty(&grace_list);
}
EXPORT_SYMBOL_GPL(locks_in_grace);
20 changes: 5 additions & 15 deletions trunk/fs/lockd/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ static DEFINE_MUTEX(nlmsvc_mutex);
static unsigned int nlmsvc_users;
static struct task_struct *nlmsvc_task;
static struct svc_rqst *nlmsvc_rqst;
int nlmsvc_grace_period;
unsigned long nlmsvc_timeout;

/*
Expand Down Expand Up @@ -85,30 +84,21 @@ static unsigned long get_lockd_grace_period(void)
return nlm_timeout * 5 * HZ;
}

unsigned long get_nfs_grace_period(void)
{
unsigned long lockdgrace = get_lockd_grace_period();
unsigned long nfsdgrace = 0;

if (nlmsvc_ops)
nfsdgrace = nlmsvc_ops->get_grace_period();

return max(lockdgrace, nfsdgrace);
}
EXPORT_SYMBOL(get_nfs_grace_period);
static struct lock_manager lockd_manager = {
};

static void grace_ender(struct work_struct *not_used)
{
nlmsvc_grace_period = 0;
locks_end_grace(&lockd_manager);
}

static DECLARE_DELAYED_WORK(grace_period_end, grace_ender);

static void set_grace_period(void)
{
unsigned long grace_period = get_nfs_grace_period() + jiffies;
unsigned long grace_period = get_lockd_grace_period();

nlmsvc_grace_period = 1;
locks_start_grace(&lockd_manager);
cancel_delayed_work_sync(&grace_period_end);
schedule_delayed_work(&grace_period_end, grace_period);
}
Expand Down
12 changes: 6 additions & 6 deletions trunk/fs/lockd/svc4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept test requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rc;
}
Expand Down Expand Up @@ -123,7 +123,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept new lock requests during grace period */
if (nlmsvc_grace_period && !argp->reclaim) {
if (locks_in_grace() && !argp->reclaim) {
resp->status = nlm_lck_denied_grace_period;
return rc;
}
Expand Down Expand Up @@ -169,7 +169,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down Expand Up @@ -202,7 +202,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept new lock requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down Expand Up @@ -341,7 +341,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept new lock requests during grace period */
if (nlmsvc_grace_period && !argp->reclaim) {
if (locks_in_grace() && !argp->reclaim) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down Expand Up @@ -374,7 +374,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down
12 changes: 6 additions & 6 deletions trunk/fs/lockd/svcproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept test requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rc;
}
Expand Down Expand Up @@ -153,7 +153,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept new lock requests during grace period */
if (nlmsvc_grace_period && !argp->reclaim) {
if (locks_in_grace() && !argp->reclaim) {
resp->status = nlm_lck_denied_grace_period;
return rc;
}
Expand Down Expand Up @@ -199,7 +199,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down Expand Up @@ -232,7 +232,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept new lock requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down Expand Up @@ -373,7 +373,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept new lock requests during grace period */
if (nlmsvc_grace_period && !argp->reclaim) {
if (locks_in_grace() && !argp->reclaim) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down Expand Up @@ -406,7 +406,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
resp->cookie = argp->cookie;

/* Don't accept requests during grace period */
if (nlmsvc_grace_period) {
if (locks_in_grace()) {
resp->status = nlm_lck_denied_grace_period;
return rpc_success;
}
Expand Down
1 change: 0 additions & 1 deletion trunk/fs/nfsd/lockd.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ nlm_fclose(struct file *filp)
static struct nlmsvc_binding nfsd_nlm_ops = {
.fopen = nlm_fopen, /* open file for locking */
.fclose = nlm_fclose, /* close file */
.get_grace_period = get_nfs4_grace_period,
};

void
Expand Down
8 changes: 4 additions & 4 deletions trunk/fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
/* Openowner is now set, so sequence id will get bumped. Now we need
* these checks before we do any creates: */
status = nfserr_grace;
if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
if (locks_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
goto out;
status = nfserr_no_grace;
if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
if (!locks_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
goto out;

switch (open->op_claim_type) {
Expand Down Expand Up @@ -575,7 +575,7 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
{
__be32 status;

if (nfs4_in_grace())
if (locks_in_grace())
return nfserr_grace;
status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
remove->rm_name, remove->rm_namelen);
Expand All @@ -596,7 +596,7 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,

if (!cstate->save_fh.fh_dentry)
return status;
if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags
if (locks_in_grace() && !(cstate->save_fh.fh_export->ex_flags
& NFSEXP_NOSUBTREECHECK))
return nfserr_grace;
status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
Expand Down
34 changes: 15 additions & 19 deletions trunk/fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
static time_t lease_time = 90; /* default lease time */
static time_t user_lease_time = 90;
static time_t boot_time;
static int in_grace = 1;
static u32 current_ownerid = 1;
static u32 current_fileid = 1;
static u32 current_delegid = 1;
Expand Down Expand Up @@ -1640,7 +1639,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
case NFS4_OPEN_CLAIM_NULL:
/* Let's not give out any delegations till everyone's
* had the chance to reclaim theirs.... */
if (nfs4_in_grace())
if (locks_in_grace())
goto out;
if (!atomic_read(&cb->cb_set) || !sop->so_confirmed)
goto out;
Expand Down Expand Up @@ -1816,12 +1815,15 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return status;
}

struct lock_manager nfsd4_manager = {
};

static void
end_grace(void)
nfsd4_end_grace(void)
{
dprintk("NFSD: end of grace period\n");
nfsd4_recdir_purge_old();
in_grace = 0;
locks_end_grace(&nfsd4_manager);
}

static time_t
Expand All @@ -1838,8 +1840,8 @@ nfs4_laundromat(void)
nfs4_lock_state();

dprintk("NFSD: laundromat service - starting\n");
if (in_grace)
end_grace();
if (locks_in_grace())
nfsd4_end_grace();
list_for_each_safe(pos, next, &client_lru) {
clp = list_entry(pos, struct nfs4_client, cl_lru);
if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
Expand Down Expand Up @@ -1974,7 +1976,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
return nfserr_bad_stateid;
else if (ONE_STATEID(stateid) && (flags & RD_STATE))
return nfs_ok;
else if (nfs4_in_grace()) {
else if (locks_in_grace()) {
/* Answer in remaining cases depends on existance of
* conflicting state; so we must wait out the grace period. */
return nfserr_grace;
Expand All @@ -1993,7 +1995,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
static inline int
io_during_grace_disallowed(struct inode *inode, int flags)
{
return nfs4_in_grace() && (flags & (RD_STATE | WR_STATE))
return locks_in_grace() && (flags & (RD_STATE | WR_STATE))
&& mandatory_lock(inode);
}

Expand Down Expand Up @@ -2693,10 +2695,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
filp = lock_stp->st_vfs_file;

status = nfserr_grace;
if (nfs4_in_grace() && !lock->lk_reclaim)
if (locks_in_grace() && !lock->lk_reclaim)
goto out;
status = nfserr_no_grace;
if (!nfs4_in_grace() && lock->lk_reclaim)
if (!locks_in_grace() && lock->lk_reclaim)
goto out;

locks_init_lock(&file_lock);
Expand Down Expand Up @@ -2779,7 +2781,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
int error;
__be32 status;

if (nfs4_in_grace())
if (locks_in_grace())
return nfserr_grace;

if (check_lock_length(lockt->lt_offset, lockt->lt_length))
Expand Down Expand Up @@ -3192,9 +3194,9 @@ __nfs4_state_start(void)
unsigned long grace_time;

boot_time = get_seconds();
grace_time = get_nfs_grace_period();
grace_time = get_nfs4_grace_period();
lease_time = user_lease_time;
in_grace = 1;
locks_start_grace(&nfsd4_manager);
printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
grace_time/HZ);
laundry_wq = create_singlethread_workqueue("nfsd4");
Expand All @@ -3213,12 +3215,6 @@ nfs4_state_start(void)
return;
}

int
nfs4_in_grace(void)
{
return in_grace;
}

time_t
nfs4_lease_time(void)
{
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,14 @@ struct lock_manager_operations {
int (*fl_change)(struct file_lock **, int);
};

struct lock_manager {
struct list_head list;
};

void locks_start_grace(struct lock_manager *);
void locks_end_grace(struct lock_manager *);
int locks_in_grace(void);

/* that will die - we need it for nfs_lock_info */
#include <linux/nfs_fs_i.h>

Expand Down
Loading

0 comments on commit 356c5fe

Please sign in to comment.