Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from torvalds:master #316

Merged
merged 15 commits into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 70 additions & 49 deletions drivers/target/target_core_xcopy.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,60 +46,83 @@ static int target_xcopy_gen_naa_ieee(struct se_device *dev, unsigned char *buf)
return 0;
}

struct xcopy_dev_search_info {
const unsigned char *dev_wwn;
struct se_device *found_dev;
};

/**
* target_xcopy_locate_se_dev_e4_iter - compare XCOPY NAA device identifiers
*
* @se_dev: device being considered for match
* @dev_wwn: XCOPY requested NAA dev_wwn
* @return: 1 on match, 0 on no-match
*/
static int target_xcopy_locate_se_dev_e4_iter(struct se_device *se_dev,
void *data)
const unsigned char *dev_wwn)
{
struct xcopy_dev_search_info *info = data;
unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
int rc;

if (!se_dev->dev_attrib.emulate_3pc)
if (!se_dev->dev_attrib.emulate_3pc) {
pr_debug("XCOPY: emulate_3pc disabled on se_dev %p\n", se_dev);
return 0;
}

memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN);
target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]);

rc = memcmp(&tmp_dev_wwn[0], info->dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN);
if (rc != 0)
return 0;

info->found_dev = se_dev;
pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev);

rc = target_depend_item(&se_dev->dev_group.cg_item);
rc = memcmp(&tmp_dev_wwn[0], dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN);
if (rc != 0) {
pr_err("configfs_depend_item attempt failed: %d for se_dev: %p\n",
rc, se_dev);
return rc;
pr_debug("XCOPY: skip non-matching: %*ph\n",
XCOPY_NAA_IEEE_REGEX_LEN, tmp_dev_wwn);
return 0;
}
pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev);

pr_debug("Called configfs_depend_item for se_dev: %p se_dev->se_dev_group: %p\n",
se_dev, &se_dev->dev_group);
return 1;
}

static int target_xcopy_locate_se_dev_e4(const unsigned char *dev_wwn,
struct se_device **found_dev)
static int target_xcopy_locate_se_dev_e4(struct se_session *sess,
const unsigned char *dev_wwn,
struct se_device **_found_dev,
struct percpu_ref **_found_lun_ref)
{
struct xcopy_dev_search_info info;
int ret;

memset(&info, 0, sizeof(info));
info.dev_wwn = dev_wwn;

ret = target_for_each_device(target_xcopy_locate_se_dev_e4_iter, &info);
if (ret == 1) {
*found_dev = info.found_dev;
return 0;
} else {
pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
return -EINVAL;
struct se_dev_entry *deve;
struct se_node_acl *nacl;
struct se_lun *this_lun = NULL;
struct se_device *found_dev = NULL;

/* cmd with NULL sess indicates no associated $FABRIC_MOD */
if (!sess)
goto err_out;

pr_debug("XCOPY 0xe4: searching for: %*ph\n",
XCOPY_NAA_IEEE_REGEX_LEN, dev_wwn);

nacl = sess->se_node_acl;
rcu_read_lock();
hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
struct se_device *this_dev;
int rc;

this_lun = rcu_dereference(deve->se_lun);
this_dev = rcu_dereference_raw(this_lun->lun_se_dev);

rc = target_xcopy_locate_se_dev_e4_iter(this_dev, dev_wwn);
if (rc) {
if (percpu_ref_tryget_live(&this_lun->lun_ref))
found_dev = this_dev;
break;
}
}
rcu_read_unlock();
if (found_dev == NULL)
goto err_out;

pr_debug("lun_ref held for se_dev: %p se_dev->se_dev_group: %p\n",
found_dev, &found_dev->dev_group);
*_found_dev = found_dev;
*_found_lun_ref = &this_lun->lun_ref;
return 0;
err_out:
pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
return -EINVAL;
}

static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op *xop,
Expand Down Expand Up @@ -246,12 +269,16 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd,

switch (xop->op_origin) {
case XCOL_SOURCE_RECV_OP:
rc = target_xcopy_locate_se_dev_e4(xop->dst_tid_wwn,
&xop->dst_dev);
rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess,
xop->dst_tid_wwn,
&xop->dst_dev,
&xop->remote_lun_ref);
break;
case XCOL_DEST_RECV_OP:
rc = target_xcopy_locate_se_dev_e4(xop->src_tid_wwn,
&xop->src_dev);
rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess,
xop->src_tid_wwn,
&xop->src_dev,
&xop->remote_lun_ref);
break;
default:
pr_err("XCOPY CSCD descriptor IDs not found in CSCD list - "
Expand Down Expand Up @@ -391,18 +418,12 @@ static int xcopy_pt_get_cmd_state(struct se_cmd *se_cmd)

static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop)
{
struct se_device *remote_dev;

if (xop->op_origin == XCOL_SOURCE_RECV_OP)
remote_dev = xop->dst_dev;
pr_debug("putting dst lun_ref for %p\n", xop->dst_dev);
else
remote_dev = xop->src_dev;

pr_debug("Calling configfs_undepend_item for"
" remote_dev: %p remote_dev->dev_group: %p\n",
remote_dev, &remote_dev->dev_group.cg_item);
pr_debug("putting src lun_ref for %p\n", xop->src_dev);

target_undepend_item(&remote_dev->dev_group.cg_item);
percpu_ref_put(xop->remote_lun_ref);
}

static void xcopy_pt_release_cmd(struct se_cmd *se_cmd)
Expand Down
1 change: 1 addition & 0 deletions drivers/target/target_core_xcopy.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct xcopy_op {
struct se_device *dst_dev;
unsigned char dst_tid_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
unsigned char local_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN];
struct percpu_ref *remote_lun_ref;

sector_t src_lba;
sector_t dst_lba;
Expand Down
12 changes: 7 additions & 5 deletions fs/nfs/delegation.c
Original file line number Diff line number Diff line change
Expand Up @@ -1011,22 +1011,24 @@ nfs_delegation_find_inode_server(struct nfs_server *server,
const struct nfs_fh *fhandle)
{
struct nfs_delegation *delegation;
struct inode *freeme, *res = NULL;
struct super_block *freeme = NULL;
struct inode *res = NULL;

list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
spin_lock(&delegation->lock);
if (delegation->inode != NULL &&
!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
freeme = igrab(delegation->inode);
if (freeme && nfs_sb_active(freeme->i_sb))
res = freeme;
if (nfs_sb_active(server->super)) {
freeme = server->super;
res = igrab(delegation->inode);
}
spin_unlock(&delegation->lock);
if (res != NULL)
return res;
if (freeme) {
rcu_read_unlock();
iput(freeme);
nfs_sb_deactive(freeme);
rcu_read_lock();
}
return ERR_PTR(-EAGAIN);
Expand Down
38 changes: 30 additions & 8 deletions fs/nfs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,29 @@ struct nfs_fs_context {
} clone_data;
};

#define nfs_errorf(fc, fmt, ...) errorf(fc, fmt, ## __VA_ARGS__)
#define nfs_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__)
#define nfs_warnf(fc, fmt, ...) warnf(fc, fmt, ## __VA_ARGS__)
#define nfs_errorf(fc, fmt, ...) ((fc)->log.log ? \
errorf(fc, fmt, ## __VA_ARGS__) : \
({ dprintk(fmt "\n", ## __VA_ARGS__); }))

#define nfs_ferrorf(fc, fac, fmt, ...) ((fc)->log.log ? \
errorf(fc, fmt, ## __VA_ARGS__) : \
({ dfprintk(fac, fmt "\n", ## __VA_ARGS__); }))

#define nfs_invalf(fc, fmt, ...) ((fc)->log.log ? \
invalf(fc, fmt, ## __VA_ARGS__) : \
({ dprintk(fmt "\n", ## __VA_ARGS__); -EINVAL; }))

#define nfs_finvalf(fc, fac, fmt, ...) ((fc)->log.log ? \
invalf(fc, fmt, ## __VA_ARGS__) : \
({ dfprintk(fac, fmt "\n", ## __VA_ARGS__); -EINVAL; }))

#define nfs_warnf(fc, fmt, ...) ((fc)->log.log ? \
warnf(fc, fmt, ## __VA_ARGS__) : \
({ dprintk(fmt "\n", ## __VA_ARGS__); }))

#define nfs_fwarnf(fc, fac, fmt, ...) ((fc)->log.log ? \
warnf(fc, fmt, ## __VA_ARGS__) : \
({ dfprintk(fac, fmt "\n", ## __VA_ARGS__); }))

static inline struct nfs_fs_context *nfs_fc2context(const struct fs_context *fc)
{
Expand Down Expand Up @@ -579,12 +599,14 @@ extern void nfs4_test_session_trunk(struct rpc_clnt *clnt,

static inline struct inode *nfs_igrab_and_active(struct inode *inode)
{
inode = igrab(inode);
if (inode != NULL && !nfs_sb_active(inode->i_sb)) {
iput(inode);
inode = NULL;
struct super_block *sb = inode->i_sb;

if (sb && nfs_sb_active(sb)) {
if (igrab(inode))
return inode;
nfs_sb_deactive(sb);
}
return inode;
return NULL;
}

static inline void nfs_iput_and_deactive(struct inode *inode)
Expand Down
28 changes: 11 additions & 17 deletions fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3536,10 +3536,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);

/* Handle Layoutreturn errors */
if (pnfs_roc_done(task, calldata->inode,
&calldata->arg.lr_args,
&calldata->res.lr_res,
&calldata->res.lr_ret) == -EAGAIN)
if (pnfs_roc_done(task, &calldata->arg.lr_args, &calldata->res.lr_res,
&calldata->res.lr_ret) == -EAGAIN)
goto out_restart;

/* hmm. we are done with the inode, and in the process of freeing
Expand Down Expand Up @@ -6384,10 +6382,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);

/* Handle Layoutreturn errors */
if (pnfs_roc_done(task, data->inode,
&data->args.lr_args,
&data->res.lr_res,
&data->res.lr_ret) == -EAGAIN)
if (pnfs_roc_done(task, &data->args.lr_args, &data->res.lr_res,
&data->res.lr_ret) == -EAGAIN)
goto out_restart;

switch (task->tk_status) {
Expand Down Expand Up @@ -6441,10 +6437,10 @@ static void nfs4_delegreturn_release(void *calldata)
struct nfs4_delegreturndata *data = calldata;
struct inode *inode = data->inode;

if (data->lr.roc)
pnfs_roc_release(&data->lr.arg, &data->lr.res,
data->res.lr_ret);
if (inode) {
if (data->lr.roc)
pnfs_roc_release(&data->lr.arg, &data->lr.res,
data->res.lr_ret);
nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
nfs_iput_and_deactive(inode);
}
Expand Down Expand Up @@ -6520,16 +6516,14 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
nfs_fattr_init(data->res.fattr);
data->timestamp = jiffies;
data->rpc_status = 0;
data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res, cred);
data->inode = nfs_igrab_and_active(inode);
if (data->inode) {
if (data->inode || issync) {
data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res,
cred);
if (data->lr.roc) {
data->args.lr_args = &data->lr.arg;
data->res.lr_res = &data->lr.res;
}
} else if (data->lr.roc) {
pnfs_roc_release(&data->lr.arg, &data->lr.res, 0);
data->lr.roc = false;
}

task_setup_data.callback_data = data;
Expand Down Expand Up @@ -7111,9 +7105,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
data->arg.new_lock_owner, ret);
} else
data->cancelled = true;
trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret);
rpc_put_task(task);
dprintk("%s: done, ret = %d!\n", __func__, ret);
trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret);
return ret;
}

Expand Down
4 changes: 2 additions & 2 deletions fs/nfs/nfs4super.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ int nfs4_try_get_tree(struct fs_context *fc)
fc, ctx->nfs_server.hostname,
ctx->nfs_server.export_path);
if (err) {
nfs_errorf(fc, "NFS4: Couldn't follow remote path");
nfs_ferrorf(fc, MOUNT, "NFS4: Couldn't follow remote path");
dfprintk(MOUNT, "<-- nfs4_try_get_tree() = %d [error]\n", err);
} else {
dfprintk(MOUNT, "<-- nfs4_try_get_tree() = 0\n");
Expand All @@ -250,7 +250,7 @@ int nfs4_get_referral_tree(struct fs_context *fc)
fc, ctx->nfs_server.hostname,
ctx->nfs_server.export_path);
if (err) {
nfs_errorf(fc, "NFS4: Couldn't follow remote path");
nfs_ferrorf(fc, MOUNT, "NFS4: Couldn't follow remote path");
dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = %d [error]\n", err);
} else {
dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = 0\n");
Expand Down
Loading