mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
NFSv4.1 cache mdsthreshold values on OPEN
Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
88034c3d88
commit
82be417aa3
@ -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);
|
nfs_init_lock_context(&ctx->lock_context);
|
||||||
ctx->lock_context.open_context = ctx;
|
ctx->lock_context.open_context = ctx;
|
||||||
INIT_LIST_HEAD(&ctx->list);
|
INIT_LIST_HEAD(&ctx->list);
|
||||||
|
ctx->mdsthreshold = NULL;
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -669,6 +670,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
|
|||||||
put_rpccred(ctx->cred);
|
put_rpccred(ctx->cred);
|
||||||
dput(ctx->dentry);
|
dput(ctx->dentry);
|
||||||
nfs_sb_deactive(sb);
|
nfs_sb_deactive(sb);
|
||||||
|
kfree(ctx->mdsthreshold);
|
||||||
kfree(ctx);
|
kfree(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1782,7 +1782,14 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
|
|||||||
/*
|
/*
|
||||||
* Returns a referenced nfs4_state
|
* 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_owner *sp;
|
||||||
struct nfs4_state *state = NULL;
|
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)
|
if (opendata == NULL)
|
||||||
goto err_put_state_owner;
|
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)
|
if (dentry->d_inode != NULL)
|
||||||
opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
|
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_setattr_update_inode(state->inode, sattr);
|
||||||
nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr);
|
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_opendata_put(opendata);
|
||||||
nfs4_put_state_owner(sp);
|
nfs4_put_state_owner(sp);
|
||||||
*res = state;
|
*res = state;
|
||||||
return 0;
|
return 0;
|
||||||
err_opendata_put:
|
err_opendata_put:
|
||||||
|
kfree(opendata->f_attr.mdsthreshold);
|
||||||
nfs4_opendata_put(opendata);
|
nfs4_opendata_put(opendata);
|
||||||
err_put_state_owner:
|
err_put_state_owner:
|
||||||
nfs4_put_state_owner(sp);
|
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_exception exception = { };
|
||||||
struct nfs4_state *res;
|
struct nfs4_state *res;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
do {
|
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)
|
if (status == 0)
|
||||||
break;
|
break;
|
||||||
/* NOTE: BAD_SEQID means the server and client disagree about the
|
/* 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;
|
struct nfs4_state *state;
|
||||||
|
|
||||||
/* Protect against concurrent sillydeletes */
|
/* 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))
|
if (IS_ERR(state))
|
||||||
return ERR_CAST(state);
|
return ERR_CAST(state);
|
||||||
ctx->state = state;
|
ctx->state = state;
|
||||||
@ -2779,7 +2807,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
|||||||
fmode = ctx->mode;
|
fmode = ctx->mode;
|
||||||
}
|
}
|
||||||
sattr->ia_mode &= ~current_umask();
|
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);
|
d_drop(dentry);
|
||||||
if (IS_ERR(state)) {
|
if (IS_ERR(state)) {
|
||||||
status = PTR_ERR(state);
|
status = PTR_ERR(state);
|
||||||
|
@ -1630,3 +1630,15 @@ out_free:
|
|||||||
kfree(data);
|
kfree(data);
|
||||||
goto out;
|
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;
|
||||||
|
}
|
||||||
|
@ -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);
|
const struct nfs_pgio_completion_ops *compl_ops);
|
||||||
int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head,
|
int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head,
|
||||||
const struct nfs_pgio_completion_ops *compl_ops);
|
const struct nfs_pgio_completion_ops *compl_ops);
|
||||||
|
struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
|
||||||
|
|
||||||
/* nfs4_deviceid_flags */
|
/* nfs4_deviceid_flags */
|
||||||
enum {
|
enum {
|
||||||
@ -360,6 +361,14 @@ static inline int pnfs_return_layout(struct inode *ino)
|
|||||||
return 0;
|
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
|
#ifdef NFS_DEBUG
|
||||||
void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
|
void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
|
||||||
#else
|
#else
|
||||||
@ -485,6 +494,18 @@ static inline int pnfs_layoutcommit_inode(struct inode *inode, bool sync)
|
|||||||
return 0;
|
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 /* CONFIG_NFS_V4_1 */
|
||||||
|
|
||||||
#endif /* FS_NFS_PNFS_H */
|
#endif /* FS_NFS_PNFS_H */
|
||||||
|
@ -102,6 +102,7 @@ struct nfs_open_context {
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct nfs4_threshold *mdsthreshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfs_open_dir_context {
|
struct nfs_open_dir_context {
|
||||||
|
Loading…
Reference in New Issue
Block a user