Commit 82be417a authored by Andy Adamson's avatar Andy Adamson Committed by Trond Myklebust
Browse files

NFSv4.1 cache mdsthreshold values on OPEN

parent 88034c3d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -641,6 +641,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f
	nfs_init_lock_context(&ctx->lock_context);
	ctx->lock_context.open_context = ctx;
	INIT_LIST_HEAD(&ctx->list);
	ctx->mdsthreshold = NULL;
	return ctx;
}

@@ -669,6 +670,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
		put_rpccred(ctx->cred);
	dput(ctx->dentry);
	nfs_sb_deactive(sb);
	kfree(ctx->mdsthreshold);
	kfree(ctx);
}

+33 −5
Original line number Diff line number Diff line
@@ -1782,7 +1782,14 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
/*
 * Returns a referenced nfs4_state
 */
static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
static int _nfs4_do_open(struct inode *dir,
			struct dentry *dentry,
			fmode_t fmode,
			int flags,
			struct iattr *sattr,
			struct rpc_cred *cred,
			struct nfs4_state **res,
			struct nfs4_threshold **ctx_th)
{
	struct nfs4_state_owner  *sp;
	struct nfs4_state     *state = NULL;
@@ -1807,6 +1814,11 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode
	if (opendata == NULL)
		goto err_put_state_owner;

	if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
		opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
		if (!opendata->f_attr.mdsthreshold)
			goto err_opendata_put;
	}
	if (dentry->d_inode != NULL)
		opendata->state = nfs4_get_open_state(dentry->d_inode, sp);

@@ -1832,11 +1844,19 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode
			nfs_setattr_update_inode(state->inode, sattr);
		nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr);
	}

	if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server))
		*ctx_th = opendata->f_attr.mdsthreshold;
	else
		kfree(opendata->f_attr.mdsthreshold);
	opendata->f_attr.mdsthreshold = NULL;

	nfs4_opendata_put(opendata);
	nfs4_put_state_owner(sp);
	*res = state;
	return 0;
err_opendata_put:
	kfree(opendata->f_attr.mdsthreshold);
	nfs4_opendata_put(opendata);
err_put_state_owner:
	nfs4_put_state_owner(sp);
@@ -1846,14 +1866,21 @@ out_err:
}


static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred)
static struct nfs4_state *nfs4_do_open(struct inode *dir,
					struct dentry *dentry,
					fmode_t fmode,
					int flags,
					struct iattr *sattr,
					struct rpc_cred *cred,
					struct nfs4_threshold **ctx_th)
{
	struct nfs4_exception exception = { };
	struct nfs4_state *res;
	int status;

	do {
		status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, &res);
		status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
				       &res, ctx_th);
		if (status == 0)
			break;
		/* NOTE: BAD_SEQID means the server and client disagree about the
@@ -2177,7 +2204,8 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags
	struct nfs4_state *state;

	/* Protect against concurrent sillydeletes */
	state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, ctx->cred);
	state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr,
			     ctx->cred, &ctx->mdsthreshold);
	if (IS_ERR(state))
		return ERR_CAST(state);
	ctx->state = state;
@@ -2779,7 +2807,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
		fmode = ctx->mode;
	}
	sattr->ia_mode &= ~current_umask();
	state = nfs4_do_open(dir, de, fmode, flags, sattr, cred);
	state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, NULL);
	d_drop(dentry);
	if (IS_ERR(state)) {
		status = PTR_ERR(state);
+12 −0
Original line number Diff line number Diff line
@@ -1630,3 +1630,15 @@ out_free:
	kfree(data);
	goto out;
}

struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
{
	struct nfs4_threshold *thp;

	thp = kzalloc(sizeof(*thp), GFP_NOFS);
	if (!thp) {
		dprintk("%s mdsthreshold allocation failed\n", __func__);
		return NULL;
	}
	return thp;
}
+21 −0
Original line number Diff line number Diff line
@@ -227,6 +227,7 @@ int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head,
			const struct nfs_pgio_completion_ops *compl_ops);
int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head,
			const struct nfs_pgio_completion_ops *compl_ops);
struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);

/* nfs4_deviceid_flags */
enum {
@@ -360,6 +361,14 @@ static inline int pnfs_return_layout(struct inode *ino)
	return 0;
}

static inline bool
pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
		   struct nfs_server *nfss)
{
	return (dst && src && src->bm != 0 &&
					nfss->pnfs_curr_ld->id == src->l_type);
}

#ifdef NFS_DEBUG
void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
#else
@@ -485,6 +494,18 @@ static inline int pnfs_layoutcommit_inode(struct inode *inode, bool sync)
	return 0;
}

static inline bool
pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
		   struct nfs_server *nfss)
{
	return false;
}

static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
{
	return NULL;
}

#endif /* CONFIG_NFS_V4_1 */

#endif /* FS_NFS_PNFS_H */
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ struct nfs_open_context {
	int error;

	struct list_head list;
	struct nfs4_threshold	*mdsthreshold;
};

struct nfs_open_dir_context {