/* * Get an active reference of @ses so that next call to cifs_put_tcon() won't * release it as any new DFS referrals must go through its IPC tcon.
*/ staticvoid set_root_smb_session(struct cifs_mount_ctx *mnt_ctx)
{ struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; struct cifs_ses *ses = mnt_ctx->ses;
origin_fullpath = dfs_get_path(cifs_sb, ctx->source); if (IS_ERR(origin_fullpath)) return PTR_ERR(origin_fullpath);
rc = dfs_referral_walk(mnt_ctx, &rw); if (!rc) { /* * Prevent superblock from being created with any missing * connections.
*/ if (WARN_ON(!mnt_ctx->server))
rc = -EHOSTDOWN; elseif (WARN_ON(!mnt_ctx->ses))
rc = -EACCES; elseif (WARN_ON(!mnt_ctx->tcon))
rc = -ENOENT;
} if (rc) goto out;
/* * If @ctx->dfs_automount, then update @ctx->dstaddr earlier with the DFS root * server from where we'll start following any referrals. Otherwise rely on the * value provided by mount(2) as the user might not have dns_resolver key set up * and therefore failing to upcall to resolve UNC hostname under @ctx->source.
*/ staticint update_fs_context_dstaddr(struct smb3_fs_context *ctx)
{ struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr; int rc = 0;
int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
{ struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; bool nodfs = ctx->nodfs; int rc;
rc = update_fs_context_dstaddr(ctx); if (rc) return rc;
rc = get_session(mnt_ctx, NULL); if (rc) return rc;
/* * If called with 'nodfs' mount option, then skip DFS resolving. Otherwise unconditionally * try to get an DFS referral (even cached) to determine whether it is an DFS mount. * * Skip prefix path to provide support for DFS referrals from w2k8 servers which don't seem * to respond with PATH_NOT_COVERED to requests that include the prefix.
*/ if (!nodfs) {
rc = dfs_get_referral(mnt_ctx, ctx->UNC + 1, NULL); if (rc) {
cifs_dbg(FYI, "%s: no dfs referral for %s: %d\n",
__func__, ctx->UNC + 1, rc);
cifs_dbg(FYI, "%s: assuming non-dfs mount...\n", __func__);
nodfs = true;
}
} if (nodfs) {
rc = cifs_mount_get_tcon(mnt_ctx); if (!rc)
rc = cifs_is_path_remote(mnt_ctx); return rc;
}
if (!ctx->dfs_conn) {
ctx->dfs_conn = true;
cifs_mount_put_conns(mnt_ctx);
rc = get_session(mnt_ctx, NULL);
} if (!rc)
rc = __dfs_mount_share(mnt_ctx); return rc;
}
sb = cifs_get_dfs_tcon_super(tcon); if (!IS_ERR(sb))
cifs_sb = CIFS_SB(sb);
/* Tree connect to last share in @tcon->tree_name if no DFS referral */ if (!server->leaf_fullpath ||
dfs_cache_noreq_find(server->leaf_fullpath + 1, &ref, &tl)) {
rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name,
tcon, tcon->ses->local_nls); goto out;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.